From 3de1d34c20d577e406616ac52bf75cc2fb28d63c Mon Sep 17 00:00:00 2001 From: h7x4 Date: Sun, 5 Jul 2026 03:45:06 +0900 Subject: [PATCH] web/some_assembly_required_3 --- web/some_assembly_required_3/index.html | 12 + web/some_assembly_required_3/index.js | 195 +++++++++++++++ web/some_assembly_required_3/index.wasm | Bin 0 -> 918 bytes web/some_assembly_required_3/index.wat | 310 ++++++++++++++++++++++++ web/some_assembly_required_3/solve.py | 20 ++ 5 files changed, 537 insertions(+) create mode 100644 web/some_assembly_required_3/index.html create mode 100644 web/some_assembly_required_3/index.js create mode 100644 web/some_assembly_required_3/index.wasm create mode 100644 web/some_assembly_required_3/index.wat create mode 100755 web/some_assembly_required_3/solve.py diff --git a/web/some_assembly_required_3/index.html b/web/some_assembly_required_3/index.html new file mode 100644 index 0000000..6ec79d3 --- /dev/null +++ b/web/some_assembly_required_3/index.html @@ -0,0 +1,12 @@ + + + + + + +

Enter flag:

+ + +

+ + diff --git a/web/some_assembly_required_3/index.js b/web/some_assembly_required_3/index.js new file mode 100644 index 0000000..edd8a7f --- /dev/null +++ b/web/some_assembly_required_3/index.js @@ -0,0 +1,195 @@ +const constants = [ + 'exports', + '270328ewawLo', + 'instantiate', + '1OsuamQ', + 'Incorrect!', + 'length', + 'copy_char', + 'value', + '1512517ESezaM', + 'innerHTML', + 'check_flag', + 'result', + '1383842SQRPPf', + '924408cukzgO', + 'getElementById', + '418508cLDohp', + 'input', + 'Correct!', + '573XsMMHp', + 'arrayBuffer', + '183RUQBDE', + '38934oMACea', +]; + +const get_const = function(addr, _seemingly_unused) { + addr = addr - 0x11d; + let result = constants[addr]; + return result; +}; + +// Stack aligner of some sort? +(function() { + while (!![]) { + try { + const result = + -parseInt(get_const(0x122)) + + -parseInt(get_const(0x12f)) + + -parseInt(get_const(0x126)) * -parseInt(get_const(0x12b)) + + -parseInt(get_const(0x132)) + + parseInt(get_const(0x124)) + + -parseInt(get_const(0x121)) * -parseInt(get_const(0x11f)) + + parseInt(get_const(0x130)); + if (result === 0x252604) break; + else constants['push'](constants['shift']()); + } catch (e) { + constants['push'](constants['shift']()); + } + } +}()); + +let exports; + +// Load the WebAssembly module and get its exports +(async () => { + let checkFlagWasm = await fetch('./index.wasm'), + arrayBufferResult = await WebAssembly['instantiate'](await checkFlagWasm['arrayBuffer']()), + arrayBufferResultInstance = arrayBufferResult['instance']; + exports = arrayBufferResultInstance['exports']; +})(); + +function onButtonPress() { + let value = document['getElementById']('input')['value']; + const copy_char = exports['copy_char']; + + for (let i = 0x0; i < value['length']; i++) { + const char_code = value['charCodeAt'](i); + copy_char(char_code, i); + } + + exports['copy_char'](0x0, value['length']), exports['check_flag']() == 0x1 + ? document['getElementById']('result')['innerHTML'] = 'Correct!' + : document['getElementById']('result')['innerHTML'] = 'Incorrect!'; +} + +// First attempt at reverse engineering copy_char/func3. +// This is a relatively direct translation. + +function copy_char(var0, var1) { + const key = "\xf1\xa7\xf0\x07\xed"; + // (global $global0 (mut i32) (i32.const 66864)) + // (global $global1 i32 (i32.const 1072)) + const var2 = exports['global0']['value']; + const var3 = 16; + const var4 = var2 - var3; + exports['memory']['buffer'][var4 + 12] = var0; + exports['memory']['buffer'][var4 + 8] = var1; + var5 = exports['memory']['buffer'][var4 + 12]; + if (var5 !== 0) { + const var6 = 4; + const var7 = exports['memory']['buffer'][var4 + 8]; + const var8 = 5; + const var9 = var7 % var8; + const var10 = var6 - var9; + const var11 = key.charCodeAt(var10); + const var12 = 24; + const var13 = var11 << var12; + const var14 = var13 >> var12; + const var15 = exports['memory']['buffer'][var4 + 12]; + const var16 = var15 ^ var14; + exports['memory']['buffer'][var4 + 12] = var16; + } + const var17 = exports['memory']['buffer'][var4 + 12]; + const var18 = exports['memory']['buffer'][var4 + 8]; + exports['memory']['buffer'][var18 + 1072] = var17; +} + +// Let's shorten it more and get rid of all the memory shuffling + +function copy_char(c, i) { + const key = "\xf1\xa7\xf0\x07\xed"; + if (c !== 0) { + const key_index = (4 - (i % 5)); + const key_char = key.charCodeAt(key_index); + c ^= key_char; + } + exports['memory']['buffer'][i + 1072] = c; +} + + +// copy_char +// (func $func3 (param $var0 i32) (param $var1 i32) +// (local $var2 i32) (local $var3 i32) (local $var4 i32) (local $var5 i32) (local $var6 i32) (local $var7 i32) (local $var8 i32) (local $var9 i32) (local $var10 i32) (local $var11 i32) (local $var12 i32) (local $var13 i32) (local $var14 i32) (local $var15 i32) (local $var16 i32) (local $var17 i32) (local $var18 i32) +// global.get $global0 +// local.set $var2 +// i32.const 16 +// local.set $var3 +// local.get $var2 +// local.get $var3 +// i32.sub +// local.set $var4 +// local.get $var4 +// local.get $var0 +// i32.store offset=12 +// local.get $var4 +// local.get $var1 +// i32.store offset=8 +// local.get $var4 +// i32.load offset=12 +// local.set $var5 +// block $label0 +// local.get $var5 +// i32.eqz +// br_if $label0 +// i32.const 4 +// local.set $var6 +// local.get $var4 +// i32.load offset=8 +// local.set $var7 +// i32.const 5 +// local.set $var8 +// local.get $var7 +// local.get $var8 +// i32.rem_s +// local.set $var9 +// local.get $var6 +// local.get $var9 +// i32.sub +// local.set $var10 +// local.get $var10 +// i32.load8_u offset=1067 +// local.set $var11 +// i32.const 24 +// local.set $var12 +// local.get $var11 +// local.get $var12 +// i32.shl +// local.set $var13 +// local.get $var13 +// local.get $var12 +// i32.shr_s +// local.set $var14 +// local.get $var4 +// i32.load offset=12 +// local.set $var15 +// local.get $var15 +// local.get $var14 +// i32.xor +// local.set $var16 +// local.get $var4 +// local.get $var16 +// i32.store offset=12 +// end $label0 +// local.get $var4 +// i32.load offset=12 +// local.set $var17 +// local.get $var4 +// i32.load offset=8 +// local.set $var18 +// local.get $var18 +// local.get $var17 +// i32.store8 offset=1072 +// return +// ) +// (data (i32.const 1024) "\9dn\93\c8\b2\b9A\8b\94\90\dd>\94\97\90\dd?\c4\c2\c9\dd4\c2\c5\97\db1\93\92\c0\da6\93\93\c1\d9>\91\c1\97\90\00\00") diff --git a/web/some_assembly_required_3/index.wasm b/web/some_assembly_required_3/index.wasm new file mode 100644 index 0000000000000000000000000000000000000000..8cc55fe3bb174290afa69743024dc9c249ebf8fc GIT binary patch literal 918 zcmZQbEY4+QU|?VrW=UXRNMNe3XRJ?PV5|qR7?@dE7#NwDSy&kh7#SH^nHd?F*vvWW z867utv2fQjIBwtok*mRE1DM>v1rmX>A&MA4B8=SZ%Ncpua#M5jiz=BI1mok&6N_`> zlM{1t;*(4Ai;5W-*osSvl5-0f7`c)&Qj@de({d8i8JJiz^9o8!m>D^f^9w5DlQR;F z7?_!}Q!AO7c;e$ziu2<$67y1WQkj{#;^R{iOA_N#^HP{uc;n;KbMliCbK;W{i&L3d zx#QzAQWFaxJT~6=c!)zFe0HAr_>#n=oKy&xgX665KlyrO@T#$&5VhM$${AcBqE^5 z?#QUfp}?-dk)_C~z@oqjQp&E&z@W&bz@orq#lQ_x#-qsX$f(Gpz^%ZOrO2zmqQGm$ z#G}9sQpTsiqQGaxz@@;V%fPM3@A#ilQ9yxTL7-4kkjX(oke2}>Aq0{TRuEDUE>si& z32`Zkf`r5rL>0se6~z@q6vVR?K~9%2W0K)v;s&YVR+I#(ky4OUkSbJ^1_^N~%7BDq z6=W1-3l-%Qq!r~Afj7bLUVHrhj1#NzACr0jiM+QYuQc`4eY~WC2 zQeaYG6kt?jR$x|SQDA_CuDc?eW4$7~0-FMRu_A{fqavpQhXQAzB9{UeKlfxtMnOnC z382Lj4 zj1om&1zrW7Qbj(9A^Zyb3Vg+i0tze&0%lA+V6X5f3W6j#6onLo6a=jpHgNEBbK5d8 zI5u!_YtPM_d}7m1$L=W;?%GY6KH;wYkwYi%njAVh{kGxcNe6D3O`d%4rrpGY(\94\97\90\dd?\c4\c2\c9\dd4\c2\c5\97\db1\93\92\c0\da6\93\93\c1\d9>\91\c1\97\90\00\00") + (data (i32.const 1067) "\f1\a7\f0\07\ed") +) diff --git a/web/some_assembly_required_3/solve.py b/web/some_assembly_required_3/solve.py new file mode 100755 index 0000000..378411f --- /dev/null +++ b/web/some_assembly_required_3/solve.py @@ -0,0 +1,20 @@ +#!/usr/bin/env python3 + +output = b"\x9dn\x93\xc8\xb2\xb9A\x8b\x94\x90\xdd>\x94\x97\x90\xdd?\xc4\xc2\xc9\xdd4\xc2\xc5\x97\xdb1\x93\x92\xc0\xda6\x93\x93\xc1\xd9>\x91\xc1\x97\x90\x00\x00" +key = b"\xf1\xa7\xf0\x07\xed" + +def copy_char_inv(c: int, i: int) -> int: + if c != 0: + key_index = (4 - (i % 5)) + key_char = key[key_index] + c ^= key_char + return c + +def main(): + for i, c in enumerate(output): + b = copy_char_inv(c, i) + print(chr(b), end="") + print() + +if __name__ == "__main__": + main()