From 33a12532975258e543b0b50f9eeb981f952d85ed Mon Sep 17 00:00:00 2001 From: h7x4 Date: Sat, 4 Jul 2026 23:38:36 +0900 Subject: [PATCH] web/some_assembly_required_2 --- web/some_assembly_required_2/check_flag.wasm | Bin 0 -> 843 bytes web/some_assembly_required_2/check_flag.wat | 281 +++++++++++++++++++ web/some_assembly_required_2/index.html | 12 + web/some_assembly_required_2/index.js | 105 +++++++ web/some_assembly_required_2/solve.py | 10 + 5 files changed, 408 insertions(+) create mode 100644 web/some_assembly_required_2/check_flag.wasm create mode 100644 web/some_assembly_required_2/check_flag.wat create mode 100644 web/some_assembly_required_2/index.html create mode 100644 web/some_assembly_required_2/index.js create mode 100755 web/some_assembly_required_2/solve.py diff --git a/web/some_assembly_required_2/check_flag.wasm b/web/some_assembly_required_2/check_flag.wasm new file mode 100644 index 0000000000000000000000000000000000000000..5e11191dcdfb61fe6bb86e05a679184fd46aee40 GIT binary patch literal 843 zcmZQbEY4+QU|?VrW=UXRNMNe3XRJ?PV5|qR7?@dE7#NwDSy&kh7#SH^nHd?F*bF)9 z867utv2fQjIBwtokquyS0~Zn-BFz92VdQ3C$jHN%o0^+nRLR637$0ArSezT5oS2gn zpInk(RLsD@R$Nk)oLj)a$d#Otnw%Yz|0dL zpHiG3pOKiCl9S5J#1$W(l30=$pPHA#%*-1fpPrMSl$aBrlvtd~%)%WXpOKna0O7In z#>YdP0O7Oo#K)H;Cgr3;xa?fLEG$e6+>eEm6j;re1VB6yMK%Q%1vWD#9wrB72at$>BD*7_B8LLI0!Nl2 zrvi%tCrBx~E(3!imja6dmlXpyNEweJw
j{>&>PnIID0*eB#8555JH%J+u0*eBl z6$6(7i!KAVBERE*MnwSyeg%O-ML{M91wmd0h=dSGLRdjaLAX#+1SG_zC<+o1QxH`U zD^wI$5K$1%Rs=a+!i-6Vhlv}chFeh*q((|XQbDRvQ5qz~r6>aul2wpVkS$b{Q;=4a zSCCUwP>@$pa8p!tWK>jAP*hMVR8&?_<^{PO?@Ei)z=u!m(7wH37axt$of>m3;sLCHsv(XoL;kx79`fl+`_ky(LR zkwt+461wh+Y>xGc>RV#jGT~Y5Zkp>e7$Y=#lD~1gm{M_6|j0}zq9NgL! uiP`DiF@D8)1{S&Y76w^aR+-jWR=EcD**ST+HkpQ27Iv9AS($mI3=9DDZI#{t literal 0 HcmV?d00001 diff --git a/web/some_assembly_required_2/check_flag.wat b/web/some_assembly_required_2/check_flag.wat new file mode 100644 index 0000000..a0981f9 --- /dev/null +++ b/web/some_assembly_required_2/check_flag.wat @@ -0,0 +1,281 @@ +(module + (table $table0 1 1 funcref) + (memory $memory0 2) + (global $global0 (mut i32) (i32.const 66864)) + (global $global1 i32 (i32.const 1072)) + (global $global2 i32 (i32.const 1024)) + (global $global3 i32 (i32.const 1328)) + (global $global4 i32 (i32.const 1024)) + (global $global5 i32 (i32.const 66864)) + (global $global6 i32 (i32.const 0)) + (global $global7 i32 (i32.const 1)) + (export "memory" (memory $memory0)) + (export "__wasm_call_ctors" (func $func0)) + (export "strcmp" (func $func1)) + (export "check_flag" (func $func2)) + (export "input" (global $global1)) + (export "copy_char" (func $func3)) + (export "__dso_handle" (global $global2)) + (export "__data_end" (global $global3)) + (export "__global_base" (global $global4)) + (export "__heap_base" (global $global5)) + (export "__memory_base" (global $global6)) + (export "__table_base" (global $global7)) + (func $func0 + ) + (func $func1 (param $var0 i32) (param $var1 i32) (result 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) (local $var19 i32) (local $var20 i32) (local $var21 i32) (local $var22 i32) (local $var23 i32) (local $var24 i32) (local $var25 i32) (local $var26 i32) (local $var27 i32) (local $var28 i32) (local $var29 i32) (local $var30 i32) (local $var31 i32) (local $var32 i32) (local $var33 i32) (local $var34 i32) (local $var35 i32) (local $var36 i32) (local $var37 i32) (local $var38 i32) (local $var39 i32) (local $var40 i32) (local $var41 i32) (local $var42 i32) (local $var43 i32) + global.get $global0 + local.set $var2 + i32.const 32 + local.set $var3 + local.get $var2 + local.get $var3 + i32.sub + local.set $var4 + local.get $var4 + local.get $var0 + i32.store offset=24 + local.get $var4 + local.get $var1 + i32.store offset=20 + local.get $var4 + i32.load offset=24 + local.set $var5 + local.get $var4 + local.get $var5 + i32.store offset=16 + local.get $var4 + i32.load offset=20 + local.set $var6 + local.get $var4 + local.get $var6 + i32.store offset=12 + block $label1 + loop $label2 + local.get $var4 + i32.load offset=16 + local.set $var7 + i32.const 1 + local.set $var8 + local.get $var7 + local.get $var8 + i32.add + local.set $var9 + local.get $var4 + local.get $var9 + i32.store offset=16 + local.get $var7 + i32.load8_u + local.set $var10 + local.get $var4 + local.get $var10 + i32.store8 offset=11 + local.get $var4 + i32.load offset=12 + local.set $var11 + i32.const 1 + local.set $var12 + local.get $var11 + local.get $var12 + i32.add + local.set $var13 + local.get $var4 + local.get $var13 + i32.store offset=12 + local.get $var11 + i32.load8_u + local.set $var14 + local.get $var4 + local.get $var14 + i32.store8 offset=10 + local.get $var4 + i32.load8_u offset=11 + local.set $var15 + i32.const 255 + local.set $var16 + local.get $var15 + local.get $var16 + i32.and + local.set $var17 + block $label0 + local.get $var17 + br_if $label0 + local.get $var4 + i32.load8_u offset=11 + local.set $var18 + i32.const 255 + local.set $var19 + local.get $var18 + local.get $var19 + i32.and + local.set $var20 + local.get $var4 + i32.load8_u offset=10 + local.set $var21 + i32.const 255 + local.set $var22 + local.get $var21 + local.get $var22 + i32.and + local.set $var23 + local.get $var20 + local.get $var23 + i32.sub + local.set $var24 + local.get $var4 + local.get $var24 + i32.store offset=28 + br $label1 + end $label0 + local.get $var4 + i32.load8_u offset=11 + local.set $var25 + i32.const 255 + local.set $var26 + local.get $var25 + local.get $var26 + i32.and + local.set $var27 + local.get $var4 + i32.load8_u offset=10 + local.set $var28 + i32.const 255 + local.set $var29 + local.get $var28 + local.get $var29 + i32.and + local.set $var30 + local.get $var27 + local.set $var31 + local.get $var30 + local.set $var32 + local.get $var31 + local.get $var32 + i32.eq + local.set $var33 + i32.const 1 + local.set $var34 + local.get $var33 + local.get $var34 + i32.and + local.set $var35 + local.get $var35 + br_if $label2 + end $label2 + local.get $var4 + i32.load8_u offset=11 + local.set $var36 + i32.const 255 + local.set $var37 + local.get $var36 + local.get $var37 + i32.and + local.set $var38 + local.get $var4 + i32.load8_u offset=10 + local.set $var39 + i32.const 255 + local.set $var40 + local.get $var39 + local.get $var40 + i32.and + local.set $var41 + local.get $var38 + local.get $var41 + i32.sub + local.set $var42 + local.get $var4 + local.get $var42 + i32.store offset=28 + end $label1 + local.get $var4 + i32.load offset=28 + local.set $var43 + local.get $var43 + return + ) + (func $func2 (result i32) + (local $var0 i32) (local $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) + i32.const 0 + local.set $var0 + i32.const 1072 + local.set $var1 + i32.const 1024 + local.set $var2 + local.get $var2 + local.get $var1 + call $func1 + local.set $var3 + local.get $var3 + local.set $var4 + local.get $var0 + local.set $var5 + local.get $var4 + local.get $var5 + i32.ne + local.set $var6 + i32.const -1 + local.set $var7 + local.get $var6 + local.get $var7 + i32.xor + local.set $var8 + i32.const 1 + local.set $var9 + local.get $var8 + local.get $var9 + i32.and + local.set $var10 + local.get $var10 + return + ) + (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) + 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 + local.get $var4 + i32.load offset=12 + local.set $var6 + i32.const 8 + local.set $var7 + local.get $var6 + local.get $var7 + i32.xor + local.set $var8 + local.get $var4 + local.get $var8 + i32.store offset=12 + end $label0 + local.get $var4 + i32.load offset=12 + local.set $var9 + local.get $var4 + i32.load offset=8 + local.set $var10 + local.get $var10 + local.get $var9 + i32.store8 offset=1072 + return + ) + (data (i32.const 1024) "xakgK\5cNsn08m?80jj:i;j:m0?klnmiljinu\00\00") +) diff --git a/web/some_assembly_required_2/index.html b/web/some_assembly_required_2/index.html new file mode 100644 index 0000000..6ec79d3 --- /dev/null +++ b/web/some_assembly_required_2/index.html @@ -0,0 +1,12 @@ + + + + + + +

Enter flag:

+ + +

+ + diff --git a/web/some_assembly_required_2/index.js b/web/some_assembly_required_2/index.js new file mode 100644 index 0000000..a7c36cb --- /dev/null +++ b/web/some_assembly_required_2/index.js @@ -0,0 +1,105 @@ +// NOTE: most of the code here used to reference into constants, +// but I have rewritten it to use literals directly. + +const constants = [ + 'copy_char', + 'value', + '207aLjBod', + '1301420SaUSqf', + '233ZRpipt', + '2224QffgXU', + 'check_flag', + '408533hsoVYx', + 'instance', + '278338GVFUrH', + 'Correct!', + '549933ZVjkwI', + 'innerHTML', + 'charCodeAt', + './check_flag.wasm', + 'result', + '977AzKzwq', + 'Incorrect!', + 'exports', + 'length', + 'getElementById', + '1jIrMBu', + 'input', + '615361geljRK', +]; + +const get_const = function(addr, _seemingly_unused) { + addr = addr - 0xc3; + let result = constants[addr]; + return result; +}; + +// Stack aligner of some sort? +(function() { + while (!![]) { + try { + const result = + -parseInt(get_const(0xc8)) * -parseInt(get_const(0xc9)) + + -parseInt(get_const(0xcd)) + + parseInt(get_const(0xcf)) + + parseInt(get_const(0xc3)) + + -parseInt(get_const(0xc6)) * parseInt(get_const(0xd4)) + + parseInt(get_const(0xcb)) + + -parseInt(get_const(0xd9)) * parseInt(get_const(0xc7)); + + if (result === 0x4bb06) break; + else constants['push'](constants['shift']()); + } catch (_0x4f8a) { + constants['push'](constants['shift']()); + } + } +}()); + +let exports; + +// Load the WebAssembly module and get its exports +(async () => { + let checkFlagWasm = await fetch('./check_flag.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!'; +} + +// Reverse engineered from check_flag.wat +// func3, i.e. copy_char + +// function func3(var0, var1) { +// global0 = 0x10500; +// var2 = global0; +// var3 = 0x10; +// var4 = (var2 - var3); +// store(var4 + 12, var0); +// store(var4 + 8, var1); +// var5 = load(var4 + 12); +// if (var5 != 0) { +// var6 = load(var4 + 12); +// var7 = 0x8; +// var8 = (var6 ^ var7); +// store(var4 + 12, var8); +// } +// var9 = load(var4 + 12); +// var10 = load(var4 + 8); +// store(0x430, (var10 & 0xFF)); +// return; +// } + +// It seems like copy_char xors all characters with 0x8 before transferring them? diff --git a/web/some_assembly_required_2/solve.py b/web/some_assembly_required_2/solve.py new file mode 100755 index 0000000..107a27d --- /dev/null +++ b/web/some_assembly_required_2/solve.py @@ -0,0 +1,10 @@ +#!/usr/bin/env python3 + +FLAG_ENC = b"xakgK\\Nsn08m?80jj:i;j:m0?klnmiljinu" + +def main(): + for char in FLAG_ENC: + print(chr(char ^ 0x08), end='') + +if __name__ == '__main__': + main()