获得源码
很多PHP程序都是开源的、找到官网下载最新的源码包就好了(站长之家,A5源码)安装网站
安装网站
在本地搭建网站,一边审计一边调试。实时跟踪各种动态变化
网站结构
浏览源码文件夹,了解该程序的大致目录入口文件
入口文件
index.php
、admin.php
文件一般是整个程序的入口,详细读一下index
文件可以知道程序的架构、运行流程、包含那些配置文件,包含哪些过滤文件以及包含那些安全过滤文件,了解程序的业务逻辑
配置文件
一般类似config.php
等文件,保存一些数据库相关信息、程序的一些信息
直接使用工具可以扫出一些敏感的参数:
例如:
1)通过select
、insert
结合from
和where
等关键字,判定是一条SQL
语句,然后通过对字符串的识别,判断这个SQL
语句里边的参数有没有拼接或者单引号过滤。
2)HTTP
头里边的HTTP_CLIENT
、HTTP_X_FORWARDFOR
等获取到的IP地
址经常没有过滤就直接拼接到了SQL语句中,并且因为是在$_SERVER
变
量中,不受GPC的影响,因此可以查找HTTP_CLIENT
、HTTP_X_FORWARDFOR
关键字来快速寻找漏洞。
重装
打开install.php
文件查看
首先此处,判断完lock
文件后直接进行的重定向,没有exit
结束,所以install.php
下面还是会继续执行的
if ( file_exists($_SERVER["DOCUMENT_ROOT"].'/sys/install.lock') ) {
header( "Location: ../index.php" );
}
require_once '../header.php';
只需要自己搭建环境,用burp拦截,将安装的请求包复制下来,然后将host
改成目标的地址就可以对目标进行重新安装了
install.php
此处将POST
数据接收后没有过滤直接复制给了变量$dbname
if ( $_POST ) {
if ( $_POST["dbhost"] == "" ) {
exit( '数据库连接地址不能为空' );
}elseif ( $_POST["dbuser"] == "" ) {
exit( '数据库数据库登录名' );
}elseif ( $_POST["dbname"] == "" ) {
exit( '请先创建数据库名称' );
}
$dbhost = $_POST["dbhost"];
$dbuser = $_POST["dbuser"];
$dbpass = $_POST["dbpass"];
$dbname = $_POST["dbname"];
$con = mysql_connect( $dbhost, $dbuser, $dbpass );
此处将字符串进行拼接,拼接成php
文件的形式赋值给变量$str_tmp
,其中就包括$dbname
变量
然后打开config.php
文件,将变量中的内容进行写入
发送数据包
此时我们再看config.php
中的内容
vauditdemo-- -";phpinfo();//";
payload分析:
因为没有做过滤,所以$dbname
的值被用户恶意写入,然后又将$dbname
在config.php
中赋给$database
。
当程序去用$dbname
中的值去创建数据库时,由于-- -
符号为mysql
中的注释符,所以后面的字符不会被当作数据库的名称带入,就不会报错。
在config.php
中在给$database
赋值时,";
对前面的赋值操作进行了拼接,让后面的恶意代码成功执行
首先正常打开安装界面进行安装
我们来看一下install安装那块的代码
这个函数写了当安装成功存在lock
文件时,将页面重定向并且执行exit
但是这个函数并不是类的初始化函数,并没有被调用,也就是说if判断
、重定向
、还有exit结束
都是不起作用的
安装成功后当我们再去访问安装界面路径时,可以看到并没有重定向,这里可以证明重装漏洞确实存在
在install安装中的代码,此处是直接将从$_POST
获取的数据,给了$config_data
这个数组,然后放到write_config
函数中去执行
我们追踪一下write_config
函数
此函数将conf.tpl
和user.tpl
的内容读取出来,然后进行替换
将conf.tpl
和user.tpl
中和数组config
索引相同的字符串,替换成对应的索引的值,替换后分别写入两个config.php
中
就是将读取的conf.tpl
和user.tpl
中的这些
替换成索引对应的值,也就是替换成之前$_POST
传入的对应的值,然后分别写入到app/common/conf/config.php
和app/user/conf/config.php
中
user.tpl
文件与app/user/conf/config.php
文件与对比
上面也说过$_POST
提交的数据是没有做过滤的,所以当我们提交时什么样,写到config.php
文件里也是同样的
此时我们就可以在提交表前缀处构建闭合语句,去闭合app/user/conf/config.php
中);
提交完成后再看app/user/conf/config.php
,语句已经插入成功