Access Denied CTF 2022
This weekend, I participated the Access Denied CTF 2022. I solved a couple of reversing challenges and had really fun.
babyc
A file written in C was given. I didn't get what the FLAG was, but I could predict it. Therefore, I wrote a python script below and predicted some words.
#Python flag = [-111, -47, -47, -79, -39, -39, 49, -79, 97, -127, -79, 49, -55, 9, 27, 89, -19, 59, 97, 49, -19, 89, -37, 121, -37, 89, -69, -37, -19, -111, 89, -37, -19, 113, -71, 97, -19, -101, 49, 49, 11, 91, -69, 11, -79, -87] tmp = {-111:"a", -47:"c", -79:"e", -39:"s", 49:"d", 97:"n", -127:"i", -55:"{", 9:"x", -87:"}", 89:"r", -19:"_", 121:"v", -37:"3", -69:"5", 113:"f", -71:"u", 11:"8", 91:"2"} for i in range(len(flag)): if (flag[i] in tmp): flag[i] = tmp[flag[i]] print(flag)
Then, got flag.
Enormous
An ELF file was given. Many conditional branch were in there, so wrote a python script with angr below.
#Python - angr import angr import claripy proj = angr.Project("./enormous") state = proj.factory.entry_state() sim = proj.factory.simulation_manager(state) sim.explore(find=(0x400000+0x3950), avoid=(0x400000+0x3963)) if len(sim.found) > 0: print("Yes") print(sim.found[0].posix.dumps(0))
Then, got flag.
Binary
An ELF file was given. Below is the main function. Encoding an input and comparing it with the flag. Simple.
This is an encoding function.
In line 11, it generates a pseudorandom number which generates the same number regardless of the time of attempts (=means executions). In line 12, a variable "uvar3" will be 0. Between line 13 and line 15 are below.
(now - (flag[i] + 0 & 0x3fffffff)) & 0x7f
So, wrote a python script below. Global variable "flag" is an array of pseudorandom numbers. Global variable "tmp" are the contents of the flag in line 14 in the main function.
#Python tmp = ["48","29","4c","58","44","72","2e","51","17","36","1f","0f","6d","5e","16","7a","6f","75","46","57","7e","19","57","75","29","4c","0d","14","68","7e","3b","4d","1a","1e", "79","30","10","3b","53","0a","11","3c","66","78","0e","1d","0f","36","60","66","4a"] flag = [1804289383, 846930886, 1681692777, 1714636915, 1957747793, 424238335, 719885386, 1649760492, 596516649, 1189641421, 1025202362, 1350490027, 783368690, 1102520059, 2044897763, 1967513926, 1365180540, 1540383426, 304089172, 1303455736, 35005211, 521595368, 294702567, 1726956429, 336465782, 861021530, 278722862, 233665123, 2145174067, 468703135, 1101513929, 1801979802, 1315634022, 635723058, 1369133069, 1125898167, 1059961393, 2089018456, 628175011, 1656478042, 1131176229, 1653377373, 859484421, 1914544919, 608413784, 756898537, 1734575198, 1973594324, 149798315, 2038664370, 1129566413] print(len(tmp), len(flag)) for i in range(len(flag)): # Decimal conversion now = "0x" + str(tmp[i]) now = int(now, 16) ans = (now - (flag[i] + 0 & 0x3fffffff)) & 0x7f print(chr(ans), end='') print("\n")
Then, got flag.
LLVM
A file wrote in Low Level Virtual Machine language was given. I did commands below, and made an ELF file.
llc <file_name>.ll (←generates .s file) gcc <file_name>.s -o <ELF_file_name>
Used Ghidra and decompiled it. The main function is below.
This code can be divided into two parts: changing the index and changing the character. For example, the first character of the "flag" array is 2C and the index is 0, so we look for the index with the character "00" in the array a3. If the index of "00" in array a3 is 2E, the next step is to find the index of 2E in array a2. Doing the same for array a1, we finally find that 2C is the 60th characters of the flag. We took this way. A python script below is a solver for this problem. I didn't get all letters of the FLAG, but could predict some characters. I think that you can also guess it.
#Python flag = ["2c", "2f", "2c", "cf", "cd", "09", "09", "4e", "09", "64", "2f", "cd", "0f", "c4", "6c", "84", "09", "8d", "84", "6f", "8c", "84", "6e", "ae", "09", "09", "4e", "8c", "6f", "c4", "64", "ac", "4e", "84", "24", "84", "a4", "8c", "8e", "8e", "ce", "e4", "6f", "e4", "2f", "8e", "09", "24", "4d", "8e", "4f", "8c", "ae", "4e", "e4", "8e", "a4", "6e", "64", "6e", "8c", "6c", "4f", "84", "6e", "6f", "09", "64"] a1 = ["1e", "25", "0a", "3f", "1a", "04", "09", "31", "0e", "01", "40", "13", "15", "19", "38", "2b", "1f", "05", "1b", "43", "32", "02", "3a", "23", "1c", "3e", "20", "33", "2e", "27", "37", "00", "24", "1d", "3b", "0c", "41", "07", "3d", "22", "2c", "2a", "0d", "06", "42", "0b", "03", "08", "0f", "12", "36", "35", "26", "28", "30", "2f", "39", "29", "34", "10", "17", "18", "14", "3c", "11", "2d", "21", "16"] a2 = ["10", "0a", "35", "38", "1b", "21", "20", "07", "3f", "05", "04", "01", "3d", "18", "0e", "2e", "2c", "1d", "3c", "1a", "40", "1c", "1f", "28", "06", "14", "15", "00", "30", "33", "09", "02", "43", "32", "3a", "0c", "12", "11", "17", "39", "25", "29", "19", "0d", "2d", "2a", "08", "16", "1e", "2f", "41", "26", "24", "27", "3b", "2b", "0f", "36", "23", "13", "0b", "22", "34", "3e", "03", "37", "31", "42"] a3 = ["27", "3b", "3e", "07", "26", "16", "1e", "2d", "3a", "28", "03", "2b", "31", "02", "0a", "41", "1c", "37", "04", "34", "2a", "1b", "17", "3c", "1f", "12", "40", "14", "11", "22", "32", "30", "0e", "2e", "36", "18", "19", "3f", "0f", "33", "2f", "0b", "24", "1d", "38", "00", "0c", "35", "09", "21", "1a", "42", "01", "15", "13", "05", "08", "25", "2c", "43", "06", "23", "20", "3d", "0d", "39", "29", "10"] # Changing the index part ans = ["a" for p in range(68)] for i in range(len(flag)): now1 = "0x" + flag[i] for j in range(len(a3)): now2 = "0x" + a3[j] if (i == int(now2, 16)): for k in range(len(a2)): now3 = "0x" + a2[k] if (j == int(now3, 16)): for h in range(len(a1)): now4 = "0x" + a1[h] if (k == int(now4, 16)): ans[h] = flag[i] break break break #to replace words which alredy known. tmp = {'ce':"a", '8e':"c", '4e':"e", '8c':"s", '6e':"d", '2f':"n", 'cf':"i", '8d':"{", '09':"_"} for i in range(len(ans)): if (ans[i] in tmp): ans[i] = tmp[ans[i]] # Changing the character part def find_moji(x): import string string = string.ascii_letters + string.digits + string.punctuation for i in string: now = ord(i) ^ 0x17 now = ((now & 0xf) << 4) + (now >> 4) now = (now << 1) or (now & 0x80) == 0x80 if (str(hex(now)) == x): return i for i in range(len(ans)): if (len(ans[i]) != 1): now = find_moji("0x" + ans[i]) ans[i] = now print(ans)
Did this, then got flag.