wargame/Lord Of Buffer overflow

[LOB] goblin

LimeLee 2018. 8. 13. 02:03


소스코드 분석



cobolt 문제와 비슷하게 16byte 크기의 buffer가 존재하므로 같은 방법을 이용해도 괜찮을 듯 하다.

다른 점은 이번 문제에선 인자로 받지 않지 않는다. 이는 인자값을 넘기는 `` 대신 다른 명령을 통해 해결할 수 있다.

문제는 stdin이라는 힌트다. cobolt와 같은 방법을 했는데 쉘을 따지지 않는데 이유를 알려면 시스템 적인 배경지식이 어느정도 있어야 알 수 있는 듯하다. 아직까지도 완벽한 이해는 하지 못했다.


문제 풀이




여러가지 방법이 있겠지만, 쉘 코드의 주소로 이동하는 데에는 cobolt와 별 다른 차이점이 없으므로 환경 변수와 NOP Sled 기법을 이용한다.



환경변수는 프로그램을 만들어 출력했다. 위치는 0xbffffea8임을 알 수 있다.

인자 값이 아닌 프로그램의 입력 값으로 보낼 때는 파이프( | ) 명령어를 이용하면 된다. 

예상 페이로드는 'DUMMY * 20 + (쉘 코드가 있는 환경 변수의 대략적인 주소)' 가 될 것이라 생각했다.

하지만 예상 페이로드 | ./cobolt 를 보내면 Segmentation Fault는 커녕 아무런 동작을 안하고 cobolt의 쉘만 떠 있다.



잘못 된 페이로드인가 추측하고 strace를 통해 바이너리 추적을 해보았지만 프로그램은 쉘 코드가 있는 주소로 점프했고, 제대로 쉘을 실행한 것을 확인할 수 있다. 결과적으로 쉘은 실행이 되었지만 명령을 받지 않고 종료했다. 위 그림의 빨간 선 부분이 전 문제들에서는 쉘을 얻었을 때, 입력을 받을 때까지 진행하지 않고 대기하고 있는 부분이다. 하지만 이번 문제에서는 대기하지 않고 바로 종료하였다. 


힌트가 stdin이였기에 예상 페이로드에 < test.txt를 하여 실행시켜보았지만 별 다른 변화없이 shell은 종료되었다.


다음엔 페이로드 뒤에 my-pass같은 명령어를 바로 넣으면 되는 건가 싶어 페이로드 뒤에 ;ls 를 넣고 실행 시켜 보았더니 ls로 출력된 값이 전부 stdin으로 넘어가는 것을 확인할 수 있었다. 정확한 원인은 잘 모르지만, 페이로드를 입력하고 쉘은 실행되었지만 페이로드가 끝나면서 stdin이 종료되고 그와 함께 쉘이 함께 종료되었다고 추측할 수 있다. 


https://security.stackexchange.com/questions/155844/using-cat-file-cat-to-run-a-simple-bof-exploit


위 페이지를 참고하여 해결하였다. stdin이 종료되기 때문에 ;cat을 이용하여 stdin을 종료시키지 않고 프로그램에 입력을 그대로 할수 있다는 내용으로 추측된다. 종료되지 않는 이유는 정확히 모르지만 python의 stdin은 종료하고 ; 다음 명령어의 cat이 다시 stdin을 쉘에 넘겨줄 수 있다.  이 부분에 대해선 추가적으로 시스템 공부를 해볼 필요가 있을 것 같다.



위의 URL 주소의 정보를 참고하여 페이로드를 ('DUMMY * 20 + (쉘 코드가 있는 환경 변수의 대략적인 주소)';cat) 으로 변경하고 바이너리 추적을 한다. 이번에는 stdin이 종료되지 않아 쉘에서 계속 입력을 받도록 대기를 하고, exit 명령을 수행한 것을 볼 수 있다.



strace 명령을 위한 임시파일이 아닌 setuid가 걸려있는 문제 파일에 페이로드를 보내 다음 계정의 패스워드를 알아낸다.


'wargame > Lord Of Buffer overflow' 카테고리의 다른 글

[LOB] orc  (0) 2018.08.13
[LOB] cobolt  (0) 2018.08.07
[LOB] gremlin  (0) 2018.08.07