PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [C++] Remote Konsole



Arktus
14.12.2011, 17:28
Hey,

ich bin momentan dabei, ein Programm zu schreiben, dass zu einem bestimmten Zeitpunkt einen Port öffnet und das nach Senden eines Passworts eine Konsole "bereitstellt".

Folgendes Problem:

Das obengenannte Programm läuft auf einem Server, ich connecte auf den Port. Jetzt möchte ich Befehle direkt an die Konsole schicken.
Nur wie mache ich das genau? Soll ich erst mit CreateProcess() die cmd öfffnen? Und wie leite ich die Eingaben dann an die Konsole weiter und wie schicke ich die "Antwort" der Konsole an den Clienten zurück?

Wäre schick wenn mir jmd. ein paar Denkanstöße geben könnte. :-)

Barbers
14.12.2011, 17:39
ist es ne windows oder ne linux installation aufm dem server?
wobei in beiden fällen helfen könnte die cmd.exe oder die jeweilige bash zu starten als prozess

Arktus
14.12.2011, 17:42
Erstmal nur für Windows, später kann man das immer noch auf Linux umschreiben.
Ja das starten ist ja kein Problem, aber meine Server-Anwendung nimmt dann die Befehle des Clienten entgegen und muss diese Befehle irgendwie an die Konsole weiterleiten und die Ausgabe der Konsole an den Clienten zurückschicken.

Ich hab leider keine Ahnung wie das geht, eventuell über Pipes, aber da hab ich nicht wirklich Ahnung von. :P

ocz
14.12.2011, 17:52
pipes, siehe msdn

Bonkers
14.12.2011, 18:01
Hab das gerade gefunden und leicht modifiziert.
Grundlegend funktioniert das, ist aber noch buggy.



#include <windows.h>
#include <stdio.h>

#define MAX_BUFFER_SIZE 512

int EmulateCommandPrompt(LPSTR cmdline)
{
STARTUPINFO sti = { 0 };
SECURITY_ATTRIBUTES sats = { 0 };
PROCESS_INFORMATION pi = { 0 };
HANDLE pipin_w, pipin_r, pipout_w, pipout_r;
BYTE buffer[MAX_BUFFER_SIZE];
DWORD writ, excode, read, available;
int ret = 0;

pipin_w = pipin_r = pipout_w = pipout_r = NULL;

for(;;)
{
//set SECURITY_ATTRIBUTES struct fields
sats.nLength = sizeof(sats);
sats.bInheritHandle = TRUE;
sats.lpSecurityDescriptor = NULL;

//create child's stdout pipes
if(!CreatePipe(&pipout_r, &pipout_w, &sats, 0)) break;
//and its stdin pipes
if(!CreatePipe(&pipin_r, &pipin_w, &sats, 0)) break;
printf("Created pipes\n");

//now set STARTUPINFO struct fields (from the child's point of view)
sti.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
sti.wShowWindow = SW_HIDE;
sti.hStdInput = pipin_r;
sti.hStdOutput = pipout_w;
sti.hStdError = pipout_w;

//create the process...
if(!CreateProcess(NULL, "cmd.exe", NULL, NULL, TRUE,
0, NULL, NULL, &sti, &pi)) break;
printf("Created process (%s)\n", cmdline);

//now have a continuous loop to get and recieve info
for(;;)
{
//make sure process is still running
GetExitCodeProcess(pi.hProcess, &excode);
if(excode != STILL_ACTIVE) break;
//printf("Process still running\n");

//give it time to set up/react
Sleep(50);

//now check to see if process has anything to say
if(!PeekNamedPipe(pipout_r, buffer,
sizeof(buffer), &read, &available, NULL)) ret = 10;
//printf("Peeked\n");

//is there anything to be read in the pipe?
if(read)
{
do
{
ZeroMemory(buffer, sizeof(buffer));
//read it and print to stdout
if(!ReadFile(pipout_r, buffer, sizeof(buffer), &read, NULL) || !read) ret = 7;
buffer[read] = 0;
fprintf(stdout, "%s", buffer);
if(ret) break;
}
while(read >= sizeof(buffer));
}

//make sure we didn't run into any errors
if(!ret)
{
//get info and write it to pipe
ZeroMemory(buffer, sizeof(buffer));
fgets(buffer, sizeof(buffer), stdin);
if(!strnicmp(buffer, "exit", 4)) ret = 12;
if(!WriteFile(pipin_w, buffer, strlen(buffer), &writ, NULL)) ret = 8;
}
if(ret) break;
}

break;
}

//clean up any unfinished business
if(pipin_w != NULL) CloseHandle(pipin_w);
if(pipin_r != NULL) CloseHandle(pipin_r);
if(pipout_w != NULL) CloseHandle(pipout_w);
if(pipout_r != NULL) CloseHandle(pipout_r);
if(pi.hProcess != NULL) CloseHandle(pi.hProcess);
if(pi.hThread != NULL) CloseHandle(pi.hThread);

return ret;
}

int main(int argc, char *argv[])
{
EmulateCommandPrompt(NULL);

return 0;
}

ocz
14.12.2011, 18:05
Das mit dem Boundary Checking lernen wir aber nochmal, ja?

Bonkers
14.12.2011, 18:06
Wie gesagt, hab das gefunden und nur zwei kleine Änderungen gemacht.
Es funktioniert so weit, das reichte mir gerade.

IRET
14.12.2011, 20:20
Ich glaub du willst was lernen (wenn nicht, dann musst du).
Hier für Linux und Windows ein Tutorial: www.andreadrian.de/remsh/index.html

blackberry
14.12.2011, 20:21
Kleiner Tipp nebenbei: kein vernünftiger Mensch spawnt auf Windows eine Shell. Da hast du schon ein von dir geschriebenes Programm mit potentiell allen Möglichkeiten auf dem Server laufen und schießt dir absichtlich ins Bein, damit du den Server auf Krücken übernehmen kannst.

G36KV
14.12.2011, 21:02
kein vernünftiger Mensch spawnt auf Windows eine Shell.
Das hab ich früher permanent gemacht. Sowas braucht man z.B. in der FXP Scene wenn man Server übernehmen möchte.

Das bringt dich auf die Spur für Windows ohne Pipe:
STARTF_USESTDHANDLES + CreateProcess

MSDN lesen und mit diesen Stichwörtern findest du viele Reverse/Connect Shell Beispiele.