back to blog

HTB University CTF 2023 — RiseFromTheDead (hard)

Here’s the challenge’s details:

Challenge description

This time, we get 2 binary file, rise and core, which core file is generated from the executable ”./rise flag.”

File description

There are some key information that we can get from this part of the code. This program will open a file, and map 4096 bytes of the file to the memory with mmap. After that, v6 = (__int64)v5; will converts the memory-mapped region pointer v5 to a 64-bit integer. If the memory mapping is successful, it will call init_shuffle_list and shuf on the memory region.

Main function

Next, we have to check what is inside the init_shuffle_list function.

init_shuffle_list function

This function is responsible to initialize a shuffle list based on random values obtained from dev/urandom. It will first open dev/urandom to obtain some random bytes, and then it will do some loop and store it in buf to get the shuffle list. pos_in_list function is used to check if the obtained random bytes is already present in the shuffle list. If the byte is not in the shuffle list, it will append the byte and the corresponding character from the input buffer to the shuffle list with append_list function.

shuf function

Inside the shuf function, we can see that it perform a linked list iteration, where the first field represent the index, and the second one represent the character. And then the function will update an array (a2) at the index (result) with the character from the linked list node. After updating the array, the function will sets the character in the linked list node to 0 to mark a node as “used”.

We can conclude that this program will generate random number, shuffle the flag based on that random number, and then store the random number and the flag that been shuffled in the code program.

So how to find the flag?

First, we will use gdb to open core file. From the main function in rise file, we know that to open the core with gdb, the command is gdb program ./core

We open the program core with gdb

We can suspect that the data in the RBX is the encrypted flag, because the length of the data is 175, the same as the length of the shuffle list. We have to search where is the encrypted flag location

We can try to search it with search in gdb. But first, we have to convert it to little endian format.

from pwn import *
from Crypto.Util.number import *
val = bytes_to_long(b"b5xo1ar_")
res = p64(val, endian='little')
print(res.hex())

Searching for the encrypted flag

We know that the enc flag is in the load6 too. So, we have to look inside the load6. How? The program is use mmap to perform memory mapping, so we can use vmmap to analyze it.

vmmap of the core file

We find the start and end of the load6 file, so we can take a look inside it

Encrypted flag

We see that the enc flag is on the address 0x564e4bea4880, the same as when we search it

The random number that are appear between 21 is the index of the flag. So, now we can make the solver and get the flag.

with open('shuf.txt', 'r') as f:
    data = f.readlines()

indices = [int(line.strip(), 16) for line in data]
str = 'b5xo1ar_gmcrirttdne8ohsoshf6t/:ewm1ea8a_2h4r/ms7cetH6nig2oss}__eyer6aot{_ea_/peot./4-2tho.fb7Bac7_rerr__/su1_n!5p8e/c.7Tlcm_saos_sdm_rpa6p3tl2recty_22ffemef_i0e03u-vl5enh9deru'
flag = ''.join(str[i] for i in indices)

print(flag)

The Flag!

We got the point!