前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >HCTF2017的三个WriteUp

HCTF2017的三个WriteUp

作者头像
信安之路
发布2018-08-08 15:02:44
4920
发布2018-08-08 15:02:44
举报
文章被收录于专栏:信安之路信安之路

本文作者 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。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2017-11-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 信安之路 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 0x00 题目
  • 0x01 Evr_Q
  • 0x02 guestbook
    • 思路:
      • EXP:
      • 0x03 babystack
        • 思路:
          • EXP:
          • 个人作品展
          • 个人简介
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档