PHP源碼分析之parse
前言:
之前從phithon師傅的代碼審計小密圈看到pupiles師傅發過一篇文章,講了parse_url()的很多小tricks,可惜只是給出了tricks的利用方法,並沒有從底層原理上進行分析,正好我最近也在研究PHP源碼,於是就給分析了一波。
本文測試使用的PHP版本為7.0.30
http://pupiles.com/%E8%B0%88%E8%B0%88parse_url.html
函數分析:
parse_url()定義在extstandardurl.c中第337行
第334行調用zend_parse_parameters()對參數進行解析,第一參數就是傳入的URL字元串,第二個參數是可選的我們暫時不做研究。
第348行,調用php_url_parse_ex()對URL字元串進行解析,返回值保存在resource中,resource定義在341行,是一個php_url類型的結構體:
跟入php_url_parse_ex()
這個函數接收兩個參數,分別是URL字元串和其長度
第100行聲明了一個ret指針並為其分配了一個php_url結構,用於保存返回值
之後初始化s指向字元串開頭,ue指向字元串結尾
第一個trick:
此時我們傳入的字元串為 /pupiles.com:80
第107行把e指向了字元「:」所在的位置
第109行把s賦值給p
此時的指針結構入如下:
112行的if中有四個條件:
1.*p非字元
2.*p非數字
3.*p != 『+』
4.*p != 『-』
很明顯,p指向的第一個字元是』/』,滿足上述條件
113行再次進行判斷,其中兩個條件:
1.e + 1
2.e
114行 goto parse_port;
parse_port在第177行:
執行到第179行時指針結構如下:
181行的循環之後:
185行中if條件滿足
187行中,因為pp - p == 2,所以把從指針p開始的兩個字元複製到port_buf中,port_buf定義在99行:
188行追加一個空字元終止字元串,此時port_buf的值為: 80
189行從port_buf解析出port並在191行賦值給ret結構體的port成員
至此port解析完成,進入到215行的parse_host:
217行把ue賦值給e:
218行把p指向了字元』/』的位置:
219行把p賦值給e:
此時 e == s,故不會進入229行的if
繼續向下:
246行的if不滿足,進入到251行的else中
找到zend_memrchr()的定義:
傳入的參數n即(e-s),由於e == s,即e - s == 0,可知n == 0
在zend_memrchr()的第189行,可知n
因此p == NULL,不會進入255行的if,而是進入到281行的else中:
281行把e賦值給p,還是和之前一樣:
286行由於p == s,因此(p-s)
自己寫一個PHP文件測試一下:
$url = $_GET["url"];
var_dump(parse_url($url));
第二個trick:
實測一下:
在埠號之後加一個字元就會被當做path解析了,神奇!
繼續分析一波:
這個字元串的解析過程和上述基本一致,不同發生在了parse_port中:
在185行時各指針如下:
由於此時185行的if不滿足因此會進入到207行,跳轉到just_path中:
305行把ue賦值給e:
由於字元串中不存在字元』#』和』?』
因此306和316行的if都不滿足
326行s
331行返回結構體ret
後記:
本人不才,看C看的好心累,只分析了前兩個trick,剩下的trick有興趣的師傅歡迎投稿分享~!
ChaMd5安全招聘~
美團點評集團
移動安全專家(協議分析、安全審計方向)
移動安全專家(產品研發方向)
百度安全實驗室
AI安全產品研發工程師
AI安全研究員
北京天際友盟信息技術有限公司
安全開發工程師
情報/數據分析師
Python爬蟲工程師
用戶體驗設計師
JAVA工程師
Web前端工程師
售前工程師
華東區銷售總監
西安訊蜂科技有限公司
前端開發工程師
安全工程師
安全研究員
人工智慧研究員
數據分析研究員
銷售經理
TAG:ChaMd5安全團隊 |