注意:本文分享给安全从业人员,网站开发人员和运维人员在日常工作中使用和防范恶意攻击,请勿恶意使用下面描述技术进行非法操作。

[TOC]

0x00 前言介绍

描述:HPP参数污染的定义:HTTP Parameter Pollution简称HPP也称之为“HPP参数污染”,HPP是一种注入型的漏洞攻击者通过在HTTP请求中插入特定的参数来发起攻击,如果Web应用中存在这样的漏洞,可以被攻击者利用来进行客户端或者服务器端的攻击还能绕过WAF。


0x01 HPP原理

描述:简单的说就是使用相同的名称提供多个HTTP参数可能会导致应用程序以意想不到的方式解释值。
由于HTTP参数污染(简言之HPP)影响所有web技术的构建块,所以存在服务器端和客户端攻击;通过利用这些效果攻击者可以绕过输入验证、触发应用程序错误或修改内部变量值。
通过上面OWASP的截取WIKI我们知道实际这个漏洞就是采用多个同名参数,比如:

#E.G:
https://weiyigeek.com/test.php?color=red&color=blue

不同的后端对其解析是不同的备忘清单如下:
WeiyiGeek.
补充:

Web服务器 参数获取函数
PHP/Apache $_GET("par")
JSP/Tomcat Request.getParameter("par")
Perl(CGI)/Apache Param("par")
Python/Apache getvalue("par")
ASP/IIS Request.QueryString("par")
All (comma-delimited string)

又比如搜索引擎对于HPP解析理解是不同的:
假如这个URL:https://www.baidu.com/s?wd=whoami&wd=WeiyiGeek

  • 百度会理解成让百度搜索:whoami #选择了第一个参数,放弃了第二个参数。
  • 雅虎会理解成让雅虎搜索:WeiyiGeek  #选择了第二个参数,放弃了第一个参数。
  • 谷歌会理解成让谷歌搜索:whoami WeiyiGeek #两个参数同时选择。

总结:

  • 不同的后端解释语言对于重复的同名参数请求的处理方式是不一样的;
  • 而不同的搜索引擎主要就是三种情况了,由于源于不同的网站对处理参数的处理方式不同

0x02 HPP利用

描述:HPP参数污染攻击方式在网站接受用户输入,将其用于生成发往其它系统的HTTP请求,并且不校验用户输出的时候发生。
它以两种方式产生通过服务器(后端)或者通过客户端

(1)HPP客户端攻击
描述:比如有这样一个网站,用来给其他人在2个候选人之间投票,这个网站的URL和代码是这样的:

Url : 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>

#我们根据HPP原理以及后端语言解析可知,JSP来说在有2个相同的名称的参数的时候会取第一个值,所以不管投票人选择的是谁始终都是张三得票。
Url : http://host/election.jsp?poll_id=4568&candidate=zhang
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> #其实还是为张三投票

客户端的攻击一般会是如下流程:

  • 存在HPP漏洞网站->攻击者生成精心设计的恶意URL->将其分发给普通用户->请求服务器端(写入数据库)->攻击成功


(2)HPP服务端攻击
描述:它有个独立的集中认证服务器用来做用户权限方面的认证,另外的业务服务器专门用来处理业务,对外的门户实际上紧紧只是用来做请求的转发。
那么看看一个本来紧紧只是具有只读权限的用户,如果发送如下请求给服务器:

//比如某网站的实现如下:
void 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);}

根据我们知道的Web服务器参数处理的方式这个用户可以通过认证做一些本来没有权限做的事情。

http://www.weiyigeek.org/page?action=view&userid=zhangsan&target=bizreport&action=edit


(3)HPP参数污染安全设备绕过
描述:HPP还可以被攻击者用来绕过一些Web应用防火墙(WAF, WebApp Firewall),HTTP参数污染注入源于网站对于提交的相同的参数的不同处理方式导致
假设输入:

#示例服务端有可能会将key处理为select 1,2,3,4 from table,从而导致SQL注入
www.backlion.org/a?key=select&key=1,2,3,4 from table #因为在参数id里面存在明显的SQL注入的模板:select…from…而会被WAF成功拦截。

#但是如果换成HPP的方式:
show_user.aspx?id=5;select+1&id=2&id=3+from+users+where+id=1-- #没有任何参数具备select…from…的特征,可能就可以绕过WAF的拦截了。
http://www.xishaonian.com/hello.php?id=select 1&id=2,3,4 from admin #还可以与XSS结合使用


0x03 HPP案例

1.HPP与XSS组合
描述:案例是关于Apple Cups的,它是被许多UNIX系统利用的打印系统实际是绕过系统的验证机制;
利用如下的方式触发一个XSS攻击:

#第一个kerberos直到被用于构建动态HTML内容前都没有被验证。
http://127.0.0.1:631/admin/?kerberos=onmouseover=alert(1)&kerberos #原因是这个验证系统只采纳了第二个kerberos的值,这个值为空因此不会触发。
#最终在web站点的上下文中javascript语句被执行


2.HPP与HTML注入
HPP 客户端涉及到向链接和其它src属性注入额外的参数。在 OWASP 的一个例子中,假设我们拥有下列代码:

<? $val=htmlspecialchars($_GET['par'],ENT_QUOTES); ?> <a href="/page.php?action=view&par='.<?=$val?>.'">View Me!</a>

它从 URL 接受par的值,确保它是安全的,并从中创建链接。现在如果攻击者提交了: http://host/page.php?par=123&action=edit

产生的链接可能为:导致应用接受编辑操作而不是查看操作:

<a href="/page.php?action=view&par=123&action=edit">View Me!</a>


3.HPP付款签名验证(有利于价值)
描述:比如付款链接一般会有重要的参数构建的签名是由某些重要的字段组成的加了同名的字段以后;
有可能在签名的时候验证了第一个付款金额参数,但是在实际付款的时候用了后面的一个付款金额参数,导致签名被绕了过去。
模拟案例:

#Reuqest
POST https://www.example.com/transferMoney.php
#Params
amount=1000&fromAccount=12345

当应用处理请求时,它生成自己的发往其它后端系统的 POST 请求,这实际上会使用固定的toAccount参数来处理事务。

分离后端 URL:https://backend.example/doTransfer.php
分离后端参数:toAccount=9876&amount=1000&fromAccount=12345

#假设攻击者修改了发往网站的 POST 请求来提交toAccount参数像这样:
amount=1000&fromAccount=12345&toAccount=99999

#存在 HPP 漏洞的站点就会将请求转发给另一个后端系统(然而在PHP处理最后1个参数值则触发漏洞攻击)
toAccount=9876&amount=1000&fromAccount=12345&toAccount=9999 #将钱转账给恶意用户调教得账户(99999)而不是由系统设置的预期账户(9876)。


4.HPP参数污染实例
HackerOne 社交分享按钮
描述:HackerOne 包含的链接用于在知名社交媒体站点上分享内容,例如 Twitter,Fackbook以及其他。这些社交媒体的链接包含用于社交媒体链接的特定参数。
攻击者可以将另一个 URL 参数追加到链接中,并诱惑受害者点击

#U参数的值诱惑受害者点击,尝试通过社交媒体链接分享内容,恶意链接就会变为:
https://www.facebook.com/sharer.php?u=https://hackerone.com/blog/introducing-signal?&u=https://vk.com/durov

#参数u就会拥有比第一个参数更高的优先级,之后会用于 Fackbook 的发布。在 Twitter 上发布时建议的默认文本也会改变:
https://hackerone.com/blog/introducing-signal?&u=https://vk.com/durov&text=another_site:https://vk.com/durov


Twitter 取消订阅

#Poc:默认取最后一个人参数
https://twitter.com/i/u?t=1&cn=bWV&sig=657&iid=F6542&uid=1134885524&uid=1134885524&nid=22+26 #成功取消订阅了其它用户的邮件提醒


0x04 安全防御

  • 1.HPP是一种新的注入型漏洞要防止这种漏洞,除了要做好对输入参数的格式验证外,另外还需要意识到HTTP协议是允许同名的参数的,在整个应用的处理过程中要意识到这一点从而根据业务的特征对这样的情况作正确的处理。

  • 2.让WAF或其他网关设备(比如IPS)在检查URL时,对同一个参数被多次赋值的情况进行特殊处理。由于HTTP协议允许相同参数在URL中多次出现,因此这种特殊处理需要注意避免误杀的情况

  • 3.在代码层面编写WEB程序时,要通过合理的$_GET方法获取URL中的参数值,而尝试获取web服务器返回给程序的其他值时要慎重处理。


0x05 总结补充

文章参考来源: