Troll의 소스를 확인하도록 하겠습니다.



첫번째로 보이는 차이점은 11번째부터 15번째라인까지의 내용이 변경 되었네요.

입력 할 수 있는 argument의 갯수가 제한이 없던 것에서 1개로 바뀌었습니다.

대신 argv[0]의 길이 제한은 사라졌네요.

여전히 버퍼나, 환경변수나, argv[1]0으로 초기화 하는 것으로 보아서 링크 파일을 이용해서 argv[0]에 쉘코드를 입력해야 할 것 같습니다.

 

그럼 파일의 이름을 쉘코드로 하는 링크파일을 생성해 주겠습니다.

어라.. 파일이 생성이 안되네요그 이유는 바로 쉘코드에 포함되어 있는 \x2f때문입니다. \x2f“/”인데요. 따라서 경로가 한번 나눠지게 되고 정상적으로 링크가 생성되지 않는 것입니다.

이번 문제의 핵심은 이 \x2f를 포함하고 있지 않은 쉘코드를 이용하는 것입니다.

 

이러한 쉘코드를 흔히 다형성 쉘코드라고 부릅니다.

다형성 쉘코드란 쉘코드를 암호화하고, 사용하기 전에 복호화를 원본 쉘코드를 다시 구하여 동작하는 쉘코드를 말합니다.

더미다같은 패킹과 비슷한 개념이라 생각하면 될것 같습니다.

 

제가 사용한 다형성 쉘코드는 다음과 같습니다.

"\xd9\xc5\xd9\x74\x24\xf4\xb8\x15\xc3\x69\xd7\x5d\x29\xc9\xb1\x0b\x31\x45\x1a\x03\x45\x1a\x83\xc5\x04\xe2\xe0\xa9\x62\x8f\x93\x7c\x13\x47\x8e\xe3\x52\x70\xb8\xcc\x17\x17\x38\x7b\xf7\x85\x51\x15\x8e\xa9\xf3\x01\x98\x2d\xf3\xd1\xb6\x4f\x9a\xbf\xe7\xfc\x34\x40\xaf\x51\x4d\xa1\x82\xd6"

 

우선 NOP슬라이드를 포함한 쉘코드를 이름으로 하는 링크를 생성하도록 하겠습니다.

NOP슬라이드는 많아서 나쁠거 없으니 한 100개쯤

 

그리고 적당히 ret값을 넣어 오류를 유도하도록 하겠습니다.


 

에러가 났으니 보다 구체적으로 쉘코드의 위치를 얻기 위해 core dump 디버깅을 하도록 하겠습니다.


NOP슬라이드가 보이네요. 얼추 0xbfffff50쯤을 ret 주소로 하면 될듯 합니다.


빙고~! 쉘이 떳네요.

 

이제 원본 파일을 대상으로 공격하도록 하겠습니다.

정상적으로 troll의 쉘을 획득하였습니다.

패스워드는 aspirin이네요..

이 문제 풀려고 3일동안 삽질했더니 아스피린이 간절하긴 합니다

뭔가 센스있는 패스워드이네요 ㅎ

orge의 소스를 확인하도록 하겠습니다.

darkelf의 소스코드에 비하여 한부분이 추가되었습니다.



argv[0]의 크기가 77인지 확인하는 코드가 추가 되었습니다.

 

argv[0]은 프로그램을 실행할때 첫번째 인자를 의미 합니다.

$./orge라고 프로그램을 실행하게 되면

argv[0]에는 /home/darkelf/./orge가 들어가게 됩니다.

, 프로그램의 이름이 /home/darkelf를 포함하여 77byte가 되어야 합니다.

그런데 권한이 없기 때문에 우리가 직접 이 프로그램의 이름을 변경할 수는 없습니다.

따라서 심볼릭 링크를 이용하여 다른 파일을 실행해서 orge를 실행해 주면 argv[0]를 마음대로 바꿀수 있습니다.

(심볼릭 링크에 대한 정보는 구글을 이용해 주세요)

 

ln –s orge link명령어를 통해 orge의 링크파일을 생성해 주고, ./link를 실행하면

argv[0]에는 /home/darkelf/./link가 들어가게 됩니다.

 

이방법을 이용하여 이름이 긴 파일을 생성해 주면 됩니다.

총 필요한 argv[0]77byte 이므로 /home/darkelf/14byte를 제외하고 파일의 이름을 63byte로 생성해 주면 됩니다.

 

그리고 페이로드는 이전 문제를 풀던것과 동일하게 argv[2]NOP슬라이드와 쉘코드를 넣는 방식을 이용하면 될듯 합니다.

 

그럼 우선 테스트를 위하여 tmp폴더에 orge를 옮기고 링크파일을 생성하도록 하겠습니다.

링크파일은 경로가 /home/darkelf에 이어 /tmp 4byte가 추가되었기 때문에 파일의 이름은 59byte가 될듯 하네요.

테스트를 해봤더니 정상적으로 조건을 통과하네요.

Argv[0]./가 들어가는 것을 없애기 위하여 절대 경로로 실행하였습니다.

상대경로로 명령어를 실행하실 분은 이름의 길이를 계산할때 ./ 2byte를 고려해주셔야 합니다.

 

예상 페이로드는 다음과 같습니다.


이제 ebp값을 알아내기 위하여 gdb로 디버깅을 하겠습니다.

알아낸 ebp의 위치는 0xbffffa38입니다. 입력 값에 따라서 프로그램이 들어가는 메모리의 위치가 변경될 수 있기 때문에 실행시 입력 페이로드도 동일하게 넣어 주어야 합니다.

 

보다 정확하게 페이로드의 위치를 구하기 위하여 x/40x $ebp 명령어를 통하여 ebp부터의 메모리 내용을 확인하도록 하겠습니다.

확인 결과 ret의 주소를 0xbffffc08쯤으로 하면 될듯 합니다.

 

수정된 페이로드를 넣어 실행하도록 하겠습니다.

역시나 한번에 안되고 에러가 뜨네요.

 

core dump를 이용하여 gdb 디버깅을 통해 쉘코드의 위치를 확인하도록 하겠습니다.

0xbfffffb8 이후로는 쉘코드가 들어갈 공간이 충분하지 않습니다.

 

따라서 다시 ebp부터의 값을 확인해 보도록하겠습니다.

0x90들이 들어 있는부분의 한 지점을 잡아주면 됩니다.

 

페이로드의 Ret0xbffffba0으로 수정하여 다시 실행해 보도록 하겠습니다.

정상적으로 쉘이 획득이 되었네요.

 

복사파일에서 쉘이 획득 되었으므로 이제 원본 파일을 대상으로 진행하면 될듯 합니다.


우선 길이가 63byte인 심볼릭 링크를 생성하고 페이로드를 입력해 보도록 하겠습니다.


성공적으로 orge의 쉘이 획득 되었네요.

orge의 패스워드는 timewalker입니다.

darkelf의 소스코드를 보도록 하겠습니다.


orc에서 wolfman으로 갈 때 buffer hunter가 추가 되었는데, darkelf로 가니깐 argument의 길이를 체크하는 부분이 추가가 되었네요.

 

Argv[1] 뒷부분에 쉘코드를 입력하는 것을 방지 하기 위해서 추가한 코드같은데, orc에서부터 저희가 해왔던 풀이법은 argv[2]에 쉘코드를 입력하는 방법이니 그대로 적용해도 될듯합니다.(페이로드 하나가지고 너무 우려먹네요…)

 

앞선 방법과 마찬가지로 페이로드를 작성해 주면 될듯 합니다.

http://grayfieldbox.tistory.com/entry/LOBLord-Of-BufferOverflow-goblin-orc

에러가 날때 해결법 또한 앞선 방법과 마찬가지로 하면 되구요.

http://grayfieldbox.tistory.com/entry/LOBLord-Of-BufferOverflow-orc-wolfman

darkelf의 비밀번호는 kernel crashed입니다.

+ Recent posts