엄범



`` 0x3``번 system call을 호출하는데, 이는 ``c read()``다.

그리고 곧바로 read 결과 처음 4byte로 return하기 때문에 아주 심플한 바이너리다.


ASLR과 NX가 적용되어 있기 때문에 shellcode로 리턴하는 것은 불가능.

libc.so가 매핑되지 않는, 단일 바이너리이기 때문에 RTL도 불가능하다.


```

   0x8048107 <pwn+17>:  int    0x80

   0x8048109 <pwn+19>:  ret    

```

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


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


eax를 `` 0xb``로 설정하고 ``c 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가 넘어가기 때문.