【攻防世界】Reverse—— dmd-50 writeup

int __cdecl main(int argc, const char **argv, const char **envp)
{
  __int64 v3; // rax
  __int64 v4; // rax
  __int64 v5; // rax
  __int64 v6; // rax
  __int64 v7; // rax
  __int64 v8; // rax
  __int64 v9; // rax
  __int64 v10; // rax
  __int64 v11; // rax
  __int64 v12; // rax
  __int64 v13; // rax
  __int64 v14; // rax
  __int64 v15; // rax
  __int64 v16; // rax
  __int64 v17; // rax
  __int64 v18; // rax
  __int64 v19; // rax
  __int64 v20; // rax
  __int64 v21; // rax
  int result; // eax
  __int64 v23; // rax
  __int64 v24; // rax
  __int64 v25; // rax
  __int64 v26; // rax
  __int64 v27; // rax
  __int64 v28; // rax
  __int64 v29; // rax
  __int64 v30; // rax
  __int64 v31; // rax
  __int64 v32; // rax
  __int64 v33; // rax
  __int64 v34; // rax
  __int64 v35; // rax
  __int64 v36; // rax
  __int64 v37; // rax
  char v38; // [rsp+Fh] [rbp-71h] BYREF
  char v39[16]; // [rsp+10h] [rbp-70h] BYREF
  char v40[8]; // [rsp+20h] [rbp-60h] BYREF
  __int64 v41; // [rsp+28h] [rbp-58h]
  char v42[56]; // [rsp+30h] [rbp-50h] BYREF
  unsigned __int64 v43; // [rsp+68h] [rbp-18h]

  v43 = __readfsqword(0x28u);
  std::operator<<<std::char_traits<char>>(&std::cout, "Enter the valid key!\n", envp);
  std::operator>><char,std::char_traits<char>>(&edata, v42);
  std::allocator<char>::allocator(&v38);
  std::string::string(v39, v42, &v38);
  md5(v40, v39);
  v41 = std::string::c_str((std::string *)v40);
  std::string::~string((std::string *)v40);
  std::string::~string((std::string *)v39);
  std::allocator<char>::~allocator(&v38);
  if ( *(_WORD *)v41 == 14391
    && *(_BYTE *)(v41 + 2) == 48
    && *(_BYTE *)(v41 + 3) == 52
    && *(_BYTE *)(v41 + 4) == 51
    && *(_BYTE *)(v41 + 5) == 56
    && *(_BYTE *)(v41 + 6) == 100
    && *(_BYTE *)(v41 + 7) == 53
    && *(_BYTE *)(v41 + 8) == 98
    && *(_BYTE *)(v41 + 9) == 54
    && *(_BYTE *)(v41 + 10) == 101
    && *(_BYTE *)(v41 + 11) == 50
    && *(_BYTE *)(v41 + 12) == 57
    && *(_BYTE *)(v41 + 13) == 100
    && *(_BYTE *)(v41 + 14) == 98
    && *(_BYTE *)(v41 + 15) == 48
    && *(_BYTE *)(v41 + 16) == 56
    && *(_BYTE *)(v41 + 17) == 57
    && *(_BYTE *)(v41 + 18) == 56
    && *(_BYTE *)(v41 + 19) == 98
    && *(_BYTE *)(v41 + 20) == 99
    && *(_BYTE *)(v41 + 21) == 52
    && *(_BYTE *)(v41 + 22) == 102
    && *(_BYTE *)(v41 + 23) == 48
    && *(_BYTE *)(v41 + 24) == 50
    && *(_BYTE *)(v41 + 25) == 50
    && *(_BYTE *)(v41 + 26) == 53
    && *(_BYTE *)(v41 + 27) == 57
    && *(_BYTE *)(v41 + 28) == 51
    && *(_BYTE *)(v41 + 29) == 53
    && *(_BYTE *)(v41 + 30) == 99
    && *(_BYTE *)(v41 + 31) == 48 )
  {
    v3 = std::operator<<<std::char_traits<char>>(&std::cout, 84LL);
    v4 = std::operator<<<std::char_traits<char>>(v3, 104LL);
    v5 = std::operator<<<std::char_traits<char>>(v4, 101LL);
    v6 = std::operator<<<std::char_traits<char>>(v5, 32LL);
    v7 = std::operator<<<std::char_traits<char>>(v6, 107LL);
    v8 = std::operator<<<std::char_traits<char>>(v7, 101LL);
    v9 = std::operator<<<std::char_traits<char>>(v8, 121LL);
    v10 = std::operator<<<std::char_traits<char>>(v9, 32LL);
    v11 = std::operator<<<std::char_traits<char>>(v10, 105LL);
    v12 = std::operator<<<std::char_traits<char>>(v11, 115LL);
    v13 = std::operator<<<std::char_traits<char>>(v12, 32LL);
    v14 = std::operator<<<std::char_traits<char>>(v13, 118LL);
    v15 = std::operator<<<std::char_traits<char>>(v14, 97LL);
    v16 = std::operator<<<std::char_traits<char>>(v15, 108LL);
    v17 = std::operator<<<std::char_traits<char>>(v16, 105LL);
    v18 = std::operator<<<std::char_traits<char>>(v17, 100LL);
    v19 = std::operator<<<std::char_traits<char>>(v18, 32LL);
    v20 = std::operator<<<std::char_traits<char>>(v19, 58LL);
    v21 = std::operator<<<std::char_traits<char>>(v20, 41LL);
    std::ostream::operator<<(v21, &std::endl<char,std::char_traits<char>>);
    result = 0;
  }
  else
  {
    v23 = std::operator<<<std::char_traits<char>>(&std::cout, 73LL);
    v24 = std::operator<<<std::char_traits<char>>(v23, 110LL);
    v25 = std::operator<<<std::char_traits<char>>(v24, 118LL);
    v26 = std::operator<<<std::char_traits<char>>(v25, 97LL);
    v27 = std::operator<<<std::char_traits<char>>(v26, 108LL);
    v28 = std::operator<<<std::char_traits<char>>(v27, 105LL);
    v29 = std::operator<<<std::char_traits<char>>(v28, 100LL);
    v30 = std::operator<<<std::char_traits<char>>(v29, 32LL);
    v31 = std::operator<<<std::char_traits<char>>(v30, 75LL);
    v32 = std::operator<<<std::char_traits<char>>(v31, 101LL);
    v33 = std::operator<<<std::char_traits<char>>(v32, 121LL);
    v34 = std::operator<<<std::char_traits<char>>(v33, 33LL);
    v35 = std::operator<<<std::char_traits<char>>(v34, 32LL);
    v36 = std::operator<<<std::char_traits<char>>(v35, 58LL);
    v37 = std::operator<<<std::char_traits<char>>(v36, 40LL);
    std::ostream::operator<<(v37, &std::endl<char,std::char_traits<char>>);
    result = 0;
  }
  return result;
}

其功能是接收用户输入的一个密钥(key),并对该密钥进行MD5哈希计算。然后,程序将检查生成的哈希值是否等于预设的固定哈希值。

  1. 首先,程序提示用户输入一个有效的密钥。

  2. 接着,读取用户输入的密钥并存储在v42缓冲区中。

  3. 使用md5(v40, v39)函数对密钥进行MD5哈希运算,并将结果存储在v40指向的内存区域。

  4. 然后获取哈希值的C字符串表示形式,存放在变量v41指向的位置。

  5. 对于这个MD5哈希值进行一系列字节级别的比较,以验证它是否与预设的固定哈希值相匹配。这个固定的哈希值为:‘780438d5b6e29db089bc4f0225935c0’

    如果用户输入的密钥经过MD5哈希后的值与预设的哈希值匹配,则输出 "Thank you! The key is valid." 并返回0作为程序退出状态码。

    若不匹配,则输出 "Invalid key!" 并同样返回0作为退出状态码。

通过在线网站进行md5解密

grape是两次解密的结果,而程序中只有一次加密,所以flag是grape的一次md5加密后的值:

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值