web ctf中的計算器

web ctf中的計算器

web ctf中的計算器

1 簡介

某ctf的web題是計算器,主要就是考腳本編寫能力,自動化提交,總體還算簡單。 服務端的php文件javascript

2 實現數學表達式計算

使用instaparse這個庫,寫parser很是方便,雖然有點殺雞用牛刀,代碼以下: php

 1: (require '[instaparse.core :as insta :refer [defparser]])
 2: 
 3: (defparser ques-exp
 4:   "expr = add-sub '='
 5: <add-sub> = mul-div | add | sub
 6: add = add-sub <'+'> mul-div
 7: sub = add-sub <'-'> mul-div
 8: <mul-div> = term | mul | div
 9: mul = mul-div <'*'> term
10: div = mul-div <'/'> term
11: <term> = number
12: number = #'[0-9]+'
13: "
14:   :auto-whitespace :standard ;; 忽略空格
15:   )
16: 
17: ;;; 測試解析器
18: (ques-exp "234 + 55 * 28 = ")
19: ;; => [:expr [:add [:number "234"] [:mul [:number "55"] [:number "28"]]] "="]
20: 
21: (defn eval-exp
22:   "執行表達式"
23:   [exp-str]
24:   (->> (ques-exp exp-str)
25:        (insta/transform {:add +
26:                          :sub -
27:                          :mul *
28:                          :div /
29:                          :number clojure.edn/read-string
30:                          :expr (fn [a _] a) ;; 忽略右邊的=
31:                          :sign nil})))
32: 
33: (eval-exp "234 + 55 * 28 = ")
34: ;; => 1774
35: 
36: (eval-exp "2 * 3 / 2 - 8 + 6 / 3 = ")
37: ;; => -3

3 請求表達式和提交計算結果

接下來就是請求頁面,解析出表達式,並提交結果: html

 1: (require '[reaver :as html]) ;; 使用Jsoup解析html
 2: (require '[clj-http.client :as http]) ;; http請求
 3: (require '[clj-http.cookies :as cookies])
 4: 
 5: ;; 使用統一的cookie,用於保存session
 6: (def cs (cookies/cookie-store))
 7: 
 8: (def default-header
 9:   {:headers {"User-Agent" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.50 Safari/537.36"
10:              "Accept-Charset" "utf-8"}
11:    ;; 使用本地代理,方便查找問題
12:    :proxy-host "127.0.0.1"
13:    :proxy-port 8080
14:    :cookie-policy :standard
15:    :insecure? true
16:    })
17: 
18: (def ctf-u "http://192.168.47.129/web/html/index.php")
19: 
20: (defn extract-exp
21:   "從html中提取出表達式字符串"
22:   [html]
23:   (some-> (html/parse html)
24:           (html/extract [] "form > div" html/text)
25:           (->> (apply str))))
26: 
27: (defn get-question
28:   "獲取問題"
29:   []
30:   (-> (http/get ctf-u (merge default-header {:cookie-store cs}))
31:       :body
32:       extract-exp))
33: 
34: (defn post-ans
35:   "提交答案"
36:   [ans]
37:   (-> (http/post ctf-u (merge default-header
38:                               {:cookie-store cs
39:                                :form-params ans}))
40:       :body))
41: 
42: 
43: ;; 提交一次測試
44: (get-question)
45: ;; => "+3572241+1162006+6727538*7357031-2782980-5908042+5687297*3471162+9574274="
46: ;; => "+3688345*6914278-7003441+7001140+2403633*2570857+7772803-1273673*2507819="
47: 
48: ;; 此次的題目須要前面再加一個數字
49: (eval-exp (str "123456" *1))
50: ;; => 69236240589747
51: 
52: ;; 提交一次請求,返回"must input some big number ~"
53: (post-ans {:ans *1
54:            :input 123456})

看後面的提示<!–the big number is the fist prime after 1000000 –>,須要計算素數: java

 1: (def certainty 10)
 2: 
 3: (defn prime? [n]
 4:   "n是否爲一個素數"
 5:   (.isProbablePrime (BigInteger/valueOf n) certainty))
 6: 
 7: (defn gen-prime
 8:   "從start開始產生一個素數"
 9:   [start]
10:   (first
11:    (filter prime?
12:            (range start Integer/MAX_VALUE))))
13: 
14: (gen-prime 20)
15: ;; => 23
16: 
17: (def i1 (gen-prime 1000000))
18: 
19: ;; 再請求一次
20: (->> (get-question)
21:      (str i1)
22:      eval-exp
23:      (hash-map :input i1 :ans)
24:      post-ans)
25: 
26: ;; 返回結果仍是不對,固然看源碼能夠知道,生成的素數位數不對,少個0。
27: ;; 再來一次
28: (def i1 (gen-prime 10000000))
29: (->> (get-question)
30:      (str i1)
31:      eval-exp
32:      (hash-map :input i1 :ans)
33:      post-ans)
34: ;;; 這一次只有slow down的消息,證實提交的input數字是對的

4 循環提交

單次提交測試沒有問題,就能夠循環提交計算結果,直到返回的頁面中沒有提問,就算計算完成: git

 1: ;; 添加了better-cond依賴,爲了使用cond let子句
 2: (refer-clojure :exclude '[cond])
 3: (require '[better-cond.core :refer [cond]])
 4: 
 5: (defn process-answer
 6:   " 不斷請求答案,直到返回的頁面中沒有提問
 7:  `format-fn` 格式化請求返回的表達式
 8:  `answer-fn` 格式化提交的form內容"
 9:   [{:keys [format-fn answer-fn]
10:     :or {format-fn identity
11:          answer-fn #(hash-map :ans %)}}]
12:   (loop [ques (get-question)
13:          result ""]
14:     (cond
15:       (empty? ques) result
16: 
17:       ;; 計算表達式
18:       :let [ans (-> (format-fn ques)
19:                     (doto println)
20:                     (eval-exp))]
21: 
22:       ;; 表達式計算錯誤
23:       (insta/failure? ans) (println :process "no eval result for" ques)
24: 
25:       ;; 提交結果
26:       :let [r (-> (answer-fn ans)
27:                   (post-ans))]
28: 
29:       (do
30:         (println :process "question:" ques "anser:" ans)
31:         (recur (extract-exp r)
32:                r)))))
33: 
34: (process-answer {:format-fn #(str i1 %)
35:                  :answer-fn #(hash-map :input i1 :ans %)})
36: 

能夠看到post提交答案,返回的都是slow down,如今加入延時,延時數字要本身調整,固然看了代碼才知道是2-3秒: github

1: (process-answer {:format-fn #(str i1 %)
2:                  :answer-fn (fn [e]
3:                               (Thread/sleep 2000.)
4:                               {:ans e
5:                                :input i1})})
6: ;; => "\n\t\t<script language=\"javascript\"> \n\t\talert(\"right answer\"); \n\t </script> got flag....................."

5 總結

考察的就是基本的腳本編程能力,http GET/POST請求,表達式解析計算。 web

做者: ntestoc編程

Created: 2019-06-10 週一 16:48cookie

相關文章
相關標籤/搜索