Using GDB to Develop Exploits - A Basic Run Through

EDB-ID:

13205

CVE:

N/A


Author:

c0ntex

Type:

papers


Platform:

Multiple

Date:

2006-04-08


Become a Certified Penetration Tester

Enroll in Penetration Testing with Kali Linux , the course required to become an Offensive Security Certified Professional (OSCP)

GET CERTIFIED

                       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 <main+0>:    push   %ebp
0x08048716 <main+1>:    mov    %esp,%ebp
0x08048718 <main+3>:    sub    $0x68,%esp
0x0804871b <main+6>:    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 <strcpy+0>:  push   %ebp
0x42079dd1 <strcpy+1>:  mov    %esp,%ebp
0x42079dd3 <strcpy+3>:  push   %esi
0x42079dd4 <strcpy+4>:  mov    0x8(%ebp),%esi
0x42079dd7 <strcpy+7>:  mov    0xc(%ebp),%edx
0x42079dda <strcpy+10>: mov    %esi,%eax
0x42079ddc <strcpy+12>: sub    %edx,%eax
0x42079dde <strcpy+14>: lea    0xffffffff(%eax),%ecx
0x42079de1 <strcpy+17>: jmp    0x42079df0 <strcpy+32>
0x42079de3 <strcpy+19>: nop
0x42079de4 <strcpy+20>: nop
0x42079dfb <strcpy+43>: mov    %esi,%eax
0x42079dfd <strcpy+45>: pop    %esi
0x42079dfe <strcpy+46>: pop    %ebp
0x42079dff <strcpy+47>: ret
End of assembler dump.


Show content pointed to by a pointer
0x08054e2c in blah (p=0x41414141 <Address 0x41414141 out of bounds>) 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 <mkdir>:      0x424425ff      0x00680806      0xe9000000      0xffffffe0
0x8048ba4 <chown>:      0x424825ff      0x08680806      0xe9000000      0xffffffd0
0x8048bb4 <strchr>:     0x424c25ff      0x10680806      0xe9000000      0xffffffc0
0x8048bc4 <write>:      0x425025ff      0x18680806      0xe9000000      0xffffffb0


Print string values in the .bbs section
(gdb) x/5s 0x08060340+11000
0x8062e38 <G+10968>:     'A' <repeats 200 times>...
0x8062f00 <G+11168>:     'A' <repeats 200 times>...
0x8062fc8 <G+11368>:     'A' <repeats 200 times>...
0x8063090 <G+11568>:     'A' <repeats 200 times>...
0x8063158 <G+11768>:     'A' <repeats 200 times>...
(gdb) x/5x 0x08072e18
0x8072e18:      0x41414141      0x41414141      0x41414141      0x41414141
0x8072e28:      0x41414141


Print the address for library system call
(gdb) x/x strcpy
0x42079da0 <strcpy>:    0x56e58955
(gdb) x/x system
0x42041e50 <system>:    0x83e58955
(gdb) x/x printf
0x42052390 <printf>:    0x83e58955
(gdb) x/x exit
0x4202b0f0 <exit>:      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

# milw0rm.com [2006-04-08]