adding validated services? patching forcad_local.py
This commit is contained in:
5
ctfcup2025-school-final/checkers/sonobank/.dockerignore
Executable file
5
ctfcup2025-school-final/checkers/sonobank/.dockerignore
Executable file
@@ -0,0 +1,5 @@
|
||||
target/
|
||||
.git/
|
||||
__pycache__/
|
||||
*.pyc
|
||||
data/
|
||||
7
ctfcup2025-school-final/checkers/sonobank/.gitignore
vendored
Executable file
7
ctfcup2025-school-final/checkers/sonobank/.gitignore
vendored
Executable file
@@ -0,0 +1,7 @@
|
||||
/target
|
||||
/data
|
||||
*.pyc
|
||||
__pycache__/
|
||||
.cargo
|
||||
vendor/
|
||||
venv/
|
||||
605
ctfcup2025-school-final/checkers/sonobank/Cargo.lock
generated
Normal file
605
ctfcup2025-school-final/checkers/sonobank/Cargo.lock
generated
Normal file
@@ -0,0 +1,605 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "aes"
|
||||
version = "0.8.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cipher",
|
||||
"cpufeatures",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.100"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61"
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
version = "0.10.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "block-padding"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a8894febbff9f758034a5b8e12d87918f56dfc64a8e1fe757d65e29041538d93"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43"
|
||||
|
||||
[[package]]
|
||||
name = "cbc"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6"
|
||||
dependencies = [
|
||||
"cipher",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
|
||||
|
||||
[[package]]
|
||||
name = "checker"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"crypto",
|
||||
"hex",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sysex",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cipher"
|
||||
version = "0.4.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad"
|
||||
dependencies = [
|
||||
"crypto-common",
|
||||
"inout",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cpufeatures"
|
||||
version = "0.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crypto"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"aes",
|
||||
"anyhow",
|
||||
"cbc",
|
||||
"crypto-bigint",
|
||||
"sha2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crypto-bigint"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "96272c2ff28b807e09250b180ad1fb7889a3258f7455759b5c3c58b719467130"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
"rand_core 0.6.4",
|
||||
"subtle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crypto-common"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.10.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
|
||||
dependencies = [
|
||||
"block-buffer",
|
||||
"crypto-common",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "equivalent"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.14.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
|
||||
dependencies = [
|
||||
"typenum",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"r-efi",
|
||||
"wasip2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.16.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100"
|
||||
|
||||
[[package]]
|
||||
name = "hex"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "inout"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01"
|
||||
dependencies = [
|
||||
"block-padding",
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.82"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b011eec8cc36da2aab2d5cff675ec18454fad408585853910a202391cf9f8e65"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.177"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.7.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273"
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_enum"
|
||||
version = "0.7.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b1207a7e20ad57b847bbddc6776b968420d38292bbfe2089accff5e19e82454c"
|
||||
dependencies = [
|
||||
"num_enum_derive",
|
||||
"rustversion",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_enum_derive"
|
||||
version = "0.7.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ff32365de1b6743cb203b710788263c44a03de03802daf96092f2da4fe6ba4d7"
|
||||
dependencies = [
|
||||
"proc-macro-crate",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.21.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9"
|
||||
dependencies = [
|
||||
"zerocopy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-crate"
|
||||
version = "3.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983"
|
||||
dependencies = [
|
||||
"toml_edit",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.103"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.42"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "r-efi"
|
||||
version = "5.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.9.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1"
|
||||
dependencies = [
|
||||
"rand_chacha",
|
||||
"rand_core 0.9.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
|
||||
dependencies = [
|
||||
"ppv-lite86",
|
||||
"rand_core 0.9.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||
dependencies = [
|
||||
"getrandom 0.2.16",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.9.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38"
|
||||
dependencies = [
|
||||
"getrandom 0.3.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustversion"
|
||||
version = "1.0.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.228"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
|
||||
dependencies = [
|
||||
"serde_core",
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_core"
|
||||
version = "1.0.228"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.228"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.145"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"memchr",
|
||||
"ryu",
|
||||
"serde",
|
||||
"serde_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha2"
|
||||
version = "0.10.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cpufeatures",
|
||||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "subtle"
|
||||
version = "2.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.111"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "390cc9a294ab71bdb1aa2e99d13be9c753cd2d7bd6560c77118597410c4d2e87"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sysex"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"crypto",
|
||||
"num_enum",
|
||||
"rand",
|
||||
"sha2",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_datetime"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f2cdb639ebbc97961c51720f858597f7f24c4fc295327923af55b74c3c724533"
|
||||
dependencies = [
|
||||
"serde_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_edit"
|
||||
version = "0.23.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6485ef6d0d9b5d0ec17244ff7eb05310113c3f316f2d14200d4de56b3cb98f8d"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"toml_datetime",
|
||||
"toml_parser",
|
||||
"winnow",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_parser"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0cbe268d35bdb4bb5a56a2de88d0ad0eb70af5384a99d648cd4b3d04039800e"
|
||||
dependencies = [
|
||||
"winnow",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5"
|
||||
|
||||
[[package]]
|
||||
name = "uuid"
|
||||
version = "1.18.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2f87b8aa10b915a06587d0dec516c282ff295b475d94abf425d62b57710070a2"
|
||||
dependencies = [
|
||||
"getrandom 0.3.4",
|
||||
"js-sys",
|
||||
"serde",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.1+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
|
||||
|
||||
[[package]]
|
||||
name = "wasip2"
|
||||
version = "1.0.1+wasi-0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7"
|
||||
dependencies = [
|
||||
"wit-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.105"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da95793dfc411fbbd93f5be7715b0578ec61fe87cb1a42b12eb625caa5c5ea60"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"once_cell",
|
||||
"rustversion",
|
||||
"wasm-bindgen-macro",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.105"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "04264334509e04a7bf8690f2384ef5265f05143a4bff3889ab7a3269adab59c2"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.105"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "420bc339d9f322e562942d52e115d57e950d12d88983a14c79b86859ee6c7ebc"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.105"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "76f218a38c84bcb33c25ec7059b07847d465ce0e0a76b995e134a45adcb6af76"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "0.7.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wit-bindgen"
|
||||
version = "0.46.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59"
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy"
|
||||
version = "0.8.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4ea879c944afe8a2b25fef16bb4ba234f47c694565e97383b36f3a878219065c"
|
||||
dependencies = [
|
||||
"zerocopy-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy-derive"
|
||||
version = "0.8.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf955aa904d6040f70dc8e9384444cb1030aed272ba3cb09bbc4ab9e7c1f34f5"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
17
ctfcup2025-school-final/checkers/sonobank/Cargo.toml
Normal file
17
ctfcup2025-school-final/checkers/sonobank/Cargo.toml
Normal file
@@ -0,0 +1,17 @@
|
||||
[package]
|
||||
name = "checker"
|
||||
edition = "2024"
|
||||
version = "0.1.0"
|
||||
|
||||
[[bin]]
|
||||
name = "checker"
|
||||
path = "src/main.rs"
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1.0.100"
|
||||
sysex = { path = "./service_src/crates/sysex" }
|
||||
crypto = { path = "./service_src/crates/crypto" }
|
||||
uuid = { version = "1.18.1", features = ["v4", "serde"] }
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
serde_json = "1"
|
||||
hex = "0.4.3"
|
||||
5
ctfcup2025-school-final/checkers/sonobank/README_HOWTO
Normal file
5
ctfcup2025-school-final/checkers/sonobank/README_HOWTO
Normal file
@@ -0,0 +1,5 @@
|
||||
убедиться, что в ../../services/sonobank лежит сам сервис (или поместить в service_src)
|
||||
|
||||
docker run -u $(id -u):$(id -g) -v ./:/app -v ./service_src:/app/service_src -w /app rust:1.91.1 cargo build --release
|
||||
|
||||
форкаду скормить полученный бинарь ./target/release/checker
|
||||
@@ -0,0 +1,9 @@
|
||||
tasks:
|
||||
- name: sonobank
|
||||
checker: sonobank/checker
|
||||
default_score: ???
|
||||
checker_timeout: 30
|
||||
puts: 1
|
||||
gets: 1
|
||||
places: 1
|
||||
checker_type: pfr
|
||||
BIN
ctfcup2025-school-final/checkers/sonobank/checker
Executable file
BIN
ctfcup2025-school-final/checkers/sonobank/checker
Executable file
Binary file not shown.
1
ctfcup2025-school-final/checkers/sonobank/checker_stress_test/.gitignore
vendored
Executable file
1
ctfcup2025-school-final/checkers/sonobank/checker_stress_test/.gitignore
vendored
Executable file
@@ -0,0 +1 @@
|
||||
detailed.log
|
||||
@@ -0,0 +1,160 @@
|
||||
from pathlib import Path
|
||||
import asyncio
|
||||
import random
|
||||
import string
|
||||
import time
|
||||
|
||||
# run cargo build or cargo build --release before this
|
||||
|
||||
OK = 101
|
||||
CORRUPT = 102
|
||||
MUMBLE = 103
|
||||
DOWN = 104
|
||||
CHECKER_ERROR = 110
|
||||
|
||||
|
||||
RELEASE = True
|
||||
EXPECTED_CHECK_CODE = OK
|
||||
EXPECTED_PUT_CODE = OK
|
||||
EXPECTED_GET_CODE = OK
|
||||
CHECKS_PER_SECOND = 5
|
||||
CHECKS_PER_REPORT = 100
|
||||
MAX_PARALLEL_CHECKS = CHECKS_PER_SECOND * 3
|
||||
VULNS = 1
|
||||
TIMEOUT = 30
|
||||
HOST = "127.0.0.1"
|
||||
|
||||
assert VULNS == 1, "multiple vulns not supported."
|
||||
|
||||
check_period = 1 / CHECKS_PER_SECOND
|
||||
|
||||
if RELEASE:
|
||||
checker_binary_path = Path("../target/release/checker")
|
||||
else:
|
||||
checker_binary_path = Path("../target/debug/checker")
|
||||
|
||||
detailed_log_filepath = Path("detailed.log")
|
||||
|
||||
def returncode_to_string(returncode):
|
||||
if returncode == 101:
|
||||
return "OK"
|
||||
elif returncode == 102:
|
||||
return "CORRUPT"
|
||||
elif returncode == 103:
|
||||
return "MUMBLE"
|
||||
elif returncode == 104:
|
||||
return "DOWN"
|
||||
elif returncode == 110:
|
||||
return "CHECKER_ERROR"
|
||||
else:
|
||||
return "UNEXPECTED"
|
||||
|
||||
def get_random_flag():
|
||||
return "S" + "".join(random.choices(string.ascii_uppercase + string.digits, k=30)) + "="
|
||||
|
||||
output_lock = asyncio.locks.Lock()
|
||||
async def write_to_detailed_log(entry, *, also_print=False):
|
||||
async with output_lock:
|
||||
with open(detailed_log_filepath, "a") as f:
|
||||
f.write(entry + "\n")
|
||||
if also_print:
|
||||
print(entry)
|
||||
|
||||
assert checker_binary_path.exists(), "checker binary doesn't exist. run cargo build or cargo build --release before this."
|
||||
|
||||
async def do_all_checks_once():
|
||||
flag = get_random_flag()
|
||||
|
||||
check_process = await asyncio.create_subprocess_exec(
|
||||
checker_binary_path, "check", HOST,
|
||||
stdout=asyncio.subprocess.PIPE,
|
||||
stderr=asyncio.subprocess.PIPE
|
||||
)
|
||||
try:
|
||||
stdout_data, stderr_data = await asyncio.wait_for(check_process.communicate(), timeout=TIMEOUT)
|
||||
except asyncio.TimeoutError:
|
||||
stdout_data, stderr_data = await check_process.stdout.read(), await check_process.stderr.read()
|
||||
await write_to_detailed_log(
|
||||
f"CHECK({flag}): Stuck for {TIMEOUT} seconds. Make sure the checker code has it's own timeouts. stdout={stdout_data} stderr={stderr_data}",
|
||||
also_print=True
|
||||
)
|
||||
check_process.kill()
|
||||
else:
|
||||
returncode = check_process.returncode
|
||||
await write_to_detailed_log(
|
||||
f"CHECK({flag}): {returncode_to_string(returncode)} ({returncode}) stdout={stdout_data} stderr={stderr_data}",
|
||||
also_print=(EXPECTED_CHECK_CODE is not None and returncode != EXPECTED_CHECK_CODE)
|
||||
)
|
||||
|
||||
put_process = await asyncio.create_subprocess_exec(
|
||||
checker_binary_path, "put", HOST, "", flag, "1",
|
||||
stdout=asyncio.subprocess.PIPE,
|
||||
stderr=asyncio.subprocess.PIPE
|
||||
)
|
||||
try:
|
||||
stdout_data, stderr_data = await asyncio.wait_for(put_process.communicate(), timeout=TIMEOUT)
|
||||
except asyncio.TimeoutError:
|
||||
stdout_data, stderr_data = await put_process.stdout.read(), await put_process.stderr.read()
|
||||
await write_to_detailed_log(
|
||||
f"PUT({flag}): Stuck for {TIMEOUT} seconds. Make sure the checker code has it's own timeouts. stdout={stdout_data} stderr={stderr_data}",
|
||||
also_print=True
|
||||
)
|
||||
put_process.kill()
|
||||
failed = True
|
||||
else:
|
||||
returncode = put_process.returncode
|
||||
await write_to_detailed_log(
|
||||
f"PUT({flag}): {returncode_to_string(returncode)} ({returncode}) stdout(public)={stdout_data} stderr(private)={stderr_data}",
|
||||
also_print=(EXPECTED_PUT_CODE is not None and returncode != EXPECTED_PUT_CODE)
|
||||
)
|
||||
flag_id = stderr_data
|
||||
failed = returncode != OK
|
||||
|
||||
if failed:
|
||||
await write_to_detailed_log(
|
||||
f"GET({flag}): SKIPPED since PUT failed.",
|
||||
also_print=(EXPECTED_GET_CODE is not None)
|
||||
)
|
||||
return
|
||||
|
||||
get_process = await asyncio.create_subprocess_exec(
|
||||
checker_binary_path, "get", HOST, flag_id, flag, "1",
|
||||
stdout=asyncio.subprocess.PIPE,
|
||||
stderr=asyncio.subprocess.PIPE
|
||||
)
|
||||
try:
|
||||
stdout_data, stderr_data = await asyncio.wait_for(get_process.communicate(), timeout=TIMEOUT)
|
||||
except asyncio.TimeoutError:
|
||||
stdout_data, stderr_data = await get_process.stdout.read(), await get_process.stderr.read()
|
||||
await write_to_detailed_log(
|
||||
f"GET({flag}): Stuck for {TIMEOUT} seconds. Make sure the checker code has it's own timeouts. stdout={stdout_data} stderr={stderr_data}",
|
||||
also_print=True
|
||||
)
|
||||
get_process.kill()
|
||||
else:
|
||||
returncode = get_process.returncode
|
||||
await write_to_detailed_log(
|
||||
f"GET({flag}): {returncode_to_string(returncode)} ({returncode}) stdout(public)={stdout_data} stderr(private)={stderr_data}",
|
||||
also_print=(EXPECTED_GET_CODE is not None and returncode != EXPECTED_GET_CODE)
|
||||
)
|
||||
|
||||
|
||||
async def main():
|
||||
pending_tasks = []
|
||||
checks_done = 0
|
||||
while True:
|
||||
if len(pending_tasks) > 0 and pending_tasks[0].done() and (checks_done + 1) % CHECKS_PER_REPORT == 0:
|
||||
print(f"Already done {checks_done + 1} checks. {len(pending_tasks) - 1} running in parallel.")
|
||||
while len(pending_tasks) > 0 and pending_tasks[0].done():
|
||||
pending_tasks.pop(0)
|
||||
checks_done += 1
|
||||
if len(pending_tasks) <= MAX_PARALLEL_CHECKS:
|
||||
pending_tasks.append(asyncio.create_task(asyncio.wait_for(do_all_checks_once(), timeout=TIMEOUT * 3 + 10)))
|
||||
else:
|
||||
print(f"Throttling checks since there are at least {MAX_PARALLEL_CHECKS} running")
|
||||
await asyncio.sleep(check_period)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
|
||||
1
ctfcup2025-school-final/checkers/sonobank/service_src
Symbolic link
1
ctfcup2025-school-final/checkers/sonobank/service_src
Symbolic link
@@ -0,0 +1 @@
|
||||
../../services/sonobank
|
||||
331
ctfcup2025-school-final/checkers/sonobank/src/main.rs
Normal file
331
ctfcup2025-school-final/checkers/sonobank/src/main.rs
Normal file
@@ -0,0 +1,331 @@
|
||||
use anyhow::{bail, Context, Result};
|
||||
use crypto::CryptoParams;
|
||||
use crypto::U512;
|
||||
use std::env;
|
||||
use std::io;
|
||||
use std::net::UdpSocket;
|
||||
use std::panic;
|
||||
use std::process;
|
||||
use std::time::Duration;
|
||||
use sysex::{parse_sysex_response, Request, Response};
|
||||
use uuid::Uuid;
|
||||
use std::io::Write as _;
|
||||
|
||||
const UDP_PORT: u16 = 5004;
|
||||
const REQUEST_TIMEOUT: Duration = Duration::from_secs(20);
|
||||
|
||||
// ForcAD exit codes
|
||||
const OK: i32 = 101;
|
||||
const CORRUPT: i32 = 102;
|
||||
const MUMBLE: i32 = 103;
|
||||
const DOWN: i32 = 104;
|
||||
const CHECKER_ERROR: i32 = 110;
|
||||
|
||||
fn main() {
|
||||
// fcking rust exists with 101 on panic by default
|
||||
panic::set_hook(Box::new(|panic_info| {
|
||||
let stderr = std::io::stderr();
|
||||
let mut handle = stderr.lock();
|
||||
|
||||
let msg = match panic_info.payload().downcast_ref::<&str>() {
|
||||
Some(s) => *s,
|
||||
None => "Box<Any> payload",
|
||||
};
|
||||
if let Some(location) = panic_info.location() {
|
||||
let _ = writeln!(handle, "Panic at {}:{}: {}", location.file(), location.line(), msg);
|
||||
} else {
|
||||
let _ = writeln!(handle, "Panic: {}", msg);
|
||||
}
|
||||
|
||||
process::exit(CHECKER_ERROR);
|
||||
}));
|
||||
|
||||
let code = match real_main() {
|
||||
Ok(c) => c,
|
||||
Err(e) => {
|
||||
print!("checker error: {:#}", e);
|
||||
CHECKER_ERROR
|
||||
}
|
||||
};
|
||||
std::process::exit(code);
|
||||
}
|
||||
|
||||
fn real_main() -> Result<i32> {
|
||||
let args = env::args().collect::<Vec<_>>();
|
||||
if args.len() < 3 {
|
||||
println!("Usage: {} check|put|get <host> [flag_id] [flag] [vuln]", args[0]);
|
||||
return Ok(CHECKER_ERROR);
|
||||
}
|
||||
|
||||
let mode = args[1].as_str();
|
||||
let host = args[2].clone();
|
||||
|
||||
match mode {
|
||||
"check" => {
|
||||
match do_check(&host) {
|
||||
Ok(()) => Ok(OK),
|
||||
Err(e) => {
|
||||
println!("{:#}", e);
|
||||
if is_down_error(&e) {
|
||||
Ok(DOWN)
|
||||
} else {
|
||||
Ok(MUMBLE)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
"put" => {
|
||||
// ForcAD: checker.py put host flag_id flag vuln
|
||||
if args.len() < 6 {
|
||||
println!("PUT: not enough arguments");
|
||||
return Ok(CHECKER_ERROR);
|
||||
}
|
||||
if args[5] != "1" {
|
||||
println!("PUT: unknown vuln {}", args[5]);
|
||||
return Ok(CHECKER_ERROR)
|
||||
}
|
||||
let flag = args[4].clone();
|
||||
|
||||
match put_flag(&host, &flag) {
|
||||
Ok((flag_id, public_msg)) => {
|
||||
eprint!("{flag_id}");
|
||||
print!("{public_msg}");
|
||||
Ok(OK)
|
||||
}
|
||||
Err(e) => {
|
||||
println!("{:#}", e);
|
||||
if is_down_error(&e) {
|
||||
Ok(DOWN)
|
||||
} else {
|
||||
Ok(MUMBLE)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
"get" => {
|
||||
if args.len() < 6 {
|
||||
println!("GET: not enough arguments");
|
||||
return Ok(CHECKER_ERROR);
|
||||
}
|
||||
if args[5] != "1" {
|
||||
println!("GET: unknown vuln {}", args[5]);
|
||||
return Ok(CHECKER_ERROR)
|
||||
}
|
||||
let flag_id = args[3].clone();
|
||||
let flag = args[4].clone();
|
||||
|
||||
if flag.is_empty() {
|
||||
println!("GET: flag empty");
|
||||
return Ok(CHECKER_ERROR)
|
||||
}
|
||||
|
||||
let (patch_id, priv_key) = match parse_flag_id(&flag_id) {
|
||||
Ok(v) => v,
|
||||
Err(e) => {
|
||||
println!("invalid flag_id: {:#}", e);
|
||||
return Ok(CHECKER_ERROR);
|
||||
}
|
||||
};
|
||||
|
||||
match get_and_check(&host, patch_id, priv_key, &flag) {
|
||||
Ok(()) => Ok(OK),
|
||||
Err(e) => {
|
||||
println!("{:#}", e);
|
||||
if is_down_error(&e) {
|
||||
Ok(DOWN)
|
||||
} else if is_flag_mismatch(&e) {
|
||||
Ok(CORRUPT)
|
||||
} else {
|
||||
Ok(MUMBLE)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
println!("Unknown mode: {mode}");
|
||||
Ok(CHECKER_ERROR)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn is_down_error(e: &anyhow::Error) -> bool {
|
||||
e.chain()
|
||||
.any(|cause| cause.downcast_ref::<io::Error>().is_some())
|
||||
}
|
||||
|
||||
fn is_flag_mismatch(e: &anyhow::Error) -> bool {
|
||||
let s = format!("{:#}", e);
|
||||
s.contains("flag mismatch") || s.contains("flag not found")
|
||||
}
|
||||
|
||||
fn send_and_recv(host: &str, payload: &[u8], crypto_params: Option<&'static crypto::CryptoParams>) -> Result<Response> {
|
||||
let addr = format!("{host}:{UDP_PORT}");
|
||||
let sock = UdpSocket::bind("0.0.0.0:0").context("bind UDP socket")?;
|
||||
sock.set_read_timeout(Some(REQUEST_TIMEOUT))
|
||||
.context("set UDP timeout")?;
|
||||
sock.connect(&addr)?;
|
||||
|
||||
sock.send(payload)
|
||||
.context("send")?;
|
||||
|
||||
let mut buf = [0u8; 4096];
|
||||
let n = sock.recv(&mut buf).context("recv")?;
|
||||
let frame = &buf[..n];
|
||||
let resp = parse_sysex_response(frame, crypto_params).context("parse_sysex_response")?;
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
fn get_crypto_params(host: &str) -> Result<crypto::CryptoParams> {
|
||||
let resp = send_and_recv(host, &Request::GetCryptoParams.encode(), None)?;
|
||||
match resp {
|
||||
Response::GetCryptoParamsResp { modulus, base } => {
|
||||
Ok(CryptoParams::new(modulus, base)?)
|
||||
}
|
||||
Response::Error(msg) => bail!("Diag error from service: {msg}"),
|
||||
other => bail!("Unexpected response to DIAG: {:?}", other),
|
||||
}
|
||||
}
|
||||
|
||||
fn do_check(host: &str) -> Result<()> {
|
||||
let resp = send_and_recv(host, &Request::Diag.encode(), None)?;
|
||||
match resp {
|
||||
Response::Diag => {}
|
||||
Response::Error(msg) => bail!("Diag error from service: {msg}"),
|
||||
other => bail!("Unexpected response to DIAG: {:?}", other),
|
||||
}
|
||||
|
||||
let crypto_params: &'static crypto::CryptoParams = Box::leak(Box::new(get_crypto_params(host)?));
|
||||
|
||||
let lua_code =
|
||||
r#"
|
||||
function sample(t, note, velocity)
|
||||
return t*note*velocity
|
||||
end
|
||||
"#;
|
||||
|
||||
let put_req = Request::Put {
|
||||
data: lua_code.as_bytes().to_vec(),
|
||||
};
|
||||
let resp = send_and_recv(host, &put_req.encode(), Some(crypto_params))?;
|
||||
let (patch_id, private_key) = match resp {
|
||||
Response::PutResp { patch_id, private_key } => (patch_id, private_key),
|
||||
Response::Error(msg) => bail!("PUT error from service: {msg}"),
|
||||
other => bail!("Unexpected response to PUT: {:?}", other),
|
||||
};
|
||||
|
||||
let render_req = Request::RenderHash {
|
||||
patch_id,
|
||||
note: 60,
|
||||
velocity: 100,
|
||||
};
|
||||
let resp = send_and_recv(host, &render_req.encode(), Some(crypto_params))?;
|
||||
match resp {
|
||||
Response::RenderHashResp { .. } => {}
|
||||
Response::Error(msg) => bail!("RenderHash error: {msg}"),
|
||||
other => bail!("Unexpected response to RenderHash: {:?}", other),
|
||||
}
|
||||
|
||||
let get_req = Request::Get { patch_id };
|
||||
let resp = send_and_recv(host, &get_req.encode(), Some(crypto_params))?;
|
||||
let encrypted_code = match resp {
|
||||
Response::GetResp {
|
||||
public_key: _,
|
||||
encrypted_code,
|
||||
} => encrypted_code,
|
||||
Response::Error(msg) => bail!("GET error: {msg}"),
|
||||
other => bail!("Unexpected response to GET: {:?}", other),
|
||||
};
|
||||
|
||||
let decrypted = private_key
|
||||
.decrypt(&encrypted_code)
|
||||
.context("decrypt Lua code")?;
|
||||
let lua_src = String::from_utf8(decrypted).context("Lua code is not UTF-8")?;
|
||||
if lua_src != lua_code {
|
||||
bail!("Lua code changed");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn put_flag(host: &str, flag: &str) -> Result<(String, String)> {
|
||||
let crypto_params: &'static crypto::CryptoParams = Box::leak(Box::new(get_crypto_params(host)?));
|
||||
|
||||
let lua_code = format!(
|
||||
r#"
|
||||
secret = "{flag}"
|
||||
|
||||
function sample(t, note, velocity)
|
||||
return t*note*velocity
|
||||
end
|
||||
"#
|
||||
);
|
||||
|
||||
let put_req = Request::Put {
|
||||
data: lua_code.as_bytes().to_vec(),
|
||||
};
|
||||
let resp = send_and_recv(host, &put_req.encode(), Some(crypto_params))?;
|
||||
let (patch_id, private_key) = match resp {
|
||||
Response::PutResp { patch_id, private_key } => (patch_id, private_key),
|
||||
Response::Error(msg) => bail!("PUT error from service: {msg}"),
|
||||
other => bail!("Unexpected response to PUT: {:?}", other),
|
||||
};
|
||||
|
||||
let flag_id = make_flag_id(patch_id, private_key.k())?;
|
||||
let public_msg = patch_id.to_string();
|
||||
|
||||
Ok((flag_id, public_msg))
|
||||
}
|
||||
|
||||
fn get_and_check(host: &str, patch_id: Uuid, priv_key_k: U512, flag: &str) -> Result<()> {
|
||||
let crypto_params: &'static crypto::CryptoParams = Box::leak(Box::new(get_crypto_params(host)?));
|
||||
|
||||
let get_req = Request::Get { patch_id };
|
||||
let resp = send_and_recv(host, &get_req.encode(), Some(crypto_params))?;
|
||||
let encrypted_code = match resp {
|
||||
Response::GetResp {
|
||||
public_key: _,
|
||||
encrypted_code,
|
||||
} => encrypted_code,
|
||||
Response::Error(msg) => if msg.contains("ot found") {
|
||||
bail!("GET error, flag not found: {msg}")
|
||||
} else {
|
||||
bail!("GET error: {msg}")
|
||||
},
|
||||
other => bail!("Unexpected response to GET: {:?}", other),
|
||||
};
|
||||
|
||||
let priv_key = crypto::PrivateKey::from_k(crypto_params, priv_key_k)?;
|
||||
|
||||
let decrypted = priv_key
|
||||
.decrypt(&encrypted_code)
|
||||
.context("decrypt Lua code")?;
|
||||
let lua_src = String::from_utf8(decrypted).context("Lua code is not UTF-8")?;
|
||||
if !lua_src.contains(flag) {
|
||||
bail!("flag mismatch in decrypted Lua code");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[derive(serde::Serialize, serde::Deserialize)]
|
||||
struct FlagId {
|
||||
patch_id: String,
|
||||
k: String,
|
||||
}
|
||||
|
||||
fn make_flag_id(patch_id: Uuid, priv_key: &U512) -> Result<String> {
|
||||
let k_str = hex::encode(priv_key.to_be_bytes());
|
||||
let obj = FlagId {
|
||||
patch_id: patch_id.to_string(),
|
||||
k: k_str,
|
||||
};
|
||||
let json = serde_json::to_string(&obj)?;
|
||||
Ok(json)
|
||||
}
|
||||
|
||||
fn parse_flag_id(flag_id: &str) -> Result<(Uuid, U512)> {
|
||||
let obj: FlagId = serde_json::from_str(flag_id).context("flag_id JSON decode")?;
|
||||
let patch_id = Uuid::parse_str(&obj.patch_id).context("bad patch_id in flag_id")?;
|
||||
let priv_key = U512::from_be_hex(&obj.k);
|
||||
Ok((patch_id, priv_key))
|
||||
}
|
||||
Reference in New Issue
Block a user