LOB_14.bugbear->giant

해킹/LOB 2016. 1. 31. 15:03


코드가 길어지고 모르는 함수들이 나와서 조금은 당황스럽다.

처음에는 popen 하고 buffer로 옮기는 과정에서 뭔가 해줘야 하는줄 알았으나 //gain ~~~ //end 이부분은 그냥 execve함수의 주소를 가져오기 위한 부분일 뿐이다.

그러므로 지난 darkknight->bugbear 문제와 동일하게 풀되 함수만 execve를 사용하면 된다.


먼저 bugbear 폴더에 tmp폴더를 만들어서 복사본을 만들고 gdb로 열어봤다.



어셈블리 코드가 매우 길다. 블록지정한 부분이 execve_addr = lib_addr + (int)execve_offset; 부분이다.

main+201에 bp를 걸고 ebp-56에 execve의 주소가 어떻게 들어가는지 살펴보자.





0x080da023이라고 나와있어서 해당 메모리를 살펴보니 접근할 수 없다고 한다.

그래서 p execve를 해서 실제 execve의 주소를 살펴보니 0x400a9d48로 차이가 많이난다.

이 문제는 첫번째 popen이 실패하기 때문에 발생한다. 복사본은 setuid가 걸려있지 않아서 /home/giant/assassin에 대한 접근 권한이 없어서 제대로된 주소를 읽어오지 못하는 탓이다.

하지만 원본 파일에서는 아마도 제대로 execve의 주소를 가져올 것이고 그 주소는 아마도 0x400a9d48과 일치할 것이다.

먼저 원본파일에 값을 넣어 확인해보자.





처음에 리턴주소에 \x400a9d48을 넣어줬을 때 You must use execve!가 나와서 조금 당황했다.

하지만 주소가 틀렸던 것은 아니고 "\x0a"가 리눅스에서 개행으로 인식하기 때문이다. 이렇게 되면 뒷부분이 짤리게 된다.

""를 사용해서 전체 파이썬 스크립트를 감싸주니 You must use execve 메시지가 더이상 나오지 않는다. 주소가 맞는 모양이다.




그럼 이제 execve로 넘어갈 인자를 줘야하는데.. 저번처럼 SFP를 변조하는 방식으로는 못하고 main 스텍의 뒷쪽 부분을 이용해야 한다.

함수가 호출되었을때 이전 함수에서 넘어오는 인자는 ebp+8, ebp+12, ebp+16 ... 이런식으로 들어간다. 그림을 그려보면




이렇다. ret 한 후에 execve가 프롤로그 과정을 거치면서 위에 보이듯이 원래 main의 리턴주소에서 8바이트 뒷쪽부터 인자가 들어간다.

즉 페이로드를 (더미 44바이트 || 리턴주소 || 더미 4바이트 || 인자1 || 인자2 || 인자3)이렇게 넣어주면 되겠다.


그럼 이제 인자로 어떤 값들을 넣어줄까 생각해보자.

내가 실행하고자 하는 코드는 대략

char* argv2[2]={"/bin/sh", }

execve("/bin/sh", argv2, NULL);


이정도다. argv2[0]으로 "/bin/sh"를 꼭 넣어줘야 하는지 확신은 없지만 보통 들어가므로 넣어줘서 나쁠건 없다.

첫번째 인자로 넘어갈 "/bin/sh"는 system 함수의 아랫쪽에 들어있다는 사실을 알고는 있으나 이번에는 argv[2]에 직접 넣어준 다음 주소를 전달할 생각이다.

왜냐하면 두번째로 argv2 인자를 넘겨줄때 main함수의 argv 부분을 이용할 생각이기 때문인데..

argv[0]=/home/bugbear/giant

argv[1]="a"*44+rtn+인자들~~

argv[2]="/bin/sh"

이렇게 구성된 argv 테이블에 argv[2]의 주소를 argv2[0]의 주소라고 전달해 줄 것이다. 주소로 된 테이블 형식과 뒤에 4바이트 null값이 필요하기 때문이다.


자 그러면 코어파일을 만들어서 정확한 주소를 계산해보자.





복사본 파일이라 assassin 파일을 읽을 수 없는 관계로 execve의 주소를 잘못된 주소로 넘겼지만 코어파일만 생성되면 되므로 그냥 넘어가고...

떨어진 코어파일에서 0xbffffae4부분이 argv 테이블이 시작되는 부분이고 그중 세번째 0xbffffc3a가 argv[2]="/bin/sh"임을 확인했다.


첫번째 인자인 "/bin/sh"의 주소는 0xbffffc3a를,

argv2의 주소는 argv[2]부터 시작해야하므로 두번째 인자로는 0xbffffaec를 넣어주면 되겠다.

세번째 인자로는 null을 넣어줄 것인데 마침 argv[2]뒤에 4바이트 널이 있으므로 해당주소인 0xbffffaf0을 넣어주면 된다.


페이로드를 구성해보면


./giant "`python -c 'print "a"*44+"\x48\x9d\x0a\x40"+"dddd"+"\x3a\xfc\xff\xbf"+"\xec\xfa\xff\xbf"+"\xf0\xfa\xff\xbf"'`" /bin/sh

이렇게 된다.

주의할 점은 제대로된 execve의 주소(0x400a9d48)을 넣어줘야 한다는 점, 파이썬 스크립트를 ""로 감싸줘야 한다는 점 정도가 있겠다.

위 스크립트로 공격을 시도해봤다.




성공했다. 그냥 뭐 인자 전달 연습인듯.

끝-

'해킹 > LOB' 카테고리의 다른 글

LOB_16.assassin->zombie_assassin  (0) 2016.01.31
LOB_15.giant->assassin  (0) 2016.01.31
LOB_번외.bash2의 함정.  (0) 2016.01.29
LOB_13.darkknight->bugbear  (0) 2016.01.29
LOB_12.golem->darkknight  (0) 2016.01.28
Tags
Social