php代码审计入门笔记-bluecms
Ebounce
撰写于 2019年 07月 05 日

最近准备入坑代码审计了,当然作为一名萌新,肯定少不了参考很多大佬的资料了,也是经由大佬推荐,入门比较适合审计BlueCMS1.6 SP1,除了第一次看CMS的代码,犯了很萌新的错误就是,文件是一个个读的没有切入点,自然读了很久也审不出来什么东西了,好了,废话不多说,来看看这个CMS有哪些漏洞吧(我跟随大佬的脚步找到的)
<!--more-->

参考大佬文章:
https://www.freebuf.com/articles/web/166602.html

ad_js.php-SQL注入漏洞


首先第一个也就是最多被人提及的注入漏洞了,这个是直接Seay自动审计就可以审计出来的(大多数时候不要相信这个玩意儿)

然后就看到了这一串代码,这段代码只是简单的对ip参数进行了去除首位空白符的操作,并没有对用户输入进行过滤,table()函数只是为表名加上了'blue_'的前缀,而getone()函数则是将sql语句传过去,进行查询并没有进行过滤,但开头应用了一个common.inc.php,我们去看看是不是配置了什么其他过滤设置.




这里定义了如果魔术引号没有使用的话,将会对全局变量$_POST,$_GET,$_COOKIE,$_REQUEST调用deep_addslashe()函数,然后我们再去看看deep_addslashe()这个函数长什么样

我们发现这个函数将利用递归,将数组内的所有内容全部使用了addslashe()函数--即对输入中的引号加上'/'就像下面的官方手册范例一样

经由测试,魔术引号是没有打开的也就是说,我们通过GET,POST,COOKIE传进来的数据中的引号都会被加上下划线,然后注意看原来ad_js.php的sql语句,发现了吗?这是数字型的注入,也就是说我们并不需要使用引号去闭合前面的语句,因此存在注入,那么是否有回显呢?注意下方的语句:

这条语句实际上起的作用是,如果查询成功则将查询的结果,以html注释的形式回显出来,然而出现查询错误,则会完整的将查询语句回显出来(非注释)如下图:


由于是数字型注入,且有回显因此这里可以使用union联合查询注入,过程如下图:
前面已经使用order...by语句查询到了有7个列,因此接下来检查回显:

然后爆表名:

随后爆列名(这里需要注意的是由于deep_addslashe()函数的存在,这里如果使用表名加引号会自动被加上'/',导致查询失败,因此需要进行16进制编码绕过:

最后回显admin用户的信息:

ip伪造sql注入


首先阅读配置文件的时候,发现了一个问题,就是前文提及的对全局变量过滤的函数,实际上忽略了$_SERVER和$_FILES这两个全局变量,也就以为则,这两个超级变量的引用将不会有任何的处理,而根据getip()函数,表明服务器获得ip的方式既可以使用X-Forwarded-for来伪造,也可以使用client-ip来伪造,两者皆可.

既然猜测在使用ip的时候没有进行数据处理,那么可以通过全局搜索调用getip()的地方,来寻找是否有注入点的地方,如下图:


阅读这个insert语句,发现其中的变量在前后并没有过滤,或者说对getip()函数返回的结果没有进行过滤,因此这里存在注入,具体利用方式参照
blueCMSsql注入

1','1'),('','6','2','1','6',(select concat(admin_name,':',pwd) from blue_admin),'1','1


博客中的payload,思路就是闭合前一个VALUE(),再构造下一个(),这里如果输入错误的sql语句会将sql语句全部回显出来,因为这个INSERT注入会涉及很多参数,而除了回显点,都需要和前一个VALUE()保持一致.


PS:这里有个小坑的地方,回显语句后面的哪个参数是时间戳,也就是注入之后,回显的评论时候是由注入语句后那个参数决定了,之前按照上面博客的语句,注入的数据在最下面(时间为1970年).

有关用户支付功能存在的问题



这个漏洞没有办法复现,因为网站的支付模块没有开启,而我加载的时候,会提示支付模块损坏,所以暂时无法复现,但这个漏洞其实是很明显,
具体利用过程,请参照博客: https://www.freebuf.com/vuls/196190.html

注意这里POST上来的pay参数,我们可以看到前后没有做任何数据处理,就进行了包含语句的拼接,但是后面直接拼接了一个ndex.php,是不是我们只能包含带有index.php的文件呢?答案当然是否定的,由于这个CMS版本老旧,需要运行在phpstudy--PHP5.2的版本,而这个版本是存在%00截断和url长度截断的,因此可以利用这两个方法进行截断,从而包含我们想要的文件.
PS:这里的%00用不了,因为前面$_POST会直接调用deep_addslashe()函数,让%00被加上'/',从而无法执行截断.

from参数任意包含漏洞


这个起因应该是发现一些功能会拼接这个$from参数,这个参数是用户可控参数,并且没有进行除了deep_addslashe()之外的任何处理,原来以为只是一个重定向的问题,但最后感觉问题还是挺大的,源码如下图:

这是from参数的来源,只是先判断是否为空,不为空则直接获得REQUEST的值,然后我们再来看看,哪里使用了这个可控参数.

  • first:do_login

  • 从act参数的名字可以看出,这个是在进行登陆操作的时候会调用这个参数
  • second:do_reg

  • 第二个则是进行注册时,会使用这个from参数,但这个参数通过测试,是进行重定向的作用,这个值默认为空,在判断里面空的情况下是为了重定向至user.php,但这个参数是可控的,通过用户构造恶意的base64编码后的数据,能够控制重定向的位置,这里以注册功能为例(登陆功能也是类似的):

    这里from参数的值是由base64编码之后的../../../phpMyAdmin,然后burpsuite抓到了下一步的数据包,居然是请求GET-phpMyAdmin的数据包

    而且还携带了blueCMS的参数(注意看Cookie)
    这是最开始测试时候使用的登陆功能,我们可以发现哪个showmsg.htm的页面上a标签的href已经变成了我们注入的脏数据了.

    这也就意味我们可以通过这个参数完成对文件的包含,那么我来再来看看为什么会出现这种问题,问题其实是出在showmsg()函数上面

    就是这个基本上一定会调用的这个函数

    函数原型在这里,assign()主要是将传入的值变成键值对的形式,而display()函数太长了,读完发现就只是用于在showmsg.htm页面上显示错误信息而已,问题其实是出在htm里,我们来看看源码

    这里JS就将传入的gourl传给了自动跳转的函数上面,而gourl则是传入的from值,所以用户能够通过控制from值来进行文件包含.

    修改新闻上面存在的XSS



    先来看这个功能进行了什么操作,前面的$autor,$source都进行了html实体编码,基本上不能注入,但我们看看后面剩下的参数对$content参数进行了去掉前后字符和过滤了一些数据,然后判断有没有$descript,有的话截取$descript的前90个字符(也就是长度限制),如果,如果没有$descript的话则会对$content参数再进行一次过滤,也就是说如果我们传入了$descript的值,就会少进行一次过滤,因此存在XSS的可能性.

    看看filter_data()函数原型,我们可以发现是利用了正则表达式,对元数据进行了一次过滤,也就是说我们可以通过双写绕过,同时这里没有不区分大小写的匹配,因此也可以通过大写标签绕过.最后这里过滤的标签还少了几个,可以直接使用


    总结


    最后感觉PHP代码审计还是比较有意思,当然思维模式很重要,我是一开始就从功能下手,一个个文件去审计,这样既需要搞懂CMS本身的架构逻辑,还需要大量的时间,效率真的是非常的低,因此上面参考的两篇博客都说到了思维这个东西.大佬们似乎比较建议用两个方式进行审计.
  • 从黑盒测试入手,追踪数据流,从而快速判断哪些功能出现问题,缺点是很容易漏掉一些不容易注意的网页

  • 从用户输入入手,对于所有的功能文件,只关注用户输入,可能还是需要搞清页面本身的逻辑,但比一行行代码的读取有效率多了.....

  • 最后希望自己在代码审计的路上能够走远点,没事多看看CMS(flag高高立起...)

    php代码审计入门笔记-bluecms

    最近准备入坑代码审计了,当然作为一名萌新,肯定少不了参考很多大佬的资料了,也是经由大佬推荐,入门比较适合审计BlueCMS1.6 SP1,除了第一次看CMS的代码,犯了很萌新的错误就是,文件是一个个读的没有切入点,自然读了很久也审不出来什么东西了,好了,废话不多说,来看看这个CMS有哪些漏洞吧(我跟随大佬的脚步找到的)
    <!--more-->

    参考大佬文章:
    https://www.freebuf.com/articles/web/166602.html

    ad_js.php-SQL注入漏洞


    首先第一个也就是最多被人提及的注入漏洞了,这个是直接Seay自动审计就可以审计出来的(大多数时候不要相信这个玩意儿)

    然后就看到了这一串代码,这段代码只是简单的对ip参数进行了去除首位空白符的操作,并没有对用户输入进行过滤,table()函数只是为表名加上了'blue_'的前缀,而getone()函数则是将sql语句传过去,进行查询并没有进行过滤,但开头应用了一个common.inc.php,我们去看看是不是配置了什么其他过滤设置.




    这里定义了如果魔术引号没有使用的话,将会对全局变量$_POST,$_GET,$_COOKIE,$_REQUEST调用deep_addslashe()函数,然后我们再去看看deep_addslashe()这个函数长什么样

    我们发现这个函数将利用递归,将数组内的所有内容全部使用了addslashe()函数--即对输入中的引号加上'/'就像下面的官方手册范例一样

    经由测试,魔术引号是没有打开的也就是说,我们通过GET,POST,COOKIE传进来的数据中的引号都会被加上下划线,然后注意看原来ad_js.php的sql语句,发现了吗?这是数字型的注入,也就是说我们并不需要使用引号去闭合前面的语句,因此存在注入,那么是否有回显呢?注意下方的语句:

    这条语句实际上起的作用是,如果查询成功则将查询的结果,以html注释的形式回显出来,然而出现查询错误,则会完整的将查询语句回显出来(非注释)如下图:


    由于是数字型注入,且有回显因此这里可以使用union联合查询注入,过程如下图:
    前面已经使用order...by语句查询到了有7个列,因此接下来检查回显:

    然后爆表名:

    随后爆列名(这里需要注意的是由于deep_addslashe()函数的存在,这里如果使用表名加引号会自动被加上'/',导致查询失败,因此需要进行16进制编码绕过:

    最后回显admin用户的信息:

    ip伪造sql注入


    首先阅读配置文件的时候,发现了一个问题,就是前文提及的对全局变量过滤的函数,实际上忽略了$_SERVER和$_FILES这两个全局变量,也就以为则,这两个超级变量的引用将不会有任何的处理,而根据getip()函数,表明服务器获得ip的方式既可以使用X-Forwarded-for来伪造,也可以使用client-ip来伪造,两者皆可.

    既然猜测在使用ip的时候没有进行数据处理,那么可以通过全局搜索调用getip()的地方,来寻找是否有注入点的地方,如下图:


    阅读这个insert语句,发现其中的变量在前后并没有过滤,或者说对getip()函数返回的结果没有进行过滤,因此这里存在注入,具体利用方式参照
    blueCMSsql注入

    1','1'),('','6','2','1','6',(select concat(admin_name,':',pwd) from blue_admin),'1','1


    博客中的payload,思路就是闭合前一个VALUE(),再构造下一个(),这里如果输入错误的sql语句会将sql语句全部回显出来,因为这个INSERT注入会涉及很多参数,而除了回显点,都需要和前一个VALUE()保持一致.


    PS:这里有个小坑的地方,回显语句后面的哪个参数是时间戳,也就是注入之后,回显的评论时候是由注入语句后那个参数决定了,之前按照上面博客的语句,注入的数据在最下面(时间为1970年).

    有关用户支付功能存在的问题



    这个漏洞没有办法复现,因为网站的支付模块没有开启,而我加载的时候,会提示支付模块损坏,所以暂时无法复现,但这个漏洞其实是很明显,
    具体利用过程,请参照博客: https://www.freebuf.com/vuls/196190.html

    注意这里POST上来的pay参数,我们可以看到前后没有做任何数据处理,就进行了包含语句的拼接,但是后面直接拼接了一个ndex.php,是不是我们只能包含带有index.php的文件呢?答案当然是否定的,由于这个CMS版本老旧,需要运行在phpstudy--PHP5.2的版本,而这个版本是存在%00截断和url长度截断的,因此可以利用这两个方法进行截断,从而包含我们想要的文件.
    PS:这里的%00用不了,因为前面$_POST会直接调用deep_addslashe()函数,让%00被加上'/',从而无法执行截断.

    from参数任意包含漏洞


    这个起因应该是发现一些功能会拼接这个$from参数,这个参数是用户可控参数,并且没有进行除了deep_addslashe()之外的任何处理,原来以为只是一个重定向的问题,但最后感觉问题还是挺大的,源码如下图:

    这是from参数的来源,只是先判断是否为空,不为空则直接获得REQUEST的值,然后我们再来看看,哪里使用了这个可控参数.

  • first:do_login

  • 从act参数的名字可以看出,这个是在进行登陆操作的时候会调用这个参数
  • second:do_reg

  • 第二个则是进行注册时,会使用这个from参数,但这个参数通过测试,是进行重定向的作用,这个值默认为空,在判断里面空的情况下是为了重定向至user.php,但这个参数是可控的,通过用户构造恶意的base64编码后的数据,能够控制重定向的位置,这里以注册功能为例(登陆功能也是类似的):

    这里from参数的值是由base64编码之后的../../../phpMyAdmin,然后burpsuite抓到了下一步的数据包,居然是请求GET-phpMyAdmin的数据包

    而且还携带了blueCMS的参数(注意看Cookie)
    这是最开始测试时候使用的登陆功能,我们可以发现哪个showmsg.htm的页面上a标签的href已经变成了我们注入的脏数据了.

    这也就意味我们可以通过这个参数完成对文件的包含,那么我来再来看看为什么会出现这种问题,问题其实是出在showmsg()函数上面

    就是这个基本上一定会调用的这个函数

    函数原型在这里,assign()主要是将传入的值变成键值对的形式,而display()函数太长了,读完发现就只是用于在showmsg.htm页面上显示错误信息而已,问题其实是出在htm里,我们来看看源码

    这里JS就将传入的gourl传给了自动跳转的函数上面,而gourl则是传入的from值,所以用户能够通过控制from值来进行文件包含.

    修改新闻上面存在的XSS



    先来看这个功能进行了什么操作,前面的$autor,$source都进行了html实体编码,基本上不能注入,但我们看看后面剩下的参数对$content参数进行了去掉前后字符和过滤了一些数据,然后判断有没有$descript,有的话截取$descript的前90个字符(也就是长度限制),如果,如果没有$descript的话则会对$content参数再进行一次过滤,也就是说如果我们传入了$descript的值,就会少进行一次过滤,因此存在XSS的可能性.

    看看filter_data()函数原型,我们可以发现是利用了正则表达式,对元数据进行了一次过滤,也就是说我们可以通过双写绕过,同时这里没有不区分大小写的匹配,因此也可以通过大写标签绕过.最后这里过滤的标签还少了几个,可以直接使用


    总结


    最后感觉PHP代码审计还是比较有意思,当然思维模式很重要,我是一开始就从功能下手,一个个文件去审计,这样既需要搞懂CMS本身的架构逻辑,还需要大量的时间,效率真的是非常的低,因此上面参考的两篇博客都说到了思维这个东西.大佬们似乎比较建议用两个方式进行审计.
  • 从黑盒测试入手,追踪数据流,从而快速判断哪些功能出现问题,缺点是很容易漏掉一些不容易注意的网页

  • 从用户输入入手,对于所有的功能文件,只关注用户输入,可能还是需要搞清页面本身的逻辑,但比一行行代码的读取有效率多了.....

  • 最后希望自己在代码审计的路上能够走远点,没事多看看CMS(flag高高立起...)

    评论区(暂无评论)

    这里空空如也,快来评论吧~

    我要评论