Cracking 101
Ora viva!
O software há dias estava a tentar descobrir como se cracka um simples strncmp(3), então eu fiquei com ideias de criar um breve *curso* de cracking para os iniciantes.
Começamos com o seguinte sores:
#include <stdio.h> int main() { char loljews[10]; printf("--> "); scanf("%s",&loljews); if(strncmp(loljews,"morte",5)==0) { printf(" OK ;-)\n"); } else { printf(" FAiLED!\n"); } return 1; }
O código julgo que é auto-explicativo. O que se pretende é, depois de ter o programa compilado alterar o executável de forma a que aceite qualquer palavra sem ser "morte" e diga OK.
Então corri o programa no gdb e fiz "disassemble main"
Dump of assembler code for function main: 0x08048464 <main+0>: push %ebp 0x08048465 <main+1>: mov %esp,%ebp 0x08048467 <main+3>: and $0xfffffff0,%esp 0x0804846a <main+6>: sub $0x20,%esp 0x0804846d <main+9>: mov $0x8048590,%eax 0x08048472 <main+14>: mov %eax,(%esp) 0x08048475 <main+17>: call 0x8048368 <printf@plt> # print "-->" 0x0804847a <main+22>: mov $0x8048595,%eax 0x0804847f <main+27>: lea 0x16(%esp),%edx 0x08048483 <main+31>: mov %edx,0x4(%esp) 0x08048487 <main+35>: mov %eax,(%esp) 0x0804848a <main+38>: call 0x8048378 <__isoc99_scanf@plt> 0x0804848f <main+43>: movl $0x5,0x8(%esp) 0x08048497 <main+51>: movl $0x8048598,0x4(%esp) 0x0804849f <main+59>: lea 0x16(%esp),%eax 0x080484a3 <main+63>: mov %eax,(%esp) 0x080484a6 <main+66>: call 0x8048398 <strncmp@plt> # faz o call ao strncmp 0x080484ab <main+71>: test %eax,%eax 0x080484ad <main+73>: jne 0x80484bd <main+89> # Se não é igual, salta pra bad_boy 0x080484af <main+75>: movl $0x804859e,(%esp) # good_boy 0x080484b6 <main+82>: call 0x8048388 <puts@plt> # print "OK" 0x080484bb <main+87>: jmp 0x80484c9 <main+101> # salta para o fim 0x080484bd <main+89>: movl $0x80485a6,(%esp) # bad_boy 0x080484c4 <main+96>: call 0x8048388 <puts@plt> # print "failed" 0x080484c9 <main+101>: mov $0x1,%eax # fim 0x080484ce <main+106>: leave 0x080484cf <main+107>: ret
Primeiro uma lista de instruções normalmente usadas para o cracking e os seus opcodes em hexadecimal.
JNE - Jump if Not Equal - 75
JE - Jump if Equal - 74
JMP - Jump - EB
NOP - No Operation - 90
JA - Jump if Above - 77
JB - Jump if Below - 72
JNA - Jump if Not Above - 76
JLE - Jump if Less or Equal - 7E
JL - Jump if Less - 7C
O que se pretende então é alterar ali aquele JNE em <main+73>. Mas para o quê? A primeira ideia seria inverter o sentido do jump, em vez de ser JNE passava a ser JE. Mas assim ficávamos com um problema, ao metermos "morte" iamos parar ao "failed".
Então o que podemos fazer perguntam vocês?
Para explicar primeiro precisei de instalar um hex editor para Linux. O biew pareceu-me bem. Abri o executável nele e andei à procura do naco de código acima (do gdb).
000004A6:E8EDFEFFFF calln file:00000398 000004AB:85C0 test eax,eax 000004AD:750E jne file:000004BD 000004AF:C704249E850408 mov [esp],0804859E 000004B6:E8CDFEFFFF calln file:00000388 000004BB:EB0C jmps file:000004C9 000004BD:C70424A6850408 mov [esp],080485A6 000004C4:E8BFFEFFFF calln file:00000388 000004C9:B801000000 mov eax,00000001 000004CE:C9 leave
O que eu fiz foi alterar os os bytes do JNE e da posição para onde salta "75 0E", para dois NOPs (No Operation - Não faz nada) "90 90". Assim ele nunca faz o teste, e segue sempre em frente para o good_guy e depois sai.
Espero que isto tenha alguma utilidade para alguém! Para a próxima talvez haja um com algo mais complexo tipo Username com Serial derivada do Username ou algo do género.
Até la, fiquem bem e crackem muito ;-)
amei!
Humm
Muito bem!
Algo util! :)
Posta mais disso!