刷微博正好看到P神的活动,学习了。

简单记录下jar分析一般步骤:
源码下载后,JD-GUI反编译,或者到IDEA中放进lib便可以查看反编译class源码。
如果需要调试,IDEA打断点后,配置Remote如下
屏幕快照 2018-11-25 下午6.31.18

命令启动

再点击IDEA右上角的DEBUG即可。

程序结构:
屏幕快照 2018-11-25 下午6.34.08

首先我们可以从SpringBoot的配置 application.yml看起

主要就是一个黑名单,一个用户的提供。

其他文件 :
SmallEvaluationContext 继承 StandardEvaluationContext,主要是提供一个上下文环境,相当于一个容器。
ChallengeApplication 用于启动
Encryptor 加密解密工具类
KeyworkProperties 使用黑名单时需要
UserConfig 用户模型,可以看到在RemberMe时使用了Encryptor

主要看MainController
屏幕快照 2018-11-25 下午6.41.24

我们从登录看起

判断用户名密码,如果勾选了remberMe则浏览器存入加密后的cookie。
最后跳转hello.html

屏幕快照 2018-11-25 下午6.45.23

打开页面后其中比较敏感的一个操作就是对Cookie的处理,如下

程序判断rememberMeValue存在后,直接对其进行解密,然后将其setAttribute,接下来可以看到this.getAdvanceValue(username.toString())
我们来看这个方法。

其实就是与其跟黑名单做正则匹配,如果匹配成功则抛出HttpStatus.FORBIDDEN,如果没有匹配到则进行正常流程,在SmallEvaluationContext进行SpEL表达式解析。注意,这里就存在El表达式注入的问题了。
在JAVA中我们可以通过

来执行命令,但在这个题目中使用了黑名单。
所以这里我们需要使用反射来构造一条调用链,这样就可以在关键字处使用字符串拼接来达到绕过黑名单的效果。
不熟悉反射的小伙伴可以先学习一下,这里我直接给出POC 还有一些注意的点。

我们选择利用curl来配合执行命令,所以如下,字符串拼接很好理解,很容易绕过了正则匹配。

运行一下,可以看到我们成功接受到了请求。
屏幕快照 2018-11-25 下午7.04.58

接下来我们需要将其构造为SpEl的解析格式,主要就是改一个T() 。在SpEL中,使用T()运算符会调用类作用域的方法和常量。
需要注意的一个点,在JAVA中Runtime中exec对复杂一点的linux命令执行不了…我们需要将其参数改成如下才可以

所以我们构造如下POC 来执行命令并获取结果,这里一个小技巧就是使用base64来传数据。

获取目录
之后cat flag,如下,再像上面一样加密后存入cookie中即可。

屏幕快照 2018-11-25 下午6.44.00
屏幕快照 2018-11-25 下午6.17.31
屏幕快照 2018-11-25 下午6.17.42

最后,师傅们Tql,感谢p神的题目。
屏幕快照 2018-11-25 下午6.33.22