SpringBoot框架SpEL表达式注入漏洞复现与原理分析( 二 )

SpringBoot框架SpEL表达式注入漏洞复现与原理分析
文章插图
strVal的值变为timestamp,所以在indexOf判断时,由于没出现${,所以变为了-1,跳过了while循环,直接执行下边的return result.toString();
继续跟进,下一步是调用resolvePlaceholder方法,此函数的作用是查找this.context中对应参数的值并返回,如下图:

SpringBoot框架SpEL表达式注入漏洞复现与原理分析

文章插图
发现拿到了时间戳"timestamp" -> "Wed Oct 19 00:38:36 CST 2022",然后赋值给propVal,此时不为空,进入下一个if循环,再次调用parseStringValue 。
SpringBoot框架SpEL表达式注入漏洞复现与原理分析

文章插图
接着进行replace替换,将原来的${timestamp}处的值替换成了 Wed Oct 19 00:38:36 CST 2022,最后return result.toString();返回,如下图:
SpringBoot框架SpEL表达式注入漏洞复现与原理分析

文章插图
然后寻找template中的下一个参数位,这次的参数是error,流程与上面基本一样,这里不再细致分析 。
SpringBoot框架SpEL表达式注入漏洞复现与原理分析

文章插图
接着第三个参数是status,同理
SpringBoot框架SpEL表达式注入漏洞复现与原理分析

文章插图
最后是第四个参数message,重点来了,这个值是用户输入的 。接着分析,跟进parseStringValue方法
SpringBoot框架SpEL表达式注入漏洞复现与原理分析

文章插图
拿到message对应的值,也就是用户输入的payload
SpringBoot框架SpEL表达式注入漏洞复现与原理分析

文章插图
赋值给propVal,接着调用parseStringValue
SpringBoot框架SpEL表达式注入漏洞复现与原理分析

文章插图
这次调用去除了${}
SpringBoot框架SpEL表达式注入漏洞复现与原理分析

文章插图
最后进入resolvePlaceholder,成功执行T(java.lang.Runtime).getRuntime().exec(new String(new byte[]{0x63,0x61,0x6c,0x63})),弹出计算器,分析结束 。
SpringBoot框架SpEL表达式注入漏洞复现与原理分析

文章插图
参考文章https://www.cnblogs.com/litlife/p/10183137.html
https://www.cnblogs.com/zpchcbd/p/15536569.html
https://blog.csdn.net/haduwi/article/details/126326511
https://blog.csdn.net/weixin_54902210/article/details/124533353

经验总结扩展阅读