PHP漏洞全解(八)-HTTP響應(yīng)拆分
HTTP請求的格式
1)請求信息:例如“Get /index.php HTTP/1.1”,請求index.php文件
2)表頭:例如“Host: localhost”,表示服務(wù)器地址
3)空白行
4)信息正文
“請求信息”和“表頭”都必須使用換行字符(CRLF)來結(jié)尾,空白行只能包含換行符,不可以有其他空格符。
下面例子發(fā)送HTTP請求給服務(wù)器www.yhsafe.com
GET /index.php HTTP/1.1↙ //請求信息
Host:www.yhsafe.com↙ //表頭
HTTP請求和響應(yīng)的例子
打開cmd輸入telnet,輸入open www.00aq.com 80
打開連接后輸入
GET /index.php HTTP/1.1↙
Host:www.00aq.com↙

返回的首頁內(nèi)容
使用PHP來發(fā)送HTTP請求
header函數(shù)可以用來發(fā)送HTTP請求和響應(yīng)的表頭
函數(shù)原型
void header(string string [, bool replace [, int http_response_code]])
string是HTTP表頭的字符串
如果replace為TRUE,表示要用目前的表頭替換之前相似的表頭;如果replace為FALSE,表示要使用多個相似的表頭,默認值為TRUE
http_response_code用來強制HTTP響應(yīng)碼使用http_response_code的值
實例:
- // 打開Internet socket連接
- $fp = fsockopen(www.00aq.com, 80);
- // 寫入HTTP請求表頭
- fputs($fp, "GET / HTTP/1.1\r\n");
- fputs($fp, "Host: www.00aq.com\r\n\r\n");
- // HTTP響應(yīng)的字符串
- $http_response = "";
- while (!feof($fp))
- {
- // 讀取256位的HTTP響應(yīng)字符串
- $http_response .= fgets($fp, );
- }
- // 關(guān)閉Internet socket連接
- fclose($fp);
- // 顯示HTTP響應(yīng)信息
- echo nl2br(htmlentities($http_response));
- ?>
HTTP響應(yīng)拆分攻擊
HTTP響應(yīng)拆分是由于攻擊者經(jīng)過精心設(shè)計利用電子郵件或者鏈接,讓目標用戶利用一個請求產(chǎn)生兩個響應(yīng),前一個響應(yīng)是服務(wù)器的響應(yīng),而后一個則是攻擊者設(shè)計的響應(yīng)。此攻擊之所以會發(fā)生,是因為WEB程序?qū)⑹褂谜叩臄?shù)據(jù)置于HTTP響應(yīng)表頭中,這些使用者的數(shù)據(jù)是有攻擊者精心設(shè)計的。
可能遭受HTTP請求響應(yīng)拆分的函數(shù)包括以下幾個:
header(); setcookie(); session_id(); setrawcookie();
HTTP響應(yīng)拆分通常發(fā)生在:
Location表頭:將使用者的數(shù)據(jù)寫入重定向的URL地址內(nèi)
Set-Cookie表頭:將使用者的數(shù)據(jù)寫入cookies內(nèi)
實例:
- header("Location: " . $_GET['page']);
- ?>
請求
GET /location.php?page=http://www.00aq.com HTTP/1.1↙
Host: localhost↙
↙
返回
HTTP/1.1 302 Found
Date: Wed, 13 Jan 2010 03:44:24 GMT
Server: Apache/2.2.8 (Win32) PHP/5.2.6
X-Powered-By: PHP/5.2.6
Location: http://www.00aq.com
Content-Length: 0
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html
訪問下面的鏈接,會直接出現(xiàn)一個登陸窗口
http://localhost/location.php?page=%0d%0aContent-Type:%20text/html%0d%0aHTTP/1.1%20200%20OK%0d%0aContent-Type:%20text/html%0d%0aContent-Length:%20158%0d%0a%0d%0a
轉(zhuǎn)換成可讀字符串為:
Content-Type: text/html
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 158
一個HTTP請求產(chǎn)生了兩個響應(yīng)
防范的方法:
1)替換CRLF換行字符
- header("Location: " . strtr($_GET['page'], array("\r"=>"", "\n"=>"")));
- ?>
2)使用最新版本的PHP
PHP最新版中,已經(jīng)不允許在HTTP表頭內(nèi)出現(xiàn)換行字符
隱藏HTTP響應(yīng)表頭
apache中httpd.conf,選項ServerTokens = Prod, ServerSignature = Off
php中php.ini,選項expose_php = Off