• PHP漏洞全解(八)-HTTP响应拆分


    本文主要介绍针对PHP网站HTTP响应拆分,站在攻击者的角度,为你演示HTTP响应拆分。

    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 OK
    200是标识状态的是数字,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的值

    实例:

    1. // 打开Internet socket连接 
    2. $fp = fsockopen(www.00aq.com, 80); 
    3. // 写入HTTP请求表头 
    4. fputs($fp, "GET / HTTP/1.1 "); 
    5. fputs($fp, "Host: www.00aq.com "); 
    6. // HTTP响应的字符串 
    7. $http_response = ""; 
    8. while (!feof($fp)) 
    9. // 读取256位的HTTP响应字符串 
    10. $http_response .= fgets($fp, ); 
    11. // 关闭Internet socket连接 
    12. fclose($fp); 
    13. // 显示HTTP响应信息 
    14. echo nl2br(htmlentities($http_response)); 
    15. ?> 

    HTTP响应拆分攻击

    HTTP响应拆分是由于攻击者经过精心设计利用电子邮件或者链接,让目标用户利用一个请求产生两个响应,前一个响应是服务器的响应,而后一个则是攻击者设计的响应。此攻击之所以会发生,是因为WEB程序将使用者的数据置于HTTP响应表头中,这些使用者的数据是有攻击者精心设计的。

    可能遭受HTTP请求响应拆分的函数包括以下几个:

    header(); setcookie(); session_id(); setrawcookie();

    HTTP响应拆分通常发生在:

    Location表头:将使用者的数据写入重定向的URL地址内

    Set-Cookie表头:将使用者的数据写入cookies内

    实例:

    1.     header("Location: " . $_GET['page']); 
    2. ?> 

    请求

    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帐号%20密码%20

    转换成可读字符串为:

    Content-Type: text/html

    HTTP/1.1 200 OK

    Content-Type: text/html

    Content-Length: 158

    帐号
    密码

    一个HTTP请求产生了两个响应

    防范的方法:

    1)替换CRLF换行字符

    1.     header("Location: " . strtr($_GET['page'], array(" "=>"",    " "=>""))); 
    2. ?> 

    2)使用最新版本的PHP

    PHP最新版中,已经不允许在HTTP表头内出现换行字符

    隐藏HTTP响应表头

    apache中httpd.conf,选项ServerTokens = Prod, ServerSignature = Off

    php中php.ini,选项expose_php = Off

  • 相关阅读:
    springMVC学习--RESTful支持
    Java中的值传递和引用传递
    SpringMVC学习--json
    SpringMVC学习--文件上传
    SpringMVC学习--异常处理器
    SpringMVC学习--数据回显
    SpringMVC学习--校验
    SpringMVC学习--参数绑定
    SpringMVC学习--功能完善
    SpringMVC学习--springmvc和mybatis整合
  • 原文地址:https://www.cnblogs.com/milantgh/p/3839988.html
Copyright © 2020-2023  润新知