3

Using GDB to develop exploits - A basic run through

by c0ntex | c0ntexb[at]gmail.com

www.open-security.org

---------------------------------------------------------

This document provides some useful basic commands to use with GDB during debug of applications for vulnerability

development and troubleshooting.

From the GDB man page:

"The purpose of a debugger such as GDB is to allow you to see what is going on тАШтАШinsideтАЩтАЩ another

program while it executes тАФ or what another program was doing at the moment it crashed."

Launch GDB against either a binary, a core file or a Process ID

$ gdb ./vuln

$ gdb ./vuln ./core

$ gdb -c ./core

$ gdb -silent `pidof vuln`

Set arguments for the application to execute with

(gdb) set args `perl -e 'print "A" x 50000'`

Set environment variables

(gdb) set env PATH=`perl -e 'print "A" x 50000'`

Set breakpoints

(gdb) b main // Breaks at main()

Breakpoint 1 at 0x8048fd9: file vuln.c, line 627.

(gdb) break strcpy // Breaks at strcpy()

Breakpoint 2 at 0x42079dd4

(gdb) break vuln.c:vuln_func

(gdb) rbreak ^vuln[_]func$

List defined breakpoints

(gdb) info b

Num Type Disp Enb Address What

1 breakpoint keep y 0x08048fd9 in main at vuln.c:627

Run the binary

(gdb) run

Starting program: /vuln/vuln `perl -e 'print "A" x 1000'`

Breakpoint 3, main (argc=2, argv=0xbfffee54) at vuln.c:627

627 CONSTRUCTGLOBALS();

(gdb)

Follow process forking

(gdb) set follow-fork-mode {parent, child, ask}

Show register addresses

(gdb) i r

eax 0x49488fa8 1229492136

ecx 0x8074e68 134696552

edx 0x42131300 1108546304

ebx 0x42130a14 1108544020

esp 0xbfffc190 0xbfffc190

ebp 0xbfffc1f8 0xbfffc1f8

esi 0x41414140 1094795584

edi 0x8074e70 134696560

eip 0x420744b0 0x420744b0

Show function dissasembly

(gdb) disas

Dump of assembler code for function main:

0x08048715 : push %ebp

0x08048716 : mov %esp,%ebp

0x08048718 : sub $0x68,%esp

0x0804871b : and $0xfffffff0,%esp

Show stored values on the stack

(gdb) print $esp

$1 = (void *) 0xbfffc190

(gdb) x/5x $esp-10 // Hex

0xbfffedf6: 0xee084000 0x9442bfff 0x0a140805 0x53604213

0xbfffee06: 0xee284001

(gdb) x/5s $esp-10 //String

0xbfffedf6: ""

0xbfffedf7: "@\b???B\224\005\b\024\n\023B`S\001@(???tU\001B\002"

0xbfffee12: ""

0xbfffee13: ""

0xbfffee14: "T???`???,X\001@\002"

(gdb) x/5d $esp-10 //Decimal

0xbfffedf6: -301449216 -1807564801 169084933 1398817299

0xbfffee06: -299352063

(gdb) x/5i $esp-10 //Instructions

0xbfffedf6: add %al,0x8(%eax)

0xbfffedf9: out %al,(%dx)

0xbfffedfa: (bad)

0xbfffedfb: mov $0x8059442,%edi

0xbfffee00: adc $0xa,%al

(gdb) set $esp = 0

(gdb) print $esp

$3 = (void *) 0x0

Show where in the source file we are

(gdb) list

622 int argc;

623 char *argv[];

624 {

625 int r;

626

627 CONSTRUCTGLOBALS();

628 p = checkid(argc, argv);

629 DESTROYGLOBALS();

630 strcpy(id_d, p);

631 while(1) {

Show where execution is

(gdb) where

#0 main (argc=2, argv=0xbfff2764) at vuln.c:627

#1 0x42015574 in __libc_start_main () from /lib/tls/libc.so.6

(gdb)

Continue executing

(gdb) c //Resume code execution

Continuing.

Breakpoint 2, 0x42079dd4 in strcpy () from /lib/tls/libc.so.6

(gdb) s //Step into next function

Single stepping until exit from function vuln1,

which has no line number information.

check_vuln () at vuln1.c:259

259 whoUID = (u_id ? sys_UID_secret :

(gdb) s

309 usrIDnum = numIDnum = 0;

(gdb) c //Continue again

Continuing.

Breakpoint 2, 0x42079dd4 in strcpy () from /lib/tls/libc.so.6

(gdb) c //Continue again

Continuing.

Program received signal SIGSEGV, Segmentation fault.

0x41414141 in ?? ()

Show last frame on the stack

(gdb) where 1

#0 0x41414141 in ?? ()

(More stack frames follow...)

Show failing frame info

(gdb) info frame 0

Stack frame at 0xbfff3588:

eip = 0x41414141; saved eip 0x80530c2

called by frame at 0xbfff35c8

Arglist at 0xbfff3588, args:

Locals at 0xbfff3588, Previous frame's sp in esp

Saved registers:

ebp at 0xbfff3588, eip at 0xbfff358c

Show values in some useful registers

(gdb) x/x $eip

0x41414141: Cannot access memory at address 0x41414141

(gdb) x/x $ebp

0xbfff3588: 0xbfff35c8

(gdb) x/x $esp

0xbfff354c: 0x08053309

Disassemble strcpy function

(gdb) disas strcpy

Dump of assembler code for function strcpy:

0x42079dd0 : push %ebp

0x42079dd1 : mov %esp,%ebp

0x42079dd3 : push %esi

0x42079dd4 : mov 0x8(%ebp),%esi

0x42079dd7 : mov 0xc(%ebp),%edx

0x42079dda : mov %esi,%eax

0x42079ddc : sub %edx,%eax

0x42079dde : lea 0xffffffff(%eax),%ecx

0x42079de1 : jmp 0x42079df0

0x42079de3 : nop

0x42079de4 : nop

0x42079dfb : mov %esi,%eax

0x42079dfd : pop %esi

0x42079dfe : pop %ebp

0x42079dff : ret

End of assembler dump.

Show content pointed to by a pointer

0x08054e2c in blah (p=0x41414141

) at vuln.c:284

284 for (; *p; INCSTR(p))

(gdb) x/x p

0x41414141: Cannot access memory at address 0x41414141

Display executable sections

(gdb) main info sec

Exec file:

`/root/vuln', file type elf32-i386.

0x080480f4->0x08048107 at 0x000000f4: .interp ALLOC LOAD READONLY DATA HAS_CONTENTS

0x08048108->0x08048128 at 0x00000108: .note.ABI-tag ALLOC LOAD READONLY DATA HAS_CONTENTS

0x08048128->0x080482c4 at 0x00000128: .hash ALLOC LOAD READONLY DATA HAS_CONTENTS

0x080482c4->0x080486c4 at 0x000002c4: .dynsym ALLOC LOAD READONLY DATA HAS_CONTENTS

0x080486c4->0x080488ce at 0x000006c4: .dynstr ALLOC LOAD READONLY DATA HAS_CONTENTS

0x080488ce->0x0804894e at 0x000008ce: .gnu.version ALLOC LOAD READONLY DATA HAS_CONTENTS

0x08048950->0x08048990 at 0x00000950: .gnu.version_r ALLOC LOAD READONLY DATA HAS_CONTENTS

0x08048990->0x080489b8 at 0x00000990: .rel.dyn ALLOC LOAD READONLY DATA HAS_CONTENTS

0x080489b8->0x08048b78 at 0x000009b8: .rel.plt ALLOC LOAD READONLY DATA HAS_CONTENTS

0x08048b78->0x08048b8f at 0x00000b78: .init ALLOC LOAD READONLY CODE HAS_CONTENTS

0x08048b90->0x08048f20 at 0x00000b90: .plt ALLOC LOAD READONLY CODE HAS_CONTENTS

0x08048f20->0x080594c0 at 0x00000f20: .text ALLOC LOAD READONLY CODE HAS_CONTENTS

0x080594c0->0x080594db at 0x000114c0: .fini ALLOC LOAD READONLY CODE HAS_CONTENTS

0x080594e0->0x0805f2e9 at 0x000114e0: .rodata ALLOC LOAD READONLY DATA HAS_CONTENTS

0x0805f2ec->0x0805f2f0 at 0x000172ec: .eh_frame ALLOC LOAD READONLY DATA HAS_CONTENTS

0x08060000->0x0806015c at 0x00018000: .data ALLOC LOAD DATA HAS_CONTENTS

0x0806015c->0x08060224 at 0x0001815c: .dynamic ALLOC LOAD DATA HAS_CONTENTS

0x08060224->0x0806022c at 0x00018224: .ctors ALLOC LOAD DATA HAS_CONTENTS

0x0806022c->0x08060234 at 0x0001822c: .dtors ALLOC LOAD DATA HAS_CONTENTS

0x08060234->0x08060238 at 0x00018234: .jcr ALLOC LOAD DATA HAS_CONTENTS

0x08060238->0x08060328 at 0x00018238: .got ALLOC LOAD DATA HAS_CONTENTS

0x08060340->0x08072e18 at 0x00018340: .bss ALLOC

0x00000000->0x00000462 at 0x00018340: .comment READONLY HAS_CONTENTS

0x00000000->0x00000258 at 0x000187a8: .debug_aranges READONLY HAS_CONTENTS

0x00000000->0x000006bf at 0x00018a00: .debug_pubnames READONLY HAS_CONTENTS

0x00000000->0x000448b3 at 0x000190bf: .debug_info READONLY HAS_CONTENTS

0x00000000->0x0000386e at 0x0005d972: .debug_abbrev READONLY HAS_CONTENTS

0x00000000->0x000049d8 at 0x000611e0: .debug_line READONLY HAS_CONTENTS

0x00000000->0x00001640 at 0x00065bb8: .debug_frame READONLY HAS_CONTENTS

0x00000000->0x00004d32 at 0x000671f8: .debug_str READONLY HAS_CONTENTS

0x00000000->0x000006a8 at 0x0006bf2a: .debug_ranges READONLY HAS_CONTENTS

Print data in the .plt section

(gdb) x/20x 0x08048b84

0x8048b84 <_init+24>: 0x423c35ff 0x25ff0806 0x08064240 0x00000000

0x8048b94 : 0x424425ff 0x00680806 0xe9000000 0xffffffe0

0x8048ba4 : 0x424825ff 0x08680806 0xe9000000 0xffffffd0

0x8048bb4 : 0x424c25ff 0x10680806 0xe9000000 0xffffffc0

0x8048bc4 : 0x425025ff 0x18680806 0xe9000000 0xffffffb0

Print string values in the .bbs section

(gdb) x/5s 0x08060340+11000

0x8062e38 : 'A' ...

0x8062f00 : 'A' ...

0x8062fc8 : 'A' ...

0x8063090 : 'A' ...

0x8063158 : 'A' ...

(gdb) x/5x 0x08072e18

0x8072e18: 0x41414141 0x41414141 0x41414141 0x41414141

0x8072e28: 0x41414141

Print the address for library system call

(gdb) x/x strcpy

0x42079da0 : 0x56e58955

(gdb) x/x system

0x42041e50 : 0x83e58955

(gdb) x/x printf

0x42052390 : 0x83e58955

(gdb) x/x exit

0x4202b0f0 : 0x57e58955

Finding shellcode location at +600 from $esp

(gdb) x/100x $esp+600

0xbfff38c4: 0x00000000 0x00000000 0x00000000 0x00000000

0xbfff38d4: 0x00000000 0x36690000 0x2f003638 0x746f6f72

0xbfff38e4: 0x7a6e752f 0x352d7069 0x2f31352e 0x697a6e75

0xbfff38f4: 0x41410070 0x41414141 0x41414141 0x41414141

0xbfff3904: 0x41414141 0x41414141 0x41414141 0x41414141

0xbfff3914: 0x41414141 0x41414141 0x41414141 0x41414141

0xbfff3924: 0x41414141 0x41414141 0x41414141 0x41414141

Finding opcode values at -10 offset of $esp

(gdb) x/20bx $esp-10

0xbfff2fc2: 0x06 0x08 0xc0 0xc5 0x05 0x08 0xec 0xc5

0xbfff2fca: 0x05 0x08 0x09 0x33 0x05 0x08 0x60 0x03

0xbfff2fd2: 0x06 0x08 0x18 0x0c

Return address (0xbfffc12f) alignment is off

(gdb) x/100x $esp-600

0xbfff38c4: 0x00000000 0x00000000 0x00000000 0x00000000

0xbfff38d4: 0x90900070 0x90909090 0x90909090 0x90909090

0xbfff38e4: 0x90900090 0x90909090 0x90909090 0x90909090

0xbfff38f4: 0x90900090 0x90909090 0x90909090 0x90909090

0xbfff3904: 0x90909090 0x90909090 0x90909090 0x90909090

0xbfff3914: 0x90909090 0x90909090 0x90909090 0x90909090

0xbfff3924: 0x2fbfffc1 0x00000000 0x00000000 0x00000000

(gdb) info sources

Source files for which symbols have been read in:

a=blah.c

Source files for which symbols will be read in on demand:

(gdb) info functions

All defined functions:

File blah.c:

int attach_trc(int, pid_t);

void banner(void);

int detach_trc(int, pid_t);

int main(int, char **);

int show_trc(int, struct user_regs_struct);

Non-debugging symbols:

0x080483c0 _init

0x08048488 _start

0x080484ac call_gmon_start

0x080484d0 __do_global_dtors_aux

0x08048504 frame_dummy

0x080488d0 __libc_csu_init

0x08048924 __libc_csu_fini

0x08048968 __do_global_ctors_aux

0x0804898c _fini

(gdb) info file

Symbols from "/tmp/blah".

Local exec file:

`/tmp/blah', file type elf32-i386.

Entry point: 0x8048488

0x08048114 - 0x08048127 is .interp

0x08048128 - 0x08048148 is .note.ABI-tag

0x08048148 - 0x08048198 is .hash

0x08048198 - 0x08048288 is .dynsym

0x08048288 - 0x08048322 is .dynstr

0x08048322 - 0x08048340 is .gnu.version

0x08048340 - 0x08048360 is .gnu.version_r

0x08048360 - 0x08048370 is .rel.dyn

0x08048370 - 0x080483c0 is .rel.plt

0x080483c0 - 0x080483d7 is .init

0x080483d8 - 0x08048488 is .plt

0x08048488 - 0x0804898c is .text

0x0804898c - 0x080489a6 is .fini

0x080489a8 - 0x08048c36 is .rodata

0x08048c38 - 0x08048c3c is .eh_frame

0x08049c3c - 0x08049c44 is .ctors

0x08049c44 - 0x08049c4c is .dtors

0x08049c4c - 0x08049c50 is .jcr

0x08049c50 - 0x08049d18 is .dynamic

0x08049d18 - 0x08049d1c is .got

0x08049d1c - 0x08049d50 is .got.plt

0x08049d50 - 0x08049d5c is .data

0x08049d5c - 0x08049d64 is .bss

EOF


Ведете ли вы блог?

Да
Нет
Планирую


Результаты опроса

Новостной блок