铁人三项2018 pwn [heapmain] Writeup
这个题目的原题是RHME3,直接拿来二进制修改,去掉网络函数,使用socat部署。这波操作可还行
分析
废话不多说,题目漏洞比较明显,在于使用函数delete_player
后没有置空selected
导致UAF。那么,我们能用这个UAF干什么呢?
程序中player的数据结构是这样的
struct player{
int32 attack;
int32 defense;
int32 speed;
int32 precision;
char* name;
}
这块就有个关键点edit_player
中的set_name
函数,用来修改name
字段的时候用到了realloc
函数。这个函数比较特殊,可以在制定地址上重新分配一个堆,即可以对给定的指针所指的空间进行扩大或者缩小 。当然,扩大的时候会破坏其他内存则类似malloc重新分配一个指针指向的内存空间。
泄露堆地址(貌似没啥用)
首先,我们可以通过以下方法泄露堆的地址:
1.分配一个player 1,name的长度为23,则name会分配24字节。
2.选中这个player 1
3.释放这个player 1
4.显示这个player 1,这时候1->name中的fd指向player 1的地址。打印name的时候就会把player的地址打印出来。
泄露libc地址
接着,我们可以通过以下方法泄露libc的地址:
1.分配一个player 1,name的长度为23,则name会分配24字节。
2.选中这个player 1
3.释放这个player 1
4.分配一个player 2,这块内存其实是1->name。2->name长度为23,这块内存为1->player。
5.编辑player 1,1->name长度扩展为0x90。
6.再创建一个player 3(作用是隔开0x90的内存和top chunk,防止free后合并到top chunk)
7.然后释放palyer 2,也就是把1->name的内存释放,此时这块内存被放入unsorted bin里,link到main_arena上
8.show player1 会泄露出libc上的main_arena的地址,就可以计算出libc的基址,由于给了libc就可以求出system的地址
GOT劫持
接下来是控制执行流程(realloc分配内存到got上,覆盖aoit的got为system):
1.分配player 1,name长度80
2.分配player 2,name长度80
3.选中1
4.释放player 1,释放player 2
5.分配一个player 3,name的长度为23,内容为'a'*16 + atoi_got
。此时player3 的内存为player2,player3->name为player1。
6.修改player->name为system,此时会将atoi_got分配给我们,然后system的地址会填入atoi。
7.最后输入sh即可
EXPLOIT
最后的利用脚本点击https://blog.formsec.cn/2018/06/05/%E9%93%81%E4%BA%BA%E4%B8%89%E9%A1%B92018-pwn-heapmain-Writeup/
查看
往期精彩回顾
DedeCMS任意用户密码重置漏洞
从CPU漏洞Meltdown&Spectre看侧信道攻击
渗透技巧 | Windows上传并执行恶意代码的N种姿势
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- C++核心准则SF.8:为所有的.h文件使用包含监护
- 利用logsave如何将命令输出保存起来
- CentOs下安装gcc/g++/gdb的方法
- 详解firewall的规则设置与命令(白名单设置)
- 二叉树:构造一棵最大的二叉树
- Ubuntu16.04 ext4格式硬盘挂载普通用户权限控制的操作方法
- Apache Spark 2.0 在作业完成时却花费很长时间结束
- centos 6.9 升级glibc动态库的详细过程
- Ubuntu18.04(linux)安装MySQL的方法步骤
- ubuntu18.0.4安装mysql并解决ERROR 1698 (28000): Access denied for user ''root''@''localhost''
- 动态在线扩容root根分区大小的方法详解
- centos7使用rpm安装mysql5.7的教程图解
- 关于Linux命令行下的数学运算示例详解
- Apache访问日志的配置与使用
- linux启动和重启nginx方法