58 lines
2.1 KiB
Python
58 lines
2.1 KiB
Python
"""HTTP client for the .NET C2's job endpoints.
|
|
|
|
Stdlib urllib so the blocking calls run off the asyncio loop via to_thread (the event
|
|
loop belongs to the browser). Each worker points at one job route group — "/jobs" for
|
|
cs.money, "/skinland/jobs" for skin.land — set once at construction.
|
|
"""
|
|
|
|
import asyncio
|
|
import json
|
|
import logging
|
|
import urllib.error
|
|
import urllib.request
|
|
|
|
log = logging.getLogger("c2")
|
|
|
|
|
|
class C2Client:
|
|
def __init__(self, base_url: str, token: str, jobs_path: str):
|
|
self._base = base_url.rstrip("/")
|
|
self._token = token
|
|
self._jobs = jobs_path.strip("/")
|
|
|
|
def _get_job_sync(self):
|
|
req = urllib.request.Request(
|
|
f"{self._base}/{self._jobs}/next", headers={"X-Worker-Token": self._token})
|
|
try:
|
|
with urllib.request.urlopen(req, timeout=15) as r:
|
|
if r.status == 204:
|
|
return None
|
|
return json.loads(r.read() or b"null")
|
|
except urllib.error.HTTPError as e:
|
|
log.warning("/%s/next -> HTTP %s", self._jobs, e.code)
|
|
return None
|
|
except urllib.error.URLError as e:
|
|
log.warning("C2 unreachable: %s", e)
|
|
return None
|
|
|
|
def _post_result_sync(self, job_id: str, payload: dict):
|
|
data = json.dumps(payload).encode()
|
|
req = urllib.request.Request(
|
|
f"{self._base}/{self._jobs}/{job_id}/result", data=data, method="POST",
|
|
headers={"X-Worker-Token": self._token, "Content-Type": "application/json"})
|
|
try:
|
|
with urllib.request.urlopen(req, timeout=60) as r:
|
|
return json.loads(r.read() or b"null")
|
|
except urllib.error.HTTPError as e:
|
|
log.warning("result -> HTTP %s: %r", e.code, e.read()[:200])
|
|
return None
|
|
except urllib.error.URLError as e:
|
|
log.warning("C2 unreachable posting result: %s", e)
|
|
return None
|
|
|
|
async def get_job(self):
|
|
return await asyncio.to_thread(self._get_job_sync)
|
|
|
|
async def post_result(self, job_id, payload):
|
|
return await asyncio.to_thread(self._post_result_sync, job_id, payload)
|