zoukankan      html  css  js  c++  java
  • 攻防世界--hackme

    测试链接:https://adworld.xctf.org.cn/media/task/attachments/33009710e3f44f04b5a4cdbaaa46f00a

    1.准备

    获取信息

    • 64位文件

    2.IDA打开

    __int64 __fastcall sub_400F8E(__int64 a1, __int64 a2)
    {
      char v3[136]; // [rsp+10h] [rbp-B0h]
      int v4; // [rsp+98h] [rbp-28h]
      char v5; // [rsp+9Fh] [rbp-21h]
      int v6; // [rsp+A0h] [rbp-20h]
      unsigned __int8 v7; // [rsp+A6h] [rbp-1Ah]
      char v8; // [rsp+A7h] [rbp-19h]
      int v9; // [rsp+A8h] [rbp-18h]
      int v10; // [rsp+ACh] [rbp-14h]
      int v11; // [rsp+B0h] [rbp-10h]
      int v12; // [rsp+B4h] [rbp-Ch]
      _BOOL4 v13; // [rsp+B8h] [rbp-8h]
      int i; // [rsp+BCh] [rbp-4h]
    
      sub_407470((__int64)"Give me the password: ", a2);
      sub_4075A0((__int64)"%s", v3);
      for ( i = 0; v3[i]; ++i )
        ;
      v13 = i == 22;
      v12 = 10;
      do
      {
        v9 = (signed int)sub_406D90("%s", v3) % 22;
        v11 = 0;
        v8 = byte_6B4270[v9];
        v7 = v3[v9];
        v6 = v9 + 1;
        v10 = 0;
        while ( v10 < v6 )
        {
          ++v10;
          v11 = 1828812941 * v11 + 12345;
        }
        v5 = v11 ^ v7;
        if ( v8 != ((unsigned __int8)v11 ^ v7) )
          v13 = 0;
        --v12;
      }
      while ( v12 );
      if ( v13 )
        v4 = sub_407470((__int64)"Congras
    ");
      else
        v4 = sub_407470((__int64)"Oh no!
    ");
      return 0LL;
    }

    3.代码分析

    这道题主要是sub_406D90函数,对于第33行代码,我们能够知道v9是0~21的整数,在这道题中,v9的在循环当中值的顺序不会影响判断,因为v9用到的地方就两个,一个在已知数组byte_6B4270和输入字符串v3的取值中,另一个在v11的循环中,因为v11最终影响的是v11^v7!=v8,又因为v7和v3[v9]有关,v8和byte_6B4270[v9]有关,因此v11,byte_6B4270[v9]和v3[v9]都应该是固定的对应关系。
    我们只需要让v9的值小于22即可,通过观察byte_6B4270,我们知道byte_6B4270数组实际长度应该就是22,又通过观察第36行代码,我们能够知道这道题实际就是取10位输入的字符,异或后,与byte_6B4270比较是否相同。
    我们只需要逆向操作就行。

    4.脚本解密

    index = [0x5F,0xF2,0x5E,0x8B,0x4E,0x0E,0xA3,0xAA,0xC7,0x93,0x81,0x3D,0x5F,0x74,0xA3,0x09,
    0x91,0x2B,0x49,0x28,0x93,0x67]
    
    flag = ''
    
    for i in range(22):
        v6 = i + 1
        v10 = 0
        v11 = 0
        while v10 < v6:
            v10 = v10 + 1
            v11 = 1828812941 * v11 + 12345
        flag += chr((index[i]^v11)&0xff)
    print (flag)
    #include <iostream>
    
    #pragma warning(disable:4996)
    using namespace std;
    
    int main()
    {
        int index[] = { 0x5F,0xF2,0x5E,0x8B,0x4E,0x0E,0xA3,0xAA,0xC7,0x93,0x81,0x3D,0x5F,0x74,0xA3,0x09,
    0x91,0x2B,0x49,0x28,0x93,0x67 };
    
        for (int i = 0; i < 22; ++i) {
            int v6 = i + 1;
            int v10 = 0;
            int v11 = 0;
            while (v10 < v6) {
                v10++;
                v11 = 1828812941 * v11 + 12345;
            }
            printf("%c", index[i] ^ v11);
        }
    
        system("PAUSE");
        return 0;
    }

    5.get flag!

    flag{d826e6926098ef46}

  • 相关阅读:
    前端工程部署
    xcode使用入门
    effective java
    java测试用例的编写
    记录一次随意操作数据库,插入新数据,导致与程序添加新数据时,引起的主键值重复问题。More than one row with the given identifier was found: 1690
    Spring.Net中的依赖注入(DI)
    记一次使用js中的this关键字在ajax中使用,因传入的this对象不同而引起的问题。
    代理模式
    异常: 指定的转换无效
    log4net.config配置启用的几种方式
  • 原文地址:https://www.cnblogs.com/Mayfly-nymph/p/12208043.html
Copyright © 2011-2022 走看看