首頁 > 軟體

python使用requests庫提交multipart/form-data請求的方法詳解

2023-01-18 14:01:32

前言

今天滲透測試的時候,發現一個介面可以越權遍歷出使用者的敏感資訊,然後想編寫python指令碼將所有資訊都給dump下來。當我檢視請求資料的時候,是如下這樣的。不同於之前的請求資料是json可以直接使用data然後封裝成字典就可以進行傳送請求

這裡的content-type是 multipart/form-data

multipart/form-data

Multipart/form-data其實就是上傳檔案的一種方式。我對它的翻譯是 “多部分表單資料” ;在生活中其實經常用到,比如說,在寫郵件時,向郵件後新增附件,附件通常使用表單新增,也就是用multipart/form-data格式上傳到伺服器。

http協定本身的原始方法其實並不支援multipart/form-data請求,它是由post方法來組合實現的

  • multipart/form-data與post方法的不同之處(請求頭,請求體)
  • multipart/form-data的請求頭必須包含一個特殊的頭資訊:Content-Type,且其值也必須規定為multipart/form-data,同時還需要規定一個內容分割符用於分割請求體中的多個post的內容,如檔案內容和文字內容自然需要分割開來,不然接收方就無法正常解析和還原這個檔案了。

multipart/form-data的請求體也是一個字串,不過和post的請求體不同的是它的構造方式,post是簡單的name=value值連線,而multipart/form-data則是新增了分隔符等內容的構造體,格式如下:

------WebKitFormBoundaryA0Srut8TBztAofvx
Content-Disposition: form-data; name="grant_type"
 
password
------WebKitFormBoundaryA0Srut8TBztAofvx

其中第一行是自定義的分割符,需要與請求頭中規定的分割符相同。

其實根據前言中的例子,可以很容易看出,這個請求體是多個類似的部分組成的:每一個部分都是以–加分隔符開始的,然後是該部分內容的描述資訊,然後一個回車,然後是描述資訊的具體內容;如果傳送的內容是一個檔案的話,那麼還會包含檔名資訊,以及檔案內容的型別。最後會以–分割符–結尾,表示請求體結束。

Python 傳送 multipart/form-data

如下,我們要模擬post如下的封包,那我們如何傳送post的資料攜帶以下紅色框中的引數了? 

1. 重要程式碼如下

data = {"id":(None,'899')}
requests.post(xx,files=data)

2. headers中的Content-Type需要註釋掉,傳送請求的時候會被自動加上,否則會報錯

編寫的python requests請求指令碼如下

執行然後使用proxychains抓取流量如下,成功模擬的請求傳送

再次提醒:Content-Type需要註釋掉!很重要!!1

補充知識:multipart/form-data 引數轉碼

比如請求引數是:

--e0ed233c-3202-47c6-9c96-f9181e308
Content-Disposition: form-data; name="id"
Content-Transfer-Encoding: binary
Content-Type: application/json; charset=UTF-8
Content-Length: 13

234545878
--e0ed233c-3202-47c6-9c96-f9181e308
Content-Disposition: form-data; name="type"
Content-Transfer-Encoding: binary
Content-Type: application/json; charset=UTF-8
Content-Length: 1

1
--e0ed233c-3202-47c6-9c96-f9181e308--

也就是說,有2個 key -> id 和 type

fields={
        "id": '234545878',
        "type": '1'
    }

直接這樣發請求,會失敗。⬆️

encode一下就能發請求了。⬇️

from requests_toolbelt.multipart.encoder import MultipartEncoder

multipart_data = MultipartEncoder(
    fields={
        "id": '1653302392217',
        "read_duration_list": read_duration_list,
        "now": now,
        "type": '1'
    }
)
header['Content-Type'] = multipart_data.content_type
header['accept'] = 'application/json'

總結

到此這篇關於python使用requests庫提交multipart/form-data請求的文章就介紹到這了,更多相關python提交multipart/form-data請求內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com