HTB University CTF 2023 — RiseFromTheDead (hard)
Here’s the challenge’s details:

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

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.

Next, we have to check what is inside the 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.

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 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())

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.

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

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)

