STDIN/STDOUT auf Socket binden bei Multiclient-Server



  • Hallo zusammen,

    das hier ist mein erster Beitrag hier weil ich mit Google und Co kein richtiges/passendes Ergebnis gefunden habe.

    Ich schreibe zur Zeit an einer Remoteshell a la NetCat oder SSH aber habe Probleme damit die STDIN und STDOUT Handles an das Socket zu binden. Ich habe gelesen dass es mit dup2 oder über STARTUPINFORMATION gehen soll. Jedoch haben die Beispiele die ich gefunden habe "das Problem" dass sie nur mit einem socket funktionieren ich hingegen habe aber einen Multiclient Server. Lange Rede kurzer Sinn hier ist der Source mit dem es nicht so recht klappen will.

    Der Teil um den es geht ist ab dem Kommentar RemoteShell zu finden. Meine (unvollständigen) versuche habe ich auskommentiert.

    Ich hoffe hier weiss jemand wie es richtig funktioniert.

    //#define WIN32_LEAN_AND_MEAN
    #define WINVER 0x0500
    
    #include "..\socket.h"
    #include "redirect.h"
    #include <iostream>
    #include <cstring>
    #include <string.h>
    #include <process.h>
    #include <windows.h>
    #include <winsock2.h>
    #include <fstream>
    #include <unistd.h>
    
    using namespace std;
    
    int main( int argc, char *argv[] ) {
        int i, ready, sock_max, max = -1;
        int client_sock[FD_SETSIZE];
        fd_set gesamt_sock, lese_sock;
    
        try {
            Socket sock1, sock2, sock3,sock4;
            sock1.create();
            sock1.bind(15000);
            sock1.listen();
            sock_max = sock1.get_m_sock();
            for( i=0; i<FD_SETSIZE; i++) {
                client_sock[i] = -1;
            }
            FD_ZERO( &gesamt_sock );
            FD_SET( sock1.get_m_sock(), &gesamt_sock );
            while(1) {
                //aktuallisiere bei jedem event
                lese_sock = gesamt_sock;
                //auf neue verbindungen warten
                ready = select( sock_max+1, &lese_sock, NULL, NULL, NULL );
                //Neuer Client?
                if( FD_ISSET(sock1.get_m_sock(), &lese_sock)) {
                        sock1.accept( sock2 );
    
                    //Speicher für neuen Client freigeben
                    for( i=0; i<FD_SETSIZE; i++ ) {
                            if( client_sock[i] < 0 ) {
                                client_sock[i] = sock2.get_m_sock();
                                break;
                            }
                    }
                    //Max. clients sind FD_SETSIZE
                    if ( i == FD_SETSIZE ) {
                        throw SockExcept( "Max. Clients erreicht" );
                    }
                    //Neuen Socket zur gesamtsocketmenge hinzufügen
                    FD_SET( sock2.get_m_sock(), &gesamt_sock );
                    //select die höchste socket nr übergeben
                    if ( sock2.get_m_sock() > sock_max ) {
                        sock_max = sock2.get_m_sock();
                    }
                    //gesamt anzahl an socket nr für anzahl an lese-sikriptoren benötigt
                    if ( i > max ) {
                        max = i;
                    }
                    if ( --ready <= 0 ) {
                        continue;
                    }
                } //schliesse if( FD_ISSET...
    
                //auf neue verbindungen von clients warten und
                //lese-diskriptoren bereitstellen
                for (i=0; i<=max; i++) {
                    string s,client;
                    char clientbuf[5];
    
                    sock3.set_m_sock( client_sock[i] );
    
                    if ( ( sock3.get_m_sock() ) < 0 ) {
                        continue;
                    }
                    if( FD_ISSET( sock3.get_m_sock(), &lese_sock ) ) {
                        //ankommende daten lesen
                        sock3.recv(s);
    
                        //authentifizierung der clients
                        if( s == "HI" ) {
                            sock3.send("Willkommen!!");
                        }
    
                        //ausgabe der client-nachricht am server
                        cout << "nachricht: " << s << endl;
                        cout.flush();
    
                        //antwort des servers an alle
                        sock3.send("Nachricht " + s + " erhalten");
    
                        //befehle die der server interpretieren soll
                        //da switch-case keine strings kann mit if..
                        //lösbar mit lookup-table?? int -> string
                        if ( s == "quit" ) {
                            sock3.close();
                            //aus der socket menge entfernen
                            FD_CLR( sock3.get_m_sock(), &gesamt_sock );
                            //ausgabe auf dem server
                            cout << "Client" << client_sock[i] << " hat verbindung beendet" << endl;
    
                            //client socket schliessen indem index auf -1 gestzt wird
                            client_sock[i] = -1;
                        }
    
                       // RemoteShell
                        if ( s == "shell" ) {
                            sock3.send("Starte Remote Shell...");
    
                            PROCESS_INFORMATION pi;
                            STARTUPINFO si;
                            SECURITY_ATTRIBUTES sa;
                            DWORD pc;
    
                            SetConsoleTitle("!!!!new!!!!");
                            //HWND hwndFound;
                            HWND hWnd = GetConsoleWindow();
                            //ShowWindow( hWnd, SW_HIDE );
                            //hwndFound=FindWindow(NULL, "!!!!");
                            HINSTANCE hInstC = GetModuleHandle( 0 );
    
                            memset( &si, 0, sizeof( si ) );
                            si.cb = sizeof( si );
                              sock3.send("vars gesetzt");
    
    //                      si.wShowWindow = SW_HIDE;
                            si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
    
    //                        if ( dup2(client_sock[i], STDIN_FILENO) < 0 ) { sock3.send("FEHLER STDIN HANDLE "); }
    //                        if ( dup2(client_sock[i], STDOUT_FILENO) < 0 ) { cout << "FEHLER STDOUT HANDLE " << endl; }
    //                        if ( dup2(client_sock[i], STDERR_FILENO) < 0 ) { cout << "FEHLER STDERR HANDLE " << endl; }
    
                          //si.hStdInput = (HANDLE)
    //                      si.hStdOutput = HANDLE)client_sock[i];
    //                      si.hStdError = (HANDLE)client_sock[i];
    
                            //si.hStdInput = si.hStdOutput = si.hStdError = (void*)sock3.get_m_sock();
    
                        CreateProcess( NULL, "cmd.exe", NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);
    
                       //sock3.send(hStdOut);
                       //sock3.send(si.hStdOutput);
    
                        WaitForSingleObject( pi.hProcess, INFINITE );
                        //GetExitCodeProcess( pi.hProcess, &pc );
    
                            CloseHandle( pi.hProcess );
                            CloseHandle( pi.hThread );
                        }
    
                        //Noch Clients/ lese-diskriptoren vorhanden?
                        if ( --ready <= 0 ) {
                            break;
                        }
                    } //schliesse if( FD_ISSET( sock3 ...
    
                } //schliesse for (i=0 ...
    
            } //schliesse while(1) ...
    
        } //schliesse try { ...
            //Esception fangen
            catch ( SockExcept& e ) {
                cout << "!!Fehler: " << e.get_SockExcept() << endl;
            }
    
            return 0;
    }
    

    Ich hoffe ich habe mit meinem ersten Post auch gleich das richtige Unterforum getroffen.

    Viele Grüße,

    Ravenmaster



  • Wolf-Alarm!



  • Jetzt nachdem wir wissen dass es aus dem Buch ist, kann mir jemand bei dem Problem helfen?


Anmelden zum Antworten