[2019红帽杯]easyRE
新手一枚,如有错误(不足)请指正,谢谢!!
题目链接:BUUCTF-re-[2019红帽杯]childRE
题目下载:点击下载
IDA64位载入,shift+F12查看字符串,然后双击过去
"x"键交叉引用,切换到关键代码
F5反汇编显示
截取的部分代码
int i; // [rsp+Ch] [rbp-114h]
char str0[36]; // [rsp+60h] [rbp-C0h]
char input1[32]; // [rsp+90h] [rbp-90h]
int v16; // [rsp+B0h] [rbp-70h]
char v17; // [rsp+B4h] [rbp-6Ch]
char input2; // [rsp+C0h] [rbp-60h]
char v19; // [rsp+E7h] [rbp-39h]
char v20; // [rsp+100h] [rbp-20h]
unsigned __int64 v21; // [rsp+108h] [rbp-18h]
v21 = __readfsqword(0x28u);
str0[0] = 73;
str0[1] = 111;
str0[2] = 100;
str0[3] = 108;
str0[4] = 62;
str0[5] = 81;
str0[6] = 110;
str0[7] = 98;
str0[8] = 40;
str0[9] = 111;
str0[10] = 99;
str0[11] = 121;
str0[12] = 127;
str0[13] = 121;
str0[14] = 46;
str0[15] = 105;
str0[16] = 127;
str0[17] = 100;
str0[18] = 96;
str0[19] = 51;
str0[20] = 119;
str0[21] = 125;
str0[22] = 119;
str0[23] = 101;
str0[24] = 107;
str0[25] = 57;
str0[26] = 123;
str0[27] = 105;
str0[28] = 121;
str0[29] = 61;
str0[30] = 126;
str0[31] = 121;
str0[32] = 76;
str0[33] = 64;
str0[34] = 69;
str0[35] = 67;
memset(input1, 0, sizeof(input1));
v16 = 0;
v17 = 0;
v0 = input1;
sub_4406E0(0LL, input1, 37LL);
v17 = 0;
v1 = input1;
if ( sub_424BA0(input1) == 36 )
{
for ( i = 0; ; ++i )
{
v1 = input1;
if ( i >= (unsigned __int64)sub_424BA0(input1) )
break;
if ( (unsigned __int8)(input1[i] ^ i) != str0[i] )
{
result = 4294967294LL;
goto LABEL_13;
}
}
sub_410CC0("continue!");
memset(&input2, 0, 0x40uLL);
v20 = 0;
v0 = &input2;
sub_4406E0(0LL, &input2, 64LL);
v19 = 0;
v1 = &input2;
if ( sub_424BA0(&input2) == 39 )
{
v3 = sub_400E44(&input2);
v4 = sub_400E44(v3);
v5 = sub_400E44(v4);
v6 = sub_400E44(v5);
v7 = sub_400E44(v6);
v8 = sub_400E44(v7);
v9 = sub_400E44(v8);
v10 = sub_400E44(v9);
v11 = sub_400E44(v10);
v12 = sub_400E44(v11);
v0 = off_6CC090;
v1 = (char *)v12;
if ( !(unsigned int)sub_400360(v12, off_6CC090) )
{
sub_410CC0("You found me!!!");
v1 = "bye bye~";
sub_410CC0("bye bye~");
}
先分析input1有关的代码,将用户输入与i异或后与在栈上存的数据进行比对
写脚本
然后知道flag前四位是flag
再分析与input2有关的代码
反复调用了sub_400E44()函数,查看后发现是base64加密,也就是进行了十次base64加密
可参考Base16,Base32,Base64编码详细学习
然后将编码后的字符串与off_6CC090处存放的字符串进行比对
编写脚本
查看网址……
参考wp
找到这段不随机的数据
发现其来自于sub_400D35函数
对sub_400D35函数进行交叉引用
发现来自.fini段的调用
而.fini段的解释是
此节区包含了可执行的指令,是进程终止代码的一部分。程序正常退出时,系统将安排执行这里的代码。
找到正确的关键代码
关键代码
v4^byte_6CC0A0[0] == ‘f’
v7 = v4
HIBYTE(v7)=HIBYTE(v4)=(*((_BYTE*)&(V4)+1))
也就是v4的下一位
byte_6CC0A3 也就是byte_6CC0A0[3]
因为第一次开始解出来flag开头是flag
可以推测就是判断v4的四位是不是与byte_6CC0A0前四位异或后等于’flag’
然后下面的异或应该是出flag的
写脚本
得出flag为flag{Act1ve_Defen5e_Test}