天天看點

CTF-Web8(涉及python腳本requests子產品)8.天下武功唯快不破

8.天下武功唯快不破

CTF-Web8(涉及python腳本requests子產品)8.天下武功唯快不破
CTF-Web8(涉及python腳本requests子產品)8.天下武功唯快不破

結合注釋及題目名稱,我們猜想可能和送出資料的速度有關

首先看源碼發現他給的提示:

CTF-Web8(涉及python腳本requests子產品)8.天下武功唯快不破

和post的參數有關,那就看看封包吧:

CTF-Web8(涉及python腳本requests子產品)8.天下武功唯快不破

發現了一個FLAG參數是用base64編碼的,解碼後内容是:P0ST_THIS_T0_CH4NGE_FL4G:Hrd54sRiP,試驗了幾次發現:後的字元是随機的,既然他提示的是快速post送出參數key,那麼我們寫python代碼得到資料送出上去就可以得到flag了,接下來直接寫py腳本構造請求頭,腳本如下:(注:key:value==> 鍵:值)

CTF-Web8(涉及python腳本requests子產品)8.天下武功唯快不破

拓展思考:

如果考慮更全面的話,腳本如下:

# coding:utf8
import requests
import base64
url = "http://ctf4.shiyanbar.com/web/10.php" # 目标URL
s = requests.Session() # 擷取 Session
response = s.get(url) # 打開連結
head = response.headers # 擷取響應頭
flag = base64.b64decode(head['flag']).split(':')[1] # 擷取相應頭中的Flag
postData = {'key': flag} # 構造Post請求體
result = s.post(url=url, data=postData) # 利用Post方式發送請求 
# (注意要在同一個Session中 , 有的時候還需要設定Cookies , 但是此題不需要)
print result.text # 列印響應内容           

大緻的執行過程就是擷取報頭中FLAG字段的内容,用base64解碼,然後作為key的值構造post請求,最後列印請求響應的内容,即flag,運作結果如下:

CTF-Web8(涉及python腳本requests子產品)8.天下武功唯快不破

但這道題很有意思的是,他其實可以不用session,貌似出題人在背景沒有用session控制通路(注:不懂的具體可學習php中session來控制頁面的通路權限),應該是通過ip的判斷實作的使用者區分,我做了一個小測試:當擷取到一個key值後構造post請求最大的延時時間是3s

CTF-Web8(涉及python腳本requests子產品)8.天下武功唯快不破

 想了想他的背景操作應該是這樣的:用戶端get請求該位址,服務端收到請求會随機生成一個的字元串,加密後作為傳回封包的FLAG字段,即base64加密的key值,。同時,背景會将加密前的該值存入資料庫,這裡會有一個時間判斷,超過3s會從資料庫中删除,若用戶端在3s内擷取key值并将他作為參數post後,背景會從資料庫中取出進行比對,比對成功将會擷取flag,但是,從資料庫中取出時需要分辨是哪個使用者在什麼時候存入的(同一個使用者可以做連續多次的get請求),是以這裡在資料庫中的一定有一個ip字段做索引,即做請求操作的ip與對應生成的随機字元串存入資料庫,當使用者post後會根據該使用者的ip來取對應的字元串,與post的字元串做比對,這樣,就可以不用session來控制通路了

  還有一道類似的題,但需要使用session來通路:http://web.sniperoj.cn:10003/

  首先還是抓包看看:

CTF-Web8(涉及python腳本requests子產品)8.天下武功唯快不破

可以看到封包裡有一個hint和get_flag字段,意思就是将get_flag解密後作為sinperOJ的值,送出post請求擷取傳回的内容,把get_flag解密後也是随機字元串,但是,他和上面那道題有一個明顯的不同,他的最大時間限制大約是24小時,是以,可以推測應該是用了session來控制通路,于是還是和之前的套路一樣,寫一個腳本來跑,把之前的稍微改一下:

CTF-Web8(涉及python腳本requests子產品)8.天下武功唯快不破

運作結果:

CTF-Web8(涉及python腳本requests子產品)8.天下武功唯快不破

補充:(來自:https://www.cnblogs.com/huchong/p/7349886.html)

函數:split()

Python中有split()和os.path.split()兩個函數,具體作用如下:

split():拆分字元串。通過指定分隔符對字元串進行切片,并傳回分割後的字元串清單(list)

os.path.split():按照路徑将檔案名和路徑分割開

一、函數說明

1、split()函數

文法:str.split(str="",num=string.count(str))[n]

參數說明:

str:   表示為分隔符,預設為空格,但是不能為空('')。若字元串中沒有分隔符,則把整個字元串作為清單的一個元素

num:表示分割次數。預設為 -1, 即分隔所有。如果存在參數num,則僅分隔成 num+1 個子字元串,并且每一個子字元串可以賦給新的變量

[n]:   表示選取第n個分片

注意:當使用空格作為分隔符時,對于中間為空的項會自動忽略

2、os.path.split()函數

文法:os.path.split('PATH')

參數說明:

  1. PATH指一個檔案的全路徑作為參數:
  2. 如果給出的是一個目錄和檔案名,則輸出路徑和檔案名
  3. 如果給出的是一個目錄名,則輸出路徑和為空檔案名

二、執行個體

1、常用執行個體

CTF-Web8(涉及python腳本requests子產品)8.天下武功唯快不破
CTF-Web8(涉及python腳本requests子產品)8.天下武功唯快不破

2、去掉換行符

CTF-Web8(涉及python腳本requests子產品)8.天下武功唯快不破

3、分離檔案名和路徑

CTF-Web8(涉及python腳本requests子產品)8.天下武功唯快不破

4、一個超級好的例子

CTF-Web8(涉及python腳本requests子產品)8.天下武功唯快不破