EncryptedScroll
Description
Elowen Moonsong, an Elven mage of great wisdom, has discovered an ancient scroll rumored to contain the location of The Dragon’s Heart. However, the scroll is enchanted with an old magical cipher, preventing Elowen from reading it.
Required Knowledge
C programming
Reverse binary file
Solve Walkthrough
1. Basic File Checks
First, I do basic file check using file
command.
challenge: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=5e966c94fbbe92e2607134ac2c0c78ee9d555b30, for GNU/Linux 4.4.0, not stripped
From the output above, we can see that it is a ELF 64-bit dynamically linked binary with PIE enabled. To get more binary protection, use the checksec
command.
[*] '/home/hurtz4eva/Nextcloud/CTF/international/htb-cyber-apocalypse/2025/rev/01_EncryptedScroll/rev_encryptedscroll/challenge'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled
Stripped: No
Mostly, all the protections is enabled and only Partial RELRO.
2. Analyze the Binary
Here's the decompiled code of some interesting functions.
undefined8 main(void)
{
long in_FS_OFFSET;
undefined1 buffer [56];
long canary;
canary = *(long *)(in_FS_OFFSET + 0x28);
anti_debug();
display_scroll();
printf(&DAT_00102220);
__isoc99_scanf(%49s,buffer);
decrypt_message(buffer);
if (canary != *(long *)(in_FS_OFFSET + 0x28)) {
/* WARNING: Subroutine does not return */
__stack_chk_fail();
}
return 0;
}
From the decompiled of decrypt_message
we got interesting information, that is the string IUC|t2nqm4gm5h5s2uin4u2d~
. The logic behind decrypt_message
is very simple, it just decrease each character of string "IUC|t2nqm4gm5h5s2uin4u2d~
" by 1 and the result will be put in buffer. Then, our input will be compared with the buffer.
3. Decrypt the Secret Message
To get the flag is simply do the logic buffer[i] = buffer[i] + -1;
. Take a look at the image below.

As you can see on the image above, the pattern of flag is appears. So, we just simply do for loop to decrypt the message. Here's my solver script.
#!/usr/bin/env python3
def solve(encrypted_message):
res = ""
len_encrypted_message = len(encrypted_message)
for i in range(len_encrypted_message):
res += chr(ord(encrypted_message[i]) - 1)
return res
if __name__ == "__main__":
encrypted_message = "IUC|t2nqm4`gm5h`5s2uin4u2d~"
decrypted_message = solve(encrypted_message)
print(decrypted_message)

Flag
HTB{s1mpl3_fl4g_4r1thm3t1c}
Last updated