HTTP請求的格式
1)請求資訊:例如“Get /index.php HTTP/1.1”,請求index.php檔案
2)表頭:例如“Host: localhost”,表示伺服器位址
3)空白行
4)資訊本文
“請求資訊”和“表頭”都必須使用換行字元CRLF)來結尾,空白行只能包含分行符號,不可以有其他空格符。
下面例子發送HTTP請求給伺服器www.yhsafe.com
GET /index.php HTTP/1.1 //請求資訊
Host:www.yhsafe.com //表頭
//空格行符號表示斷行符號鍵,在空白行之後還要在按一個空格才會發送HTTP請求,HTTP請求的表頭中只有Host表頭是必要的餓,其餘的HTTP表頭則是根據HTTP請求的內容而定。 HTTP請求的方法1)GET:請求響應2)HEAD:與GET相同的響應,只要求響應表頭3)POST:發送資料給伺服器處理,資料包含在HTTP資訊本文中4)PUT:上傳檔案5)DELETE:刪除檔案6)TRACE:追蹤收到的請求7)OPTIONS:返回伺服器所支援的HTTP請求的方法8)CONNECT:將HTTP請求的串連轉換成透明的TCP/IP通道 HTTP響應的格式伺服器在處理完用戶端所提出的HTTP請求後,會發送下列響應。1)第一行是狀態代碼2)第二行開始是其他資訊狀態代碼包含一個標識狀態的數字和一個描述狀態的單詞。例如:HTTP/1.1 200 OK200是標識狀態的是數字,OK則是描述狀態的單詞,這個狀態代碼標識請求成功。
HTTP請求和響應的例子
開啟cmd輸入telnet,輸入open www.00aq.com 80
開啟串連後輸入
GET /index.php HTTP/1.1
Host:www.00aq.com
返回HTTP響應的表頭
返回的首頁內容
使用PHP來發送HTTP請求
header函數可以用來發送HTTP請求和響應的表頭
函數原型
void header(string string [, bool replace [, int http_response_code]])
string是HTTP表頭的字串
如果replace為TRUE,表示要用目前的表頭替換之前相似的表頭;如果replace為FALSE,表示要使用多個相似的表頭,預設值為TRUE
http_response_code用來強制HTTP響應碼使用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響應的字串
- $http_response = "";
- while (!feof($fp))
- {
- // 讀取256位的HTTP響應字串
- $http_response .= fgets($fp, );
- }
- // 關閉Internet socket串連
- fclose($fp);
- // 顯示HTTP響應資訊
- echo nl2br(htmlentities($http_response));
- ?>
HTTP響應拆分攻擊
HTTP響應拆分是由於攻擊者經過精心設計利用電子郵件或者連結,讓目標使用者利用一個請求產生兩個響應,前一個響應是伺服器的響應,而後一個則是攻擊者設計的響應。此攻擊之所以會發生,是因為WEB程式將使用者的資料置於HTTP響應表頭中,這些使用者的資料是有攻擊者精心設計的。
可能遭受HTTP請求響應拆分的函數包括以下幾個:
header(); setcookie(); session_id(); setrawcookie();
HTTP響應拆分通常發生在:
Location表頭:將使用者的資料寫入重新導向的URL地址內
Set-Cookie表頭:將使用者的資料寫入cookies內
執行個體:
- 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
訪問下面的連結,會直接出現一個登陸視窗
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
轉換成可讀字串為:
Content-Type: text/html
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 158
一個HTTP請求產生了兩個響應
防範的方法:
1)替換CRLF換行字元
- header("Location: " . strtr($_GET['page'], array("\r"=>"", "\n"=>"")));
- ?>
2)使用最新版本的PHP
PHP最新版中,已經不允許在HTTP表頭內出現換行字元
隱藏HTTP響應表頭
apache中httpd.conf,選項ServerTokens = Prod, ServerSignature = Off
php中php.ini,選項expose_php = Off