當前位置:
首頁 > 知識 > Fastcgi協議分析&PHP-FPM未授權訪問漏洞&Exp編寫

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 開啟早期訪問