前言

注入类漏洞经久不衰,多年保持在owasp Top 10的首位。今天就聊聊那些被人遗忘的http头注入。用简单的实际代码进行演示,让每个人更深刻的去认识该漏洞。

HOST注入

在以往http1.0中并没有host字段,但是在http1.1中增加了host字段,并且http协议在本质也是要建立tcp连接,而建立连接的同时必须知道对方的ip和端口,然后才能发送数据。既然已经建立了连接,那host字段到底起着什么样的的作用?

Host头域指定请求资源的Intenet主机和端口号,必须表示请求url的原始服务器或网关的是比如www.test.com和mail.test.com两个域名IP相同,由同一台服务器支持,服务器可以根据host域,分别提供不同的服务,在客户端看来是两个完全不同的站点。

Host头实验总结:在http 1.1中不能缺失host字段,如果缺失, 服务器返回400 bad request,http1.1中不能缺失host字段,但host字段可以是空值。

0×01 密码重置的中毒

相信大家忘记密码时,使用邮箱找回密码并不陌生。看上去貌似能可靠只能发送到你绑的邮箱去重置密码。并且使用你自己独特的密钥令牌才能重置成功。但是好多cms和实际场景为了获取网站的域名拼接秘钥令牌的方式将连接发送到你的邮箱。但是往往获取正确的域名并不是十分的不容易, 然而用一个固定的URI来作为域名会有各种麻烦。所以一般程序员会采用(java)request.getHeader(“Host”); (php)$_SERVER['HTTP_HOST']的方式来获取域名。

上面所述的两种获取域名的方法并不可靠。都可以人为的去控制。导致当域名和令牌拼接时,攻击者通过篡改hsot值生成钓鱼连接,当受害者点击时,受害者的秘钥令牌将会直接发送到攻击者的服务器上。使其受害者的密码被攻击者篡改。

文字看上去比较绕的话,我在本地用代码将此处的业务场景进行了复现。

public class FindPass extends HttpServlet{
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) { //此处真实场景的话,是根据输入的账号去查对应的邮箱。就不繁琐的构造了。 String email =request.getParameter("email"); //此处获取了host头中的host字段,此值可以被攻击者篡改 String Host =request.getHeader("Host");
int max=200000000;
int min=100000000;
Random random = new Random(); //生成随机的秘钥令牌 int randomNubmer = random.nextInt(max-min) + min;
String content= "用户您好:<br>现在给您发送邮件的XX银行系统,您的账户"+email+"申请找回密码!<br>" +
"只需在提交请求后的三天之内,通过点击下面的链接重置您的密码:<br>"+
"http://"+Host+"?id="+randomNubmer; //此处用Host拼接了秘钥名牌 try { //调用发信接口 SendEmail.send(email, content);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(email+Host);
}
}

提交找回密码表单,篡改其中的host头值。

当用户收到密码重置邮件后,发现是钓鱼者的网址,且秘钥令牌也已参数id的形式传给给攻击者,此时攻击者可以直接使用受害者的令牌进行密码重置。

0×02 XSS:

有些网站会根据HTTP_HOST字段来进行加载css样式表。如果要为固定的话,当域名发生改变时,那么站内所有的css即将失效。而且修改的时候也将的十分头疼,因为每个页面都会引用大量的公共资源。如下是我重构的场景重现:

<?php
echo<<<EOT
测试host攻击<br>
cccccccc
<head>
<link rel="stylesheet" type="text/css" href="http://{$_SERVER['HTTP_HOST']}?id=111111" />
</head>
EOT;
echo $_SERVER["HTTP_HOST"];
?>

0×03 web缓存中毒

简单描述:

Web缓存服务器的应用模式主要是正向代理反向代理。正向代理(Proxy)模式是代理网络用户访问internet,客户端将本来要直接发送到internet上源服务器的连接请求发送给代理服务器处理。正向代理的目的是加速用户在使用浏览器访问Internet时的请求响应时间,并提高广域网线路的利用率。正向代理浏览器无需和该站点建立联系,只访问到Web缓存即可。通过正向代理,大大提高了后续用户的访问速度,使他们无需再穿越Internet,只要从本地Web缓存就可以获取所需要的信息,避免了带宽问题,同时可以大量减少重复请求在网络上的传输,从而降低网络流量,节省资费。

思路:

Apache接收到一个带有非法host header的请求,它会将此请求转发给在 httpd.conf 里定义的第一个虚拟主机。因此,Apache很有可能将带有任意host header的请求转发给应用。

场景:

一般的缓存服务器都会识别hsot,所以一般直接替换host字段会被拦截。。Varnish辨别第一个host Apache识别所有请求的host, Nginx则只是看最后一个请求。此时就可以通以下方式

GET / HTTP/1.1
Host: test.com
Host: exp.com

来绕过缓存服务器的检查。

0x04WordPress与PHPMailer结合导致命令执行

漏洞描述:

独立研究人员Dawid Golunski发现该漏洞—远程攻击者利用该漏洞,可实现远程任意代码在web服务器上执行,并使web应用陷入威胁中。攻击者主要在常见的web表单如意见反悔表单、注册表单中 ,邮件密码重置表单等使用发送的组建时利用此漏洞。

POC展示:

主要是利用host注入恶意命令导致远任意代码执行
Host : target(any -froot@localhost -be ${run{${substr{0}{1}{$spool_directory}}usr${substr{0}{1}{$spool_directory}}bin${substr{0}{1}{$spool_directory}}touch${substr{10}{1}{$tod_log}}${substr{0}{1}{$spool_directory}}tmp${substr{0}{1}{$spool_directory}}manning.test}} null)

下面针对这个做个简要分析,网上很多文章已经对此作了详细分析,我在此就不做详细分析了。

if ( !isset( $from_email ) ) {

//此处会获取SERVER_NAME字段拼接到$from_email变量上且SERVER_NAME可被攻击者控制

		$sitename = strtolower( $_SERVER['SERVER_NAME'] );
if ( substr( $sitename, 0, 4 ) == 'www.' ) {
$sitename = substr( $sitename, 4 );
} $from_email = 'wordpress@' . $sitename;
}
private function mailPassthru($to, $subject, $body, $header, $params)
{
//Check overloading of mail function to avoid double-encoding
if (ini_get('mbstring.func_overload') & 1) {
$subject = $this->secureHeader($subject);
} else {
$subject = $this->encodeHeader($this->secureHeader($subject));
}
if (ini_get('safe_mode') || !($this->UseSendmailOptions)) {
$result = @mail($to, $subject, $body, $header);
} else { //最终$params参数被@mail调用后会触发CVE-2016-10033 phpmailer命令执行漏洞执行远程命令。 $result = @mail($to, $subject, $body, $header, $params);
}
return $result;
}

X-Forwarded-For注入:

大家有没有见过这样一种场景,当你对用户网站进行的爆破或者sql注入的时候,为了防止你影响服务器的正常工作,会限制你访问,当你再次访问时,会提示你的由于你的访问频过快或者您的请求有攻击行为,限制访问几个小时内不能登陆,并且重定向到一个错误友好提示页面。

由此可以发起联想?http是无状态连接,而且自己也清空了COOKIE信息,服务器是怎么还是自己的?

首先当你有攻击行为的时候,服务器一般会把恶意用户的ip存入数据库。当每次用户请求的时候(以java语言为例),服务器通过request.getRemoteAddr()这个方法来获取请求者的ip。于是想到这个ip我们自己到底能不能伪造?答案是否定的。因为经过测试request.getRemoteAddr并不会回从数据包的请求头去获取ip字段的Value。所以推测ip地址是ip包中的soure来的,当我们发送http请求时是否可以更新soure ip来绕过限制呢,这个可以有!,但是你将不会收到对方的响应,因为在正常的TCP/IP通信中,伪造数据包来源 IP会让发送出去的数据包返回到伪造的IP上,无法实现正常的通信。这样我们也就失去的绕过的意义。

request.getRemoteAddr方法我们没办法伪造,是不是我们就无法利用这个点了呢?

结合实际一般程序员是不会通过request.getRemoteAddr方法来获取ip的,这个方法虽然获取的ip比较准确,暂无办法绕过。但实际场景中往往服务器前面会有一个代理服务器和均衡负载服务器。当使用request.getRemoteAddr方法时,获取的只是代理服务器的ip并不能获取请求者的真实ip。这时候一些程序员为了实现获取真实ip会采取如下方法。

public static String getIpAddr(HttpServletRequest request) {
String ip = request.getHeader("X-Real-IP"); if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("X-Forwarded-For");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
if (ip != null) {
if (ip.indexOf(',') > 0) {
ip = ip.split(",")[0];
}
} else {
ip = "0.0.0.0";
}
return ip;
}

X-Forwarded-For通过这个字段我们可以控制绕过ip的限制,但是当我们去绕过ip限制的时候ip会带入数据库去查询,这点我们是不是可以尝试一下sql注入。

将数据包写入文件,通过 sqlmap.py  -r  “filePath”

通过sqlmap抛出的信息,可以看到存在sql注入的点是X-Forwarded-For字段,并且爆出了mysql的版本信息和脚本语言的信息。

User-Agent注入

User-Agent、Content-Type等只要是http包中存在的都可以进行篡改。在这再说下User-Agent的头注入和Content-Type的头注入,其他的就不详细赘述。基本原理大同小异。最后会进行总结。

一般使用user-Agent,有两种场景一是记录访问者的信息,如什么浏览器、操作系统版本等。二是获取客户的user-Agent,根据你提供的信息来给你推送不同的网页。如果你手机手机访问那么返回你的页面将是小型的web界面,还有各种浏览器的特性,推送相兼容的页面。此时已经进行的数据库的入库和查询操作,如果没对此做过滤那么漏洞就产生了。

Content-Type注入又一个远程命令执行

Content-Type看见这个字段相信大家都不陌生,瞬间就会想起一个很可怕的漏洞。S2-045的远程命令执行。当Jkarta解析文件上传请求包不当,当攻击者使用恶意的Content-Type,会导致上传发生异常。从而导致Str2框架对Content-Type的内容进行ongl的解析导致命令执行。这个漏洞虽然要涉及Jkarta插件,而arta插件ommons-fileupload和commons-io包,但是这是Str2的默认插件。也就是说基本所有开发使用到上传都会导入这两个依赖包。最重要的是这个漏洞不需要真正的上传只需进行模拟上传即可,甚至可以是GET请求。具体的详细代码就不跟大家分析了,要不估计还比我这篇文章还长。有兴趣的可以到我的博客或者网上搜索那些大佬的分析。

总结

归根结底,http头攻击漏洞的产生就是因为服务器使用了不受信任的http头字段对某个业务进行的操作。而http头都是我们可以恶意篡改的。具体产生什么漏洞,就看你把这个不受信任的字段,拿去做什么样的业务操作。在平常渗透的时候,可以思考程序员们会拿着这些参数去干什么,从而更有方向的去渗透。

重新认识被人遗忘的HTTP头注入的更多相关文章

  1. 2.HTTP头注入

    重新认识被人遗忘的HTTP头注入 前言 注入类漏洞经久不衰,多年保持在owasp Top 10的首位.今天就聊聊那些被人遗忘的http头注入.用简单的实际代码进行演示,让每个人更深刻的去认识该漏洞. ...

  2. Eruda 一个被人遗忘的调试神器

    Eruda 一个被人遗忘的调试神器 引言   日常工作中再牛逼的大佬都不敢说自己的代码是完全没有问题的,既然有问题,那就也就有调试,说到调试工具,大家可能对于 fiddler.Charles.chro ...

  3. IOS 杂笔-14(被人遗忘的owner)

    *owner在开发中现在已经很少用了 有兴趣的童鞋可以看看* 我们遇到owner通常是在类似 [[[NSBundle mainBundle] loadNibNamed:@"Food" ...

  4. PHPMYWIND4.6.6前台Refer头注入+后台另类getshell分析

    下载链接 https://share.weiyun.com/b060b59eaa564d729a9347a580b7e4f2 Refer头注入 全局过滤函数如下 function _RunMagicQ ...

  5. SQL注入篇二------利用burp盲注,post注入,http头注入,利用burpsuit找注入点,宽字节注入

    1.布尔盲注burpsuit的使用 先自己构造好注入语句,利用burpsuit抓包,设置变量,查出想要的信息. 比如----查数据库名的ascii码得到数据库构造好语句 http://123.206. ...

  6. Eruda 一个被人遗忘的移动端调试神器

    引言 ​ 日常工作中再牛逼的大佬都不敢说自己的代码是完全没有问题的,既然有问题,那就也就有调试,说到调试工具,大家可能对于fiddler.Charles.chrome devtools.Firebug ...

  7. 被人遗忘的MAX_FILE_SIZE文件上传限制大小参数

    在文件上传中,我们经常会要求显 示用户上传文件大小,超过上传限制的文件就会不允许用户上传.虽然我们可以用程序去判断上传文件是否超过限制,但是其实我们的PHP程序是无法判断用户本 地文件大小的.所以等到 ...

  8. 总有一些实用javascript的元素被人遗忘在角落-slice

    slice() 方法可从已有的数组中返回选定的元素. 好吧,我承认我竟然把它忘了! 这次我在回顾一下它 语法 arrayObject.slice(start,end) 数组.slice(起始,结束) ...

  9. i节点,容易被人遗忘的节点

    部分内容转自点击打开链接 点击打开链接 前段时间做了RHCE的一道题,是iSCSi的,后来在挂载的时候说是磁盘被占用.当时资料找了很多结果还是没有找到解决方法.反倒是发现了这个inode,也是关于被占 ...

随机推荐

  1. easyui中datagrid空数据集不刷新的解决方式

    datagrid空间可以异步请求json数据,并将新数据覆盖原有数据,重绘数据表. 但是当回来空数据集的时候,js会产生这样一条错误: TypeError: rows is null for(var ...

  2. vue-router中scrollBehavior的巧妙用法

    问题:使用keep-alive标签后部分安卓机返回缓存页位置不精确问题 解决方案: <div id="app"> <keep-alive> <rout ...

  3. Greedy Gift Givers

    Greedy Gift Givers A group of NP (2 ≤ NP ≤ 10) uniquely named friends has decided to exchange gifts ...

  4. php5.3.3以上重启php-fpm的方法

    http://www.cnblogs.com/GaZeon/p/5421906.html

  5. python的request抓https的警告问题

    1.在使用requests前加入:requests.packages.urllib3.disable_warnings()2.为requests添加verify=False参数,比如:r = requ ...

  6. 口红游戏 插口红游戏 h5页面开发

    目前火热的口红机游戏,需要在设备前参与,然后成功后即可赢得口红,作为平台运营者来说还是比较重资产的,目前我们将它搬到了线上.每个人都可以远程玩这样的口红机游戏了.直接在手机微信里试玩,成功后,后台即可 ...

  7. 搭建自己的YUM源HTTP服务器

    createrepo是linux下的创建仓库的软件包.create是创建的意思,repo是repository的缩写,是仓库的意思.yum(Yellowdog Updater,Modified)主要的 ...

  8. font-family 定义的最后为什么要加一句sans-serif

    定义font-family时,最好在最后加一个sans-serif,这样如果所列出的字体都不能用,则默认的sans-serif字体能保证调用; W3C建议字体定义的时候,最后以一个类别的字体结束,例如 ...

  9. 培训补坑(day1:最短路&two-sat)

    经过12天的滚粗,终于迎来了暑期培训的结尾啦QAQ 结业考才考了90分,真是对不起孙爷(孙爷请收下我的膝盖) orz小粉兔怒D rank 1 获得小粉兔一只QAQ 由于这次12天的培训题目又比较多,算 ...

  10. scrapy爬取段子

    scrapy.py 1.cmd运行scrapy shell http://www.baidu.com response.xpath('//div[@aa="bb"]') 找到需要匹 ...