openrasp
openrasp copied to clipboard
rasp截获的http body 疑似冗余
复现环境
- jdk 1.8
- springboot(2.7.4)+内嵌jetty(9.4.49.v20220914)
- open-rasp 1.3.7
问题描述:
有一个接口通过http请求可以触发命令执行:
@PostMapping(value = "/json/unixProcess.do", consumes = APPLICATION_JSON_VALUE)
public Map<String, Object> jsonUnixProcess(@RequestBody Map<String, Object> map) throws Exception {
return unixProcess((String) map.get("cmd")); // 调用命令执行方法
}
通过postman 发送请求:
http 请求的 body 参数为 {"cmd": "cat /etc/passwd"}
debug open-rasp 1.3.7 ,发现截获的body与输入不同

com.baidu.openrasp.request.AbstractRequest#getStringBody
rasp 截获的body参数:{{"cmd": "cat /etc/passwd"}
与输入对比多了第一个字节
初步原因
open-rasp hook 了org.eclipse.jetty.server.HttpInput
中的2个方法:
1.public int read() throws IOException 2.public int read(byte[] b, int off, int len) throws IOException JettyHttpInputHook源码位置

org.eclipse.jetty.server.HttpInput 中2个方法调用关系:read() 最终会调用 read(byte[] b, int off, int len)
open-rasp 中2个方法都会读取的 http body 字节并存储,而 read() 读取body 的第一个字节,open-rasp 将body的第一个字节存储:
read(byte[] b, int off, int len) 读取全部字节,导致http body 第一个字节读取了2次。
初步优化
由于第一个hook点read()
调用read(byte[] b, int off, int len)
,因此可以去掉read()
仅保留 read(byte[] b, int off, int len)
优化前后代码:
@Override
protected void hookMethod(CtClass ctClass) throws IOException, CannotCompileException, NotFoundException {
//String srcRead1 = getInvokeStaticSrc(ServerInputHook.class, "onInputStreamRead",
// "$_,$0", int.class, Object.class);
//insertAfter(ctClass, "read", "()I", srcRead1);
String src2Read2 = getInvokeStaticSrc(ServerInputHook.class, "onInputStreamRead",
"$_,$0,$1,$2", int.class, Object.class, byte[].class, int.class);
insertAfter(ctClass, "read", "([BII)I", src2Read2);
}
优化方案经过验证,http body读取正常。
如有错误,欢迎指正~~
你好,可以提交个PR吗