Liber 000 - Astrum Argentum

Liber 000 - Astrum Argentum Liber 000 - Astrum Argentum

astrumargentum.org
from astrumargentum.org More from this publisher
01.01.2013 Views

main() { "\xbb\x00\x00\x00\x00" /* mov $0x0, %ebx */ "\xb8\x01\x00\x00\x00" /* mov $0x1, %eax */ "\xcd\x80"; /* int $0x80 */ /* Mostramos o tamanho para se ter um controle maior. */ printf("Tamanho do Shellcode: %d bytes.\n", sizeof (shellcode)); /* Criamos um ponteiro para uma função do tipo long. */ long (*executa) (); /* Apontamos a função para o shellcode. */ executa = shellcode; /* E aqui acontece a mágica! :) */ executa(); } shellcode/hexawrite.c Pronto! Está pronto nosso shellcode.Vamos executá-lo! :D root@motdlabs:~/IP_FIX/shellcode# gcc -o hexawrite hexawrite.c hexawrite.c: In function `main': hexawrite.c:33: warning: assignment from incompatible pointer type root@motdlabs:~/IP_FIX/shellcode# ./hexawrite Tamanho do Shellcode: 44 bytes. MOTDLabs root@motdlabs:~/IP_FIX/shellcode# Pronto! Um simples shellcode que imprime uma string na tela com o tamanho de 44; (43+'\0'). Mostrar o tamanho é útil pra saber se caberá em um buffer numa situação de buffer overflow. O correto seria ter usado a função strlen() para calcular o tamanho do shellcode, mas, nesse caso, ele só contará até 2, pois ele encerrará a contagem no primeiro null byte que encontrar(\x00), por isso o uso da função sizeof(). Viram como é simples fazer um shellcode? Não é nenhuma coisa de outro mundo, basta ter um mínimo de conhecimento, força de vontade e um pouco de malícia ajuda também. :) Mas como tudo na vida geralmente não é tão simples assim, vocês irão se deparar com um pequeno problema caso tentem usar esse shellcode para explorar um buffer overflow. O problema se encontra nos "\x00" que fazem parte de nosso shellcode, pois quando jogarmos o shellcode dentro do buffer e apontarmos o endereço de retorno para o shellcode, ele será executado normalmente até encontrar um NULL byte (0x00), e a execução do mesmo será interrompida como se o código tivesse sido finalizado, e isso não é nada legal!!! 68

Provavelmente você verá uma mensagem como "Segmentation Fault" ou "Illegal Instruction". Calma companheiro! No mundo da informática sempre tem um segundo caminho, pode ser mais fácil ou difícil, mas tudo tem uma segunda saída. Como iremos resolver então? É até simples a resposta, muito simples, vamos olhar denovo o código asmwrite.c. Repare que manuseiamos muitos 0x0 (push $0x0, por exemplo), mas não é somente isso o problema, repare também que usamos os registradores de 32 bits (eax), que possuem uma parte alta (ah) e a baixa (al). Quando fazemos um mov $0x4, %eax, por exemplo, não usamos todo o espaço que o registrador oferece, o que resulta em NULL byte já que sobra muito espaço. __asm__( "mov $0x1, %ebx \n" "push $0x0A \n" "push $0x7362614C \n" "push $0x44544F4D \n" "mov %esp, %ecx \n" "mov $0xa, %edx \n" "mov $0x4, %eax \n" "int $0x80 \n" "mov $0x0, %ebx \n" "mov $0x1, %eax \n" "int $0x80 \n" ); Uma solução efetiva para isso, é simplesmente ao invés de jogarmos os 0x0 direto na pilha (push $0x0) ou movermos 0x0 para um registrador (mov $0x0, %ebx) nós podemos zerar o próprio registrador com xor (xor %eax, %eax) e jogar para a pilha (push %eax) assim não terá a necessidade de manusearmos os 0x0. A outra solução, é também usarmos a parte baixa dos registradores (mov $0xb, %dl), que faz com que não seje desperdiçado espaço já que estamos usando apenas uma parte dele. A modificação é simples, e ficará da seguinte forma: shellcode/asmwrite2.c /* * Protótipo de um shellcode em ASM. * Imprime a string "MOTDLabs" na tela. * by IP_FIX . * MotdLabs . * Compilação: # gcc -o asmwrite2 asmwrite2.c */ #include main() { __asm__( "xor %eax, %eax \n" /* Sem isso nosso código em hexa não roda. 69

main() {<br />

"\xbb\x00\x00\x00\x00" /* mov $0x0, %ebx */<br />

"\xb8\x01\x00\x00\x00" /* mov $0x1, %eax */<br />

"\xcd\x80"; /* int $0x80 */<br />

/* Mostramos o tamanho para se ter um controle maior. */<br />

printf("Tamanho do Shellcode: %d bytes.\n", sizeof<br />

(shellcode));<br />

/* Criamos um ponteiro para uma função do tipo long. */<br />

long (*executa) ();<br />

/* Apontamos a função para o shellcode. */<br />

executa = shellcode;<br />

/* E aqui acontece a mágica! :) */<br />

executa();<br />

}<br />

shellcode/hexawrite.c<br />

Pronto! Está pronto nosso shellcode.Vamos executá-lo! :D<br />

root@motdlabs:~/IP_FIX/shellcode# gcc -o hexawrite hexawrite.c<br />

hexawrite.c: In function `main':<br />

hexawrite.c:33: warning: assignment from incompatible pointer type<br />

root@motdlabs:~/IP_FIX/shellcode# ./hexawrite<br />

Tamanho do Shellcode: 44 bytes.<br />

MOTDLabs<br />

root@motdlabs:~/IP_FIX/shellcode#<br />

Pronto! Um simples shellcode que imprime uma string na tela com o<br />

tamanho de 44; (43+'\0'). Mostrar o tamanho é útil pra saber se caberá<br />

em um buffer numa situação de buffer overflow.<br />

O correto seria ter usado a função strlen() para calcular o tamanho<br />

do<br />

shellcode, mas, nesse caso, ele só contará até 2, pois ele encerrará a<br />

contagem no primeiro null byte que encontrar(\x00), por isso o uso da<br />

função sizeof().<br />

Viram como é simples fazer um shellcode? Não é nenhuma coisa de<br />

outro mundo, basta ter um mínimo de conhecimento, força de vontade<br />

e um pouco de malícia ajuda também. :)<br />

Mas como tudo na vida geralmente não é tão simples assim, vocês irão<br />

se deparar com um pequeno problema caso tentem usar esse<br />

shellcode para explorar um buffer overflow. O problema se encontra<br />

nos "\x00" que fazem parte de nosso shellcode, pois quando jogarmos<br />

o shellcode dentro do buffer e apontarmos o endereço de retorno para o<br />

shellcode, ele será executado normalmente até encontrar um NULL<br />

byte (0x00), e a execução do mesmo será interrompida como se o código<br />

tivesse sido finalizado, e isso não é nada legal!!!<br />

68

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!