I made my own file manager... Here you have a DEMO version of it.
Author: Rivit
nc star.nc.jctf.pro 1337
Solution
Given ELF 64 bit file, open it using IDA. I rebase the program by using Edit->Segments->Rebase Program and put 0x555555554000 as value to make it same like in GDB.
So basically there will be dynamic call to the function after we input the menu number. All the available command can be seen on 0x0000555555566968 - 0x0000555555566AD0.
Based on the description, the given executable is DEMO version and from above image we can see that there are only 6 command include exit. Looking at available command on program we found that there is "compress" command.
So we need to find number for compress command first. Lets go to GDB.
b *0x0000555555558a5c
Now we need to find the address for menu 1 and menu 2. Go to first menu by putting 1 as the input.
Go to second menu by putting 2 as the input.
Lets calculate the number for compress menu, first find the reference for address 0x555555566A90 (CommpressCommand).
Lets try with number 7 and we will go to compress command.
Our objective is getting RCE to get flag on server. Compress command utilize system function to do compressing, lets dump the argument.
b *0x55555555D981
So it use tar command to do compression, looking at GTFOBins we know that we can abuse tar command to get shell. tar also vulnerable to wildcard injection, so we can get shell by using wildcard injection with argument same like in GTFOBins. Looking at rename command we found that we can input any character as the new filename, now we can utilize all available command to make the payload for RCE.
My favorite TV channel has recently become more interactive...
Solution
Given .asn files, after searching for a while we found repository that looks like have the same file https://github.com/igilham/mheg-slate. Looking at the reference for mheg we found that we can decompile the given file to the source code using mhgenc. After getting the source code actually it still hard to get the flag because we're not familiar with the code. Looking at another reference we found that we can debug the file using MHEGPlayer.
With above directory structure we can run the file using below command then click populate carousel from disk.
Click Play in realtime so we can interact with the program. To go to the flag validation program we can follow the screen instruction.
Press Blue
Select Extras (down-down-select)
Now we need to find where is our input processed. When we input invalid value the background will be red, so if we check in the source code we see that there is call of setBackgroundColor with color 0xff0000
So the link identifier is 2583, we can trace the call by searching 2583.
We can see on image above there is :Activate (2583) which mean that link 2583 bound with those line of code. After Activate instruction there is TestVariable instruction, lets try to find the emulator source code so we can see what is TestVariable do and also its constant. Found this reference on github. Now we have the operator and its value on this code.
$define eq 1
$define ne 2
$define lt 3
$define le 4
$define gt 5
$define ge 6
So for line 5070 until 5072 we can convert to below pseudocode
if var_70 == var_52:
link_2584()
else:
link_2583()
Until this step we know that the function that process our input is on :Link 117 (line 1228). Set breakpoint on line 1235 (click on line number) and lets analyze what the call means. To trigger the breakpoint input any value then select "Confirm".
Continue to next part, basically we just need to reverse one function for 611 - 678 because it do the same thing but with different value (based on index). It was like loop flow that has been flattened.
Now just reverse the algorithm. Although we've successfully reverse the algorithm but we can't find the valid flag. So we just notice that the length flag is not 67, so the next step we do is implement bruteforce for flag length during the reverse process.
def rev_link_611(a1):
index = var50.index(a1)
return var49[index]
def make_block(arr, length):
blocks = []
for i in range(0, len(arr), length):
blocks.append(arr[i:i+7])
return blocks
def xor(a1, a2):
tmp1 = int(a1, 2)
tmp2 = int(a2, 2)
return bin(tmp1 ^ tmp2)[2:].rjust(7, "0")
def init(length):
var63 = var51[:length]
var64 = var51[length:]
var65 = var64 + var63
return var65
# our input
var50 = "0000000000000100000100000011000010000001010000110000011100010000001001000101000010110001100000110100011100001111001000000100010010010001001100101000010101001011000101110011000001100100110100011011001110000111010011110001111101000000100001010001001000110100100010010101001100100111010100001010010101010010101101011000101101010111001011110110000011000101100100110011011010001101010110110011011101110000111001011101001110110111100011110101111100111111100000010000011000010100001110001001000101100011010001111001000100100110010101001011"
var51 = "00011001101110001010100100010001100100011001000011010001110101001111011011000100100111100100001011000010111001110101101110101100100101111010001100011110010111000010010100111100111101111011110100111010010110011010111110110111010111100100011110011100000010010100110100000110101011110101001010000010101000101001001010010111101110111110011001010100010000000110100001110100101111110100110011011100100000011011010101011110010010111111011101001111000100001101101001011000000001111110"
# invalid
# var49 = "1234567890qwertyuiopasdfghjkl{zxcvbnm_!@#$%^&*+=3DQWERTYUIOPASDFGHJKL}ZXCVBNM-"
var49 = "1234567890qwertyuiopasdfghjkl{zxcvbnm_!@#$%^&*+=QWERTYUIOPASDFGHJKL}ZXCVBNM-"
var51 = make_block(var51, 7)
var50 = make_block(var50, 7)
var70 = "11010011010000101111101110101001011001101100101000111101101110101101010000010111101110000110100001000111101100000001110010010000000001011111001101111110011110111100111000111111101000110110010111100111110001111010110100110111000001001111010001100110111000101010010001000110010001100100001101000111010100111101101100010010011110010000101100001011100111010110111010110010010111101000110001111001011100001001010011110011110111101111010011101001011001101011111011011101011110010001"
var70 = make_block(var70, 7)
for length in range(68):
try:
var65 = init(length)
# var52 == var70 for the flag
var69 = ""
for i in range(len(var70)):
var69 += xor(var70[i], var65[i])
var69 = make_block(var69, 7)
i = 0
inp = ""
while length > i:
inp += rev_link_611(var69[i])
i += 1
print(length, inp)
except Exception as e:
continue
Flag: justCTF{0ld_TV_c4n_b3_InTeR4ctIv3}
Cursed Protocol (500 pts)
Description
Dedicated for IoT devices, this handshake protocol will defeat any hacker that might try to reverse engineer the control application.