Your task is to shatter Beshcan, an irreversible algorithm concealed within.
The attachment is a static riscv64 binary. However, if we run it using qemu-riscv64 or on a latest RISC-V Linux machine, it always fails to find the flag file. Using strace, it turns out that it uses the legacy 1024 for open
syscall:
qemu-riscv64 -strace ./beshcan
3176468 brk(NULL) = 0x00000000000ce000
3176468 brk(0x00000000000ce4b0) = 0x00000000000ce4b0
3176468 brk(0x00000000000cf000) = 0x00000000000cf000
3176468 Unknown syscall 1024
3176468 fstat(1,0x00007fa509a4e080) = 0
3176468 fstat(1,0x00007fa509a4e000) = 0
3176468 write(1,0xce780,19)Missing flag file!
= 19
3176468 close(0) = 0
3176468 close(1) = 0
3176468 close(2)
We modified qemu source to add the missing mapping:
diff --git a/linux-user/riscv/syscall.tbl b/linux-user/riscv/syscall.tbl
index 845e24eb37..ab470de3ad 100644
--- a/linux-user/riscv/syscall.tbl
+++ b/linux-user/riscv/syscall.tbl
@@ -403,3 +403,4 @@
460 common lsm_set_self_attr sys_lsm_set_self_attr
461 common lsm_list_modules sys_lsm_list_modules
462 common mseal sys_mseal
+1024 common open sys_open
Now we have a qemu version that can run the binary. Then, by some manual testing, we find that the program:
flag
filesecret.enc
So we can simply enumerate 0-255
values to find their fixed mapping. Then, we reverse the mapping to get the flag image:
import string
import os
# find mapping for all characters
mapping = dict()
for ch in range(0, 256):
open("flag", "wb").write(bytes([ch] * 2))
os.system("~/qemu/build/qemu-riscv64 ./beshcan")
data = open("secret.enc", "rb").read()
print(ch, data)
mapping[data[0:2]] = ch
mapping[data[2:4]] = ch
# this is the original secret.enc file
enc = open("secret.enc.bak", "rb").read()
plain = bytearray()
for i in range(0, len(enc), 2):
plain.append(mapping[enc[i : i + 2]])
open("flag.jpg", "wb").write(plain)
Flag: ASIS{7H1S_iZ_jUsT_0n3_raNdOm_5hUfF1E!}
.