攻防世界-reverse-reverse-for-the-holy-grail-350
Posted pluie
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了攻防世界-reverse-reverse-for-the-holy-grail-350相关的知识,希望对你有一定的参考价值。
拖到linux中调试
IDA中查看主函数
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v3; // ebx
int v4; // ebx
__int64 v5; // rbx
void *v7; // [rsp+0h] [rbp-70h]
__int64 v8; // [rsp+10h] [rbp-60h]
void *v9; // [rsp+20h] [rbp-50h]
__int64 v10; // [rsp+30h] [rbp-40h]
void *v11; // [rsp+40h] [rbp-30h]
__int64 v12; // [rsp+48h] [rbp-28h]
char v13; // [rsp+50h] [rbp-20h]
v11 = &v13;
v12 = 0LL;
v13 = 0;
std::__ostream_insert<char,std::char_traits<char>>(&std::cout, "What... is your name?", 21LL);
std::endl<char,std::char_traits<char>>(&std::cout);
std::operator>><char,std::char_traits<char>,std::allocator<char>>(&std::cin, &v11);
std::__ostream_insert<char,std::char_traits<char>>(&std::cout, "What... is your quest?", 22LL);
std::endl<char,std::char_traits<char>>(&std::cout);
std::istream::ignore((std::istream *)&std::cin);
std::getline<char,std::char_traits<char>,std::allocator<char>>(&std::cin, &v11);
std::__ostream_insert<char,std::char_traits<char>>(&std::cout, "What... is the secret password?", 32LL);
std::endl<char,std::char_traits<char>>(&std::cout);
std::operator>><char,std::char_traits<char>,std::allocator<char>>(&std::cin, &userIn);
v7 = &v8;
std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::_M_construct<char *>(
&v7,
(_BYTE *)userIn,
(_BYTE *)(qword_601AE8 + userIn));
v3 = validChars(&v7);
if ( v7 != &v8 )
operator delete(v7);
if ( v3 < 0 )
goto LABEL_14;
v9 = &v10;
std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::_M_construct<char *>(
&v9,
(_BYTE *)userIn,
(_BYTE *)(qword_601AE8 + userIn));
v4 = stringMod((__int64 *)&v9); //关键函数
if ( v9 != &v10 )
operator delete(v9);
if ( v4 < 0 )
{
LABEL_14:
std::__ostream_insert<char,std::char_traits<char>>(&std::cout, "Auuuuuuuugh", 11LL);
std::endl<char,std::char_traits<char>>(&std::cout);
}
else
{
std::__ostream_insert<char,std::char_traits<char>>(&std::cout, "Go on. Off you go. tuctf{", 25LL);
v5 = std::__ostream_insert<char,std::char_traits<char>>(&std::cout, userIn, qword_601AE8);
std::__ostream_insert<char,std::char_traits<char>>(v5, "}", 1LL);
std::endl<char,std::char_traits<char>>(v5);
}
if ( v11 != &v13 )
operator delete(v11);
return 0;
}
stringMod函数:
__int64 __fastcall stringMod(__int64 *input_password_str)
{
__int64 v1; // r9
__int64 v2; // r10
__int64 v3; // rcx
signed int v4; // er8
int *v5; // rdi
int *v6; // rsi
signed int v7; // ecx
signed int v8; // er9
int v9; // er10
unsigned int v10; // eax
int v11; // esi
int v12; // esi
int v14[24]; // [rsp+0h] [rbp-60h]
memset(v14, 0, 0x48uLL);
v1 = input_password_str[1];
if ( v1 )
{
v2 = *input_password_str;
v3 = 0LL;
v4 = 0;
do
{
v12 = *(char *)(v2 + v3);
v14[v3] = v12;
if ( 3 * ((unsigned int)v3 / 3) == (_DWORD)v3 && v12 != firstchar[(unsigned int)v3 / 3] )// 第 0,3,6,9,12,15个字符对应firstchar的六个字符
v4 = -1;
++v3;
}
while ( v3 != v1 );
}
else
{
v4 = 0;
}
v5 = v14;
v6 = v14;
v7 = 666;
do
{
*v6 = v7 ^ *(unsigned __int8 *)v6; // 每个字符与v7异或
v7 += v7 % 5;
++v6;
}
while ( &v14[18] != v6 );
v8 = 1;
v9 = 0;
v10 = 1;
v11 = 0;
do
{
if ( v11 == 2 )
{
if ( *v5 != thirdchar[v9] ) // 异或后的字符串的第 2,5,8,11,14,17位对应thirdchar的六个数
v4 = -1;
if ( v10 % *v5 != masterArray[v9] )
v4 = -1;
++v9;
v10 = 1;
v11 = 0;
}
else
{ //只有v11==2时才校验字符,所以
v10 *= *v5; // v10 == 异或后的字符串的第 0+3*n 位 乘以第 1+3*n 位
if ( ++v11 == 3 )
v11 = 0;
}
++v8;
++v5;
}
while ( v8 != 19 ); // 循环 1~18
return (unsigned int)(v7 * v4);
}
stringMod函数校验过程一共分为三部分,第一部分中需要值得注意的是:
v3
是int型,除以一个数后小数部分会被去掉,所以3 * ((unsigned int)v3 / 3) == (_DWORD)v3
成立的条件是v3
是3
的倍数,因此flag的第 3*n
个字符对应firstchar的六个字符
脚本
i = 666
num = [] # v7
flag = ‘A**i**n**E**o**a**‘ # flag第0+3*n位对应firstchar
Xorflag = [] # flag每位与v7异或的结果
thirdchar = [0x2ef, 0x2c4, 0x2dc, 0x2c7, 0x2de, 0x2fc]
masterarray = [0x1d7, 0xc, 0x244, 0x25e, 0x93, 0x6c]
for j in range(18): # 求v7
num.append(i)
i += (i % 5)
temp_num = 0
for i in range(2, len(flag)+1, 3): # 求flag 第 1+3*n位
temp = thirdchar[temp_num] ^ num[i]
temp_num += 1
flag = flag[:i] + chr(temp) + flag[i+1:]
temp_num = 0
for i in range(len(flag)): # flag每位与v7异或
temp = ord(flag[i]) ^ num[i]
Xorflag.append(temp)
for i in range(1, 19, 3): # 求flag第1+3*n位
for j in range(32, 128):
j ^= num[i]
temp = j * Xorflag[i-1] % Xorflag[i+1]
if temp == masterarray[temp_num]:
flag = flag[:i] + chr(j ^ num[i]) + flag[i+1:]
temp_num += 1
break
print("tuctf{" + flag + ‘}‘)
以上是关于攻防世界-reverse-reverse-for-the-holy-grail-350的主要内容,如果未能解决你的问题,请参考以下文章