Skip to content

Commit f95f06d

Browse files
committed
Proper handling of mumble exceptions
1 parent 989f408 commit f95f06d

File tree

2 files changed

+48
-31
lines changed

2 files changed

+48
-31
lines changed

checker/src/admin_simulator.py

Lines changed: 44 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import os
99
import re
1010
import os
11-
from playwright.async_api import async_playwright
11+
from playwright.async_api import async_playwright, Playwright, Browser, BrowserContext
1212

1313
_browsers: dict[int, dict[str, any]] = {}
1414

@@ -28,39 +28,24 @@ def __init__(self, client: AsyncClient, logger: LoggerAdapter):
2828
self.admin_password = "]!V$JuOzx@fi%pvG,lF!"
2929
self.admin_username = "admin"
3030
self.service_url = str(client.base_url)
31-
32-
async def _get_browser(self):
33-
pid = os.getpid()
34-
entry = _browsers.get(pid)
35-
if entry and entry.get("browser"):
36-
return entry["browser"]
37-
38-
playwright = await async_playwright().start()
39-
browser = await playwright.chromium.launch(
40-
headless=True,
41-
args=['--no-sandbox',
42-
'--disable-setuid-sandbox',]
43-
)
44-
_browsers[pid] = {"playwright": playwright, "browser": browser}
45-
return browser
4631

4732
async def _solve_admin_challenge(self, encrypted_b64: str):
4833
if not CRYPTO_AVAILABLE:
49-
raise MumbleException("cryptography package missing for admin challenge")
34+
raise MumbleException("Cryptography package missing for admin challenge")
5035

5136
try:
5237
ciphertext = base64.b64decode(encrypted_b64)
5338
except Exception as e:
54-
raise MumbleException(f"Invalid base64 in challenge: {e}")
39+
raise MumbleException(f"Invalid base64 in challenge")
5540

5641
pem_path = os.path.join(os.path.dirname(__file__), 'admin_private.pem')
5742
try:
5843
with open(pem_path, 'rb') as f:
5944
private_key = serialization.load_pem_private_key(f.read(), password=None)
6045
except FileNotFoundError:
61-
raise MumbleException("admin_private.pem not found for admin challenge")
46+
raise MumbleException("checker's side (1)")
6247
except Exception as e:
63-
raise MumbleException(f"Unable to load admin private key: {e}")
48+
raise MumbleException(f"checker's side (2)")
6449

6550
try:
6651
plaintext = private_key.decrypt(
@@ -69,7 +54,7 @@ async def _solve_admin_challenge(self, encrypted_b64: str):
6954
)
7055
decrypted_text = plaintext.decode()
7156
except Exception as e:
72-
raise MumbleException(f"RSA decryption failed: {e}")
57+
raise MumbleException(f"checker's side (3)")
7358

7459
return decrypted_text
7560

@@ -95,11 +80,11 @@ async def load_feedback_page(self) -> None:
9580

9681
response = await self.client.get("/admin-challenge")
9782
if response.status_code != 200:
98-
raise MumbleException("Failed to get admin challenge")
83+
raise MumbleException("Failed to login as admin")
9984

10085
match = re.search(r'<pre[^>]*>(.*?)</pre>', response.text, re.DOTALL)
10186
if not match:
102-
raise MumbleException("Could not find encrypted challenge on page")
87+
raise MumbleException("Could not find encrypted challenge on page (please wrap it in <pre> tags)")
10388

10489
encrypted_b64 = match.group(1).strip()
10590

@@ -112,7 +97,7 @@ async def load_feedback_page(self) -> None:
11297
)
11398

11499
if response.status_code not in [200, 201, 302]:
115-
raise MumbleException(f"Failed to submit admin challenge solution: {response.text}, {response.status_code}")
100+
raise MumbleException(f"Failed to login as admin")
116101

117102
cookies = []
118103
for ck in self.client.cookies.jar:
@@ -125,9 +110,32 @@ async def load_feedback_page(self) -> None:
125110
'secure': ck.secure
126111
})
127112

128-
browser = await self._get_browser()
129113
try:
130-
context = await browser.new_context()
114+
pid = os.getpid()
115+
entry = _browsers.get(pid)
116+
if not entry or not entry["browser"].is_connected():
117+
if entry:
118+
await entry["browser"].close()
119+
await entry["playwright"].stop()
120+
121+
p: Playwright = await async_playwright().start()
122+
b: Browser = await p.chromium.launch(
123+
headless=True,
124+
args=["--no-sandbox", "--disable-setuid-sandbox"]
125+
)
126+
_browsers[pid] = {"playwright": p, "browser": b}
127+
browser = _browsers[pid]["browser"]
128+
except Exception as e:
129+
if browser:
130+
await browser.close()
131+
if _browsers[pid]["playwright"]:
132+
await _browsers[pid]["playwright"].stop()
133+
if pid in _browsers:
134+
_browsers.pop(pid, None)
135+
raise MumbleException(f"checker's side (4)")
136+
137+
try:
138+
context: BrowserContext = await browser.new_context()
131139
await context.route("**/*", lambda route, request:
132140
route.abort() if request.resource_type in ("image", "stylesheet", "font")
133141
else route.continue_()
@@ -141,9 +149,16 @@ async def load_feedback_page(self) -> None:
141149
if "/admin/feedback" not in page.url:
142150
raise MumbleException(f"Admin was redirected to problems page - service unavailable")
143151
except Exception as e:
144-
self.logger.warning(f"Admin simulation failed: {e}")
145-
raise MumbleException(f"Admin simulation error: {e}")
146-
finally:
152+
if context:
153+
await context.close()
154+
if browser:
155+
await browser.close()
156+
if _browsers[pid]["playwright"]:
157+
await _browsers[pid]["playwright"].stop()
158+
if pid in _browsers:
159+
_browsers.pop(pid, None)
160+
raise MumbleException(f"checker's side (5)")
161+
else:
147162
await context.close()
148163

149164
async def post_new_message(self) -> None:

checker/src/checker.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -523,9 +523,11 @@ async def havoc_admin_simulation(task: HavocCheckerTaskMessage, client: AsyncCli
523523

524524
try:
525525
await simulator.load_feedback_page()
526+
except Exception as e:
527+
raise MumbleException(f"Admin could not post message or visit feedback page: {e}")
528+
529+
try:
526530
await simulator.post_new_message()
527-
logger.info("Admin simulation completed successfully")
528-
529531
except Exception as e:
530532
raise MumbleException(f"Admin could not post message or visit feedback page.")
531533

0 commit comments

Comments
 (0)