ssti+format格式化字符串漏洞
background
在某次内部赛中遇见的的题,我打了一天都没做出来。整场就一道web,给我整不会了,60人平台带不动,只能给两个环境题,一道web一道pwn,sb平台不能限制用户启动容器的数量,真tm无语……
题目简述
上来就是一个请输入用户名的页面,输入完成后跳转到商品页面。点击商品详情就显示“hello XXX,这件商品的价格是XXX”
点击buyflag提示money money money
抓包分析发现就是通过session来进行鉴权的,session不对就会跳转到一个页面
一开始不知道也没想那么多,jwt解了一下发现是hs256,扫了目录没发现私钥就直接和jwt杠上了,改none这些都没用,然后就执着的跑key,rockyou跑完了,各种常见字典都跑了,还生成了4位数所有密码的排列组合,都无效。
后面想到了hello**,于是才想起来考点可能在ssti(当时比赛的时候有师傅说这题是xss,没毛病,确实有xss,hhhhh),49,{77}都直接报错了。接下来就是常规操作,但是一直报错,给我整到怀疑人生了。
在报错页面我看到了部分源码的我发现了代码里面写的commodity.name,commodity.money这类的字眼,于是我{commodity.name},这样确实解析了。{commodity.name.__class__.__bases__}
这样也ok了
正当我以为要上高速的时候,又是报错,给我整到怀疑人生了。{commodity.name.__class__.__bases__.__subclasses__()}
这其实是正常,因为format函数无法执行__subclasses__()
这样的方法,所以这题也压根不能rce
我在想:这是啥环境{{"".__class__}}
这种为啥都能报错?难道删掉了空字符串?不可能吧,他到底是怎么限制我的。
后面看了wp才知道过滤了{{
和{
%,匹配到了就抛出异常,然后考点就是利用format格式化字符串的漏洞去打出flask的key,然后伪造jwt.以下是wp内容
format格式化字符串漏洞
这里属实是我知识盲区了,格式化字符串漏洞一直以为只有在pwn里才会有。这里先看一下python的格式化字符串方法,我知道的有三种
%格式化
这是Python中旧式的字符串格式化方式,它使用百分号字符作为占位符。例如,%s表示字符串占位符,%d表示整数占位符。
name = "w3lkin" |
str.format()
这是Python 2.6引入的一种新式字符串格式化方法,它使用花括号{}来表示占位符。例如,{0}表示第一个参数,{1}表示第二个参数。
name = "w3lkin" |
不带数字默认按顺序填充,也可以使用数字来指定填充位置
name = "w3lkin" |
还可以使用参数的形式来填充
print("My name is {name} and I'm {age} years old.".format(name="w3lkin",age=18)) |
f-strings
这是Python 3.6引入的一种新式字符串格式化方法,它使用前缀f和花括号{}来表示占位符。例如,{name}表示名为name的变量。
name = "w3lkin" |
string.Template
使用标准库中的模板字符串类进行字符串格式化。
from string import Template |
其中最安全的是f-strings方法