目录
重装漏洞
根据大佬们的总结,重装漏洞可以以下几种类型:
-
自动删除这个安装文件
通过生成一个lock文件来判断程序是否安装过
-
根本无验证
安装完成后不会自动删除文件,又不会生成lock判断是否安装过
-
安装file
直接用GET提交step绕过,直接进入下一步
-
变量覆盖导致重装
可以GET,POST,COOKIE 任意提交一个变量名$insLockfile,给其赋空值,覆盖掉$insLockfile,从而让file_exists为false就不会退出
-
判断lock后,无exit
判断是否存在lock文件,如果存在lock文件,就会header到index.php,但是header后并没有exit,所以 并不会退出,类似的还有javascript弹个框
-
解析漏洞
在安装完成后会将install.php 重命名为index.php.bak,但是由于Apache的解析漏洞:如果无法识别到最后一个后缀的话,就会向上解析,那么就又变成了php了,然后结合安装时的变量覆盖又成重装了。
-
满足一些条件不会退出的
这次复现的两个漏洞,都属于第五类。当页面跳转到主页之后,原来的php进程依然存在,导致可以重装,而当配置信息没有经过过滤而被直接写入了文件当中,就可能会导致getshell。寻找此类漏洞应该尝试去跟踪配置信息的最终去处,并检查是否有过滤。通过构造闭合语句利用漏洞。
复现 vauditdemo重装漏洞
漏洞复现
访问 http://127.0.0.1/install/install.php
提交数据库信息,用brupsuite抓包。(为了便于演示,我将header()语句注释了)
1 |
POST /install/install.php HTTP/1.1 |
将dbname修改为:
testdb;-- -";phpinfo();//
提交。
跳转到index之后可以看到phpinfo()信息
复现成功
代码分析
平台的install.php安装页面, 安装之前会有一段验证是否已经安装的判断语句:
1 |
if ( file_exists($_SERVER["DOCUMENT_ROOT"].'/sys/install.lock') ) { |
判断安装生成的lock文件是否存在,如果存在,就重定向到index.php
但是这里存在一个错误,当页面重定向到index之后,并没有执行exit语句来结束进程,所以install.php的进程一直存在。这时如果用brupsuite抓包,提交的数据会被判断语句之后的代码所执行,就会导致重装漏洞。
判断语句后,获取了一些环境信息之后就通过POST方法获取数据库的信息。
(代码经过省略)
1 |
if ( $_POST ) { |
可以看到,页面通过所提交的dbhost, dbuser, dbpass, dbname来获取数据库基本信息。
在判断数据库信息是否符合安装条件之后,页面将一段判断是否已经安装的php脚本写入到config.php里。
问题出在其中的一条语句:
1 |
$str_tmp.="\$database=\"$dbname\"; \r\n"; |
可知,dbname是可控的。
当我们将dbname设置为:
testdb;-- -";phpinfo();//
-- - 是为了注释掉后面的sql语句
"; 闭合php语句
// 注释掉后面的php语句
config.php里的语句就会变成:
1 |
$database="testdb; -- -"; phpinfo();//"; |
也就会执行phpinfo(), 当我们把phpinfo()修改为:eval($_POST['abc'])
就可以直接getshell;
zswin博客重装漏洞 getshell 复现
在百度上直接搜到的一个重装漏洞,博客系统有点老了,但是拿来学习还是不错的。
参考:https://shuimugan.com/bug/view?bug_no=119025
漏洞复现
在已经安装好的博客,直接访问:
http://127.0.0.1/zwin/install.php?m=install&c=index&a=setconf
不会跳转到主页,直接进入安装向导页面。
其他地方正常填写,将数据表前缀改为:
zs_');phpinfo();//
点击下一步,数据库就可以创建成功
之后再访问:
http://127.0.0.1/zwin/app/user/conf/config.php
可以看到phpinfo(),把phpinfo()修改为:eval($_POST['abc'])
就可以直接getshell;
漏洞复现成功
代码分析
存在漏洞的页面:
install/install/controller/indexcontroller.class.php
页面开头存在一个index()方法用于判断是否安装成功:
1 |
public function index(){ |
根据参考文章的说法:
但是这个不是类的初始化函数所以不影响其他方法的使用。
我在页面当中没有找到引用index()方法的语句,应该是ThinkPHP框架的一些固定用法吧。这个问题等后面学习了ThinkPHP框架后再说。
继续往下看。
1 |
public function finish_done() { |
可知,在finish_done()方法中,有一个函数为write_config(),所传递的参数为数据库配置信息。
而这些数据配置信息,都没有经过过滤或检查。都是直接接收POST数据来进行传递的。
跟踪这个函数至:install/install/common/function.php
1 |
function write_config($config, $auth){ |
可知,函数的功能是读取sqldata目录下的两个配置文件,将传递进来的数据库配置信息分别写入到两个config.php里去。
先看一下user.sql:
1 |
|
除了DB_NAME, DB_PREFIX可以修改以外,修改其他的数据配置会导致数据库创建失败。
所以,这里可以利用的就存在两处
将DB_NAME赋值为:
zswin1]');phpinfo();//
或者将DB_PREFIX赋值为:
zs_');phpinfo();//
都可以利用成功。
/App/User/Conf/config.php就会变成:
1 |
define('UC_DB_DSN', 'mysql://root:[email protected]:3306/zswin1]');phpinfo();//'); // 数据库连接,使用Model方式调用API必须配置此项 |
sqldata/conf.tpl也是一样的步骤,只不过user.tql可以更容易闭合语句。
遇到的问题
- 对框架的结构还是不太了解,是否调用,如何调用也不太清楚。需要去学习一下框架的基本知识。
- By:threezh1.com
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论