ELF文件,32位
直接IDA查看反编译代码
int __fastcall main(int a1, char **a2, char **a3)
{
int result; // $v0
int i; // [sp+18h] [+18h] BYREF
char v5[36]; // [sp+1Ch] [+1Ch] BYREF
setbuf((FILE *)stdout, 0);
setbuf((FILE *)stdin, 0);
printf("Give me your flag:");
scanf("%32s", v5); //flag有32位
for ( i = 0; i < 32; ++i )
*((_BYTE *)&i + i + 4) ^= 32 - (_BYTE)i; // 异或加密
if ( !strncmp(v5, fdata, 5u) ) // fdata和经过一次加密flag前5位比较
result = sub_4007F0(v5); // 二次加密
else
result = puts("Wrong");
return result;
}
查看二次加密函数
int __fastcall sub_4007F0(const char *a1)
{
char v1; // $v1
int result; // $v0
size_t i; // [sp+18h] [+18h]
for ( i = 5; i < strlen(a1); ++i )
{
if ( (i & 1) != 0 ) //判断奇偶
v1 = (a1[i] >> 2) | (a1[i] << 6); // 低2位和高6位交换
else
v1 = (4 * a1[i]) | (a1[i] >> 6); // 高2位和低6位交换
a1[i] = v1;
}
if ( !strncmp(a1 + 5, (const char *)off_410D04, 0x1Bu) ) // off_410D04和和经过二次加密flag后27位比较
result = puts("Right!");
else
result = puts("Wrong!");
return result;
}
Exp
flag = list(map(ord, 'Q|j{g'))
flag += [0x52, 0xFD, 0x16, 0xA4, 0x89, 0xBD, 0x92, 0x80, 0x13, 0x41,
0x54, 0xA0, 0x8D, 0x45, 0x18, 0x81, 0xDE, 0xFC, 0x95, 0xF0,
0x16, 0x79, 0x1A, 0x15, 0x5B, 0x75, 0x1F]
for i in range(5, 32):
if i & 1:
flag[i] = ((flag[i] << 2) | (flag[i] >> 6)) & 0xff # & 0xff为了只取低8位
else:
flag[i] = ((flag[i] >> 2) | (flag[i] << 6)) & 0xff
for i in range(32):
flag[i] ^= 32 - i
print(''.join(map(chr, flag)))
输出
qctf{ReA11y_4_B@89_mlp5_4_XmAn_}