elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Guía rápida para descarga de herramientas gratuitas de seguridad y desinfección


  Mostrar Mensajes
Páginas: 1 2 3 4 5 6 7 8 [9] 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 ... 28
81  Programación / Programación C/C++ / Pattern Scanner en: 6 Marzo 2011, 09:56 am
Un Pattern Scanner es una función capaz de "encontrar" algo que nos interesa en un módulo externo (puede utilizarse incluso sobre otro proceso aunque ya es más complicado) sin importar la versión de ese módulo (dll,exe,etc.), la única condición para que nuestro Pattern Scanner funcione es que lo que tomamos de referencia no varíe en las distintas versiones de dicho módulo.

Lo primero que se debe hacer es definir que se quiere obtener (esto puede ser una variable o función de dicho módulo del cual no se tengan referencias para llegar), para hacerlo se puede hacer uso de ingeniería inversa (o sea, desensamblar el módulo).

Veamos un ejemplo (en nuestro propio módulo con el fin de visualizarlo): creamos un simple programa con una sola función:

Código
  1. #include <windows.h>
  2.  
  3. char titulo[]="titulo";
  4. char mensaje[]="un mensaje";
  5.  
  6. void funcionascanear(void){
  7.  MessageBox(0,mensaje,titulo,0);
  8. }
  9.  
  10. int main(void){
  11.  funcionascanear();
  12.  return 0;
  13. }

abrimos nuestro programa con ollydbg y buscamos nuestra función:

Código
  1. 004012D0  /$  55                 PUSH    EBP
  2. 004012D1  |.  89E5               MOV     EBP, ESP
  3. 004012D3  |.  83EC 18            SUB     ESP, 18
  4. 004012D6  |.  C74424 0C 00000000 MOV     DWORD PTR SS:[ESP+C], 0          ; |
  5. 004012DE  |.  C74424 08 00204000 MOV     DWORD PTR SS:[ESP+8], generico.0>; |ASCII "titulo"
  6. 004012E6  |.  C74424 04 07204000 MOV     DWORD PTR SS:[ESP+4], generico.0>; |ASCII "un mensaje"
  7. 004012EE  |.  C70424 00000000    MOV     DWORD PTR SS:[ESP], 0            ; |
  8. 004012F5  |.  E8 86080000        CALL    <JMP.&USER32.MessageBoxA>        ; \MessageBoxA
  9. 004012FA  |.  83EC 10            SUB     ESP, 10
  10. 004012FD  |.  C9                 LEAVE
  11. 004012FE  \.  C3                 RETN

en base a este código ASM crearemos un "patron" que nos lleve a dicha función (nuestro objetivo en este caso será modificar el mensaje)

Citar
55                            PUSH    EBP
89E5                         MOV     EBP, ESP
83EC 18                    SUB     ESP, 18
C74424 0C 00000000 MOV     DWORD PTR SS:[ESP+C], 0          ; |
C74424 08 00204000 MOV     DWORD PTR SS:[ESP+8], generico.0>; |ASCII "titulo"
C74424 04 07204000 MOV     DWORD PTR SS:[ESP+4], generico.0>; |ASCII "un mensaje"
C70424 00000000      MOV     DWORD PTR SS:[ESP], 0            ; |
E8 86080000             CALL    <JMP.&USER32.MessageBoxA>        ; \MessageBoxA
83EC 10                    SUB     ESP, 10
C9                            LEAVE
C3                            RETN

lo que está en rojo será nuestro patrón (se lo puede complicar más, y es preferible, pero para nuestro ejemplo servirá), por lo tanto generamos una función que lo detecte:

Código
  1. char *findmsgbypattern(){
  2.  unsigned char *p;
  3.  //dirección inicio / fin del escaneo
  4.  for(p=0x00401000;p<0x00401FFF;p++){
  5.    //nuestro patron
  6.    if(p[0]==0x55&&p[1]==0x89&&p[3]==0x83&&p[6]==0xC7&&p[14]==0xC7&&p[22]==0xC7){
  7.      //dirección de la variable tomada del código
  8.      return (char *)*(void**)&p[26];
  9.    }
  10.  }
  11.  return NULL;
  12. }

Un detalle a destacar de la función es que &p[26] nos devolverá la dirección de memoria de la instrucción, pero no de la variable, entonces mediante el *(void**) obtendremos la verdadera dirección.

Ahora ya podemos escanear nuestro código, y en caso de encontrar nuestra variable modificarla:

Código
  1. #include <windows.h>
  2.  
  3. char titulo[]="titulo";
  4. char mensaje[]="un mensaje";
  5.  
  6. void funcionascanear(void){
  7.  MessageBox(0,mensaje,titulo,0);
  8. }
  9.  
  10. char *findmsgbypattern(){
  11.  unsigned char *p;
  12.  //dirección inicio / fin del escaneo
  13.  for(p=0x00401000;p<0x00401FFF;p++){
  14.    //nuestro patron
  15.    if(p[0]==0x55&&p[1]==0x89&&p[3]==0x83&&p[6]==0xC7&&p[14]==0xC7&&p[22]==0xC7){
  16.      //dirección de la variable tomada del código
  17.      return (char *)*(void**)&p[26];
  18.    }
  19.  }
  20.  return NULL;
  21. }
  22.  
  23. int main(void){
  24.  char *msg=findmsgbypattern();
  25.  if(msg)
  26.    strcpy(msg,"mi mensaje");
  27.  funcionascanear();
  28.  return 0;
  29. }

Solo cabe aclarar que en el caso de modificar un string la variable original debe ser de un tamaño adecuado para nuestra modificación.

S2

PD: El ejemplo fue compilado con Mingw (GCC), es casi seguro que no funcione en otros compiladores (VC, etc), para hacerlo funcionar hay que rearmar el patrón.

PD2: Existen librerías que permiten buscar patrones de forma más sencilla, como por ejemplo (formato olly):

Código
  1. findpattern(dirinicio,dirfin,"XX????XX??????XX????XX");

pero lo que hacen al fin y al cabo es lo mismo.
82  Programación / PHP / Re: Simple AntiBot en PHP en: 19 Febrero 2011, 17:05 pm
Es bypaseable xD, aunque creo que cualquier antibot se puede bypasear nomas sabiendo su algoritmo. Lo único que te puedo recomendar es que no muestre tus archivo antibot, aunque no muestres el source, mirando bien el funcionamiento de la web puedes saber como funciona tu antibotne.

el protocolo es solo de ida, les va a llevar su buen rato descifrarlo...  ;), además, eso es configurable, se lo puede complicar tanto como se quiera...  :P

S2
83  Programación / PHP / Simple AntiBot en PHP en: 19 Febrero 2011, 05:16 am
bueno, dado que estaba sufriendo varios ataques en mi web (no se ni me interesa de quien) tube que implementar un antibot parecido al que se usaba en este sitio (inspirado en lo que puso el-brujo en un post aunque mucho más simple)

Código
  1. <?php /* antibot.php */
  2.  
  3. function checkBot(){
  4. //cookie params
  5. @ini_set('session.use_cookies',1);
  6. @ini_set('session.cookie_lifetime',31536000);//un año
  7. @ini_set('session.use_only_cookies',1);
  8. @ini_set('session.cookie_path','/');
  9. // configufación de variables PHP
  10. @ini_set('session.name',"AntiBot");//nombre de la cookie
  11. //otras opciones  
  12. @ini_set('session.hash_function',0);
  13. @ini_set('session.use_trans_sid',0);
  14. @ini_set('session.save_path','/tmp');
  15.  
  16. if(!isset($_SESSION['bottime']))
  17. $_SESSION['bottime']=rand(100,999);
  18. $bottime=$_SESSION['bottime'];
  19.  
  20. if(isset($_REQUEST['antibotkey']))
  21. $_SESSION['antibotkey']=$_REQUEST['antibotkey'];
  22. if(isset($_SESSION['antibotkey'])&&isset($_SESSION['bottime'])){
  23. $antibotkey=$_SESSION['antibotkey'];
  24. if(!empty($antibotkey)&&sha1($_SERVER['HTTP_USER_AGENT'].$bottime)==$antibotkey)
  25.  return null;
  26. }
  27.  
  28. if(!isset($_SESSION['botcount']))
  29. $_SESSION['botcount']=0;
  30. else
  31. $_SESSION['botcount']++;
  32.  
  33. if($_SESSION['botcount']>10){
  34. $_SESSION['botcount']=0;
  35. @header("Location: http://www.google.com");
  36. }
  37.  
  38. return sha1($_SERVER['HTTP_USER_AGENT'].$bottime);
  39. }
  40.  
  41. ?>

Código
  1. <?php /* index.php */
  2. /********************************* Anti Bot ************************************/
  3.  
  4. include 'antibot.php';
  5. $antibotkey=checkBot();
  6. if(!empty($antibotkey))
  7. die("<a href='index.php?antibotkey=$antibotkey'>Haz Click Aquí para Entrar al Sitio</a><br/><br/>Este Mensaje es mostrado para evitar el ingreso de Bots y solo lo verás una vez.<br/><br/>Disculpe las molestias.");
  8.  
  9. /********************************* Anti Bot ************************************/

se puede optimizar, se le pueden agregar más checkeos, etc... pero es para tener una base dado que la que se utilizó acá en el foro no es público el código... je  :xD, pero como supongo es algo temporal no me calenté mucho en mejorarlo :)

S2

PD: El protocolo no es ese, pero es perecido, je
84  Programación / Programación C/C++ / Re: Subir un archivo a un FTP en: 16 Febrero 2011, 22:54 pm
Bien, ya he conseguido que funcione, pero ahora tengo un pequeño problema.
La primera vez que se ejecuta este programa en un equipo salta una alarma del firewall de windows que hay que darle manualmente a desbloquear.

poné el código en una dll e inyectala a otro proceso... je

S2
85  Seguridad Informática / Análisis y Diseño de Malware / Re: VEH Api Hook en: 14 Febrero 2011, 22:38 pm
Hay un pequeño detalle sobre el uso del veh hook (o esta forma de usarlo), y es que cuando llaman a VirtualProtect no están cambiando el acceso a X bytes de memoria, sino a las páginas donde se encuentran esos X bytes, dicho de otra forma:

Citar
    pag1   -    pag2
[...     XX][XX     ...]

estarían no solo cambiando los permisos de los bytes XXXX sinó de las dos páginas (cada página suele tener 512 bytes), por lo que podría pasar que al ejecutarse alguna parte de algunas de las páginas externas a los bytes que uno quiere proteger también se provoque una excepción.

S2

PD: se que el post es viejo pero creo que merece aclararse eso :P
86  Programación / Programación C/C++ / Re: ¿como detectar nuevos procesos en ejecucion? en: 23 Diciembre 2010, 05:18 am
en cuanto a hooks tb tenes NtCreateThread o NtOpenFile que pueden ser usados con el mismo fin, pero fuera de eso, con el tema de las notificaciones con PsSetLoadImageNotifyRoutine y PsSetCreateThreadNotifyRoutine también se pueden hacer cosas interesantes, pero (dada la fima digital de drivers de x64) dentro del modo usuario creo que con los hooks cbt (creación de ventanas etc.) se pueden bloquear algunas cosas, yo para cosas simples con CreateToolhelp32Snapshot y buscando el ejecutable he logrado corromperlos antes que terminen de cargarse... (obviamente que hay un consumo extra de procesador, pero... es en modo usuario)

S2
87  Programación / Programación C/C++ / Re: Duda sobre saltos, de apihooking en: 22 Diciembre 2010, 05:05 am
acá tenes unas cuantas variantes:

Código
  1. case DETOUR_TYPE_STC_JC:
  2.        pDirApi[0] = 0xF9;
  3.        pDirApi[1] = 0x0F;
  4.        pDirApi[2] = 0x82;
  5.        *(DWORD*)&pDirApi[3]=(DWORD)(newDirApi-pDirApi)-7;
  6.      break;
  7.      case DETOUR_TYPE_CLC_JNC:
  8.        pDirApi[0] = 0xF8;
  9.        pDirApi[1] = 0x0F;
  10.        pDirApi[2] = 0x83;
  11.        *(DWORD*)&pDirApi[3]=(DWORD)(newDirApi-pDirApi)-7;
  12.      break;
  13.      case DETOUR_TYPE_NOP_NOP_JMP:
  14.        pDirApi[0]=0x90;
  15.        pDirApi[1]=0x90;
  16.        pDirApi[2]=0xE9;
  17.        *(DWORD*)&pDirApi[3]=(DWORD)(newDirApi-pDirApi)-7;
  18.      break;
  19.      case DETOUR_TYPE_PUSH_EAX_RET:
  20.        pDirApi[0]=0xB8;
  21.        *(DWORD*)&pDirApi[1]=(DWORD)newDirApi;
  22.        pDirApi[5]=0x50;
  23.        pDirApi[6]=0xC3;
  24.      break;
  25.      case DETOUR_TYPE_NOP_PUSH_RET:
  26.        pDirApi[0]=0x90;
  27.        pDirApi[1]=0x68;
  28.        *(DWORD*)&pDirApi[2]=(DWORD)newDirApi;
  29.        pDirApi[6]=0xC3;
  30.      break;
  31.      case DETOUR_TYPE_JMP_EAX:
  32.        pDirApi[0]=0xB8;
  33.        *(DWORD*)&pDirApi[1]=(DWORD)newDirApi;
  34.        pDirApi[5]=0xFF;
  35.        pDirApi[6]=0xE0;
  36.      break;
  37.      case DETOUR_TYPE_JMP_JMP:
  38.        pDirApi[-5]=0xE9;
  39.        *(DWORD*)&pDirApi[-4]=(DWORD)(newDirApi-pDirApi);
  40.        pDirApi[0]=0xEB;
  41.        pDirApi[1]=0xF9;
  42.      break;
  43.      case DETOUR_TYPE_PUSH_RET:
  44.        pDirApi[0]=0x68;
  45.        *(DWORD*)&pDirApi[1]=(DWORD)newDirApi;
  46.        pDirApi[5]=0xC3;
  47.      break;
  48.      case DETOUR_TYPE_NOP_JMP:
  49.        pDirApi[0]=0x90;
  50.        pDirApi[1]=0xE9;
  51.        *(DWORD*)&pDirApi[2]=(DWORD)(newDirApi-pDirApi)-6;
  52.      break;
  53.      default://DETOUR_TYPE_JMP
  54.        pDirApi[0]=0xE9;
  55.        *(DWORD*)&pDirApi[1]=(DWORD)(newDirApi-pDirApi)-5;
  56.      break;

y las instrucciones ASM referentes a jmps:

Código
  1. EB cb JMP rel8 Jump short, relative, displacement relative to next instruction.
  2. E9 cw JMP rel16 Jump near, relative, displacement relative to next instruction.
  3. E9 cd JMP rel32 Jump near, relative, displacement relative to next instruction.
  4. FF /4 JMP r/m16 Jump near, absolute indirect, address given in r/m16.
  5. FF /4 JMP r/m32 Jump near, absolute indirect, address given in r/m32.
  6. EA cd JMP ptr16:16 Jump far, absolute, address given in operand.
  7. EA cp JMP ptr16:32 Jump far, absolute, address given in operand.
  8. FF /5 JMP m16:16 Jump far, absolute indirect, address given in m16:16.
  9. FF /5 JMP m16:32 Jump far, absolute indirect, address given in m16:32.

S2
88  Programación / Programación C/C++ / Re: Principios básicos de desarrollo de drivers en Windows - Lenguaje C en: 11 Diciembre 2010, 03:37 am
está bueno el post aunque le faltarían algunas cosas como destacar bien las diferencias entre los distintos modos (user/kernel), aporto un par de funciones que no las encontré en la red o si las encontré no funcionaban bien (por lo menos estas me funcan a mi :P), capaz a alguno le sirve...

Código
  1. BOOL DDKAPI ImageFullPath(PEPROCESS eprocess,PCHAR fullname){
  2.  BOOL ret=FALSE;BYTE buffer[sizeof(UNICODE_STRING)+MAX_PATH*sizeof(WCHAR)];
  3.  HANDLE handle;DWORD returnedLength=0;ANSI_STRING DestinationString;
  4.  if(NT_SUCCESS(ObOpenObjectByPointer(eprocess,OBJ_KERNEL_HANDLE,NULL,GENERIC_READ,0,KernelMode,&handle))){
  5.    if(NT_SUCCESS(ZwQueryInformationProcess(handle,ProcessImageFileName,buffer,sizeof(buffer),&returnedLength))){
  6.      RtlUnicodeStringToAnsiString(&DestinationString,(UNICODE_STRING*)buffer,TRUE);
  7.      strncpy(fullname,DestinationString.Buffer,DestinationString.Length);ret=TRUE;
  8.      fullname[DestinationString.Length]=0;RtlFreeAnsiString(&DestinationString);
  9.    }
  10.    ZwClose(handle);
  11.  }
  12.  return ret;
  13. }
  14.  
  15. BOOL DDKAPI ImageFileName(PEPROCESS eprocess,PCHAR filename){
  16.  CHAR sImageFullPath[MAX_PATH]={0};
  17.  if(ImageFullPath(eprocess,sImageFullPath)){
  18.    PCHAR pIFN=sImageFullPath,pIFP=sImageFullPath;
  19.    while(*pIFP)if(*(pIFP++)=='\\')pIFN=pIFP;
  20.    strcpy(filename,pIFN);return TRUE;
  21.  }
  22.  return FALSE;
  23. }
  24.  
  25. DWORD GetProcessIdByHandle(HANDLE Process){
  26.  PROCESS_BASIC_INFORMATION ProcessBasicInfo;
  27.  if(NT_SUCCESS(ZwQueryInformationProcess(Process,ProcessBasicInformation,&ProcessBasicInfo,sizeof(PROCESS_BASIC_INFORMATION),NULL)))
  28.    return ProcessBasicInfo.UniqueProcessId;
  29.  return 0;
  30. }
  31.  
  32. NTSTATUS MmAllocateUserBuffer(PVOID *BaseAddress,ULONG Size){
  33.  return ZwAllocateVirtualMemory(NtCurrentProcess(), BaseAddress, 0L, &Size, MEM_COMMIT, PAGE_READWRITE);
  34. }
  35.  
  36. NTSTATUS MmFreeUserBuffer(PVOID *BaseAddress){
  37.  ULONG RegionSize = 0;
  38.  return ZwFreeVirtualMemory(NtCurrentProcess(), BaseAddress, &RegionSize, MEM_RELEASE);
  39. }
  40.  
  41. PSERVICE_DESCRIPTOR_TABLE DDKAPI GetServiceDescriptorShadowTableAddress(){
  42.  PBYTE check = (PBYTE)&KeAddSystemServiceTable;
  43. PSERVICE_DESCRIPTOR_TABLE rc=0;UINT i;
  44. for (i=0; i<1024; i++) {
  45.  rc = *(PPSERVICE_DESCRIPTOR_TABLE)check;
  46. if(!MmIsAddressValid(rc)||((PVOID)rc==(PVOID)&KeServiceDescriptorTable)
  47. ||(memcmp(rc,&KeServiceDescriptorTable,sizeof(SYSTEM_SERVICE_TABLE)))){
  48. check++;
  49. rc = 0;
  50. }
  51. if (rc)
  52. break;
  53. }
  54. return rc;
  55. }

S2

PD: Esto fue compilado con GCC, con Visual Studio pueden cambiar un par de cosas como por ejemplo: &KeAddSystemServiceTable se convertiría en KeAddSystemServiceTable.
89  Programación / Programación C/C++ / Re: porque al compilar pesa tanto un programa? en: 29 Noviembre 2010, 06:45 am
es por una característica de gcc cuando se utilizan las STL, y es debido a que en este compilador el código del la STL es embebido en el ejecutable final (lo cual no pasa con visual c++ debido a que dichas funcionalidades están en una dll externa), pero no te tiene que importar eso, dado que, al fin y al cabo, ambos pesan lo mismo en memoria (con gcc es un solo módulo, con visual c, son 2 o más)

cita de la página compilador mingw:

Citar
C++ programs using the Standard Template Library (ie/ #include <iostream>) cause a large part of the library to be statically linked into the binary. The need to statically link the stdc++ into the binary is two fold. First MSVCRT.dll does not contain C++ stdlib constructs. Second the legal implications of generating a libstdc++.dll are restricted by the licensing associated with the library. If you wish to keep your file size down use strip to remove debugging information and other verbatim found in the binary.

S2
90  Programación / Programación C/C++ / Re: [TALLER][C++] Empezando a manejar los punteros en: 18 Noviembre 2010, 00:27 am
Ok, básicamente, según entendí hasta ahora, los punteros sirven de mucho para reducir el consumo de memoria. En vez de usar una variable, hacemos un "espejo" de ella.  ::)

y no solo para eso, tienen muchos usos, acá tenes un ejemplo que si lo completás de entender, se puede decir que casi dominás punteros...

http://foro.elhacker.net/programacion_general/programas_para_resolver_problemas-t199992.0.html;msg964683#msg964683

S2
Páginas: 1 2 3 4 5 6 7 8 [9] 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 ... 28
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines