Decompiling the file, we find it runs the encryptFlag function on the first argument, then prints the output out as hex.
The encrypt flag function runs some complicated airthmetic thing, which doesn't really matter that much, or at all.
What's notable is that the encryption is kind of a rolled byte by byte. That is, the same byte preceded by the same text before it will encrypt to the same thing.
Knowing the flag format, rgbCTF{flag}, we can use a byte by byte bruteforce.
I recreated the function inside of python and attempted to run the bruteforce there, but I got non-preferable results. So, I did this again, this time recreating the code in c and compiling it, then created a python wrapper script to run the bruteforce.
I'm not sure exactly why, but I had to constantly switch between the two scripts, using one to brute the next part of the flag, subbing it into the other to brute the next part of the flag, subbing that in... etc.
Anyhow after all of my pain and a little trial and error i was able to create the final flag.
Python script with recreation:
Copy import string
def encryptflag ( toencrypt ):
index = 0
bvvar3 = toencrypt [ index ]
while True :
curbyte = bvvar3
uVar2 = curbyte - 10 & 0x ff
uVar4 = curbyte
if (bvvar3 < 0x 50 ) and (uVar4 == uVar2 or 0x 50 < uVar2) :
uVar4 = curbyte + 0x 46 & 0x ff
uVar4 = (uVar4 - 7 ^ 0x 43 ) & 0x ff
pbVar1 = index + 1
toencrypt [ index ] = (uVar4 << 6 ) | (uVar4 >> 2 )
bvvar3 = toencrypt [ pbVar1 ]
if bvvar3 == 0 : break
uVar4 = pbVar1 % 5
bvvar3 = bvvar3 << ( - uVar4 & 7 ) | bvvar3 >> (uVar4 & 0x ff )
if uVar4 == 2 :
bvvar3 = bvvar3 - 1
toencrypt [ pbVar1 ] = bvvar3
bvvar3 = toencrypt [ pbVar1 ]
index = pbVar1
for i in range ( len (toencrypt)):
toencrypt [ i ] = toencrypt [ i ] & 255
enc = [ 0x 0A , 0x FB , 0x F4 , 0x 88 , 0x DD , 0x 9D , 0x 7D , 0x 5F , 0x 9E , 0x A3 , 0x C6 , 0x BA , 0x F5 , 0x 95 , 0x 5D , 0x 88 , 0x 3B , 0x E1 , 0x 31 , 0x 50 , 0x C7 , 0x FA , 0x F5 , 0x 81 , 0x 99 , 0x C9 , 0x 7C , 0x 23 , 0x A1 , 0x 91 , 0x 87 , 0x B5 , 0x B1 , 0x 95 , 0x E4 ]
flag = list ( b "rgbCTF{ARM_ar1thm3t1c_r0cks_fad" )
l = len (flag)
flag += [ 0 ] * ( len (enc) - len (flag) )
temparr = flag [:]
for i in range (l, len (enc)):
for j in map ( ord ,string.ascii_lowercase + string.ascii_uppercase + '0123456789_}' ):
temparr = flag [:]
temparr [ i ] = j
encryptflag (temparr)
if temparr [ i ] == enc [ i ]:
flag [ i ] = j
break
print (flag)
inter = map ( chr ,flag)
print ( '' . join (inter))
arr = list ( b "rgbCTF{" ) + [ 0 ]
encryptflag (arr)
print ( ", " . join ( map ( hex ,arr)))
Python script that used the binary I recompiled:
Copy import os
import string
from pwn import *
flag = "rgbCTF{ARM_ar1thm3t1c_r0cks_fad96"
enc = [ 0x 0A , 0x FB , 0x F4 , 0x 88 , 0x DD , 0x 9D , 0x 7D , 0x 5F , 0x 9E , 0x A3 , 0x C6 , 0x BA , 0x F5 , 0x 95 , 0x 5D , 0x 88 , 0x 3B , 0x E1 , 0x 31 , 0x 50 , 0x C7 , 0x FA , 0x F5 , 0x 81 , 0x 99 , 0x C9 , 0x 7C , 0x 23 , 0x A1 , 0x 91 , 0x 87 , 0x B5 , 0x B1 , 0x 95 , 0x E4 ]
def getlast ( string ):
response = os . popen ( f "./arm { string } " ). read (). split ( ", " )
return int (response[ - 2 ], 16 )
for i in range ( len (flag), len (enc)):
for j in string . ascii_lowercase + string . ascii_uppercase + '0123456789_}' :
try :
resp = getlast (flag + j)
if resp == enc [ i ]:
flag += j
print (flag)
break
except :
pass
else :
flag += '-'
print (flag. encode ())
"""
for j in map(chr,range(256)):
try:
resp = getlast(flag + j)
if resp == enc[len(flag)]:
print(j)
except:
pass
"""
source of binary i recompiled:
Copy #include < stdlib .h >
#include < stdio .h >
#define true 1
void encryptFlag (char * flag);
int main (int param_1 , char * argv[])
{
char * pcVar1;
char * pbVar2;
char abStack272 [ 256 ];
pcVar1 = stpcpy ((char * )abStack272 , argv[ 1 ]);
encryptFlag (abStack272);
pbVar2 = abStack272;
for (int i = 0 ; i < strlen (argv[ 1 ]); i ++ ){
printf ( "%02X, " , (uint)((pbVar2[i] & 0xff )));
}
putchar ( 10 );
return 0 ;
}
void encryptFlag (char * flag)
{
char * curpointer;
char * pbVar1;
uint uVar2;
char bVar3;
uint curbyte;
uint uVar4;
bVar3 = * flag;
curpointer = flag;
if (bVar3 == 0 ) {
return ;
}
while ( 1 ) {
curbyte = (uint)bVar3;
uVar2 = curbyte - 10 & 0xff ;
uVar4 = curbyte;
if ((bVar3 < 0x50 ) && (uVar4 = uVar2 , 0x50 < uVar2)) {
uVar4 = curbyte + 0x46 & 0xff ;
}
uVar4 = (uVar4 - 7 ^ 0x43 ) & 0xff ;
pbVar1 = curpointer + 1 ;
* curpointer = (char)(uVar4 << 6 ) | (char)(uVar4 >> 2 );
bVar3 = * pbVar1;
if (bVar3 == 0 ) break ;
uVar4 = (int)(pbVar1 + - (int)flag) % 5 ;
bVar3 = bVar3 << ( - uVar4 & 7 ) | bVar3 >> (uVar4 & 0xff );
if (uVar4 == 2 ) {
bVar3 = bVar3 - 1 ;
}
* pbVar1 = bVar3;
bVar3 = * pbVar1;
curpointer = pbVar1;
}
return ;
}
Flag: rgbCTF{ARM_ar1thm3t1c_r0cks_fad961}