本文分为两个部分:
ecshop 2.x getshell
Bypass ecshop 3.x WAF
Exploit
ecshop 2.x
SQLi POC
RCE POC
Analyze
ecshop 2.x
SQLi
在前台用户登录页面,变量从referer中获取,传递到函数中。
user.php
跟进。
includes/cls_template.php
当不是数组且不为空时,添加到当前对象的数组中。
将上述变量显示到页面上需要函数。跟进一下。
includes/cls_template.php
通过这里通过->来获取最终呈现在页面上的结果,也就是变量的值,关于Smarty的知识简单的介绍一下。
这里使用了Smarty这个PHP模板框架,原理如图所示。
登录页面的模板文件在,编译后的php文件路径为,其中使用了值的部分如图所示。
所以我们通过referer控制的值,经过编译以及PHP的运行,最后的呈现出来的结果如下图所示。
回到函数,得到的值后判断其中是否存在,这是一个常量,在这里是,然后进行分割,并进入函数。
重点来了,一眼看上去这个东西就有问题,一是存在反序列化,二是使用动态调用函数。全局搜索一下主要定位在lib_insert里。在这里就先用这个函数。
includes/lib_insert.php
这里可以比较明显的看出SQL语句存在拼接。这里只用了id和num两个参数,所以我们只需要序列化构造这两个参数就可以。这里用id这个参数,这里可以使用extractvalue就行,如果用produce analyse的话5.6.6以上的版本不支持。这里不再赘述了,POC如所示。
RCE
继续看这个函数的后半段。
是可控的,是从数据库中取出来的
209行的这个变量加上了并传入了函数,看一眼函数。
可以发现,对于开头是的文件名带进了这个看起来就很敏感的函数。所以回函数看看如何控制的值。
includes/lib_insert.php
从数据库查询出来的表中,字段的值要与反序列化出来的数组的字段相等,才会进行赋值。那么上面通过控制来进行注入的方式就不是那么好用了,主要还得通过来传递payload。
字段这里给4,为了不执行switch逻辑,以免节外生枝。
所以构造如下payload:
把order by limit给注释掉就可以无限制进行注入了。
回到includes/cls_template.php的函数。跟进一下的前一步处理。
还是一个比较复杂的正则,但是问题不大,可以使用来看看这个函数匹配了哪些东西。
先看第一个正则,这个正则主要是过滤一些关键字,分为三个部分,第一个部分匹配除了以外的所有字符,第二部分值一些敏感函数的关键字,最后匹配空格和前半括号一次。
第二个正则不用管,只要不进入if这段逻辑就可以了,最后return的正则也比较简单,就是将匹配到(花括号中的内容)的值传递给,这里phpStorm跟不进去,可以将cls_template.php复制出来,然后在外面调用。
我们先给一个简单的poc:,因为phpinfo在第一个正则会被过滤,所以注释一下,绕过第一个正则。
includes/cls_template.php
可以看到在变量第一个字符为$的时候进入 ,跟一下。
这里有一个巨坑的地方,不知道是不是我字体的原因,我这里的phpstorm居然在单双引号中不显示这个字符。坑爆了,刚开始以为是匹配,后来发现是匹配,升级到最新版本可以解决这个问题。
我们给poc加上$,带进去试试。
跳入中的图中标出的逻辑。跟进函数。
可以看到在这个函数中给poc拼接了一些字符串。
所以最终的处理是这样的。
闭合一下。
所以最后带进eval的值如图所示。
构造最终的poc应该为。序列化一下。
这个POC执行一下发现,报错了。
调了一下发现是在反序列化的时候有一个参数的空的。
看了一下中间生成的模板,发现其他在分割的时候都如下图所示。
这个主要是函数中的这一段。
所以最后的POC如下所示。
领取专属 10元无门槛券
私享最新 技术干货