BUUCTF Reverse 逆向方向 9-16题 详解wp

目录

不一样的flag_迷宫

SimpleRev_小端序

Java逆向解密

luck_guy

JustRE

刮开有奖_特殊加密

简单注册器

pyre


觉得这篇文章不错的话就收藏、点赞、评论、关注我吧~

相关推荐:

1-8题详解博客 看这里→ BUUCTF逆向1-8题wp

逆向工具下载  点这里→ 爱盘 - 在线破解工具包

逆向入门博客  看这里→ 逆向入门规划

不一样的flag_迷宫

BUUCTF Reverse 逆向方向 9-16题 详解wp_第1张图片

分析代码

11:给出字符长度为25的字符串

14-19:打印提示信息。由此可知字符为迷宫,25个字符可以构造成边长为5的字符迷宫

20-48:完善程序逻辑,可不用分析

49-56:按r键将数字转换为字符,可知在此迷宫中,移动到“1”处会中断游戏,移动到“#”处则通关游戏,同时可知其他字符时可为通关路径

BUUCTF Reverse 逆向方向 9-16题 详解wp_第2张图片

根据所给字符进行换行排列,构成迷宫,移动路径如下:

*1111
01000
01010
00010
1111#

下下下右右上上右右下下下

即为:222441144222。此为flag

SimpleRev_小端序

此文件为elf文件,是小端序存储(wlf文件一般无后缀名)

BUUCTF Reverse 逆向方向 9-16题 详解wp_第3张图片

小端序存储时的字符串需要逆序:

当早已存储在变量中,或代码中的函数中,此时无需逆序;

当对声明的变量赋值,且为小端序时,需要逆序(如下方代码情况)

分析代码,每行函数及变量处理结果见注释中标识。有字符串变量key、text,以及输入字符串变量v1经过处理最终存入str2中。即v1与key相运算后存入str2中,将str2与text对比相同即为正确输入,而其中所需要输入的v1即为flag。

BUUCTF Reverse 逆向方向 9-16题 详解wp_第4张图片

编写程序爆破出flag。通过for循环遍历ASCII码与key运算,将每次处理后的值与text的字符逐个对比,相同后则输出字符串,即可得到flag的值

#include 
int main()
{
    char text[10] = "killshadow";
    char  key[10] = "adsfkndcls";
    int v3 = 10;
    int v5 = 10;
    int i, j;
    for (i = 0; i < 10; i++)
    {
        for (j = 0; j < 128; j++)
        {
            if (j <= '`' || j > 'z')
            {
                if (j > '@' && j <= 'Z')
                {
                    if ((j - 39 - key[v3 % v5] + 97) % 26 + 97 == text[i])
                    {
                        printf("%c", j);
                        v3++;
                        break;
                    }
                }
            }
            else
                if ((j - 39 - key[v3 % v5] + 97) % 26 + 97 == text[i])
                {
                    printf("%c", j);
                    v3++;
                    break;
                }
        }
    }
}

KLDQCUDFZO

Java逆向解密

使用recaf工具打开

BUUCTF Reverse 逆向方向 9-16题 详解wp_第5张图片

编写脚本

KEY = [180, 136, 137, 147, 191, 137, 147, 191, 148,
       136, 133, 191, 134, 140, 129, 135, 191, 65]
s = ""
for i in range(len(KEY)):
    s += chr(KEY[i] - 64 ^ 0x20)
print(s)

luck_guy

分析代码

BUUCTF Reverse 逆向方向 9-16题 详解wp_第6张图片

10-14行是先获取时间戳,然后获得随机数,这是伪随机,与flag处理代码关联不大

代码主要内容为处理字符串,可以推测出,主要步骤顺序是:

case 4:将待处理的字符串初始化

case 5:处理相应的字符串

case 1:输出已知字符串f1与处理后的f2即为flag

编写程序

方法一:用python写

f1 = "GXY{do_not_"
f2 = "icug`of\x7F"
f2 = list(f2)
for j in range(8):
    if ( j % 2 == 1 ):
        f2[j] = chr(ord(f2[j]) - 2 )
    else:
        f2[j] = chr(ord(f2[j]) - 1 )
f2 = ''.join(f2)
print(f1,f2)

方法二:用C写

#include 
int main()
{
    char f1[] = "GXY{do_not_";
    char f2[] = "icug`of\x7F";
    int j;
    for (j = 0; j <= 7; ++j)
    {
        if (j % 2 == 1)
            f2[j] -= 2;
        else
            --f2[j];
    }
    printf("%s%s",f1,f2);
}

GXY{do_not_hate_me}

JustRE

不言而喻

BUUCTF Reverse 逆向方向 9-16题 详解wp_第7张图片

刮开有奖_特殊加密

分析代码

BUUCTF Reverse 逆向方向 9-16题 详解wp_第8张图片

首先输入字符串string

首先使用sub_4010F0对10个字节的字符进行加密(由于这10字节大小的变量连续存储存储,所以只需以第一个变量v7为操作数即可)-> v7~v16

分两次获取v18。

第一次v18被string索引为5、6、7的字符分别赋值,最终被sub_40100加密后传给v4。第二次v18被string索引为2,、3、4的字符分别赋值,最终被sub_40100加密后传给v5。

点击sub_40100函数可以推测为base64加密(Base64编码使用了一个由64个字符组成的字符集,通常包括A-Z、a-z、0-9和+/。这些字符被赋予了对应的数值,用于表示字节的值。 Base64编码字符串的长度不为4的倍数,需要使用=填充。

随后进入if判断语句,与输入字段进行对比。

前三个字符与加密的字符相关,加密后进行相关运算即可(运算脚本建议使用C语言编写,因为对于ASCII码运算更方便,Python需要使用函数)。

后六个字符串为base64加密后的,两组分别解密即可。

sub_4010F0未知加密方式,但可根据点开的伪代码编写C语言脚本

int占四个字节,所以伪代码有 i*4,转换C语言代码可以视为是i

#include 
int  sub_4010F0(char* a1, int a2, int a3)
{
    int result; // eax
    int i; // esi
    int v5; // ecx
    int v6; // edx
    result = a3;
    for ( i = a2; i <= a3; a2 = i )
  {
      v5 = i;
      v6 = i[a1];
      if ( a2 < result && i < result )
    {
        do
      {
          if ( v6 > a1[result]) 
        {
            if ( i >= result )
              break;
            ++i;
            a1[v5] = a1[result];
            if ( i >= result )
              break;
            while ( a1[i] <= v6 )
          {
              if ( ++i >= result )
                goto LABEL_13;
          }
            if ( i >= result )
              break;
            v5 = i;
            a1[result] = a1[i];
        }
          --result;
      }
        while ( i < result );
    }
      LABEL_13:
      a1[result] = v6 ;
      sub_4010F0(a1, a2, i - 1);
      result = a3;
      ++i;
  }
    return result;
}
int main()
{
    char str[] = "ZJSECaNH3ng";
    sub_4010F0(str,0,10);
    printf("%s", str);
    return 0;
}

简单注册器

使用jadx打开apk文件,分析源码

flag为处理后的bbb字符串

BUUCTF Reverse 逆向方向 9-16题 详解wp_第9张图片

截取源码在java环境中运行,得到flag

public class test {
public static void main(String[] args){
	char[] x = "dd2940c04462b4dd7c450528835cca15".toCharArray();
    x[2] = (char) ((x[2] + x[3]) - 50);
    x[4] = (char) ((x[2] + x[5]) - 48);
    x[30] = (char) ((x[31] + x[9]) - 48);
    x[14] = (char) ((x[27] + x[28]) - 97);
    for (int i = 0; i < 16; i++) {
        char a = x[31 - i];
        x[31 - i] = x[i];
        x[i] = a;
    }
    String bbb = String.valueOf(x);
    System.out.print(bbb);
    }
}

59acc538825054c7de4b26440c0999dd

pyre

可以在在线网站反编译pyc文件为py文件:pyc反编译

也可以使用(python3.8) uncompyle6 库 工具:

pip3 install uncompyle6 -i https://pypi.tuna.tsinghua.edu.cn/simple
uncompyle6 -o attachment.py attachment.pyc

分析代码

BUUCTF Reverse 逆向方向 9-16题 详解wp_第10张图片

源代码通过逐字符遍历,使用先加法后取余的方式做了第一次加密,又通过逐字符遍历,使用顺序相邻异或运算的方式做了第二次加密。

编写脚本

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

首先对第二次加密进行解密,因为两次异或运算等于本身,所以解密是对code语句进行一次逆序异或运算,这里注意索引范围(索引i最大为lenth-1,但是运算的方程中需要引用i+1,所以索引i最大需变为为lenth-2)。

然后再对第二次加密进行解密,直接将其中的加号换为减号即可(此处还对反编译中的冗余部分做了化简)。最终运行代码,即可得到flag。

GWHT{Just_Re_1s_Ha66y!}

你可能感兴趣的:(CTF_Reverse,网络安全,安全,学习方法,经验分享,系统安全,笔记)