CTF逆向几题 pyre至room多题

文章讲述了如何处理.pyc文件的加密,通过Python反编译工具和加密算法解析,以及在ACTF比赛中遇到的tar文件和包含exe的壳的处理,包括脱壳和分析加密逻辑。涉及凯撒密码等加密技术的破解。
摘要由CSDN通过智能技术生成
1.pyre

我们下载发现文件的后缀是.pyc 而且用python打开后是一团乱码

这时候该怎么办呢 搜索到可以尝试用python反编译工具打开(使用网站就可)

代码如下:

print 'Welcome to Re World!'
print 'Your input1 is your flag~'
l = len(input1)
for i in range(l):
    num = ((input1[i] + i) % 128 + 128) % 128//对字符串的每一位进行加密而且确保在128内
    code += num
​
for i in range(l - 1):
    code[i] = code[i] ^ code[i + 1]//这个应该是前一位与后一位进行异或后赋值给前一位
​
print code
code = [
    '\x1f',
    '\x12',
    '\x1d',
    '(',
    '0',
    '4',
    '\x01',
    '\x06',
    '\x14',
    '4',
    ',',
    '\x1b',
    'U',
    '?',
    'o',
    '6',
    '*',
    ':',
    '\x01',
    'D',
    ';',
    '%',
    '\x13']

这段python代码中存在着一段小加密(按注释所写) 而且还给了加密后的code

写脚本回推一下(有点冗杂了)

code = [
    '\x1f',
    '\x12',
    '\x1d',
    '(',
    '0',
    '4',
    '\x01',
    '\x06',
    '\x14',
    '4',
    ',',
    '\x1b',
    'U',
    '?',
    'o',
    '6',
    '*',
    ':',
    '\x01',
    'D',
    ';',
    '%',
    '\x13']
l = len(code)
for i in range(l-2,-1,-1):
    code[i] = chr(ord(code[i]) ^ ord(code[i + 1]))
​
for i in range(l):
    print(chr((ord(code[i]) - i) % 128), end="")

得到flag

2.[ACTF新生赛2020]easyre

文件下载后是.tar后缀 不知道是什么 里面打开后则是两个exe 这是什么东西我也忘了

反正不影响我们做题 我们找到里面较大的文件 先查壳

是32位 还有一个upx的壳(之前介绍过用upx脱壳 这次用小辣椒脱壳)

脱壳完毕

这是脱了壳的伪代码

int __cdecl main(int argc, const char **argv, const char **envp)
{
  _BYTE v4[12]; // [esp+12h] [ebp-2Eh] BYREF
  _DWORD v5[3]; // [esp+1Eh] [ebp-22h]
  _BYTE v6[5]; // [esp+2Ah] [ebp-16h] BYREF
  int v7; // [esp+2Fh] [ebp-11h]
  int v8; // [esp+33h] [ebp-Dh]
  int v9; // [esp+37h] [ebp-9h]
  char v10; // [esp+3Bh] [ebp-5h]
  int i; // [esp+3Ch] [ebp-4h]
​
  __main();
  qmemcpy(v4, "*F'\"N,\"(I?+@", sizeof(v4));
  printf("Please input:");
  scanf("%s", v6);
  if ( v6[0] != 65 || v6[1] != 67 || v6[2] != 84 || v6[3] != 70 || v6[4] != 123 || v10 != 125 )//if判断ACT{} 很像flag的形式
    return 0;
  v5[0] = v7;
  v5[1] = v8;
  v5[2] = v9;//V7到v9就是ACTF{}括号中的内容
  for ( i = 0; i <= 11; ++i )//这个if判断可以判断出ACT{}括号里的值长度为12,而且v4=byte_402000[输入的数组的每一位值-1]
  {
    if ( v4[i] != _data_start__[*((char *)v5 + i) - 1] )//在_data_start__字符串中过一个字符再-1, 再与v4进行比较查看是否相等
      return 0;
  }
  printf("You are correct!");
  return 0;
}

一开始给我们定义了一个数组,v4=[42,70,39,34,78,44,34,40,73, 63, 43, 64],之后又让我们输入一个字符串,再经过两轮if判断,根据注释那看来再结合一下data_start__的值就可以写脚本了,思路就是把v4数组中的每个元素+1和data_start中的字符进行比较,相同则输出得到flag。

一定注意:这个7E也是其中的一部分 应该是由ida的过度编译导致的 7E后面的h是代表其由16进制输出形式 当然也可以直接shift+e提取

脚本如下

v4 = [42, 70, 39, 34, 78, 44, 34, 40, 73, 63, 43, 64]
flag = ''
__data_start__ = '~}|{zyxwvutsrqponmlkjihgfedcba`_^]\[ZYXWVUTSRQPONMLKJIHGFEDCBA@?>=<;:9876543210/.-,+*)(\'&%$# !"'//一开始忘记了27h
for i in v4:
    flag = flag + chr(__data_start__.find(chr(i)) + 1)
    print(flag)

得到flag

3.[ACTF]room

先查壳 发现是32位无壳

看字符串,找到了关键函数func(),伪代码如下

  v15 = 'Q';
  v16 = 's';
  v17 = 'w';
  v18 = '3';
  v19 = 's';
  v20 = 'j';
  v21 = '_';
  v22 = 'l';
  v23 = 'z';
  v24 = '4';
  v25 = '_';
  v26 = 'U';
  v27 = 'j';
  v28 = 'w';
  v29 = '@';
  v30 = 'l';
  v31 = '\0';
  printf("Please input:");
  scanf("%s", &v5);
  result = v5;
  if ( v5 == 65 )
  {
    result = v6;
    if ( v6 == 67 )
    {
      result = v7;
      if ( v7 == 84 )
      {
        result = v8;
        if ( v8 == 70 )
        {
          result = v9;
          if ( v9 == 123 )
          {
            result = v14;
            if ( v14 == 125 )
            {
              v1 = v10;
              v2 = v11;
              v3 = v12;
              v4 = v13;
              for ( i = 0; i <= 15; ++i )
              {
                if ( *((_BYTE *)&v1 + i) > 64 && *((_BYTE *)&v1 + i) <= 90 )// 大写字母
                  *((_BYTE *)&v1 + i) = (*((char *)&v1 + i) - 51) % 26 + 65;
                if ( *((_BYTE *)&v1 + i) > 96 && *((_BYTE *)&v1 + i) <= 122 )// 小写字母,按r查看即可
                  *((_BYTE *)&v1 + i) = (*((char *)&v1 + i) - 79) % 26 + 97;
              }
              for ( i = 0; i <= 15; ++i )
              {
                result = (unsigned __int8)*(&v15 + i);
                if ( *((_BYTE *)&v1 + i) != (_BYTE)result )
                  return result;
              }
              result = printf("You are correct!");
            }
          }
        }
      }
    }
  }
  return result;
}

程序就是让我们输入一个字符串,判断大小写然后再进行相应的运算,最后得到了程序开头的数组Qsw3sj_lz4_Ujw@

编写脚本得

x =[81,115,119,51,115,106,95,108,122,52,95,85,106,119,64,108]
flag = ''
for k in range(0,16):
    for i in range(0,127):  
        z = i
        if i > 64 and i <= 90:
            i = (i-51)%26 + 65
        if i > 96 and i <= 122:
            i = (i-79)%26 + 97
        if(i == x[k]):
            flag += chr(z)
​
print(flag)
​
​

得到flag为Cae3ar_th4_Gre@t(看样子和凯撒密码什么的有关系)

  • 35
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值