找了一个比较小众的版本的PHP开源程序,选择了一个比较老的版本,参考了网上一些别人的审计方法同时我自己也进行了部分审计。本片文章就是记录自己的审计过程。
重新安装+GetShell
初识安装过程
文件的安装位置在:install/goinstall.php
在goinstall.php引入了文件
1 | require_once("../class/c_md5.php"); |
c_md5.php,是封装好的用于对密码加密的函数
install_func.php,包含了每一步需要执行的函数的方法,如step1()
、step2()
、step3()
、step4()
以及chkoutput()
。chkoutput()
用于检查是否是非法提交,是否按照安装顺序安装网站。
安装绕过
网站的具体的安装逻辑如下:
1 | switch ($_GET["g"]) { |
通过switch对参数g
判断目前安装进度。默认情况下,通过检查是否存在cmsconfig.php
文件判断网站是否已经安装。而其中的chkoutpost()
方法用于判断是否越权提交。
install/install_fun.php:chkoutpost()
:
1 | function chkoutpost() { |
通过referer判断是否为越权安装,很明显是被可以绕过的。
getshell
步骤4:
1 | function step4() { |
在step4()
函数中,第1行到12行是读取用户输入,虽然将用户的配置写入到config_empty.php
生成config.php
,至此整个系统安装完毕。
install/config_empty.php
代码:
1 | $root="@root@"; #MySQL服务器 |
所有的变量名都是使用双引号,那么就可以执行命令了。
POC
通过firefox的插件设置referer值
在重新安装中加入代码
访问cmsconfig.php
修复
这个漏洞在新版1.0.4中已经修复了,在安装成功之后直接删除goinstall.php
即可。
登录绕过
登录逻辑
登录绕过这个代码写的比较的有意思。
管理员登录的代码在login.php
中ad/login.php
1 | function jsloginpost() { |
jsloginpost()
函数就是用来处理管理员登录。
在其中调用了loginpass($loginlong);
,此函数是在c_login.php
中定义的。
ad/c_login.php
代码进行了加密,为了方便看,对部分代码进行了删减:
1 | // 判断用户是否已经登录的函数 |
函数loginpass($str)
中的参数$str
表示的cookie的有效时间。
登录之后在,拼凑用户的表示$txtchkad = $_SERVER['HTTP_USER_AGENT'] . '_' . $_SERVER['REMOTE_ADDR'] . '_' . $date;
,将其写入到/cache/txtchkad.txt
。
在判断登录的函数中的判断逻辑是:
1 | // 读取txtchkad.txt文件 |
管理员登录的逻辑判断代码为:
判断一:
1 | @$_SESSION["chkad"] == '' && @$_COOKIE["chkad"] == '' |
如果session和cookie中得chkad
都会空,则认定管理员没有登录
判断二:
1 | @$txtchkad = fread($fp, 4096); //读取文件内容 |
如果$txtchkad == $txtchkad2
,则需要用户登录,那么就说明$txtchkad中不含@$_COOKIE["chkad"]
.
绕过方法
自此,绕过方法就很简单了,主要str_replace(@$_COOKIE["chkad"], '', $txtchkad);
能够执行,即$txtchkad
中含有@$_COOKIE["chkad"]
内容即可。又因为在写入到txtchkad
包括$_SERVER['HTTP_USER_AGENT'] . '_' . $_SERVER['REMOTE_ADDR'] . '_' . $date
。那么就可以将chkad
设置为user-agent,_,:
等都可以绕过了。
POC
在登录页面,添加chkad
的cookie值
访问ad/index.html
直接进入后台。
修复
这个漏洞在1.0.4中仍然存在
SQL注入
所有的SQL注入完全是拼接的写法,没有使用pdo,也没有对输入进行过滤,所以在很多地方都存在SQL注入。
管理员登录
ad/login.php:jsloginpost()
1 | function jsloginpost() { |
判断管理员是否登录的代码:
1 | $tab = $tabhead . "adusers"; |
没有进行任何的过滤,万能用户名直接可以进。
POC
hit.php注入
1 | $g = $_GET['g']; |
很明显id存在SQL注入
但是上面update
语句会报错,update axublog_arts set hit=hit+1 WHERE id= -1 union select 1,2,3,4,5,6,7,8,9,10;
art.php
art.php是管理员后台页面用于对当前的文章进行管理,但是并没有做登录验证,直接可以访问到所有的文章。
URL为host\ad\art.php
其中的主要逻辑代码如下:
1 | @$g = $_GET["g"]; |
可以看到其中的del()
没有对ic
参数进过滤,直接进行了Delelte的操作DELETE FROM " . $tab . " WHERE id=" . $id
。
delete语句同样会存在sql注入的问题,但是delete的错误语句不会回显,所以无法显示内容,所以不存在SQL注入。
art.php
中的文章编辑函数
1 | function edit() { |
其中的artidgetart()
函数位于class/c_db.php
中,代码如下:
1 | function artidgetart($artid) { |
很明显的SQL注入。
POC如下:
修复
这个漏洞在新版中也已经进行了修复。修复的方式主要对权限绕过进行了限制,同时也增加了SQL注入的判断。
总结
发现很多的漏洞都与后台的管理有关,但是如果将后台管理员的目录ad
修改为其他的目录,可能上述的很多漏洞都无法使用了。估计这个cms还是存在很多的漏洞,以后再接着发吧。