Hacking/Pwn.

ROP with libc leak

2018. 9. 19. 22:29



레드벨벳 웬디


 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