本文由红日安全成员: licong 编写,如有不当,还望斧正。

前言

优客365网站分类导航系统是个跨平台的开源软件,基于PHP+MYSQL开发构建的开源网站分类目录管理系统,具有操作简单、功能强大、稳定性好、扩展性及安全性强、二次开发及后期维护方便,可以帮您迅速、轻松地构建起一个强大、专业的分类目录或网址导航网站。

目录结构

│ .htaccess
│ AdminYouke365.php 后台管理页面
│ config.php 全局配置文件
│ index.php 网站主页
├─app 应用目录
├─data 应用运行时目录
├─install 应用安装目录
├─mobile 手机模块
├─public WEB资源目录
├─theme 应用皮肤资源目录
├─themes 应用皮肤资源目录
├─uploads 文件上传存放目录
├─vendor 第三方类库目录

代码执行流程分析

对程序目录结构确定以后,便于我们更好的定位代码,接下来看一下代码的执行流程,在index.php代码26行下断点,点击搜索,程序成功断下,F7跟进:

进入到\core\start.php文件中,在代码85行出现$_module$_controller变量,跟进一下Router类的init方法,用传入的$config变量中的值对类中变量进行了初始化,该值不可控。无法利用。

接下来调用了Router类的url方法,未跟进函数执行,$param返回值如下:



通过$param变量中的值发现,该方法将url中的参数进行了处理,数组$param中module,controller不为空,则赋值到$_module,$_controller变量中,然后定义成了常量__MODULE__,__CONTROLLER__,在程序217行,进行字符串拼接并包含该文件。继续跟踪被包含文件:

得到文件路径: app\home\controller\search.php

url:http://127.0.0.1/home/search.html?mod=search&type=name&query=sdfd

对比一下两个地址,猜测,第一个/后的位置代表了app文件夹中的子目录,第二个/后地址代表所要请求的php文件,将html更换成php。mod参数在该文件没有体现。由此我们确定了程序如何传参,在我们找到漏洞存在页面以后,便知道如果构造相应的参数才能到达该页面。

代码审计

SQL注入

漏洞分析

app\home\controller\feedback.php

猜测I函数对用户输入进行处理,跟进一下:

函数参数$filters未设置的情况,默认使用htmlspecialchars函数对传入参数进行了处理。接下来我们看一下W3Cschool对该函数的说明:

以下是PHP手册中对预定义字符的说明:

对该函数的详细说明可参考PHP手册:
http://php.net/manual/zh/function.htmlspecialchars.php

I函数在调用htmlspecialchars函数对传入参数进行处理时,并未设置flags参数,单引号未进行编码,猜想可能存在SQL注入。

在代码32行,判断$fb_nick是否为空,$fb_email进行了邮箱验证,可跟进一下验证部分,看看是否存在绕过,代码44行,判断$fb_content是否为空然后进行长度判断,不能小于20字符,然后将数据进行了insert操作,猜测存在sql注入漏洞。

漏洞验证

在传入参数位置下断点,跟进$Db->insert方法:

从执行的sql语句观察到单引号未过滤,证明SQL注入存在。

漏洞利用:

该cms屏蔽了报错信息,且插入的内容需要管理员才能查看,利用有限,大佬们有啥思路可交流一下。
数据库执行语句如下:
INSERT INTO yk365_feedback (fb_nick,fb_email,fb_content,fb_date) VALUES ('123','[email protected]','1231231231223123123123123123122222222222222222222222222222222222222222222222222222','1534056939')

如未屏蔽数据库报错信息,可采用以下payload进行报错注入:
fb_nick = 123','123','123' or extractvalue(1,concat(0x7e,database()))) #

在数据库执行语句后,可报错得到数据内容。

INSERT INTO yk365_feedback (fb_nick,fb_email,fb_content,fb_date) VALUES ('123','123','123' or extractvalue(1,concat(0x7e,database())))#,'[email protected]','1231231231223123123123123123122222222222222222222222222222222222222222222222222222','1534056939')

SQL注入2

漏洞分析

\member\controller\article.php

感觉他少打了一个post,$art_content使用addslashes函数过滤,cate_id参数转换为int,无法利用,可利用参数$art_title,$copy_from,$copy_url,继续往下跟踪代码:

代码105行,对$art_title进行了过滤,跟进censor_words函数:

先判断$keywords$content是否为空,如果为空,直接返回true,不为空,则将$keywords中的内容以','作为分割符,存储到变量$wordarr中,然后在$content中进行正则匹配,如果存在关键字中的内容,则返回false。发现keywords部分内容与安全过滤无关,所以$art_title变量也可以利用。继续往下跟代码:

$copy_from,$copy_url没任何处理,然后直接进行了insert操作,猜测存在SQL注入漏洞,该测试需要注册账号。

漏洞验证

在会员中心进行文章添加时,一直报错,动态调试发现在代码96行,对$cate_id进行了判断,采用burp抓包发现,该参数为出现在请求参数中,于是在burp中添加了该参数。然后发送请求。

在标题字段输入art_title=121' or sleep(5)# 后页面 延迟返回,证明SQL注入存在。下面insert也存在注入,不测试了。

漏洞利用

将burp抓包内容放入txt文档,执行 sqlmap.py -r 6.txt --dbms=mysql

SQL注入3

漏洞分析

/member/controller/login.php

$nick_name转义无法利用,$pass$open_id可利用,接下来,通过用户名查询到密码,并与输入密码的MD5值进行比较。由此$pass变量我们也无法利用。继续往下:

程序一直未对$open_id变量进行处理,直接传入到了update函数,猜测存在SQL注入漏洞。

漏洞验证

使用burp抓包并手动加上open_id参数,进入update函数,发现执行的SQL语句中,单引号未过滤,证明SQL注入存在。

漏洞利用
$strSql = "UPDATE `$table` SET $strSql WHERE $where";

$strSql =login_time='1534054455',login_ip='2130706433',login_count='11',open_id='123''

在yk365_users表user_type字段中,标识了该用户的身份,如果能够更改该值,则可获取到管理员权限。

于是尝试构造 open_id = 123',user_type='admin'# , user_type字段更改成功,并能通过该账户进入管理员后台。

结语

​ 在seebug上看到该cms 1.0.7版本存在SQL注入,抱着玩的心态下载了最新版。如果该CMS全局默认使用addslashes函数进行转义,就没SQL注入了。开发人员对htmlspecialchars函数的使用不正确,导致了众多SQL注入点出现,还有可以利用的地方。感兴趣的可以下载玩玩。审计新手,有问题大家多交流。后面还有一篇getshell,中间踩了很多坑,想单独写一篇。

源链接

Hacking more

...