Move or Not
use IDA to decompile it.
__int64 __fastcall main(__int64 a1, char **a2, char **a3)
{
int v4; // [rsp+8h] [rbp-38h]
int i; // [rsp+Ch] [rbp-34h]
char s2; // [rsp+10h] [rbp-30h]
unsigned __int64 v7; // [rsp+38h] [rbp-8h]
v7 = __readfsqword(0x28u);
i = 0;
printf("First give me your password: ", a2, a3);
__isoc99_scanf("%d", &v4);
if ( v4 != 98416 )
{
puts("You don't know static analysis !");
exit(0);
}
printf("Second give me your key: ");
__isoc99_scanf("%d", &v4);
v4 -= 49;
for ( i = 0; i <= 11; ++i )
*((_BYTE *)unknown_function + i) += v4;
unknown_function(s1);
printf("Then Verify your flag: ");
__isoc99_scanf("%s", &s2);
if ( !strcmp(s1, &s2) )
puts("You are right. Congratulations !!");
else
puts("You don't know dynamic analysis !");
return 0LL;
}
So easily find first key is hardcoded value, 98416
. But Second key is seem more complex. It input some value on v4, and add it to unknown_function
’s first 11byte. Second key must 1byte, 0x00 to 0xFF, but don’t know exact value. Via some test, I know the second key is ‘2’, 50. If I can set breakpoint on strcmp, I can see what is s1 directly, but I can’t.(It may because of ASLR, but don’t know exact reason). So I reverse it only static analyse.
objdump -s -j .data ./pro
To see data section in binary, I use this command and see unknown_function
is folloing value:
7f2e264782c6007f061f4782c701802f0b4883c70180070d4883c7018007414883c701802f0d4883c7018007204883c70180073c4883c7018007484883c70180076f4883c70180073b4883c7018007594883c7018007464883c701802f144883c7018007084883c7018007014883c7018007314883c7018007184883c701802f094883c7018007114883c701802f054883c701802f454883c70180071a4883c70180072d4883c701802f0b4883c7018007554883c7018007184883c7018007194883c701802f3b4883c701802f094883c7018007084883c701800758c3
and to make analyse easier, I want to make original asm, and make following code.
with open('pro.txt', 'r') as f:
asm1 = f.readline() # first 11 byte of unknown_function
asm2 = f.readline() # and rest parts of unknown_function
asm1arry = []
for i in range(0, len(asm1) - 2, 2):
asm1arry.append(asm1[i:i+2])
newasma = ""
for asm in asmarry:
n = format(int(asm, 16) + 1, 'x')
if len(n) < 2:
n = '0' + n
newasmarray += n
newasm += asm2
print(newasm)
And I use online assembler. (After CTF, I realize modify binary and open it via IDA is perfect way, but during CTF, I use online assembler and analyze assembler.) Via assembly, I see unknown_function
is used to encrypt flag by add or subtract some value on each flag byte. So I collect encrypted flag(s1) and key. Make python script to collect key is very graceful way, but key length is only 32byte so I just make key by my hand.
s1 = '69417855 2e7c2633 300c2920 2848656832473a62 64795246 3b0a4f59 6e3d6c25'.replace(' ', '')
enc_flag = []
for i in range(0, len(s1), 2):
enc_flag.append(s1[i:i+2])
key = [-0x27,0x20,-0xb,0xd, 0x41,-0xd, 0x20, 0x3c, 0x48, 0x6f, 0x3b, 0x59, 0x46, -0x14, 0x8, 0x1, 0x31, 0x18, -0x9, 0x11, -0x5, -0x45, 0x1a, 0x2d, -0xb, 0x55, 0x18,0x19, -0x3b, -0x9, 0x8, 0x58]
flag = ""
for i in range(32):
flag += chr(int(enc_flag[i],16) + key[i])
print(flag)
So this is decrypt function, and flag is: BambooFox{dyn4mic_1s_4ls0_gr34t}
.