ROP with libc leak
레드벨벳 웬디
CTF 문제를 풀 때 ROP를 이용해서 공격하는 문제들이 항상 나오는데, 이번에 Layer7 CTF talmo_party 문제와 사이버가디언즈 2회차 문제들을 풀어보면서 입력받는 함수가 없을 때 어떤 식으로 ROP exploit 코드를 구성하는지 알게 되어 블로그에 글을 남긴다.
만약 입력받는 함수에서 stdin을 통한 fgets() 함수를 사용했을 경우, 우리는 ROP chain에서 fgets()를 사용할 수 없게 된다.
왜냐하면 stdin을 인자로서 넘겨줄 수 있는 방법이 없기 때문이다. 실제 코드에서 stdin을 인자로 넘겨줄 때는 libc 상의 실제 주소로 들어가기 때문에 우리는 libc leak 이라는 것을 통해서 stdin을 사용해야한다. (그런데 libc leak 을 하게 되면 ROP를 거의 성공했다고 보아도 무방..ㅋㅋ)
Libc가 로드되었다는 것은 함수의 주소들이 실제로 메모리 상에 존재한다고 볼 수 있다. 따라서 우리는 함수의 실제 주소들을 알게 된다면 그게 어떤 함수일지라도 실행시킬 수 있게 된다. 그래서 우리는 Libcbase를 릭하여 Libc의 주소를 갖고 오는 것이다.
Libc는 PIE 환경이기 때문에
| (함수의 실제 주소) - (Libc상의 PIE가 적용된 함수의 주소) = &Libc_base
가 된다. 우리는 Libc에서 특정함수에 PIE가 적용된 값을 알 수 있기 때문에 libc leak을 통해 함수의 실제 주소를 구할 수 있다.
그럼 Libc Leak은 어떻게 하냐.
puts@plt()를 이용해서 아무 함수의 got값을 Leak 할 수 있다. (GOT에는 함수의 실제 주소가 들어가있다.)
따라서 puts@plt(puts@got); 후 나온 값이 puts 의 실제 주소라는 것이고,
puts - puts@libc = libc base 라는 것이다.
그럼 이걸 응용해서 system 함수의 실제 주소도 구할 수 있다.
system = &libc base + system@libc
그리고 그걸 이용해서 system("/bin/sh\x00"); 을 하면 쉘을 획득하게 된다.
(보통 이런 류의 ROP 문제가 나올 때는 항상 립씨까지 같이 주기 때문에 libc 상의 /bin/sh\x00 을 찾아서 인자로 넣어주면 된다.)
끝.
'Hacking > Pwn.' 카테고리의 다른 글
잊기전에 적어두는 bash trick (0) | 2018.11.06 |
---|---|
FSB 공격시 유용한 것들 (0) | 2018.07.27 |
LoB에서 bash2 명령을 사용하는 이유 (0) | 2018.07.13 |
python jail (0) | 2018.06.21 |
Shell Escaping tips (0) | 2018.04.17 |