IMyoungho 2019. 4. 25. 19:22

이번에 풀 문제는 Gift이다.




해당 문제는 NX만 걸려있는 상태이다.




문제를 실행시켜보았다.

프로그램이 실행되면 어떠한 주소 두 개를 출력해주고

사용자에게 입력을 받는다. 나는 "aaaa"을 입력하였다.

입력 후에는 내가 입력한 문자열이 출력되고

더 사용자에게 입력을 받는다.



IDA를 이용해서 코드를 보도록 하겠다.

굉장히 간단한 코드였다. 그리고 출력해주는 주소는 binsh과 system이었다.



binsh은 "/bin/sh"이 아닐까? 하는 생각을 했었는데 눈으로 확인해보니

그냥 고정주소인 영역을 준 것 같았다. 이름을 binsh이라고

한 것으로보아 이 곳에 "/bin/sh"을 넣어서 쓰라고 준 것 같다.



system의 경우 system 함수였다. 역시 ASLR이 걸려있어서

계속해서 주소가 바뀌므로 기준으로 사용하라고 준 것 같다.



이전에 풀었던 문제와 마찬가지로 풀면 되겠다고 생각했지만

이번에는 libc파일을 주지않아서 로컬에서 쉘이 따졌지만

서버에서는 따지지 않았다. 그러므로 정확한 offset이 필요했다.

음.. .이럴땐 어떻게해야 정확한 offset을 구할 수 있을까??



* Thanks to Py0zz1 *



방법은 바로 libc database를 이용하면 된다. Web버전과 다운로드해서

쓰는 방법이 있는데 나는 web을 사용했다. https://libc.blukat.me/

주소에서 뒤의 3바이트를 이용하면 어떤 libc를 사용하고 있는지 찾아준다.

우리가 바로 leak할 수 있는 주소는 바로 system이므로 system함수의 주소 중

하위 3바이트인 0x940을 이용하기로 했다.



그림과 같이 검색을 해보니 system함수의 offset을 알 수 있었다.




마찬가지로 gets함수의 offset도 구할 수 있었다.

gets함수의 offset을 구하는 이유는 입력을 통해 문제에서

힌트로주는 고정 주소 영역 binsh에 "/bin/sh"을 입력하기 위해서다.




그렇다면 이제 마지막으로 ret위치와 gets에 사용할 Gadget만 구하면 된다.

역시 간단하게 구할 수 있었다. ret는 sfp를 포함한 136개의 dummy

다음에 존재하고 있음을 알게되었다. 그러므로 136개의 dummy를 주자.



Gadget의 경우 gets함수의 인자가 1개이므로 pop ret 즉, pr gadget을

구하면 된다~ 간단하게 objdump 명령어를 사용하자!!

이렇게 pr gadget도 구할 수 있었다. 필요한 것은 이제 모두 구했다.!!

지금까지의 내용을 바탕으로 Payload를 구성해보자!!




< Payload >

Payload의 구성은 다음과 같다. 우선 문제에서 주어준 힌트 주소를

변수로 받아둔다. 그 다음 system과 system offset의 차이를 이용해서 

libc base 주소를 구해준다. 구한 libc base에 gets함수의 offset을 더해서

gets함수의 실제주소도 구해준다. 다음으로는 pr gadget을 이용하여 gets를

사용한다. 인자로는 binsh(고정주소 영역)을 주고 "/bin/sh\x00"을 입력해준다.

그렇게되면 binsh에 "/bin/sh\x00"이 저장되게 된다. 마지막으로

system함수를 호출하고 인자로 방금 "/bin/sh\x00"을 저장한 binsh의

주소를 인자로 넘겨주면 "/bin/sh"이 실행되면서 쉘을 딸 수 있게 된다.




이렇게 FLAG를 볼 수 있었다~~

반응형