本文由“合天智汇”公众号首发,作者:萌新

前言


这道题目应该是pwnable.kr上Toddler's Bottle最难的题目了,涉及到相对比较难的堆利用的问题,所以拿出来分析。

登录

看看源程序

程序中有几点要注意的地方:

1. 定义的OBJ结构体中一个指针4字节,buf[]数组8字节

2. Unlink()的过程其实就是双向链表中摘下中间那一块的过程

3. 主函数中malloc了三个结构体,并通过指针连成了双向链表A<->B<->C

4. 打印出A的栈地址,堆地址,这两个地址这里记做stack,hep,待会儿在分析中会用到

5. 漏洞在于gets函数会造成溢出,同时通过随后的unlink()进行利用

具体而言什么是unlink呢?

unlinked 是堆溢出中的一种常见形式,通过将双向列表中的空闲块拿出来与将要free的物理相邻的块进行合并。(将双向链表上的chunk卸载下来与物理chunk合并)。Unlink漏洞的利用条件就是有3个以上的空闲chunk链表,其中最前面的chunk存在有堆溢出。没错我们这次的题目就存在这个情况

解链的原理相信学过数据结构的师傅们都清楚了

对照着这次的程序,BK相当于A,P相当于B,FD相当于C

这次需要用到的漏洞溢出漏洞技术称为Dword shoot。在进行双向链表的操作过程中,有溢出等的情况下,删除的chunk的fd、bk两个指针被恶意的改写的话,就会在链表删除的时候发生的漏洞。

对应到本题的程序,将被删除的chunk为B,而我们可以通过溢出A来修改B的fd,bk,修改后会引发什么漏洞呢?我们接下来详细说明。

把二进制文件下到本地分析

要我们攻击的最终是目的是劫持返回地址,写入shellcode的地址,以及为了能够溢出A,修改B的指针等操作,我们都需要看看汇编中一些关键量的地址

关键的地方:

1. A在栈上的地址是ebp-0x14,即ebp-0x14=stack=&A

2. 最后的ret,作用是赋值给eip寄存器,而我们要做的就是修改esp寄存器的内容为shellcode的地址

3. 通过lea esp,[ecx-0x4]可以知道esp的值来自[ecx-4]

4. leave指令对esp没影响

5. mov ecx,DWORD PTR[ebp-0x4],可知,ecx的值来自[ebp-4]

6. 综上,我们只需要把shellcode的地址写到[ebp-8]地址(事实上这样很不方便,我们下面实际上是把shellcode地址+4写到[ebp-4]地址,这样的话,shellcode地址+4-4,传给esp的时候恰好就是shellcode的地址)

推论:

(1)由1得,ebp-4等于stack+0x14-0x4

(2)heap_是A在堆中的地址,加上在buf前有fd,bk链各个指针共8个字节,所以shellcode的地址是写到了heap+0x8处,所以 (shellcode地址+4)=(heap+0x8)+0x4

只要实现了* (ebp-4)=&shellcode+4,则ecx就被覆盖成了&shellcode+4,然后执行了

 0x08048603 <+212>:   lea    esp,[ecx-0x4]
0x08048606 <+215>: ret

我们就拿到shell了

我们前面留下了一个问题:

被删除的chunk为B,修改B的fd,bk,修改后会引发什么漏洞

先举个简单的例子看看

设我们修改了B->fd=!!!!,B->bk=@@@@

在调用unlink(B)时,

    BK=P->bk;
FD=P->fd;
FD->bk=BK;
BK->fd=FD;
对应执行的流程是这样子的
BK=*(B+4)=@@@@ //B->bk前还有B->fd,占4字节
FD=*(B)=!!!!
*(FD+4)=*(!!!!+4)=BK=@@@@
*(BK)=*(@@@@)=FD=!!!!

通过红色字体的关系,我们知道,修改了B的fd,bk之后,就可以在进行覆盖操作

这里我们设修改了B->bk=[ebp-4],B->fd=&shellcode+4

则进过unlink(B)之后会有

*(&shellcode+4+4)=[ebp-4]   //这个结果无影响
* (ebp-4)=&shellcode+4 //实现了* (ebp-4)=&shellcode+4,因为*(ebp-4)覆给ecx,则ecx就被覆盖成了&shellcode+4,然后就可以拿到shell了

接下来具体看看怎么布局

我们知道

shellcode地址+4=heap+0x8+0x4=heap+12,来修改B->fd

ebp-4=stack+0x14-0x4=stack+16,来修改B->bk

A的buf大小是8字节,写了shellcode地址花了4字节,因为最小单位为16字节,所以还剩16-4=12字节需要填充,我们填充12个A

综上,得到了如下的布局

shellcode的地址是什么呢

而heap和stack的地址每次运行时都会打印出来的

综上,写出exp:

上传到服务器

执行得到shell

值得注意的是,本题的unlink利用是比较古老的方式了,现在的glibc已经加入了很多新的保护措施

包括:

Double Free检测

该机制不允许释放一个已经处于free状态的chunk。因此,当攻击者将second
chunk的size设置为-4的时候,就意味着该size的PREV_INUSE位为0,也就是说second chunk之前的first
chunk(我们需要free的chunk)已经处于free状态,那么这时候再free(first)的话,就会报出double
free错误。相关代码如下:

#!c

next size非法检测

该机制检测next size是否在8到当前arena的整个系统内存大小之间。因此当检测到next size为-4的时候,就会报出invalid next size错误。相关代码如下:

双链表冲突检测

该机制会在执行unlink操作的时候检测链表中前一个chunk的fd与后一个chunk的bk是否都指向当前需要unlink的chunk。这样攻击者就无法替换second chunk的fd与fd了。相关代码如下:

也出现很多新的技巧的关于unlink的CTF题目,如:

HITCON 2014 stkof
0CTF 2016 – Zerostorage
0CTF 2015 'freenote'
HITCON CTF 2016: Secret Holder
强网杯2018 silent2

这些题目有兴趣的师傅们可以自行去pwn

参考

1.https://paper.seebug.org/papers/Archive/drops2/Linux%E5%A0%86%E6%BA%A2%E5%87%BA%E6%BC%8F%E6%B4%9E%E5%88%A9%E7%94%A8%E4%B9%8Bunlink.html

2.https://heap-exploitation.dhavalkapil.com/attacks/unlink_exploit.html

3. https://paper.seebug.org/papers/Archive/refs/2015-1029-yangkun-Gold-Mining-CTF.pdf

4. https://cysecguide.blogspot.com/2017/10/pwnablekr-unlink-solution.html

5.cft wiki

萌新带你开车上p站(番外篇)的更多相关文章

  1. 萌新带你开车上p站(二)

    本文作者:萌新 前情提要:萌新带你开车上p站(一) 0x04flag  看题目描述似乎是一个和脱壳相关的逆向题目 按照给出的地址先下载过来 file看看 是个可执行文件 执行之 emm什么都看不出来, ...

  2. 萌新带你开车上p站(Ⅳ)

    本文作者:萌新 前情回顾: 萌新带你开车上p站(一) 萌新带你开车上p站(二) 萌新带你开车上P站(三) 回顾一下前篇,我们开始新的内容吧 0x12 登录后看源码 通读程序,逻辑是这样子的: 输入6个 ...

  3. 萌新带你开车上p站(三)

    本文作者:萌新 前情回顾: 萌新带你开车上p站(一) 萌新带你开车上p站(二) 0x08 题目给的提示是和运算符优先级有关 登录后直接看源码 mistake@pwnable:~$ ls flag mi ...

  4. 萌新带你开车上p站(一)

    本文作者:萌新 0x01前言 这一系列文章为pwnable.krToddlr’s Bottle的全部题解,其中有三道题目相对而言稍难或者说比较经典,单独成篇,其他题目的题解放在一起发出来. 0x02f ...

  5. 萌新带你开车上p站(终极番外)

    本文由“合天智汇”公众号首发,作者:萌新 0x01前言 这关其实和pwn关系不大,主要考察的都是linux下一些函数的操作,考察linux的基本功.涉及到的知识点包括一些经典的函数原型.IO重定向.文 ...

  6. 萌新学习Python爬取B站弹幕+R语言分词demo说明

    代码地址如下:http://www.demodashi.com/demo/11578.html 一.写在前面 之前在简书首页看到了Python爬虫的介绍,于是就想着爬取B站弹幕并绘制词云,因此有了这样 ...

  7. 萌新笔记——C++里创建 Trie字典树(中文词典)(二)(插入、查找、导入、导出)

    萌新做词典第二篇,做得不好,还请指正,谢谢大佬! 做好了插入与遍历功能之后,我发现最基本的查找功能没有实现,同时还希望能够把内存的数据存入文件保存下来,并可以从文件中导入词典.此外,数据的路径是存在配 ...

  8. 留学萌新Essay写作须知

    Essay是留学生们接触比较多的一项留学生作业,但尽管如此,依旧有部分同学对于essay写作是没有足够的把握的.随着开学季的到来,很多萌新初次接触Essay写作,难免会有很多不懂得地方.所以今天小编就 ...

  9. 从Webpack源码探究打包流程,萌新也能看懂~

    简介 上一篇讲述了如何理解tapable这个钩子机制,因为这个是webpack程序的灵魂.虽然钩子机制很灵活,而然却变成了我们读懂webpack道路上的阻碍.每当webpack运行起来的时候,我的心态 ...

随机推荐

  1. 《 OO第一作业周期(前四周)总结 》

    作为一名软件工程的大学生,很高兴能够以这样一种方式,实现对博客编写零的突破.专业课老师也介绍了编写博客给我们带来的帮助,听了以后,我感觉到了培养出写博客的习惯,是一件多么有意义的事! 话不多说,让我们 ...

  2. 手写一个Promise/A+,完美通过官方872个测试用例

    前段时间我用两篇文章深入讲解了异步的概念和Event Loop的底层原理,然后还讲了一种自己实现异步的发布订阅模式: setTimeout和setImmediate到底谁先执行,本文让你彻底理解Eve ...

  3. 实验七 MySQL语言结构

    实验七 MySQL语言结构 一.  实验内容: 1. 常量的使用 2. 变量的使用 3. 运算符的使用 4. 系统函数的使用 二.  实验项目:员工管理数据库 用于企业管理的员工管理数据库,数据库名为 ...

  4. 运行npm安装wepy2踩坑error EEXIST 问题

    windows 10安装wepy2 以前用过wepy1,现在要学习wepy2,运行以下命令出错 npm install @wepy/cli -g # 全局安装 WePY CLI 工具 打开log文件, ...

  5. CSS超链接样式,去除下划线等

    控制超链接样式 链接的四种状态: a:link - 普通的.未被访问的链接 a:visited - 用户已访问的链接 a:hover - 鼠标指针位于链接的上方 a:active - 链接被点击的时刻 ...

  6. chrome浏览器的json格式化插件

    JSON-Handle   下载地址:         http://jsonhandle.sinaapp.com/ 插件下载后,在浏览器输入:chrome://extensions/ 将下载后的文件 ...

  7. .Net微服务实践(五)[服务发现]:Consul介绍和环境搭建

    目录 介绍 服务发现 健康检查.键值存储和数据中心 架构 Consul模式 环境安装 HTTP API 和Command CLI 示例API介绍 最后 在上篇.Net微服务实践(四)[网关]:Ocel ...

  8. Apache Hudi 设计与架构最强解读

    感谢 Apache Hudi contributor:王祥虎 翻译&供稿. 欢迎关注微信公众号:ApacheHudi 本文将介绍Apache Hudi的基本概念.设计以及总体基础架构. 1.简 ...

  9. 11-Json提取器使用

    1.使用json提取关键信息 有时候接口返回数据为json数据或者直接为一个列表,可使用这个更简单快捷 json数据: 这样的,数据有在result里面以列表形式存在,也有在列表外的,可在json提取 ...

  10. 通过GSM模块发送经纬度求救信息。

    本博客作为实验笔记,仅供学习交流.(转载请注明出处) 本实验通过GSM模块:SIM900a,实现向特定手机发送sos求救信号,并且利用GPS模块:微科VK2828U7G5LF,将经纬度信息同时发送到手 ...