You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
We were given a ROM for the Varvara system running on Uxntal assembly. The ROM loads the provided shellcode into memory, checks if the lower 4 bits of each byte are not in [0, 2, 3, 6, 7, 0xe], and if true, executes it. The goal is to read the flag located at "flag".
14
+
We were given a ROM for the Varvara system running on Uxntal assembly. The ROM loads the provided shellcode into memory, checks if the lower 4 bits of each byte are not in [0, 2, 3, 6, 7, 0xe], and if true, executes it. The goal is to read the flag located at `"flag"`.
15
15
---
16
16
17
17
## Basics
18
18
19
-
We were given a ROM for the Varvara system running on Uxntal assembly. The ROM loads the provided shellcode into memory, checks if the lower 4 bits of each byte are not in [0, 2, 3, 6, 7, 0xe], and if true, executes it. The goal is to read the flag located at `flag`.
19
+
We were given a ROM for the Varvara system running on Uxntal assembly. The ROM loads the provided shellcode into memory, checks if the lower 4 bits of each byte are not in [0, 2, 3, 6, 7, 0xe], and if true, executes it. The goal is to read the flag located at `"flag"`.
and gives us the output. The [ROM](auxin2.rom) loads the provided hex-encoded code to address 0x1d0, checks the lower 4 bits of each byte, and executes it if they are not forbidden. Our output has to be <= 112 bytes.
28
30
29
31
## Shellcode Without Constraints
@@ -45,7 +47,9 @@ We communicate with the I/O through `DEO` and `DEI` to load the flag at a specif
45
47
46
48
## Initial Plan
47
49
48
-
After deliberation, we decided to write a self-modifying shellcode, where the last n bytes are the shellcode itself without forbidden bytes, and the prior bytes modify the shellcode to contain forbidden bytes. Here is the instruction table (forbidden instructions are marked in red): 
50
+
After deliberation, we decided to write a self-modifying shellcode, where the last n bytes are the shellcode itself without forbidden bytes, and the prior bytes modify the shellcode to contain forbidden bytes. Here is the instruction table (forbidden instructions are marked in red):
51
+
52
+

49
53
50
54
No `PUSH`, `POP`, `DEO`, `DEI`, or `DUP` are allowed. Luckily, most instructions in this assembly come with a `k` variant, meaning the instruction will execute but not pop values from the stack. Since the `INC` instruction is allowed, we come up with the following plan:
51
55
@@ -75,7 +79,9 @@ LDA2k INC2 SWP2 STA2k
75
79
The final step is to obtain the address 0x223 (where our shellcode to be changed starts). Luckily, one of our teammates comes up with a way to do so using the initial state of the stack ([02, 04]). All we have to do then is implement the [program](decoder.tal) and write a short [script](pepe.py) which substitutes the address we read from to (0x151 + offset) and uses one of the tricks on it if necessary. The Uxn binaries needed to run the script can be downloaded from [here](https://git.sr.ht/~rabbits/uxn).
76
80
77
81
## Flag
78
-
CTF{Sorry__n0_Music_thi5_t1m3}
82
+
83
+
CTF{Sorry\_\_n0_Music_thi5_t1m3}
79
84
80
85
## Conclusion
86
+
81
87
A pretty interesting but relatively simple code golf challenge. Interestingly, the final program has only 3 or so bytes to spare, so we are quite close to the limit.
0 commit comments