Alikas-0x01
题目:实验吧whatamitoyou
用IDA打开,进入main函数,F5。(F5重度依赖者,菜了)
分析可知,memset语句后数据应为数组。对每组都按快捷键Y修改类型,改为char a[0x128]
[记得从后往前改(即从v5开始)]
memset(&v5, 0, 0x128uLL);
v5 = 2334397743343431513LL;
v6 = 2338620985787316589LL;
v7 = 2338323056846008934LL;
v8 = 8583972389067452009LL;
v9 = 199253324399LL;
v3 = &v10;
memset(&v10, 0, 0xD8uLL);
//修改后
memset(v5, 0, sizeof(v5));
strcpy(v5, "You are my best friends in the world.");//这里字符转换了,快捷键R
v3 = &v5[40];
memset(&v5[40], 0, 0xD8uLL);
*(_DWORD *)&v5[288] = 3;
根据题目提示“你会唱歌吗”和题目内出现的字符串,可以搜索到一首歌My Best Friends InThe World(What Am I To You?)。对比歌词可知,题目内的歌词是乱序的。
修改类型后可看到后面的赋值语句发生变化。分析可知,该数组内,前256个字节存储歌词,后用存储三个指针,分别指向三句不同的歌词。
*(_QWORD *)&v5[256] = &v245;
*(_QWORD *)&v5[264] = &v237;
*(_QWORD *)&v5[272] = &v86;
*(_QWORD *)&v5[280] = &v214;
创建数据结构lyric,内含两个成员,一个是char a[256],储存歌词;一个是lyric *q[3],存放3个指向下一句歌词所在的数据结构的地址。[插入数据结构在IDA的Structures窗口中,插入教程就在窗口内注释部分]
00000000 ; Ins/Del : create/delete structure
00000000 ; D/A/* : create structure member (data/ascii/array)
00000000 ; N : rename structure or structure member
00000000 ; U : delete structure member
00000000 ; [00000018 BYTES. COLLAPSED STRUCT Elf64_Sym. PRESS CTRL-NUMPAD+ TO EXPAND]
00000000 ; ---------------------------------------------------------------------------
00000000
00000000 lyric struc ; (sizeof=0x118, mappedto_6)
00000000 a db 256 dup(?)
00000100 q dq 3 dup(?) ; offset
00000118 lyric ends
00000118
00000000 ; [00000018 BYTES. COLLAPSED STRUCT Elf64_Rela. PRESS CTRL-NUMPAD+ TO EXPAND]
00000000 ; [00000010 BYTES. COLLAPSED STRUCT Elf64_Dyn. PRESS CTRL-NUMPAD+ TO EXPAND]
对数组进行再一次修改类型lyric a,修改后如下:
memset(&v5, 0, 0x128uLL);
strcpy(v5.a, "You are my best friends in the world.");
v3 = &v5.a[40];
memset(&v5.a[40], 0, 0xD8uLL);
接下来分析计算flag算法
v80 = &v41; //&41 为第一句歌词地址
v79 = 1;
v78 = 0;
while ( 1 )
{
v77 = *a2[1];//a2即为输入的字符串
if ( !v77 )
break;
if ( v79 & 1 )
v78 *= v79;
else
v78 /= v79;
v78 += (v77 - 32) * *&v80[1].a[8];
v80 = *&v80->a[8 * (v77 - 65 + 32LL)];// 根据[8*(输入的字符-65+32)]得到了下一句歌词
++v79;
v3 = a2[1] + 1;
a2[1] = v3;
}
if ( v80 == &v65 )//由这句猜测,将歌词从第一句开始到最后一句即可得flag
{
printf("Your password is tjctf{", a2, v3, a2);
while ( v78 )
{
v76 = v78 % 16;
v78 /= 16;
putchar(v76 + 97);
}
puts("}");
}
else
{
puts("Nope.");
}
由上述分析即歌词顺序可知:
例:歌词第一句为”Everyone, Bubblegum I’m so dumb,”,下一句是”I should have just told you”,
由[8*(输入-65+32)]可知输入的第一个字符是67=‘C’。
若输入的第一个字符为A,则得到what I lost
若输入的第一个字符为B,则得到what am I to you
若输入的第一个字符为D,则得到Am I a joke,your knight,oryou brother?
依次类推,得到剩下的输入。
完整的输入为CBDABCADBCCABBABBABACBCCABDADBABABB
Linux下运行,即得flag:
附上:歌词