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

 

 


Tema destacado: Usando Git para manipular el directorio de trabajo, el índice y commits (segunda parte)


  Mostrar Temas
Páginas: [1] 2
1  Programación / Ingeniería Inversa / CrackMe if you can III (Reborn) en: 15 Enero 2013, 06:00 am
Tras mucho tiempo de no postear en este foro, me decidí hacer este pequeño y tonto crackme para el que tenga ganas de jugar con el... cabe aclarar que es demasiado simple como para parchearlo por lo que la idea es obtener un usuario y clave válido por lo menos (aunque un keygen no es muy complicado una vez entendido el algoritmo)... :P

Sin más preámbulo se los dejo: CrackMe if you can III (Reborn)

S2
2  Programación / Programación C/C++ / Problema con Cast en Visual C en: 30 Marzo 2012, 22:23 pm
Buenas, estoy haciendo un programa con clases y me encontré con una incompatibilidad muy rara de Visual C, el siguiente código funciona perfectamente con GCC pero con Visual C me da error :S

Código
  1. class XX{
  2. public:
  3. };
  4.  
  5. class XY{
  6. public:
  7. };
  8.  
  9. typedef void (XX::*pfun)(void);
  10.  
  11. class X:public XX,XY{
  12. public:
  13. int ff(int a){
  14. return a;
  15. }
  16. static pfun f;
  17. static struct _t{
  18. pfun f;
  19. }t;
  20. };
  21.  
  22. pfun X::f=pfun(&X::ff);//??????
  23. struct X::_t X::t={pfun(&X::ff)};//??????

Citar
1>main.cpp(28): error C2440: '<function-style-cast>' : no se puede realizar la conversión de 'int (__thiscall X::* )(int)' a 'pfun'
1>          Los punteros a miembros tienen distintas representaciones; no se puede realizar la conversión entre ellos
1>main.cpp(29): error C2440: '<function-style-cast>' : no se puede realizar la conversión de 'int (__thiscall X::* )(int)' a 'pfun'
1>          Los punteros a miembros tienen distintas representaciones; no se puede realizar la conversión entre ellos

si utilizo herencia simple funciona... el tema es con la herencia múltiple:

Código
  1. class X:public XX,XY

alguno que utilice ese compilador me puede tirar un cable?

S2
3  Programación / Programación C/C++ / Code Virtualization en C en: 14 Abril 2011, 19:59 pm
buenas, tras tiempo depurando programas con códigos en parte virtualizados se me planteó la duda como hacer un sistema de virtualización de código, por eso armé "esto" que no está completo ni nada, pero que puede llegar a servir de ejemplo supongo  :P

el conjunto de instrucciones no está totalmente definido, solo definí un par de opcodes para hacer pruebas (faltan muchas instrucciones), además no está implementado la parte de modificación de flags del proceso.

Código
  1. #define _WIN32_WINNT 0x0500
  2. #include <windows.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5.  
  6. /*
  7. REGISTERS
  8. =========
  9. 0 eax
  10. 2 ebx
  11. E ecx
  12. 4 edx
  13. C ebp
  14. 6 esp
  15. A edi
  16. 8 esi
  17.  
  18. OPCODES
  19. =======
  20. 00 YYYYYYYY ->  jmp long
  21. 01 YYYY     ->  jmp short
  22. 02 YY       ->  jmp word
  23. 03 YYYY     ->  je  short
  24. 04 YY       ->  je  word
  25. 05 YYYY     ->  jne short
  26. 06 YY       ->  jne word
  27.  
  28. //MOV REG, 00000
  29. 14 YYYYYYYY ->  mov eax, long
  30. 15 YYYYYYYY ->  mov ecx, long
  31. 16 YYYYYYYY ->  mov edx, long
  32. 17 YYYYYYYY ->  mov ebx, long
  33. 18 YYYYYYYY ->  mov esp, long
  34. 19 YYYYYYYY ->  mov ebp, long
  35. 1A YYYYYYYY ->  mov esi, long
  36. 1B YYYYYYYY ->  mov edi, long
  37.  
  38. //MOV [REG-X], XXXXXXXX
  39. 1C XX YYYYYYYY ->  mov (R) , long ->  X reg X offset
  40.  
  41. //MOV REG, [REG-X]
  42. 1E XX  ->  mov eax, (R) ->  X reg X reg
  43. 1F XX  ->  mov ebx, (R)
  44. 20 XX  ->  mov ecx, (R)
  45. 21 XX  ->  mov edx, (R)
  46. 22 XX  ->  mov ebp, (R)
  47. 23 XX  ->  mov esp, (R)
  48. 24 XX  ->  mov edi, (R)
  49. 25 XX  ->  mov esi, (R)
  50.  
  51. //MOV REG, REG
  52. 26 XX  ->  mov R, R
  53.  
  54. //MOV [REG-X], REG
  55. 28 XX  ->  mov (R), eax ->  X reg X offset
  56. 29 XX  ->  mov (R), ebx
  57. 2A XX  ->  mov (R), ecx
  58. 2B XX  ->  mov (R), edx
  59. 2C XX  ->  mov (R), ebp
  60. 2D XX  ->  mov (R), esp
  61. 2E XX  ->  mov (R), edi
  62. 2F XX  ->  mov (R), esi
  63.  
  64. //SUB EDX, EAX
  65. 32 XX  ->  sub R, R   ->  X reg X reg
  66.  
  67. //LEA EAX, [EBP-8]
  68. 3C XX  ->  lea eax, (R) ->  X reg X reg
  69. 3D XX  ->  lea ebx, (R)
  70. 3E XX  ->  lea ecx, (R)
  71. 3F XX  ->  lea edx, (R)
  72. 40 XX  ->  lea ebp, (R)
  73. 41 XX  ->  lea esp, (R)
  74. 42 XX  ->  lea edi, (R)
  75. 43 XX  ->  lea esi, (R)
  76.  
  77. */
  78.  
  79. typedef struct _REGISTERS{
  80.  ULONG Edi;//00
  81.  ULONG Esi;//04
  82.  ULONG Ebp;//08
  83.  ULONG Esp;//0C
  84.  ULONG Ebx;//10
  85.  ULONG Edx;//14
  86.  ULONG Ecx;//18
  87.  ULONG Eax;//1C
  88.  ULONG Flg;//20
  89.  ULONG Eip;//24
  90. }REGISTERS, *PREGISTERS;
  91.  
  92. PULONG GetReg(PREGISTERS p,WORD reg){
  93.  PULONG ret=NULL;
  94.  switch(reg){
  95.    case 0x0:// eax
  96.      ret=&p->Eax;
  97.    break;
  98.    case 0x2:// ebx
  99.      ret=&p->Ebx;
  100.    break;
  101.    case 0xE:// ecx
  102.      ret=&p->Ecx;
  103.    break;
  104.    case 0x4:// edx
  105.      ret=&p->Edx;
  106.    break;
  107.    case 0xC:// ebp
  108.      ret=&p->Ebp;
  109.    break;
  110.    case 0x6:// esp
  111.      ret=&p->Esp;
  112.    break;
  113.    case 0xA:// edi
  114.      ret=&p->Edi;
  115.    break;
  116.    case 0x8:// esi
  117.      ret=&p->Esi;
  118.    break;
  119.  }
  120.  return ret;
  121. }
  122.  
  123. void decrypt(REGISTERS p){
  124.  PBYTE b=(PBYTE)p.Eip;
  125.  BYTE Reg=0,RegEx=0;
  126.  PULONG pReg=0,pRegEx=0;
  127.  CHAR Offset=0;
  128.  
  129.  //FIX ME!
  130.  b+=2;//lo ideal sería un long jmp, pero gcc no deja setearlo (o no se como)
  131.  
  132.  //Code Start!
  133.  while(*b!=0xF0){
  134.    switch(*b){
  135.      case 0x1C://MOV [REG-X], XXXXXXXX
  136.        Reg=*(++b);
  137.        Offset=Reg&0xF;
  138.        Reg>>=4;
  139.        if(Reg&0x1)
  140.          Offset=-Offset;
  141.        Reg&=0xE;
  142.        pReg=GetReg(&p,Reg);
  143.        *((PDWORD)(*pReg+Offset))=*(DWORD*)(++b);
  144.        b+=4;
  145.      break;
  146.      case 0x21://MOV EDX, [REG-X]
  147.        Reg=*(++b);
  148.        Offset=Reg&0xF;
  149.        Reg>>=4;
  150.        if(Reg&0x1)
  151.          Offset=-Offset;
  152.        Reg&=0xE;
  153.        pReg=GetReg(&p,Reg);
  154.        p.Edx=*((PDWORD)(*pReg+Offset));
  155.        ++b;
  156.      break;
  157.      case 0x1E://MOV EAX, [REG-X]
  158.        Reg=*(++b);
  159.        Offset=Reg&0xF;
  160.        Reg>>=4;
  161.        if(Reg&0x1)
  162.          Offset=-Offset;
  163.        Reg&=0xE;
  164.        pReg=GetReg(&p,Reg);
  165.        p.Eax=*((PDWORD)(*pReg+Offset));
  166.        ++b;
  167.      break;
  168.      case 0x32://SUB REG,REG
  169.        Reg=*(++b);
  170.        RegEx=Reg&0xF;
  171.        Reg>>=4;
  172.        pReg=GetReg(&p,Reg);
  173.        pRegEx=GetReg(&p,RegEx);
  174.        p.Eax=*pReg-*pRegEx;
  175.        ++b;
  176.      break;
  177.      case 0x28://MOV [REG-X], EAX
  178.        Reg=*(++b);
  179.        Offset=Reg&0xF;
  180.        Reg>>=4;
  181.        if(Reg&0x1)
  182.          Offset=-Offset;
  183.        Reg&=0xE;
  184.        pReg=GetReg(&p,Reg);
  185.        *((PDWORD)(*pReg+Offset))=p.Eax;
  186.        ++b;
  187.      break;
  188.      default:
  189.        //FIX ME!
  190.        b++;//Opcode no válido?
  191.      break;
  192.    }
  193.  }
  194.  p.Eip=(ULONG)++b;
  195. }
  196.  
  197. void __stdcall vmachine(void);
  198. asm(
  199.  ".globl _vmachine\r\n"
  200.  "_vmachine:\r\n"//function header...
  201.  "  SUB     $0x24,%esp;\r\n"
  202.  "  PUSH    %edi;\r\n"
  203.  "  POP     (%esp);\r\n"
  204.  "  PUSH    %esi;\r\n"
  205.  "  POP     0x4(%esp);\r\n"
  206.  "  PUSH    %ebp;\r\n"
  207.  "  POP     0x8(%esp);\r\n"
  208.  "  PUSH    %ebx;\r\n"
  209.  "  POP     0x10(%esp);\r\n"
  210.  "  PUSH    %edx;\r\n"
  211.  "  POP     0x14(%esp);\r\n"
  212.  "  PUSH    %ecx;\r\n"
  213.  "  POP     0x18(%esp);\r\n"
  214.  "  PUSH    %eax;\r\n"
  215.  "  POP     0x1C(%esp);\r\n"
  216.  "  PUSHF   ;\r\n"
  217.  "  POP     0x20(%esp);\r\n"
  218.  "  LEA     0x28(%esp),%eax;\r\n"
  219.  "  MOV     %eax,0x0C(%esp);\r\n"
  220.  "  CALL    _decrypt;\r\n"
  221.  "  POPA    ;\r\n"
  222.  "  POPF    ;\r\n"
  223.  "  RET"
  224. );
  225.  
  226. void cryptme(){
  227.  int a,b,c;
  228.  asm(
  229.    " call jmp1;\n\t"
  230. "jmp1:jmp _vmachine;\n\t"
  231.  );
  232.  /*a=15,b=8;c=a-b;*/
  233.  asm(".byte\t\
  234.    0x1C,0xD4,0x0F,0x00,0x00,0x00,\
  235.    0x1C,0xD8,0x08,0x00,0x00,0x00,\
  236.    0x21,0xD4,\
  237.    0x1E,0xD8,\
  238.    0x32,0x40,\
  239.    0x28,0xDC,\
  240.    0xF0\
  241.  ");
  242.  printf("%d %d %d\n",a,b,c);
  243.  return;
  244. }
  245.  
  246. int main(void){
  247.  cryptme();
  248.  system("pause");
  249.  return 0;
  250. }

el código fue compilado sobre GCC sin ningún tipo de optimización (si se optimiza puede no funcionar correctamente porque el compilador elimina las variables sin referencias directas u otros tipos de optimizaciones)

el código:

Código
  1.  asm(
  2.    " call jmp1;\n\t"
  3. "jmp1:jmp _vmachine;\n\t"
  4.  );

se lo podría meter en una macro pero como era solo para probar lo posteo así (de paso queda a la vista para el que le interese portarlo a otro compilador).

el resultado es el siguiente, el código sin virtualizar en un debugger como olly sale:

Código
  1. void cryptme(){
  2.  int a,b,c;
  3.  a=15,b=8;c=a-b;
  4.  printf("%d %d %d\n",a,b,c);
  5.  return;
  6. }

Código
  1. 004015F2  /$  55            PUSH    EBP
  2. 004015F3  |.  89E5          MOV     EBP, ESP
  3. 004015F5  |.  83EC 28       SUB     ESP, 28
  4. 004015F8  |.  C745 FC 0F000>MOV     DWORD PTR SS:[EBP-4], 0F         ; |
  5. 004015FF  |.  C745 F8 08000>MOV     DWORD PTR SS:[EBP-8], 8          ; |
  6. 00401606  |.  8B55 F8       MOV     EDX, DWORD PTR SS:[EBP-8]        ; |
  7. 00401609  |.  8B45 FC       MOV     EAX, DWORD PTR SS:[EBP-4]        ; |
  8. 0040160C  |.  29D0          SUB     EAX, EDX                         ; |
  9. 0040160E  |.  8945 F4       MOV     DWORD PTR SS:[EBP-C], EAX        ; |
  10. 00401611  |.  8B45 F4       MOV     EAX, DWORD PTR SS:[EBP-C]        ; |
  11. 00401614  |.  894424 0C     MOV     DWORD PTR SS:[ESP+C], EAX        ; |
  12. 00401618  |.  8B45 F8       MOV     EAX, DWORD PTR SS:[EBP-8]        ; |
  13. 0040161B  |.  894424 08     MOV     DWORD PTR SS:[ESP+8], EAX        ; |
  14. 0040161F  |.  8B45 FC       MOV     EAX, DWORD PTR SS:[EBP-4]        ; |
  15. 00401622  |.  894424 04     MOV     DWORD PTR SS:[ESP+4], EAX        ; |
  16. 00401626  |.  C70424 983040>MOV     DWORD PTR SS:[ESP], CodeVirt.004>; |ASCII "%d %d %d\n"
  17. 0040162D  |.  E8 56080000   CALL    <JMP.&msvcrt.printf>             ; \printf
  18. 00401632  |.  C9            LEAVE
  19. 00401633  \.  C3            RETN

sin embargo, el código virtualizado se ve:

Código
  1. 004015F2  |$  55            PUSH    EBP
  2. 004015F3  |.  89E5          MOV     EBP, ESP
  3. 004015F5  |.  83EC 28       SUB     ESP, 28
  4. 004015F8  |.  E8 00000000   CALL    CodeVirt.004015FD
  5. 004015FD  \$^ EB B9         JMP     SHORT CodeVirt.004015B8
  6. 004015FF      1C            DB      1C
  7. 00401600      D4            DB      D4
  8. 00401601      0F            DB      0F
  9. 00401602      00            DB      00
  10. 00401603      00            DB      00
  11. 00401604      00            DB      00
  12. 00401605      1C            DB      1C
  13. 00401606      D8            DB      D8
  14. 00401607      08            DB      08
  15. 00401608      00            DB      00
  16. 00401609      00            DB      00
  17. 0040160A      00            DB      00
  18. 0040160B      21            DB      21                               ;  CHAR '!'
  19. 0040160C      D4            DB      D4
  20. 0040160D      1E            DB      1E
  21. 0040160E      D8            DB      D8
  22. 0040160F      32            DB      32                               ;  CHAR '2'
  23. 00401610      40            DB      40                               ;  CHAR '@'
  24. 00401611      28            DB      28                               ;  CHAR '('
  25. 00401612   .  DCF0          FDIVR   ST, ST                           ; |
  26. 00401614   .  8B45 F4       MOV     EAX, DWORD PTR SS:[EBP-C]        ; |
  27. 00401617   .  894424 0C     MOV     DWORD PTR SS:[ESP+C], EAX        ; |
  28. 0040161B   .  8B45 F8       MOV     EAX, DWORD PTR SS:[EBP-8]        ; |
  29. 0040161E   .  894424 08     MOV     DWORD PTR SS:[ESP+8], EAX        ; |
  30. 00401622   .  8B45 FC       MOV     EAX, DWORD PTR SS:[EBP-4]        ; |
  31. 00401625   .  894424 04     MOV     DWORD PTR SS:[ESP+4], EAX        ; |
  32. 00401629   .  C70424 983040>MOV     DWORD PTR SS:[ESP], CodeVirt.004>; |ASCII "%d %d %d\n"
  33. 00401630   .  E8 53080000   CALL    <JMP.&msvcrt.printf>             ; \printf
  34. 00401635   .  C9            LEAVE
  35. 00401636   .  C3            RETN

con lo cual se ve claramente la diferencia...

lo que se podría agregar al código es (como ya dije) un conjunto más variado de instrucciones y luego un "virtualizador" que convierta las instrucciones normales a las virtualizadas, pero, ese ya es un arduo trabajo y si a alguien le interesa tomarlo como proyecto podría ayudar  :P

S2
4  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.
5  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
6  Media / Juegos y Consolas / Inexinferis Hack FX 6 - SXE 8.0 - Wall Hack's + Extras + Anti Local Ban en: 19 Septiembre 2009, 05:54 am
bueno... gracias a que este foro me ayudó en la parte del wall (http://foro.elhacker.net/programacion_cc/empezar_a_codear_tu_propio_cheat_half_life-t176966.0.html;msg1309570#msg1309570), dejo acá un wallhack para el SXE 8.0 todos los fix... aclaro... este wall solamente fue probado en mi máquina así que desconozco si funcione siquiera en las suyas... :silbar:
prueben y después avisan... :P

2º Este es mi primer y único wall... así que no me vayan a estar mandando msg pidiéndome otro... si les funciona y les gusta... ok... sinó... lo siento... :P

acá el video (Anti Local Ban):


acá el video (Cheat FX 6):


Fix FX 6 (Test Mode)[Fuera el wall]


Activación por teclado/menu:

Citar
======================================================
F3: Panic Key
F4: Menu
======================================================


Este Fix no supone modificación alguna a la versión FX 5 más que la activación por menu y el anti local ban... así que quedan vigentes las características anteriores...

Mayor cantidad de placas de video... (hasta acá llego... si no les funciona su placa de video es incompatible!)
Compatibilidad con Counter-Strike 1.5
Compatibilidad con Windows Vista (en la PC de un amigo anda... :silbar:)


S2

Nota: El cheat solo funciona en OPENGL MODE, dejen de mandarme privados diciendo que no anda y tienen el juego en DIRECTX


PD: A partir de ahora no daré mas soporte, lucio32( Gabriel@Privated.com.ar ) se encargará del mismo y cualquier problema groso me lo comunicará...
7  Programación / PHP / La mejor forma de hacerlo? (no se que titulo ponerle) en: 21 Agosto 2009, 23:50 pm
buenas, estoy desarrollando un proyecto bajo PHP (antiormente hable de el) y el tema es que me topé con una duda de como hacer lo siguiente:

Tengo un conjunto de módulos los cuales pueden necesitar sus propias tablas en la base de datos, el tema es que cada uno de estos módulos puede tener múltiples instancias (algo así como: blog de pepito, blog de josesito), pero en si, el código que maneja el módulo "blog" es uno solo, entonces mi duda es como crear esas tablas en la base de datos:

1º Una única tabla con un identificador de instancia (1 petito, 2 josesito), el tema de esta opción es que siquiero borrar un determinado blog, tendría que hacer todo un laburo extra para eliminar unicamente las entras del X blog, y si ya no hay instancias, borrar toda la tabla...

2º Una tabla por instancia cuyo nombre esté relacionada con el nombre de esta (blog_pepito,blog_josesito), con esta opcion desaparecen las complicaciones anteriores pero aparece la complicación de mantener ese nombre de tabla en algún lado (en mi caso tengo a dispoción "variables del módulo"), pero si dicha "variable" por alguna razón desaparece (o se borra) perdería la relación con la base de datos...

3º Una tabla por instancia cuyo nombre esté relacionado con el módulo/instancia (blog_1,blog_2), con esta otra opción desaparecen las complicaciones de las anteriores pero se dificulta la lectura de la base de datos... (en realidad me parece un poco complicada...)

bueno... espero se entienda la idea y me dén alguna opinión...

S2
8  Programación / Programación C/C++ / [Source] Crypter Simple Vr 2(?) FIX 1 en: 18 Julio 2009, 04:09 am
Bueno, los que me hayan leído mis últimos post verán que arme una clase para desarmar la clásica estructura PE... el tema es que hacía un tiempo había visto el código de un crypter simple en este foro (para ser más exacto http://foro.elhacker.net/programacion_cc/source_crypter_simple-t204227.0.html;msg969905#msg969905) el cual no funcionaba muy bien (con algunos ejecutables el resultado era desastroso) porque no tenía en cuenta un par de cosas que he agregado a este nuevo crypter...

Antes que nada paso a explicar un par de cosas para que a los que le interese el código puedan seguirlo...

1º y fundamental... los tipos de direccionamiento (la parte más complicada...  :P), bueno... en esta clase que cree hay 3 tipos básicos de direccionamiento:
A:Por Offset: la clase lo que hace es subir a memoria el archivo, entonces este tipo de direccionamiento nos lleva directamente a una posición de memoria del archivo, osea suponiendo que nuestra variable que contiene el contenido del archivo se llame buffer:

Citar
Offset(10) => &buffer[10]
*Offset(0) = 'M';*Offset(1) ='Z';

B: Por RVA: la clase es capaz de resolver direcciones virtuales, en este caso al setear un valor, se calculará el offset de acuerdo a este valor y obtendremos la posición de memoria del archivo... por ejemplo:

si una sección empieza físicamente en 400, pero tiene una dirección virtual de 1000, al hacer:

Citar
RVA(1024) = &buffer[424]

sin importar en cual sección se encuentre... (el algoritmo se encarga de eso)
C: por dirección referenciada: esta última opción (que agregué en esta versión) permite obtener el offset real de una dirección (la inversa de Offset), por ejemplo si tenemos una dirección 0x431212 y queremos saber en que punto del archivo se encuentra:

Código:
Address(0x431212) = 325
Offset(325) = 0x431212

bueno, ahora si el código:

Código
  1. /////////////////////////////////////////////////////////////////////////////
  2. // Name:        PE simple crypter (FIX 1)
  3. // Purpose:     Encriptador simple de Ficheros PE
  4. // Author:      Karman
  5. // Created:     2009-10-7
  6. // Copyright:   (c) Exinferis Inc
  7. // Web:         http://www.inexinferis.com.ar
  8. // Vr. : 0.1.1
  9. /////////////////////////////////////////////////////////////////////////////
  10.  
  11. #include <stdio.h>
  12. #include "ExecAnalizer.h"
  13.  
  14. CCHAR DataDirectories[][24]={
  15.  "Export Table",
  16.  "Import Table",
  17.  "Resource Table",
  18.  "Exception Table",
  19.  "Certificate Table",
  20.  "Relocation Table",
  21.  "Debug Table",
  22.  "Architecture Table",
  23.  "Machine Table",
  24.  "Thread Local Storage",
  25.  "Load Config Table",
  26.  "Bound Import Table",
  27.  "Import Address Table",
  28.  "Delay Import Table",
  29.  "COM+ Runtime Header"
  30. };
  31.  
  32. BYTE ourcode[]={
  33.  //push old entrypoint...
  34.  0x68,0x00,0x00,0x00,0x00,
  35.  //push size of code
  36.  0x68,0x00,0x00,0x00,0x00,
  37.  //push address of code
  38.  0x68,0x00,0x00,0x00,0x00,
  39.  //call decrypt
  40.  0xE8,0x00,0x00,0x00,0x00,
  41.  //Ret
  42.  0xc3
  43. };
  44.  
  45. DWORD WINAPI GetFunctionSize(PBYTE dwStart);
  46. VOID  WINAPI descifrar(PBYTE address,INT size, DWORD oep);
  47. VOID  WINAPI cifrar(PBYTE address,INT size);
  48.  
  49. int WINAPI WinMain(HINSTANCE hInst,HINSTANCE hPInst,LPSTR lpCmd,int nShow){
  50.  DWORD nImageBase,nEntryPoint;
  51.  PIMAGE_NT_HEADERS pINH;
  52.  PIMAGE_SECTION_HEADER pISHCode;
  53.  PCHAR forig="C:\\WINDOWS\\regedit.exe";
  54.  PCHAR fcrytp="C:\\WINDOWS\\cifrado.exe";
  55.  printf("Abriendo -> %s\n",forig);
  56.  ExecAnalizer crypt(forig);
  57.  //nos aseguramos que sea PE...
  58.  if(crypt.GetDOSHeader()&&crypt.HasNewHeader()&&crypt.IsPE()){
  59.    printf("\tFile Is -> PE\n");
  60.    pINH = crypt.GetNTHeader();
  61.    //datos básicos del ejecutable
  62.    nEntryPoint=pINH->OptionalHeader.AddressOfEntryPoint;
  63.    nImageBase=pINH->OptionalHeader.ImageBase;
  64.    printf("\tEntryPoint -> %X\n",nEntryPoint);
  65.    printf("\tImageBase -> %X\n",nImageBase);
  66.    puts("Buscando Code Section:");
  67.    //sección del código
  68.    pISHCode=crypt.RVA2Section(nEntryPoint);
  69.    if(pISHCode){
  70.      printf("\tCode Section Found At -> %X\n",crypt.Address2Offset((PBYTE)pISHCode));
  71.      DWORD codeStart=pISHCode->VirtualAddress;
  72.      DWORD codeEnd=pISHCode->VirtualAddress+pISHCode->SizeOfRawData;
  73.      printf("\tCode Section Start At -> %X\n",codeStart);
  74.      printf("\tCode Section End At -> %X\n",codeEnd);
  75.      //buscamos si alguna otra cosa se encuentra tb en el area de código
  76.      puts("Buscando Tablas en Code Section (Calculando tamaño real del código)");
  77.      for(int i=0;i<15;i++){
  78.        if(pISHCode==crypt.RVA2Section(pINH->OptionalHeader.DataDirectory[i].VirtualAddress)){
  79.          printf("\t%s is in Code Section At %X - %X\n",DataDirectories[i],
  80.            pINH->OptionalHeader.DataDirectory[i].VirtualAddress,
  81.            pINH->OptionalHeader.DataDirectory[i].Size
  82.          );
  83.          DWORD tAdress=pINH->OptionalHeader.DataDirectory[i].VirtualAddress;
  84.          DWORD tSize=(pINH->OptionalHeader.DataDirectory[i].VirtualAddress+pINH->OptionalHeader.DataDirectory[i].Size);
  85.          if(nEntryPoint<tAdress){
  86.            if(codeEnd>tAdress)
  87.              codeEnd=tAdress;
  88.          }else{
  89.            if(codeStart<tSize)
  90.              codeStart=tSize;
  91.          }
  92.        }
  93.      }
  94.      puts("Tamaño real del código:");
  95.      printf("\tCode Section Start At -> %X\n",codeStart);
  96.      printf("\tCode Section End At -> %X\n",codeEnd);
  97.      // Valores reales (en el archivo)
  98.      DWORD rCodeStart=(DWORD)crypt.RVA2Offset(codeStart);
  99.      DWORD rCodeEnd=(DWORD)crypt.RVA2Offset(codeEnd);
  100.      //buscamos espacio libre dentro de la sección code para copiarnos...
  101.      puts("Buscando Espacio para nuestro Código:");
  102.      //tamaño de nuestro código...
  103.      DWORD decrypcodefuncsize=GetFunctionSize((PBYTE)descifrar);
  104.      DWORD decrypcodesize=decrypcodefuncsize+0x20;
  105.      //Espacios libres???
  106.      DWORD dwBlanks=0,dwAddress=(pISHCode->PointerToRawData+pISHCode->SizeOfRawData);
  107.      for(;((dwAddress>rCodeEnd)&&(dwBlanks<decrypcodesize));dwAddress--)
  108.        if(!*crypt.OffsetValue(dwAddress))dwBlanks++;else dwBlanks=0;
  109.      //tiene espacio???
  110.      printf("\tEspacio Necesario: %X - Espacio encontrado: %X\n",decrypcodesize,dwBlanks);
  111.      if(decrypcodesize>=dwBlanks){
  112.        printf("\tFree Space At -> %X\n",dwAddress);
  113.        //ciframos...
  114.        cifrar((PBYTE)crypt.RVAValue(codeStart),codeEnd-codeStart);
  115.        //copiamos la función que descifra
  116.        memcpy((PVOID)crypt.OffsetValue(dwAddress),(PVOID)descifrar,decrypcodefuncsize);
  117.        //armamos cabecera...
  118.        *(DWORD *)&ourcode[0x01]=nEntryPoint+nImageBase;
  119.        *(DWORD *)&ourcode[0x06]=codeEnd-codeStart;
  120.        *(DWORD *)&ourcode[0x0B]=codeStart+nImageBase;
  121.        *(DWORD *)&ourcode[0x10]=-(decrypcodefuncsize+20);
  122.        dwAddress+=decrypcodefuncsize;
  123.        memcpy((PVOID)crypt.OffsetValue(dwAddress),(PVOID)ourcode,24);
  124.        //calculamos nuevo entrypoint
  125.        pINH->OptionalHeader.AddressOfEntryPoint=crypt.Offset2RVA(dwAddress);
  126.        // Damos permiso de escritura a la sección. Si no hacemos esto nos dara error.
  127.        pISHCode->Characteristics |= IMAGE_SCN_MEM_WRITE;
  128.        // Corregimos tamaño de la sección virtual si insuficiente
  129.        if(pISHCode->Misc.VirtualSize<(crypt.Offset2RVA(dwAddress)-pISHCode->VirtualAddress+24))
  130.          pISHCode->Misc.VirtualSize=(crypt.Offset2RVA(dwAddress)-pISHCode->VirtualAddress+24);
  131.        crypt.Save(fcrytp);
  132.      }else
  133.        puts("\tSin espacio Suficiente... :(");
  134.    }
  135.  
  136.    system("pause");
  137.  }
  138. }
  139.  
  140. DWORD WINAPI GetFunctionSize(PBYTE dwStart){
  141.  PBYTE dwEnd=dwStart;
  142. while(*dwEnd!=0xC3&&*dwEnd!=0xC2)dwEnd++;
  143. if(*dwEnd==0xC2)return (dwEnd-dwStart+3);
  144. return (dwEnd-dwStart+1);
  145. }
  146.  
  147. VOID  WINAPI descifrar(PBYTE address,INT size, DWORD oep){
  148.  while(size>0){
  149.    *(address++)^=0x65;
  150.    size--;
  151.  }
  152.  //set ret to old entry point
  153.  asm("mov %0 , 0x04(%%esp)"::"r"(oep));
  154. }
  155.  
  156. VOID  WINAPI cifrar(PBYTE address,INT size){
  157.  while(size>0){
  158.    *(address++)^=0x65;
  159.    size--;
  160.  }
  161. }

Detalles a destacar a diferencia de la primera versión del cripter:
1º Checkeo "de qué se cifra": el código no cifra toda la sección CODE, ya que muchos compiladores tienen la opción de combinar dentro de la sección CODE otras estructuras (IMPORT por ejemplo), y al cifrar esta estructura el programa ya no es válido (el cifrado de la IAT va más allá de este simple código, además de que desconozco como realmente se hace)...

2º Corrección de secciones: nuevamente el código anterior agregaba su código dentro de la sección CODE, pero no verificaba que esta modificación esté dentro de los valores definidos en la sección...

3º El código para descifrar mantiene cierta "lógica" secuencial, (aunque no logré hacer funcionar el código original) cuando lo intentaba debuggear los debuggers no lo entendían...

bue... eso es todo...  :P ...

S2

PD: me olvidaba de poner la dir del code:

Crypter Simple

PD2: Desconozco si el código tenga algún problema... con los ejecutables que probé funcionó...  :P
9  Programación / PHP / MINIFRAMEWORK - que les parece la lógica? en: 22 Mayo 2009, 05:41 am
Buenas, estoy desarrollando un miniframework con el cual estoy armando páginas para varios clientes con distintas bases de datos y configuraciones de servidor... (dos puntos que me han quebrantado hasta hoy), la idea de este post es exponer como lo estoy desarrolando para ver si se puede mejorar y obviamente facilitar mi vida..  :P

La idea actual es la siguiente, está totalmente programado en objetos y tiene un solo archivo direccionador (index.php)

Hay una clase base X(base), que es la index.php crea, esta clase se encarga de inicializar la base de datos (objeto), obtener información de la versión del software y otras configuraciones generales (en DB), inicializar sesiones(objeto), obtener datos de usuarios(objeto), (si sesiones le dice que hay alguno) y obtener parámetros enviados...

Si todo ok... index.php llama a "X->visualizar", función que se encarga de crear un objeto Módulo que se crea en base a los parámetros enviados... cada módulo está en DB y tiene su grupo de variables de módulo y dos especiales que son Archivos y Secciones...

El método principal del Objeto módulo tiene únicamente dos respuestas... Falso si no existe el módulo o el usuario no tiene permisos, o el resultado del modulo en si (aclaro que trabajo con Smarty ), el módulo (dependiendo de las variables del mismo) crea dos subclases (secciones y archivos), dichas clases son dependientes del módulo, otorgando o restringiendo permisos dependiendo del módulo y usuario (un módulo no puede borrar un archivo de otro módulo o un usuario con pocos permisos no puede eliminar una sección de un usuario con más permisos, etc...), osea quedaría esta estructura (mas o menos)

Citar
       index.php
              |
         sistema
       /      |      \
   DB  sesiones  usuarios
       \      |       /
          modulo
         /     |     \
  archivos |  secciones (o categorías)
         \     |     /
       modulo en si (noticias, descargas, etc...)

ustedes que piensan? como se podría mejorar?

S2
10  Programación / Bases de Datos / (SQL) Diferencias entre tablas de una misma tabla? en: 19 Mayo 2009, 00:47 am
buenas, tengo una duda que me está volviendo loco, tengo una tabla del siguiente tipo:

Código:
eid | sid | data 
 1     1    "lara lara"
 1     1    "qewrqer"
 2     1    "asdfasdf"
 2     1    "lara lara"
 3     1    "qewrqer"
 3     0    "zxcvzcv"

falta el identificador del tabla pero es solo un campo auto incremental...

el tema es que: necesito obtener todos los datos que no pertenezcan a un "eid", que pertenezcan a un "sid" y que no se repitan... por ejemplo:

Código:
eid | sid | data 
 1     1    "lara lara"
 2     1    "asdfasdf"

cuando el eid sería 3 y el sid sería 1... actualmente lo estoy haciendo de una forma un tanto embrollada:

obtengo todos los "data"'s distintos que pertenezcan al sid 1, todos los "dats"'s distintos del eid 3 sid 1, y hago una diferencia de arreglo, eso me devuelve:

Código:
"lara lara","asdfasdf"

por lo que luego tengo que buscar la primera referencia en la tabla a un "lara lara" o un "asdfasdf" y obtengo el resultado... pero es muy embrollado y no me parece eficiente...

Alguna idea de como puedo hacerlo de otra forma?

S2
Páginas: [1] 2
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines