Loistavaa, ettC$ downgreidaus tehosi aVNC:n kanssa!
"Debug portin" (ohjausrajapinnan) lisC$C$minen on tC$ydellinen tapa eriyttC$C$
logiikka toisistaan. Proxy sC$ilyy tyhmC$nC$ "putkena ja piirtC$jC$nC$", ja
mikC$ tahansa muu ohjelma (mesh-agentti, bash-skripti, tai curl) voi
lC$hettC$C$ sille komentoja.
Rakennetaan proxyn sisC$C$n kevyt asynkroninen TCP- tai HTTP-palvelin.
Laitetaan se kuuntelemaan porttia 15942. Yksinkertaisuuden vuoksi tehdC$C$n
siitC$ kevyt JSON/TCP -socket tai asyncio.start_server -pohjainen
komentokanava.
KC$ytetC$C$n suoraa TCP-socketia JSON-payloadilla. Se on salamannopea ja voit
testata sitC$ helposti netcatilla (nc).
VNC Proxyn pC$ivitys: Debug-portti ja TC$htC$in-injektio
TC$ssC$ on tC$ydellinen koodi. Se sisC$ltC$C$ aiemmin kC$sitellyn kC$ttelyn,
pakettianalyysin, ja nyt uutena ominaisuutena API Serverin portissa 15942
sekC$ inject_visual_marker -metodin.
Huom: Voit pC$ivittC$C$ vncproxy.py:n suoraan shadow_sed -skriptillC$si tai
copy-pastella.
[GEM-EDITBOT-START]
TARGET FILE "/tmp/vncproxy.py"
REPLACE LINE 1 WITH BLOCK
import asyncio
import struct
import json
LISTEN_HOST = '0.0.0.0'
LISTEN_PORT = 5942
UPSTREAM_HOST = '127.0.0.1'
UPSTREAM_PORT = 5900
API_PORT = 15942
class VNCProxy:
def __init__(self):
# Tallennetaan aktiiviset VNC-asiakkaat (client_writer), jotta API
# voi lC$hettC$C$ niille piirtokomentoja, vaikka viesti tulee
ulkopuolelta.
self.active_clients = []
async def start(self):
vnc_server = await asyncio.start_server(self.handle_client,
LISTEN_HOST, LISTEN_PORT)
api_server = await asyncio.start_server(self.handle_api_command,
LISTEN_HOST, API_PORT)
print(f"[*] VNC Proxy kuuntelee {LISTEN_HOST}:{LISTEN_PORT}")
print(f"[*] API / Debug portti kuuntelee {LISTEN_HOST}:{API_PORT}")
async with vnc_server, api_server:
await asyncio.gather(
vnc_server.serve_forever(),
api_server.serve_forever()
)
async def handle_api_command(self, reader, writer):
""" KC$sittelee porttiin 15942 tulevat JSON-komennot """
addr = writer.get_extra_info('peername')
try:
data = await reader.read(1024)
if not data:
return
payload = json.loads(data.decode('utf-8').strip())
cmd = payload.get("command")
if cmd == "draw_marker":
x = payload.get("x", 0)
y = payload.get("y", 0)
size = payload.get("size", 20)
print(f"[API] PyyntC6 piirtC$C$ tC$htC$in X:{x} Y:{y}
Size:{size}")
# LC$hetetC$C$n piirtokomento kaikille kytketyille
VNC-asiakkaille
for client_writer in self.active_clients:
try:
await self.inject_visual_marker(client_writer, x, y,
size)
except Exception as e:
print(f"[API] Piirtovirhe clientille: {e}")
writer.write(b'{"status": "ok"}
')
await writer.drain()
except json.JSONDecodeError:
writer.write(b'{"status": "error", "message": "Invalid JSON"}
')
await writer.drain()
except Exception as e:
print(f"[API] Virhe: {e}")
finally:
writer.close()
async def inject_visual_marker(self, client_writer, x, y, size=20):
""" PiirtC$C$ punaisen laatikon VNC-asiakkaan ruudulle injektoimalla
FramebufferUpdate viestin """
start_x = max(0, x - size // 2)
start_y = max(0, y - size // 2)
# Punainen pikseli (BGRX) - TC$mC$ voi vaatia hienosC$C$tC6C$ riippuen
kC$ttelyn PixelFormatista
# YleensC$ VNC oletus on 32-bit BGRX
red_pixel = struct.pack('BBBB', 0, 0, 255, 255)
pixel_count = size * size
pixel_data = red_pixel * pixel_count
# Viestityyppi 0 (FramebufferUpdate), padding, 1 suorakulmio
header = struct.pack('>BxH', 0, 1)
# Suorakulmio: X, Y, W, H, Encoding (0 = Raw)
rect_header = struct.pack('>HHHHI', start_x, start_y, size, size, 0)
payload = header + rect_header + pixel_data
# Injektoidaan asiakkaalle menevC$C$n putkeen
client_writer.write(payload)
await client_writer.drain()
async def handle_client(self, client_reader, client_writer):
print(f"[+] Uusi VNC-asiakas yhdistetty")
self.active_clients.append(client_writer)
try:
target_reader, target_writer = await asyncio.open_connection(UPSTRE
AM_HOST, UPSTREAM_PORT)
except Exception as e:
print(f"[-] Ei yhteyttC$ VNC-palvelimeen: {e}")
self.active_clients.remove(client_writer)
client_writer.close()
return
try:
await self.handle_handshake(client_reader, client_writer,
target_reader, target_writer)
print("[*] KC$ttely onnistui, siirrytC$C$n pakettianalyysiin...")
except Exception as e:
print(f"[-] KC$ttely epC$onnistui: {e}")
self.active_clients.remove(client_writer)
client_writer.close()
target_writer.close()
return
task1 = asyncio.create_task(self.server_to_client(target_reader,
client_writer))
task2 = asyncio.create_task(self.client_to_server(client_reader,
target_writer))
await asyncio.gather(task1, task2)
# Siivous, kun yhteys katkeaa
if client_writer in self.active_clients: