Mais um blog inútil.

Agosto 21, 2009

oi lindinhos do craking

Filed under: Coding,Cracking,Useless — charlie-lindinho @ 12:07

aqui há tempos ( há mil dias ) prometi ao david publicar umas merdas sobre anti-debugging
e ao pedro enviar um crackme, mas em vez disso ( e porque sou uma merda )
resolvi apresentar aqui um exemplo de fácil compreensão e a devida explicação.

aqui vai disto :

root@inferno:[~/dev/cracking]# gdb crackme
(no debugging symbols found)
(gdb) set disassembly-flavor intel
(gdb) set write
(gdb) show write
Writing into executable and core files is on.
(gdb) file crackme
Reading symbols from /root/dev/cracking/crackme...(no debugging symbols found)...done.

(gdb) disas _start
Dump of assembler code for function _start:
0x08048060 <_start+0>: pop eax
0x08048061 <_start+1>: dec eax
0x08048062 <_start+2>: and eax,eax
0x08048064 <_start+4>: je 0x8048080 <exit>

o valor de argc é copiado para o registo EAX, em seguida este é decrementado,
pois se o crackme for executado sem argumentos o valor de argc será 1.

em seguida é realizada a operaçao lógica AND com o propósito de verificar
se o valor que reside em EAX ( argc ) é zero, caso seja, a função exit é então executada.

0x08048066 <_start+6>: mov bl,0x3
0x08048068 <_start+8>: inc eax
0x08048069 <_start+9>: and eax,ebx
0x0804806b <_start+11>: jne 0x8048080 <exit>
End of assembler dump.

aqui é atribuido o valor 3 ao registo EBX
e o registo EAX, ao ser incrementado, contém agora o valor real de argc.

por fim é novamente realizada a operação lógica AND com os registos EAX e EBX.
se estes forem diferentes a função exit é executada, caso contrário
( se o numero de argumentos corresponder a 3 ) passamos à função done.

(gdb) disas done
Dump of assembler code for function done:
0x0804806d <done+0>: xor ebx,ebx
0x0804806f <done+2>: push 0xa
0x08048071 <done+4>: push 0x656e6f64
0x08048076 <done+9>: mov al,0x4
0x08048078 <done+11>: mov bl,0x1
0x0804807a <done+13>: mov dl,0x5
0x0804807c <done+15>: mov ecx,esp
0x0804807e <done+17>: int 0x80
End of assembler dump.
(gdb) disas exit
Dump of assembler code for function exit:
0x08048080 <exit+0>: push $0x1
0x08048082 <exit+2>: pop %eax
0x08048083 <exit+3>: int $0x80
End of assembler dump.

(gdb) r 1 2 3
Starting program: /root/dev/cracking/crackme 1 2 3
(no debugging symbols found)
done

Program exited with code 01.

(gdb) x/4b _start+4
0x8048064 <_start+4>: 0x74 0x1a 0xb3 0x03
(gdb) p 0x1a
$1 = 26

( onde 0x74 é o opcode da instrução JE e 0x1a, 26 em decimal. )

ou seja, para efectuar o "je done" em vez de "je exit"
basta-nos calcular a distância em bytes entre a instrução JE e a função done, que é de 7 bytes.

(gdb) p 11-4
$2 = 7

uma vez que temos permissão para escrever no executável,
vamos então modificar um byte no segmento de código do mesmo
e posteriormente executá-lo sem argumentos :

(gdb) set *0x08048064 = 0x03b30774

(gdb) x/4b 0x08048064
0x8048064 <_start+4>: 0x74 0x07 0xb3 0x03
(gdb) x/i 0x08048064
0x8048064 <_start+4>: je 0x804806d <done>

(gdb) set write off
(gdb) file crackme
Reading symbols from /root/dev/cracking/crackme...(no debugging symbols found)...done.
(gdb) run
Starting program: /root/dev/cracking/crackme
(no debugging symbols found)
done

Program exited with code 01.
(gdb) q
root@inferno:[~/dev/cracking]#

como podemos verificar, foi-nos apresentada a mensagem "done", cumprindo assim o objectivo deste crackme.
deixo-vos aqui uma pequena merda que fiz em hepatite C para facilitar ainda mais a tarefa.

agora vou beber mil cervejas para esquecer que escrevi isto e vou dormir.

[ crackme-patch.c ]


#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>FILE *fp;

int main(int argc, char **argv){

unsigned int offset;
char *file = argv[1];

struct stat st;

if(stat(file, &st))
return EXIT_FAILURE;

fp = fopen(file, "r+");
offset = st.st_size;

while (offset) {

fseek(fp, offset, SEEK_SET);

if (fgetc(fp) == 0x1a)
patch(offset);

offset--;

}

fclose(fp);

return EXIT_SUCCESS;
}

int patch(int num){

printf("patching ... ");

fseek(fp, num, SEEK_SET);
fputc(0x07, fp);

printf("done.\n");

}

root@inferno:[~/dev/cracking]# nasm -f elf crackme.asm && ld -o crackme crackme.o
root@inferno:[~/dev/cracking]# ./crackme
root@inferno:[~/dev/cracking]# gcc -o crackme-patch crackme-patch.c
root@inferno:[~/dev/cracking]# ./crackme-patch ./crackme
patching ... done.
root@inferno:[~/dev/cracking]# ./crackme
done
root@inferno:[~/dev/cracking]#

PS: Este post foi feito plo MaDiNfO, já que o o charlie é uma merda e nem login consegue fazer com o seu proprio nick... (firefail dramas)

Comentar

widgeon
widgeon
widgeon
widgeon