HCTF2017的三个WriteUp

本文作者 7o8v 是第一个加入我的作者群的同学,根据之前文章数,奖励50元,请拉到下面看作者简介以及之前发过的所有文章,其中涉及了一些代码,如果想要利用也可以去查看作者的博客,点击阅读原文查看。

0x00 题目

感觉自己还是太菜了,比赛结束前只做出来了三道题。

Evr_Q (level - 1) guestbook (level - 2) babystack (level - 3)

0x01 Evr_Q

程序会先要求输入 User

载入到 IDA 进行分析

但是在进行 F5 反编译的时候发生了一个错误

Decompilation failure: 413238: positive sp value has been found

解决方法就是先 undefine 掉函数,再右键选择 Code,最后 Create function 就可以正常反编译了。

可以看到 User 的输入时保存在全局数组 Str 里的,然后下面的 sub_411316() 函数进行 User 的 check

这就是这个函数的主要部分了,我先爆破出第一个循环加密后的字符串,又因为第一个循环本身只用了异或,所以爆破出来之后再循环一次就是正确的 User 了,脚本如下:

User 验证成功以后,程序又要求输入 Start Code ,其实就是 flag 。

以上就是第二次输入 flag 的进行加密和验证的地方,最后的解密我也是通过爆破完成的,不算太难,脚本如下:

其实这个程序还加了一个检测调试器和一些工具进程的回调函数,如果需要动态调试的话,可以把这个函数对应跳表位置的jmp改为ret。:P

0x02 guestbook

Arch: i386-32-little RELRO: Full RELRO Stack: Canary found NX: NX enabled PIE: PIE enabled

程序主要有三个主要的功能

add() : 添加 guest see() : 打印 guest 信息 - name 和 phone del() : 删除 guest

add() 主要代码如下:

这里进行两次输入,输入 name 和 phone ,name 会保存在 bss 上,phone 会额外 malloc 一块内存进行保存。而且两个输入都有长度限制,而且 phone 还会通过 \_ctype\_b\_loc() 对字符类型进行检测,无法输入英文字母。

del():

流程比较简单:guest 标志位置 0 -> name 字段置 0 -> free 掉 phone 的内存 -> phone 的指针置 null

see():

这里通过 snprintf() 和 puts() 对 guest 的信息进行打印,snprintf() 通过格式控制先将信息打印到栈上,puts() 再将这些信息统一进行输出。

那这里就有一个问题,snprintf() 和 printf() 一样存在格式化字符串漏洞。

那我们就已经 get 到了一个格式化字符串的漏洞了。

思路:

程序保护全开,通过写 GOT 表肯定不可能了,于是我决定写 __free_hook,但是刚开始想写一个 one_gadget 完事,结果发现三个 one_gadget 都没法用,于是我在程序段找了一个栈溢出的地方,写到那里去,之后通过泄漏 text 段地址和 canary 来通过栈溢出完成攻击。

EXP:

0x03 babystack

Arch: amd64-64-little RELRO: Partial RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x400000)

很巧的是 pwnable.tw 上也有一道题叫 babystack ,而且对于这两道题我最后的解题思想也是基本一致的。

程序功能很简单,直接看 main 的代码

程序可以接受两次输入,第一次可以接受一个指针的值,之后会有一个 printf 函数将指针指向的内容以 %lld 格式打印出来。

再之后会进入一个我重命名的叫 load_filter 的函数,这个函数的作用就是创建一个系统调用白名单,这份白名单里有:

read() open() exit()

其他系统调用被调用时,内核会向进程发送 SIGSYS 信号并终止进程。

这个函数完成之后会进入下一个函数(也是我重命名过的),这个函数就可以进行栈溢出。

但是这里有一个问题就是,由于系统调用被禁用了,我们没有办法正常启 shell。

思路:

这时候有两个思路:

使过滤失效或者将 execve 加入到白名单中 利用仅有的三个系统调用获取 flag

刚开始我选择将重点放在过滤上,选择了第一种思路,走了很多弯路。因为我后来调试发现用来将过滤规则载入内核的 load 函数也是被禁用的状态。

于是后来我选择了第二种思路。

先通过 open() 打开 flag 文件,再通过 read() 将内容读入内存,再找一个同时带有 cmp 和跳转到一个被禁用的系统调用前的 je 或 jnz 的这么一个 gadget(有点难懂么? XD )。

由于跳到其他系统调用时进程接收到的信号时 SIGSYS ,而程序因为无效返回地址终止时接收到的信号是 SIGSEGV

这样我们就能对内存中的 flag 内容进行爆破了。

EXP:

由于题目特殊性,exp 看看思路就好。

个人作品展

2017-NSCTF-PWN

二进制漏洞学习笔记

栈溢出利用之Return to dl-resolve

how2heap总结-上

个人简介

笔者是一名就读于成都信息工程大学的大二狗,Syclover 混吃等死只知后退不思进取二进制选手,主要学习二进制漏洞的分析和利用。

我是从大一进校之后才开始学习信安的,说实话进校之前我都不知道信息安全是干嘛的。

刚开始学习的是 php、sql 注入之类的东西,后来不知道怎么回事学到了二进制上面去 XD,觉得挺有意思,之后就一路坚持了下来。

实话就说这么多,求二进制大佬带一波 Orz。

原文发布于微信公众号 - 信安之路(xazlsec)

原文发表时间:2017-11-13

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏岑玉海

hbase源码系列(六)HMaster启动过程

  这一章是server端开始的第一章,有兴趣的朋友先去看一下hbase的架构图,我专门从网上弄下来的。   按照HMaster的run方法的注释,我们可以了解...

61390
来自专栏技术翻译

将Elasticsearch直接连接到Java EE应用程序

时髦的大数据来自3 V:音量,种类和速度。卷是指数据的大小,品种是指不同类型的数据,而速度是指数据处理的速度。为了处理持久性大数据,NoSQL数据库可以更快地写...

17230
来自专栏青青天空树

MIME协议在邮件中的应用详解

  全称是多用途互联网邮件扩展(MIME,Multipurpose Internet Mail Extensions),在MIME出台之前,使用RFC 822只...

21510
来自专栏逆向技术

16位汇编第三讲 分段存储管理思想

      内存分段 一丶分段(汇编指令分段) 1.为什么分段?   因为分段是为了更好的管理数据和代码,就好比C语言为什么会有内存4区一样,否则汇编代码都写...

22760
来自专栏Java帮帮-微信公众号-技术文章全总结

Activiti学习详解【面试+工作】

一:Activiti第一天 1:工作流的概念 ? 说明: 1) 假设:这两张图就是XX兄弟的请假流程图 2) 图的组成部分: A. 人物:范XX 冯X刚 王X军...

76950
来自专栏分布式系统进阶

Influxdb 数据写入流程

因此对写入请求的处理就在函数 func (h *Handler) serveWrite(w http.ResponseWriter, r *http.Reque...

21330
来自专栏小狼的世界

Crontab中的除号(slash)到底怎么用?

crontab 是Linux中配置定时任务的工具,在各种配置中,我们经常会看到除号(Slash)的使用,那么这个除号到底标示什么意思,使用中有哪些需要注意的地方...

10820
来自专栏iOS技术

YYCache 源码剖析:一览亮点

YYCache 作为当下 iOS 圈最流行的缓存框架,有着优越的性能和绝佳的设计。笔者花了些时间对其“解剖”了一番,发现了很多有意思的东西,所以写下本文分享一下...

52150
来自专栏FD的专栏

Brainfuck JIT Compiler in Rust

我们都知道,对于解释型的语言实现来说,性能是大家关注的焦点。比如,这位 Tondbal ik Ni 曾经还说过:

17430
来自专栏有趣的django

37.Django1.11.6文档

第一步 入门 检查版本 python -m django --version 创建第一个项目 django-admin startproject mysite ...

51980

扫码关注云+社区

领取腾讯云代金券