测试文件:https://adworld.xctf.org.cn/media/task/attachments/7ef7678559ea46cbb535c0b6835f2f4d
1.准备
获取信息
- 64位文件
2.IDA打开
1 int __cdecl main(int argc, const char **argv, const char **envp) 2 { 3 __int64 v3; // rax 4 __int64 v4; // rax 5 __int64 v5; // rax 6 __int64 v6; // rax 7 __int64 v7; // rax 8 __int64 v8; // rax 9 __int64 v9; // rax 10 __int64 v10; // rax 11 __int64 v11; // rax 12 __int64 v12; // rax 13 __int64 v13; // rax 14 __int64 v14; // rax 15 __int64 v15; // rax 16 __int64 v16; // rax 17 __int64 v17; // rax 18 __int64 v18; // rax 19 __int64 v19; // rax 20 __int64 v20; // rax 21 __int64 v21; // rax 22 int result; // eax 23 __int64 v23; // rax 24 __int64 v24; // rax 25 __int64 v25; // rax 26 __int64 v26; // rax 27 __int64 v27; // rax 28 __int64 v28; // rax 29 __int64 v29; // rax 30 __int64 v30; // rax 31 __int64 v31; // rax 32 __int64 v32; // rax 33 __int64 v33; // rax 34 __int64 v34; // rax 35 __int64 v35; // rax 36 __int64 v36; // rax 37 __int64 v37; // rax 38 char v38; // [rsp+Fh] [rbp-71h] 39 char v39; // [rsp+10h] [rbp-70h] 40 char v40; // [rsp+20h] [rbp-60h] 41 _BYTE *v41; // [rsp+28h] [rbp-58h] 42 char v42; // [rsp+30h] [rbp-50h] 43 unsigned __int64 v43; // [rsp+68h] [rbp-18h] 44 45 v43 = __readfsqword(0x28u); 46 std::operator<<<std::char_traits<char>>(&std::cout, "Enter the valid key! ", envp); 47 std::operator>><char,std::char_traits<char>>(&edata, &v42); 48 std::allocator<char>::allocator(&v38); 49 std::string::string(&v39, &v42, &v38); 50 md5(&v40, &v39); 51 v41 = (_BYTE *)std::string::c_str((std::string *)&v40); 52 std::string::~string((std::string *)&v40); 53 std::string::~string((std::string *)&v39); 54 std::allocator<char>::~allocator(&v38); 55 if ( *v41 != '7' 56 || v41[1] != '8' 57 || v41[2] != '0' 58 || v41[3] != '4' 59 || v41[4] != '3' 60 || v41[5] != '8' 61 || v41[6] != 'd' 62 || v41[7] != '5' 63 || v41[8] != 'b' 64 || v41[9] != '6' 65 || v41[10] != 'e' 66 || v41[11] != '2' 67 || v41[12] != '9' 68 || v41[13] != 'd' 69 || v41[14] != 'b' 70 || v41[15] != '0' 71 || v41[16] != '8' 72 || v41[17] != '9' 73 || v41[18] != '8' 74 || v41[19] != 'b' 75 || v41[20] != 'c' 76 || v41[21] != '4' 77 || v41[22] != 'f' 78 || v41[23] != '0' 79 || v41[24] != '2' 80 || v41[25] != '2' 81 || v41[26] != '5' 82 || v41[27] != '9' 83 || v41[28] != '3' 84 || v41[29] != '5' 85 || v41[30] != 'c' 86 || v41[31] != '0' ) 87 { 88 v23 = std::operator<<<std::char_traits<char>>(&std::cout, 'I'); 89 v24 = std::operator<<<std::char_traits<char>>(v23, 'n'); 90 v25 = std::operator<<<std::char_traits<char>>(v24, 'v'); 91 v26 = std::operator<<<std::char_traits<char>>(v25, 'a'); 92 v27 = std::operator<<<std::char_traits<char>>(v26, 'l'); 93 v28 = std::operator<<<std::char_traits<char>>(v27, 'i'); 94 v29 = std::operator<<<std::char_traits<char>>(v28, 'd'); 95 v30 = std::operator<<<std::char_traits<char>>(v29, ' '); 96 v31 = std::operator<<<std::char_traits<char>>(v30, 'K'); 97 v32 = std::operator<<<std::char_traits<char>>(v31, 'e'); 98 v33 = std::operator<<<std::char_traits<char>>(v32, 'y'); 99 v34 = std::operator<<<std::char_traits<char>>(v33, '!'); 100 v35 = std::operator<<<std::char_traits<char>>(v34, ' '); 101 v36 = std::operator<<<std::char_traits<char>>(v35, ':'); 102 v37 = std::operator<<<std::char_traits<char>>(v36, '('); 103 std::ostream::operator<<(v37, &std::endl<char,std::char_traits<char>>); 104 result = 0; 105 } 106 else 107 { 108 v3 = std::operator<<<std::char_traits<char>>(&std::cout, 'T'); 109 v4 = std::operator<<<std::char_traits<char>>(v3, 'h'); 110 v5 = std::operator<<<std::char_traits<char>>(v4, 'e'); 111 v6 = std::operator<<<std::char_traits<char>>(v5, ' '); 112 v7 = std::operator<<<std::char_traits<char>>(v6, 'k'); 113 v8 = std::operator<<<std::char_traits<char>>(v7, 'e'); 114 v9 = std::operator<<<std::char_traits<char>>(v8, 'y'); 115 v10 = std::operator<<<std::char_traits<char>>(v9, ' '); 116 v11 = std::operator<<<std::char_traits<char>>(v10, 'i'); 117 v12 = std::operator<<<std::char_traits<char>>(v11, 's'); 118 v13 = std::operator<<<std::char_traits<char>>(v12, ' '); 119 v14 = std::operator<<<std::char_traits<char>>(v13, 'v'); 120 v15 = std::operator<<<std::char_traits<char>>(v14, 'a'); 121 v16 = std::operator<<<std::char_traits<char>>(v15, 'l'); 122 v17 = std::operator<<<std::char_traits<char>>(v16, 'i'); 123 v18 = std::operator<<<std::char_traits<char>>(v17, 'd'); 124 v19 = std::operator<<<std::char_traits<char>>(v18, ' '); 125 v20 = std::operator<<<std::char_traits<char>>(v19, ':'); 126 v21 = std::operator<<<std::char_traits<char>>(v20, ')'); 127 std::ostream::operator<<(v21, &std::endl<char,std::char_traits<char>>); 128 result = 0; 129 } 130 return result; 131 }
3.代码分析
查看第50行代码,这是一个md5加密
在看第55~86行代码的字符,猜测应该也是md5加密
780438d5b6e29db0898bc4f0225935c0
将这串字符串解密,得到
主要可以看到字符串经过2次md5解密,因此我们可以猜测,我们输入的flag是grape的1次md5加密,经过第50行代码的md5再次加密,再与780438d5b6e29db0898bc4f0225935c0比较
将grape经过1次md5加密得到
b781cbb29054db12f88f08c6e161c199
4.get flag!
b781cbb29054db12f88f08c6e161c199