Fastcgi協議分析&PHP-FPM未授權訪問漏洞&Exp編寫
搭過php相關環境的同學應該對fastcgi不陌生,那麼fastcgi究竟是什麼東西,為什麼nginx可以通過fastcgi來對接php?
Fastcgi其實是一個通信協議,和HTTP協議一樣,都是進行數據交換的一個通道。
HTTP協議是瀏覽器和伺服器中間件進行數據交換的協議,瀏覽器將HTTP頭和HTTP體用某個規則組裝成數據包,以TCP的方式發送到伺服器中間件,伺服器中間件按照規則將數據包解碼,並按要求拿到用戶需要的數據,再以HTTP協議的規則打包返回給伺服器。
類比HTTP協議來說,fastcgi協議則是伺服器中間件和某個語言後端進行數據交換的協議。Fastcgi協議由多個record組成,record也有header和body一說,伺服器中間件將這二者按照fastcgi的規則封裝好發送給語言後端,語言後端解碼以後拿到具體數據,進行指定操作,並將結果再按照該協議封裝好後返回給伺服器中間件。
和HTTP頭不同,record的頭固定8個位元組,body是由頭中的contentLength指定,其結構如下:
typedef struct { /* Header */ unsigned char version; // 版本 unsigned char type; // 本次record的類型 unsigned char requestIdB1; // 本次record對應的請求id unsigned char requestIdB0; unsigned char contentLengthB1; // body體的大小 unsigned char contentLengthB0; unsigned char paddingLength; // 額外塊大小 unsigned char reserved; /* Body */ unsigned char contentData[contentLength]; unsigned char paddingData[paddingLength]; } FCGI_Record;
頭由8個uchar類型的變數組成,每個變數1位元組。其中, 佔兩個位元組,一個唯一的標誌id,以避免多個請求之間的影響; 佔兩個位元組,表示body的大小。
語言端解析了fastcgi頭以後,拿到 ,然後再在TCP流里讀取大小等於 的數據,這就是body體。
Body後面還有一段額外的數據(Padding),其長度由頭中的paddingLength指定,起保留作用。不需要該Padding的時候,將其長度設置為0即可。
可見,一個fastcgi record結構最大支持的body大小是 ,也就是65536位元組。
剛才我介紹了fastcgi一個record中各個結構的含義,其中第二個位元組 我沒詳說。
就是指定該record的作用。因為fastcgi一個record的大小是有限的,作用也是單一的,所以我們需要在一個TCP流里傳輸多個record。通過 來標誌每個record的作用,用 作為同一次請求的id。
也就是說,每次請求,會有多個record,他們的 是相同的。
借用該文章中的一個表格,列出最主要的幾種 :
看了這個表格就很清楚了,伺服器中間件和後端語言通信,第一個數據包就是 為1的record,後續互相交流,發送 為4、5、6、7的record,結束時發送 為2、3的record。
當後端語言接收到一個 為4的record後,就會把這個record的body按照對應的結構解析成key-value對,這就是環境變數。環境變數的結構如下:
typedef struct { unsigned char nameLengthB0; /* nameLengthB0 >> 7 == 0 */ unsigned char valueLengthB0; /* valueLengthB0 >> 7 == 0 */ unsigned char nameData[nameLength]; unsigned char valueData[valueLength]; } FCGI_NameValuePair11; typedef struct { unsigned char nameLengthB0; /* nameLengthB0 >> 7 == 0 */ unsigned char valueLengthB3; /* valueLengthB3 >> 7 == 1 */ unsigned char valueLengthB2; unsigned char valueLengthB1; unsigned char valueLengthB0; unsigned char nameData[nameLength]; unsigned char valueData[valueLength ((B3 & 0x7f) > 7 == 0 */ unsigned char nameData[nameLength ((B3 & 0x7f) > 7 == 1 */ unsigned char valueLengthB2; unsigned char valueLengthB1; unsigned char valueLengthB0; unsigned char nameData[nameLength ((B3 & 0x7f)
※年輕人的時尚耳機?Bluedio T4 藍牙耳機輕體驗
※這個概念可能越來越沒價值了
※「刷臉」取廁紙用量減半,傳統公廁仍現「蹭」紙
※順風耳和千里眼誰更厲害?
TAG:推酷 |
※HPS/ARM和FPGA Fabric的相互訪問
※Digi-Key 提供對 Ultra Librarian EDA /CAD 模型的無限制訪問
※Centos7/RHEL7-firewalld設置訪問規則
※Mozilla用WebXR Viewer提供對iOS on WebXR訪問
※iPhone XS 無法訪問 App Store 的解決辦法
※蘋果限制舊Mac機型的OS X系統訪問Apple Store
※Spring Boot與Kotlin使用Spring-data-jpa簡化數據訪問層
※William E.Moerner教授將訪問上海
※部分 iOS 11 用戶無法訪問 App Store 等服務
※部分iOS 11用戶稱無法訪問App Store等服務
※Chrome OS 更新新版本可讓Linux訪問USB連接的Android設備
※Linux+Nginx+Uwsgi+Django 搭建單服務實現多域名訪問
※re:Invent 2018:AWS Ground Station可通過雲輕鬆訪問衛星數據
※iPadOS版Safari已支持訪問部分桌面版網站
※使用HTTPS Everywhere插件,默認HTTPS加密訪問網站
※Linux + Nginx + Uwsgi + Django 搭建單服務實現多域名訪問
※《Apex英雄》爆紅 《Apex Construct》訪問量激增
※《Apex英雄》爆紅《ApexConstruct》訪問量激增
※由於GDPR Instapaper暫時關閉了歐洲用戶的訪問許可權
※《Wanted Killer VR》登陸Steam 開啟早期訪問