phpcms v9.6 Content模块SQL注入漏洞分析

最近几天圈里放出来一波phpcms的0day漏洞,这就是其中一个。此漏洞觉得很有意思,而且利用也需要好几个步骤,Payload完全可以绕过WAF检测。

漏洞分析

这里我们使用反推的方法来分析这个漏洞过程。

漏洞触发点在文件/phpcms/modules/content/down.php,来看init函数:

通过GET获取到$a_k参数内容,然后$a_k参数内容进入到sys_auth函数进行解密,说明我们传入的$a_k是提前已经加密的内容了,这里我们不用关系他到底是怎么解密的。

我们继续看parse_str($a_k);,这列parse_str函数有一个Trick:

Parse_str函数会自动对传入的值将其根据&分割,然后解析到具体变量并注册变量,并且对内容进行URL解码操作。

比如我们我们传入字符串’id=123%27%20and%201=1%23’,经过parse_str函数后就变成了id=123’ and 1=1#,就是id变量的内容为123’ and 1=1#

继续往下看array(‘id’=>$id)进入了数据库操作,这里的id就是从parse_str函数处理$a_k后得到的内容,因为系统中默认是没有定义这个id的,正好通过parse_str处理后注册了id变量。

现在的问题就是

我们怎么得到这个$a_k的值,因为解密,肯定存在加密,而且这里的加密是需要系统中的auth_key的,所以我们本地使用加解密函数进行数据加解密就行不通了。

那么就只能在当前系统中找到一处能加密的接口,并且可以输出解密后内容的地方。

在文件/phpcms/modules/attachment/attachments.php,swfupload_json函数:

这里从GET获取了src参数内容,并且通过safe_replace函数处理

然后通过json格式化后进入了set_cookie函数。

我们先来看看safe_replace函数的内容,文件\phpcms\libs\functions\global.func.php:

功能就是把一些符号给替换掉了,比如%27,*,’,”等。

但是这里有一个问题如果我们传入%2*7通过safe_replace函数后变成了%27

然后门继续来看看这个set_cookie函数,文件\phpcms\libs\classes\param.class.php

可以看到,我们传入set_cookie(‘att_json’,$json_str);,将我们传入的att_json+系统中cookie的前缀作为set-cookie的key=前缀_att_json,将$json_str的内容通过sys_auth函数加密后最为set-cookie的value值。这里在sys_auth进行加密时默认使用的是system里面的auth_key,跟我们前面进行解密时使用的是同一个auth_key。

到这里,我们就清楚了:

  • 第一步传入src参数;
  • 第二步将传入的内容通过加密后返回到Cookie值;
  • 第三步将返回的Cookie值传递给a_k参数
  • 第四步a_k参数解密后进入数据库操作

因为整个过程中传递数据时是加密的,所有无视waf的防御,虽然有safe_replace函数处理,但是我们上面已经简单绕过了。

需要注意的时,在我看到的几篇分析文章中,都没有提到为什么第一步先要获取一个cookie并带入第二步获取加密的payload数据,这里我们看一下:

还是在attachments.php文件

这里一目了然,为什么需要带上cookie 访问,因为不带cookie的话就直接跳到登录了。

这里有两种方式:

  • 直接从cookie中获取名为:前缀_userid的cookie内容;
  • POST一个userid_flash

但是这两个方法获取的内容,多需要通过sys_auth解密,如果解密失败也会跳转到登录。

所以我们传入的cookie内容必须是合法的cookie,也就是通过set_cookie函数设置的cookie,因为set_cookie函数设置cookie时会通过sys_auth加密,这样解密就合法了。

那么从哪里无添加直接获取这个cookie 了,系统中应该有很多,这里使用的是wap模块里面的接口,/phpcms/modules/wap/index.php:

这里GET获取siteid,然后为siteid设置cookie,返回的就是前缀_siteid为key的cookie。

然后这个cookie就可以拿来给下一步用了。

漏洞利用:

访问:http://10.65.20.198/phpcms_v9.6.0_UTF8//index.php?m=wap&c=index&a=init&siteid=1

获取到这里的cookie:

KhLUs_siteid=923aWILP69vS49T0lonOkl-ZEWFgBRxEdmRHCEUx

然后将设置第二步的cookie:

KhLUs_userid=923aWILP69vS49T0lonOkl-ZEWFgBRxEdmRHCEUx

带上这个cookie访问:

http://10.65.20.198/phpcms_v9.6.0_UTF8/index.php?m=attachment&c=attachments&a=swfupload_json&aid=1&src=%26id=%27and%20exp(~(select%2afrom(selectconcat(0x706f6374657374,user(),0x23,version(),0x706f6374657374))x))

上面标红的那一段为我们构造的payload。

此时得到cookie:

KhLUs_att_json=a217vsJZ1FMqAjbenpUAOGzykDTKwL3z0aM6RWBZnBlh6RL6BDS8vlPFt9wPIo5mwketJHkRsNnDJr1ovMGoYTKNqLxN9NyPXt072g-7ZSR_3Rg_gdeXJW_j5VWaIIShkZFxtR87Fz9ggw6kA4ys8df0MEmMBqJFLqNBw34GZq5WBc4vW2L9dMy4WbdyKV6ofWNH2uCsQDOf-DRBYUvFg099BEUk

第三步我们将cookie,KhLUs_att_json的值付给a_k参数:

http://10.65.20.198/phpcms_v9.6.0_UTF8/index.php?m=content&c=down&a_k=a43cwJXaAds_EZJHXn6ynaZebS0WeXR3PfES7Uv7vhMbAQ89L4lcgcPQA1b1ymPV3rlDkIHPqwInr2Bhoet7ZKXybf69LQdRr7ebx15D3N_uh1ff7AQeiqL7GMo2O4_vInYDfYBzKt2loHWNI9rd45PyM9wSjJRjWi1Wwwt-l9gtACeA75G_3hqipFqd0jsi0_666ma4poOqWE-J9VkWXXwsxuIZ

然后加密的payload通过解密最后进入数据库操作,导致sql注入产生。

注入数据的利用请见附件中的exp。

注入发生后,进一步利用就各种发挥咯。

漏洞修复:

官方发布了9.6.1版本,4月12日也出了补丁,补丁地址:

http://download.phpcms.cn/v9/9.0/patch/utf8/patch_20151225_20170412_UTF8.zip

来看一下补丁的修复情况:

可以看到这里对$a_k进行过滤,并且对id进行intval转换。

所以请升级到最新版。

如果您需要了解更多内容,可以
加入QQ群:570982169
直接询问:010-68438880

Spread the word. Share this post!

Meet The Author

Leave Comment