[SCTF2019]Flag Shop
点击buy flag试试
提示没有足够的jkl
这里可以点击work去赚取jkl
正常点击要攒到flag怕是不可能,buu请求过快也会报错
先抓包看看吧
这里不能修改work赚取的jkl,尝试把cookie解码看看
修改下jkl试试看
发现报错了
又回到最开始的地方。。
扫描一下有没有源码泄露之类的
发现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
稍微看了下
发现要do和name一致才能够弹出secret
这里考察Ruby ERB注入(参考:https://www.anquanke.com/post/id/86867https://www.anquanke.com/post/id/86867 and https://blog.csdn.net/zdq0394123/article/details/8443694)
unless params[:SECRET].nil? if ENV["SECRET"].match("#{params[:SECRET].match(/[0-9a-z]+/)}") puts ENV["FLAG"] end end
这里要是 SECRET 参数存在则对其进行匹配,匹配到了就输出flag
但这里既然有匹配,就可以用全局变量读出来了,也就是用 $` 来读取匹配前的内容
构造下payload:
/work?SECRET=&name=<%=$'%>&do=<%=$'%> is working
直接使用好像不行。。
要把里面内容换位十六进制
/work?SECRET=&name=%3c%25%3d%24%27%25%3e&do=%3c%25%3d%24%27%25%3e%20is%20working
又回显了一个jwt 解码一下