# 一、漏洞环境信息
场景:输入域名或者ip信息通过ping检测连通性
http://127.0.0.1:8080/cmd/runtime?ip=localhost
http://127.0.0.1:8080/cmd/processbuild?ip=localhost
payload代码:
http://127.0.0.1:8080/cmd/runtime?ip=localhost;cat+/etc/passwd

# 二、修复说明

# 分析service层goAction添加修复后的代码
goAction
@Service
public class runTimeServiceImpl implements runTimeService {
@Override
public String goAction(String ipaddr) throws IOException {
//安全过滤,添加一下2行esapi过滤函数的处理
ipaddr= charEncoding.osCmdFilterESAPI(ipaddr);
System.out.println(ipaddr);
String cmds = "/sbin/ping -c 1 " + ipaddr; //拼接命令
String[] cmd = new String[]{"sh","-c",cmds};
//执行命令获取返回值
InputStream inputStream = Runtime.getRuntime().exec(cmd).getInputStream(); //执行命令并获取结果
StringBuilder sb = new StringBuilder();
int len = 0;
while ((len=inputStream.read())!=-1){
sb.append((char)len);
}
return sb.toString();
}
}
esapi代码
//命令执行esapi编码
static public String osCmdFilterESAPI(String content){
UnixCodec unixCodec = new UnixCodec();
return ESAPI.encoder().encodeForOS(unixCodec,content);
}
命令语句转译过程
/sbin/ping -c 1 localhost;cat /etc/passwd
||
\/
\/sbin\/ping\ -c\ 1\ localhost\;cat\ \/etc\/passwd
# 三、小结
- 成因:输入参数未过滤
- 位置:Service层
- 修复:输入过滤/ESAPI过滤
static public String osCmdFilterESAPI(String content){ UnixCodec unixCodec = new UnixCodec(); return ESAPI.encoder().encodeForOS(unixCodec,content); }