首页
社区
课程
招聘
[原创]2024长城杯初赛RE(部分题目)
发表于: 2024-9-12 00:23 4019

[原创]2024长城杯初赛RE(部分题目)

2024-9-12 00:23
4019

图片描述
有用的伪代码就这一段

看得出来关键加密就是for循环里的异或加密

简化一下就是:

根据这个if语句中的条件,确定来确定cipher

换言之,取input的32位进行对比,相同则正确,根据data2可以确定校验的后16位在data1中的位置,往前推16位即是校验的前16位

因此,正确的cipher为剩下的data1

图片描述

根据以上分析,可以将整个题简化为一个异或加密,结果与cipher对比

直接写个正面爆破即可完成:

exp

根据题目猜测它是T型迷宫

结果上网搜全是动物实验= =,

DIE查询可知是64位程序,进入ida分析 →

图片描述

初始并没有发现有什么引导输入的伪代码,开调!

if(v5 == 43)处下断点,调试可以发现终端并未让输入

这里可以确定程序是命令行传参

图片描述

在此输入再进行调试即可

图片描述

在下面的switch-case逻辑中,可以看出要求输入字符xyz

图片描述

可以看出v4是输入的path

分析这一段,do-while循环是在统计输入的字符串长度,检索到0结束

可以确定path的长度为42

这个语句,unk_7FF7D50D7000中是若干1和0组成的数组,猜测是构成迷宫的参数,dword_7FF7D50D7FA0是固定参数10

sub_7FF7D50A1230里是复杂的迷宫生成函数,对我来说难以分析我就先没管

图片描述

调试可以知道,data0、data1、data2分别存储了一个地址

根据最后的if判断语句和switch逻辑,可以知道data1指向的地址是会发生变化的

v7的地址就是data2存的地址

那么,可以分析出来,data1其实就是当前操作对应地址,最开始的的data1就是start_locdata2就是最后的地址end_loc

再但拿一个case来分析:

分析完可以得到:

图片描述

根据输入全跟地址相关,以及地址操作全在下半段

就可以考虑不管上半迷宫生成的逻辑

我们可以把1.3分析的内容全部理解为:获得start_locend_loc

idapython,把start_locend_loc的内容当作迷宫,根据switch-case的限制逻辑,利用深度搜索算法来输出符合条件的xyz,即path

参考文章:[原创]关于爆破迷宫路径的一系列思考-CTF对抗-看雪-安全社区|安全招聘|kanxue.com

CTF中迷宫题型的解题思路_ctf迷宫-CSDN博客

深度优先搜索(DFS) 总结(算法+剪枝+优化总结)-CSDN博客

用递归算法实现深度搜索

记录已经访问过的地址(相当于迷宫中已经走过的坐标)为all_visited_loc,来实现减少搜索量

图片描述

图片描述

Tips: xiran_encrypto是恶意样本分析,本质是从cha文件里解出一个数据流,clickme文件是chacha20对flag.png文件进行加密。对本人来说太难了,分析不出来QAQ,后续若能理解再来分享。

input = argv[1];
j = 1i64;
for ( i = 0i64; i != 43; ++i )
{
  input->m128i_i8[i] ^= input->m128i_u8[i + 1 + -42 * (j / 42)];
  ++j;
}
input = argv[1];
j = 1i64;
for ( i = 0i64; i != 43; ++i )
{
  input->m128i_i8[i] ^= input->m128i_u8[i + 1 + -42 * (j / 42)];
  ++j;
}
for(int i = 0; i < 43; ++i)
{
   input[i] ^= input[i + 1 - 42 * (i + 1 / 42)]
}
for(int i = 0; i < 43; ++i)
{
   input[i] ^= input[i + 1 - 42 * (i + 1 / 42)]
}
if (_mm_movemask_epi8(_mm_and_si128(_mm_cmpeq_epi8(_mm_loadu_si128(input), data1),
                                    _mm_cmpeq_epi8(_mm_loadu_si128(input + 1), data2))) == 0xFFFF)
 
data1 = [0x0A, 0x0D, 0x06, 0x1C, 0x1D, 0x05, 0x05, 0x5F, 0x0D, 0x03,
         0x04, 0x0A, 0x14, 0x49, 0x05, 0x57, 0x0A, 0x0D, 0x06, 0x1C,
         0x1D, 0x05, 0x05, 0x5F, 0x0D, 0x03, 0x04, 0x0A, 0x14, 0x49,
         0x05, 0x57, 0x00, 0x1B, 0x19, 0x02, 0x01, 0x54, 0x4E, 0x4C,
         0x56, 0x00, 0x51, 0x4B, 0x4F, 0x57, 0x05, 0x54, 0x55, 0x03,
         0x53, 0x57, 0x01, 0x03, 0x07, 0x04, 0x4A, 0x77, 0x0D]
 
data2 = [0x00, 0x1B, 0x19, 0x02, 0x01, 0x54, 0x4E, 0x4C, 0x56, 0x00,
         0x51, 0x4B, 0x4F, 0x57, 0x05, 0x54]
if (_mm_movemask_epi8(_mm_and_si128(_mm_cmpeq_epi8(_mm_loadu_si128(input), data1),
                                    _mm_cmpeq_epi8(_mm_loadu_si128(input + 1), data2))) == 0xFFFF)
 
data1 = [0x0A, 0x0D, 0x06, 0x1C, 0x1D, 0x05, 0x05, 0x5F, 0x0D, 0x03,
         0x04, 0x0A, 0x14, 0x49, 0x05, 0x57, 0x0A, 0x0D, 0x06, 0x1C,
         0x1D, 0x05, 0x05, 0x5F, 0x0D, 0x03, 0x04, 0x0A, 0x14, 0x49,
         0x05, 0x57, 0x00, 0x1B, 0x19, 0x02, 0x01, 0x54, 0x4E, 0x4C,
         0x56, 0x00, 0x51, 0x4B, 0x4F, 0x57, 0x05, 0x54, 0x55, 0x03,
         0x53, 0x57, 0x01, 0x03, 0x07, 0x04, 0x4A, 0x77, 0x0D]
 
data2 = [0x00, 0x1B, 0x19, 0x02, 0x01, 0x54, 0x4E, 0x4C, 0x56, 0x00,
         0x51, 0x4B, 0x4F, 0x57, 0x05, 0x54]
cipher = [
    0x0A, 0x0D, 0x06, 0x1C, 0x1D, 0x05, 0x05, 0x5F, 0x0D, 0x03, 0x04, 0x0A,
    0x14, 0x49, 0x05, 0x57, 0x00, 0x1B, 0x19, 0x02, 0x01, 0x54, 0x4E, 0x4C,
    0x56, 0x00, 0x51, 0x4B, 0x4F, 0x57, 0x05, 0x54, 0x55, 0x03, 0x53, 0x57,
    0x01, 0x03, 0x07, 0x04, 0x4A, 0x77, 0x0D
]
 
x = ord('f')
input = []
 
for i in range(len(cipher)):
    for num in range(32, 128):
        if x ^ num == cipher[i]:
            input.append(num)
            x = num
            break
 
flag = ''
for j in range(len(input)):
    flag += chr(input[j])
 
print('f' + flag)
 
# flag{fcf94739-da66-467c-a77f-b50d12a67437}
cipher = [
    0x0A, 0x0D, 0x06, 0x1C, 0x1D, 0x05, 0x05, 0x5F, 0x0D, 0x03, 0x04, 0x0A,
    0x14, 0x49, 0x05, 0x57, 0x00, 0x1B, 0x19, 0x02, 0x01, 0x54, 0x4E, 0x4C,
    0x56, 0x00, 0x51, 0x4B, 0x4F, 0x57, 0x05, 0x54, 0x55, 0x03, 0x53, 0x57,
    0x01, 0x03, 0x07, 0x04, 0x4A, 0x77, 0x0D
]
 
x = ord('f')
input = []
 
for i in range(len(cipher)):
    for num in range(32, 128):
        if x ^ num == cipher[i]:
            input.append(num)
            x = num
            break
 
flag = ''
for j in range(len(input)):
    flag += chr(input[j])
 
print('f' + flag)
 
# flag{fcf94739-da66-467c-a77f-b50d12a67437}
i = 0;
do
  j = i++;
while ( path[j] );
if ( i == 43 )
i = 0;
do
  j = i++;
while ( path[j] );
if ( i == 43 )
v7 = sub_7FF7D50A1230(&unk_7FF7D50D7000, dword_7FF7D50D7FA0, envp);
v7 = sub_7FF7D50A1230(&unk_7FF7D50D7000, dword_7FF7D50D7FA0, envp);
if ( argc != 1 )
    {
      m = *path == 0;
      if ( *path )
      {
        v14 = 1;
        v15 = data1;
        k = 0i64;
        do
        {
          chose = path[k];
          switch ( chose )
          {
            case 'z':
              v19 = *(v15 + 16);
              if ( !v19 || *(v15 + 26) )
                goto LABEL_12;
              break;
            case 'y':
              v19 = *(v15 + 8);
              if ( !v19 || *(v15 + 25) )
                goto LABEL_12;
              break;
            case 'x':
              v19 = *v15;
              if ( !*v15 || *(v15 + 24) )
                goto LABEL_12;
              break;
            default:
              goto LABEL_12;
          }
          data1 = v19;
          *(v19 + 27) = 1;
          k = v14;
          len = strlen(path);
          ++v14;
          v15 = v19;
          m = len <= k;
        }
        while ( !m );
      }
LABEL_12:
      if ( m && data1 == v7 )
      {
        v13 = sub_7FF7D50A1770(&qword_7FF7D50D92C0, "yes flag is flag{UUID(md5(your input))}");
        sub_7FF7D50A1B70(v13);
      }
if ( argc != 1 )
    {
      m = *path == 0;
      if ( *path )
      {
        v14 = 1;
        v15 = data1;
        k = 0i64;
        do
        {
          chose = path[k];

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

上传的附件:
收藏
免费 2
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//