前言

项目是java-sec-code:https://github.com/JoyChou93/java-sec-code

鸽了两天,在忙做其他的web。

0x01 从原版java代码分析

进入controller文件

/src/main/java/org/joychou/controller/CommandInject.java

@RestController注解下有一个CommandInject类

先来看第一个控制器codeInject

图片

get请求接受一个filepath,之后新建了一个对象ProcessBuilder,这个对象从名字就可以看出来是“进程构建者”,可以用来执行脚本或者本地命令,类似于php中的system(),以及python中的subprocess、popen等等。

builder.redirectErrorStream(true); 声明了获取标准输入输出,之后可以通过getInputStream()获取执行命令后的输出结果(如图上31行)。

此处没有任何过滤,并且有返回输出结果,可以直接通过linux命令执行特性 通过;来执行多条命令。

1
2
sh -c ls -al /tmp;cat /etc/passwd
# 等价于先执行sh -c ls -al /tmp再执行cat /etc/passwd

即使不输出返回结果,也可以通过反弹bash shell的方法拿到权限。

再来看下面的控制器

和上面的结构差不多,只不过这次并不是传输一个文件,而是通过从你请求头重获取host值,并拼接执行,例如我host为127.0.0.1

1
sh -c curl 127.0.0.1 

对接受的host没有任何的过滤,通过burp或者其他手段修改请求包中的host值,例如修改成127.0.0.1;cat /etc /passwd,拼接之后也会执行两条命令。

1
sh -c curl 127.0.0.1;cat /etc/passwd

0x01 官方修复分析

可以看出来通过一个cmdFilter函数对传进来的filepath进行过滤,我们跟进cmdFilter来看下

image-20210807221530662

image-20210807221918158

正则匹配一下,匹配多个a-zA-Z0-9_/.- 发现没有“;和空格”,因此无法进行拼接命令进行其他命令的执行

可以使用正则匹配网站 https://regex101.com/ 进行相应的测试