• JCTF 2014 小菜两碟


    测试文件:https://static2.ichunqiu.com/icq/resources/fileupload//CTF/JCTF2014/re200

    参考文章:https://blog.csdn.net/chenlycly/article/details/53378196

    1.程序分析

    检测时发现不是PE文件,但是打开16进制却发现了MZ标识,因此我们能够判断文件中存在错误。

    1.1 第一处错误

    通过观察,发现指向PE文件头的地址为E9,但是实际的地址却是E8。

    1.2 第二处错误

    将地址修改正确之后,在010Editor打开文件,导入EXE模板

    可以看到,正确的PE文件标识应该是0x00004550,但是文件中是0x00FF4550,修改FF为00

    将修改后的文件保存为EXE文件

    2.IDA打开

    定位到main函数

      1 __int64 __cdecl main_0()
      2 {
      3   int v0; // eax
      4   __int64 v1; // rax
      5   int v2; // eax
      6   int v3; // ST08_4
      7   int v4; // eax
      8   int v5; // eax
      9   int v6; // eax
     10   int v7; // eax
     11   int v8; // eax
     12   int v9; // eax
     13   int v11; // [esp-10h] [ebp-170h]
     14   int v12; // [esp-Ch] [ebp-16Ch]
     15   char *v13; // [esp-8h] [ebp-168h]
     16   int v14; // [esp-4h] [ebp-164h]
     17   int *v15; // [esp+Ch] [ebp-154h]
     18   int k; // [esp+D4h] [ebp-8Ch]
     19   int j; // [esp+E0h] [ebp-80h]
     20   int i; // [esp+ECh] [ebp-74h]
     21   char v19; // [esp+FBh] [ebp-65h]
     22   int v20; // [esp+104h] [ebp-5Ch]
     23   int Dst; // [esp+108h] [ebp-58h]
     24   int v22; // [esp+10Ch] [ebp-54h]
     25   int v23; // [esp+110h] [ebp-50h]
     26   int v24; // [esp+114h] [ebp-4Ch]
     27   int v25; // [esp+118h] [ebp-48h]
     28   char Str1; // [esp+14Ch] [ebp-14h]
     29   int v27; // [esp+14Dh] [ebp-13h]
     30   int v28; // [esp+151h] [ebp-Fh]
     31   char v29; // [esp+155h] [ebp-Bh]
     32 
     33   v0 = sub_411154(std::cout, "欢迎来到数字游戏 请输入9个数字");
     34   std::basic_ostream<char,std::char_traits<char>>::operator<<(v0, std::endl);
     35   Str1 = 0;
     36   v27 = 0;
     37   v28 = 0;
     38   v29 = 0;
     39   v20 = 0;
     40   j_memset(&Dst, 0, 0x3Cu);
     41   for ( i = 0; i < 9; ++i )
     42     std::basic_istream<char,std::char_traits<char>>::operator>>(std::cin, &v20 + i);// v20中输入9个数字
     43   if ( v22 * Dst * v20 / 11 != 106 )            // 需要满足条件1
     44     goto LABEL_31;
     45   if ( (Dst ^ v20) != v22 - 4 )                 // 需要满足条件2
     46     goto LABEL_31;
     47   HIDWORD(v1) = (v22 + Dst + v20) % 100;        // v1的计算表达式,反向推倒,需要满足条件3
     48   if ( HIDWORD(v1) != 34 )                      // v1 = 34
     49     goto LABEL_31;
     50   if ( v23 == 80 )                              // v23=80
     51   {
     52     for ( j = 0; j < 3; ++j )
     53     {
     54       HIDWORD(v1) = (j + 1) % 3;
     55       for ( *(&Str1 + j) = *((_BYTE *)&v20 + 4 * HIDWORD(v1)) + *(&v20 + j % 3); ; *(&Str1 + j) /= 2 )
     56       {
     57         while ( *(&Str1 + j) < 33 )
     58         {
     59           HIDWORD(v1) = j;
     60           *(&Str1 + j) *= 2;
     61         }
     62         if ( *(&Str1 + j) <= 126 )
     63           break;
     64         v1 = *(&Str1 + j);
     65       }
     66     }
     67     if ( v24 == 94 && v25 == 98 )               // v24=94,v25=98
     68     {
     69       for ( k = 3; k < 9; ++k )
     70       {
     71         for ( *(&Str1 + k) = *(&Str1 + (k + 1) % 3) + *(&Str1 + k % 3); ; *(&Str1 + k) /= 2 )
     72         {
     73           while ( *(&Str1 + k) < 33 )
     74             *(&Str1 + k) *= 2;
     75           if ( *(&Str1 + k) <= 126 )
     76             break;
     77         }
     78       }
     79       if ( !j_strcmp(&Str1, "*&8P^bP^b") )
     80       {
     81         v2 = sub_411154(std::cout, "success!");
     82         std::basic_ostream<char,std::char_traits<char>>::operator<<(v2, std::endl);
     83         v14 = std::endl;                        // 换行
     84         v13 = "abc}";
     85         v12 = v22;
     86         v11 = Dst;
     87         v3 = v20;
     88         v15 = &v11;
     89         v4 = sub_411154(std::cout, "jlflag{");
     90         v5 = std::basic_ostream<char,std::char_traits<char>>::operator<<(v4, v3);
     91         v6 = std::basic_ostream<char,std::char_traits<char>>::operator<<(v5, v11);
     92         v7 = std::basic_ostream<char,std::char_traits<char>>::operator<<(v6, v12);
     93         v8 = sub_411154(v7, v13);
     94         std::basic_ostream<char,std::char_traits<char>>::operator<<(v8, v14);// 以上输出的组合为v4 v3 v11 v12 v13 v14
     95         sub_4112D0(std::cin, &v19);
     96         goto LABEL_32;
     97       }
     98 LABEL_31:
     99       v9 = sub_411154(std::cout, "please try again!");
    100       std::basic_ostream<char,std::char_traits<char>>::operator<<(v9, std::endl);
    101       goto LABEL_32;
    102     }
    103   }
    104 LABEL_32:
    105   v14 = HIDWORD(v1);
    106   v13 = 0;
    107   return *(_QWORD *)&v13;
    108 }

    2.1 代码分析

    通过第90~94行代码,我们知道正确的flag为组合[v4 v3 v11 v12 v13 v14],其中v4="jlflag{",v13="abc}",v14=std::endl

    因此我们只需要求出v3,v11,v12即可,通过第85~87行代码,我们知道v12 = v22;v11 = Dst;v3 = v20;

    我们能够通过这三个变量满足的三个表示,求出三个数的值。

    3.脚本获取

    for v22 in range(100):
        for dst in range(100):
            for v20 in range(100):
                if v22*dst*v20//11 == 106 and (v22 + dst + v20) % 100 == 34:
                    if (dst^v20) == v22 - 4:
                        if (v22 + dst + v20) % 100 == 34:
                            print("jlflag{%d%d%dabc}"%(v22, dst, v20), end='
    ')

    jlflag{61315abc}
    jlflag{61513abc}
    jlflag{13615abc}
    jlflag{13156abc}
    jlflag{15613abc}
    jlflag{15136abc}

    将这6组得到的flag一组一组试,就能得到正确flag。(记得去掉jl

    4.get flag!

    flag{15613abc}

  • 相关阅读:
    HDU 1086 You can Solve a Geometry Problem too(水题,判断线段相交)
    2011ACM福州网络赛第一题 A Card Game(水题)
    Lottery hdu1099
    卡特兰数 ACM 数论
    (转)CXF的Exception问题
    简单PS合成图像(抹去某个人等)
    摄影技巧
    PS中文字变形
    螺旋阵(递归和非递归)
    路径与滤镜和自定义工具
  • 原文地址:https://www.cnblogs.com/Mayfly-nymph/p/11679173.html
Copyright © 2020-2023  润新知