Post

(MCSC2014) tinypwn - SROP

0x3번 system call을 호출하는데, 이는 read()다. 그리고 곧바로 read 결과 처음 4byte로 return하기 때문에 아주 심플한 바이너리다.

ASLR과 NX가 적용되어 있기 때문에 shellcode로 리턴하는 것은 불가능. libc.so가 매핑되지 않는, 단일 바이너리이기 때문에 RTL도 불가능하다.

1
2
3
0x8048107 <pwn+17>:  int    0x80
0x8048109 <pwn+19>:  ret

int 0x80 instruction이 있기 때문에 ROP chain을 구성해 파라미터를 푸시하고 system call할 수 있다.

read()는 읽은 byte 수를 eax로 리턴하기 때문에, 이를 이용해 eax를 적당히 설정하고 int 0x80으로 리턴하면 syscall이 실행된다.

eax를 0xb로 설정하고 int 0x80하면 exec 할 수 있겠으나, 인자를 register에 지정해주어야 하므로 ebx, ecx, edx를 컨트롤 할 수 있어야 한다.

find로 찾아보면 VDSO 영역에 ecx, edx를 컨트롤 할 수 있는 gadget이 있지만, VDSO 영역이라 mapping이 random으로 이루어지며 ebx는 컨트롤 할 수 없어 사용할 수 없다. 따라서 단순 ROP로는 해결할 수 없다.

따라서, ebx를 포함한 모든 레지스터를 컨트롤하기 위해 SROP를 사용해야 한다.

https://github.com/umbum/pwn/blob/master/exploit/mcsc_tinypwn.py

쉘이 바로 종료되는건 EOF가 넘어가기 때문.

This post is licensed under CC BY 4.0 by the author.