12 de set de 2014

GDB


O GNU Project Debugger permite executar e modificar programas compilados por etapas, examinar a memória dos programas e ver os registros do processador. O GDB suporta as linguagens ADA, C, C++, assembly, e outros.
  • Comandos básicos:
run: inicia a execução do programa.
kill: termina a execução do programa.
q: sai do gdb.
b *A: insere um breakpoint no endereço absoluto A. 
step <n>: executa a linha atual e passa para a próxima linha.
next <n>: continua a execução até a próxima linha da função atual.
display <expressão>: imprime o valor atual da variável passada como argumento.
undisplay <n>: remove a entrada "n" da lista de exibição.
print <expressão>: imprime o valor de uma variável ou expressão sem adicioná-los a lista de exibição.
info reg: lista os registros.
x /CT A:  C número de unidades para exibir.
                  T x número inteiro.
                     b binário.
                     c caractere.
                     s string que termina nula.
                  A endereço absoluto. 


disassembly-flavor att | intel: definite o estilo disassembly do debugador.         
disass main: joga o código assembly na função main. 

  • Wargames:
Vamos supor que você tenha um executável (ELF, Linux) que aceita apenas uma senha como argumento e verifica se está correto (tipo o level01 do Smash the stack):

wargame.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int
main(int argc, char **argv)
{
char senha[] = "zeldani";

if(argc < 2)
{
printf("Uso: %s <senha>n", argv[0]);
exit(1);
}

if(strncmp(argv[1], senha, strlen(senha)))
  {
 printf("FALHOU\n");
 exit(1);
  } else {
  printf("GANHOU\n");
 return(0);
  }
 return(0); 
}
 
Podemos encontrar a string usando as ferramentas strings, objdump, hexdump, ltrace ou debugando com o gdb:
$ gcc wargame.c -o wargame -g
$ gdb -q ./wargame

(gdb) set disassembly-flavor intel
(gdb) disass main

(gdb) info reg 
  0x00000000004006ba <+106>:    call   0x4004f0 <strncmp@plt>
$ man 3 strncmp
SYNOPSIS
#include <string.h>
int strcmp(const char *s1, const char *s2);
int strncmp(const char *s1, const char *s2, size_t n);
(gdb) b *0x4004f0
Breakpoint 1 at 0x4004f0
(gdb) run AAAAAA
Starting program: /home/zeldani/wargame AAAAAA
Breakpoint 1, 0x00000000004004f0 in strncmp@plt ()

Agora executamos um breakpoint no endereço da instrução call e através do info reg analisamos os primeiros 4 registros de uso geral (rax, rbx, rcx e rdx) encontrando a função strncmp(), que provavelmente guarda a string procurada.

(gdb) x/8cb $rcx
0x7fffffffdc00:    122 'z'    101 'e'    108 'l'    100 'd'    97 'a'    110 'n'    105 'i'    0 '\000'
(gdb) x/s 0x7fffffffdc00
0x7fffffffdc00:    "zeldani"
   

O comando x/8cb encontra a string do endereço 0x7fffffffdc00 do RCX, com 8 caracteres decimais e seus respectivos valores ASCII.
Done, agora é possível executar o programa. ;)

* Fontes:
http://www.lrc.ic.unicamp.br/~luciano/courses/mc202-2s2009/tutorial_gdb.txt
http://web.eecs.umich.edu/~sugih/pointers/summary.html
http://2600hertz.wordpress.com/2010/01/14/hacking-into-any-executable-using-gdb/
http://brundlelab.wordpress.com/2010/06/21/playing-with-gdb-reverse-engineer-your-way/
http://cseweb.ucsd.edu/classes/sp11/cse141/pdf/02/S01_x86_64.key.pdf
Hacking the art of exploitation - Jon Erickson

C in a nutshell: A desktop quick reference - P. Prinz, T. Crawford 
http://www.cs.mcgill.ca/~consult/info/gdb.html 
https://sourceware.org/gdb/current/onlinedocs/gdb/

0 comentários:

Postar um comentário