passcode : shellcoder
(NO DRAG, NO PASSCODE)
bash2. 소스코드를 분석해보자.
따라서 우리가 사용할 수 있는 메모리 영역은 ret 영역(4bytes) 밖에 없다. 그렇다면 다른 메모리 영역을 사용해야 한다.
우리가 자주 쓰는 함수들(printf, scanf 등)은 프로그램을 실행할 때마다 함수에 대한 정보를 프로그램에 포함시키는 것은 매우 비효율적인 일이다. 따라서 공유 라이브러리를 사용하여 컴파일하는 시점에 공유 라이브러리와 연결만 하는 방법을 사용한다.
이를 위하여 존재하는 LD_PRELOAD 라는 환경변수가 존재하는데, 이 환경변수는 공유 라이브러리 영역에 올라가게 된다.
LD_PRELOAD에 환경변수를 등록되면, 프로그램이 메모리에 올라가기 전에 환경변수에 등록한 파일을 먼저 메모리에 올린다.
우선 golem 프로그램이 공유 메모리를 사용하는지 알아보자. file 명령어로 판단할 수 있다.
또한 golem 프로그램의 메모리 구조는 다음과 같다.
—————————— High Address
| argc, argv |
——————————
| ret(4) |
——————————
| sfp(4) |
—————————— ← ebp
| buffer(40) |
——————————
| 공유 라이브러리 |
——————————
| Heap |
——————————
| Data |
——————————
| Code |
—————————— Low Address
main 함수에서 볼 수 있듯이 공유 메모리 영역은 0으로 초기화되지 않으므로 이 영역에 저장된 환경변수의 주소를 ret 주소로 덮어주면 될 것 같다.
그럼 이제 LD_PRELOAD 환경변수를 등록하는 방법을 알아보자.
- 빈 파일을 코드로 취하고, NOP Sled + shellcode(without ‘/‘)를 이름으로 하여 아래와 같은 옵션을 부여하여 컴파일한다.
- fPIC : Position-Independent Code, Regardless of CPU
- shared : 공유 라이브러리와 링크, 공유 라이브러리가 없다면 정적 라이브러리에 링크
- 컴파일된 파일을 LD_PRELOAD 의 이름으로 export 해주는데, 여기서 ‘LD_PRELOAD=절대경로’ 의 방식으로 지정해준다.
이제 환경변수를 등록해보자. 우선 빈 파일을 하나 만들어준다.
그리고 1.의 방식으로 컴파일 해준다.
성공적으로 컴파일 되었으면 이를 이용하여 2.의 방식으로 export를 해주자.
성공적으로 export 되었으니 이제 gdb로 golem 프로그램을 뜯어서 우리가 export 한 LD_PRELOAD 환경변수가 어느 주소에 저장되어 있는지 알아보자. 그 전에 tmp 디렉토리를 만들어서 golem 프로그램을 copy 해주자.
main 에 bp 를 걸어주고 프로그램을 run 하자. 그리고 공유 메모리 영역은 buffer 아래에 존재하게 되므로 esp 에서 3000정도를 빼준 지점부터 분석해보자.
우리가 export 해준 LD_PRELOAD 환경변수가 있다. 0xbffff5a4 정도를 사용해주면 될 것 같다.
또한 아래 부분에 우리가 프로그램을 gdb 상에서 run 할 때에 넣어준 인자(NOP + \bf)도 있다.
이제 payload를 짜서 쉘을 따보자.
[golem] : cup of coffee
'Pwnable > LOB' 카테고리의 다른 글
[LOB] 12. DARKKNIGHT (0) | 2020.08.28 |
---|---|
[LOB] 11. GOLEM (0) | 2020.08.28 |
[LOB] 9. VAMPIRE (0) | 2020.08.28 |
[LOB] 8. TROLL (0) | 2020.08.28 |
[LOB] 7. ORGE (0) | 2020.08.28 |