buuctf - re 刷题记录 1-18

buuctf - re 刷题记录

  • buuctf - re 刷题记录
    • 1、easyre
    • 2、reverse1
    • 4、内涵的软件
    • 5、新年快乐
    • 6、xor
    • 7、helloword
    • 8、reverse3
    • 9、不一样的flag
    • 10、SimpleRev
    • 11、Java逆向解密
    • 12、[GXYCTF2019]luck_guy
    • 14、findit
    • 15、[BJDCTF2020]JustRE
    • 16、简单注册器
    • 17、[GWCTF 2019]pyre
    • 18、[ACTF新生赛2020]easyre

1、easyre

shift+f12

image-20211029182134187

2、reverse1

buuctf - re 刷题记录 1-18_第1张图片

双击跟进str2

image-20211029183222147

24行到25行 o替换为0,flag{hell0_w0rld},虽然很简单还是写写程序多熟练

程序如下:

c语言:

buuctf - re 刷题记录 1-18_第2张图片

python:

buuctf - re 刷题记录 1-18_第3张图片## 3、reverse2

buuctf - re 刷题记录 1-18_第4张图片

简单查看下字符,疑似后半段flag,跟进对应字符查看

关键代码:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oNfwtff8-1635742416948)(C:\Users\86177\AppData\Roaming\Typora\typora-user-images\image-20211029190456094.png)]

跟进flag

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lcjGyqS5-1635742416950)(C:\Users\86177\AppData\Roaming\Typora\typora-user-images\image-20211029190749227.png)]

看代码应该也是替换字符

模仿反编译的代码写下程序

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-swsQGaV1-1635742416952)(C:\Users\86177\AppData\Roaming\Typora\typora-user-images\image-20211029191358828.png)]

这两题都是简单的替换,只是程序一个是windows的exe,另一个是linux的可执行文件

python代码更简单,可以多学习学习,方便很多

str="hacking_for_fun}"

str2=str.replace("i","1")
print("flag{"+(str2.replace("r","1"))) #str.replace(old, new[, max])

4、内涵的软件

动态调试一下

buuctf - re 刷题记录 1-18_第5张图片

但是其实这里就是输出的时候没有引入参数,值开始就已经给出了

buuctf - re 刷题记录 1-18_第6张图片

5、新年快乐

查壳 upx

buuctf - re 刷题记录 1-18_第7张图片

直接ida分析的话是打不开的,upx是压缩壳,程序基本上都被压缩加密的
脱壳

buuctf - re 刷题记录 1-18_第8张图片

主函数

buuctf - re 刷题记录 1-18_第9张图片

flag就是flag{HappyNewYear!}

6、xor

定位到关键代码

buuctf - re 刷题记录 1-18_第10张图片

找到数据

shift +E 导出数据

unsigned char ida_chars[] =
{
0x66, 0x0A, 0x6B, 0x0C, 0x77, 0x26, 0x4F, 0x2E, 0x40, 0x11,
0x78, 0x0D, 0x5A, 0x3B, 0x55, 0x11, 0x70, 0x19, 0x46, 0x1F,
0x76, 0x22, 0x4D, 0x23, 0x44, 0x0E, 0x67, 0x06, 0x68, 0x0F,
0x47, 0x32, 0x4F, 0x00
};

与前一位异或

data = [0x66, 0x0A, 0x6B, 0x0C, 0x77, 0x26, 0x4F, 0x2E, 0x40, 0x11,
        0x78, 0x0D, 0x5A, 0x3B, 0x55, 0x11, 0x70, 0x19, 0x46, 0x1F,
        0x76, 0x22, 0x4D, 0x23, 0x44, 0x0E, 0x67, 0x06, 0x68, 0x0F,
        0x47, 0x32, 0x4F, 0x00]
flag = chr(data[0])
for i in range(len(data)):
    flag += chr(data[i]^data[i-1])

print(flag)

7、helloword

解压,反编译dex文件

main函数直接找到

buuctf - re 刷题记录 1-18_第11张图片

8、reverse3

buuctf - re 刷题记录 1-18_第12张图片

无壳,32位 ,ida分析,简单看一眼字符,很可能是base64的简单加密

buuctf - re 刷题记录 1-18_第13张图片

定位到主函数

buuctf - re 刷题记录 1-18_第14张图片

可以适当修改来增加代码的可读性

输入的字符经过一个过程与str2比较,找到str2:e3nifIH9b_C@n@dH

24行经历了一个变换

在这里插入图片描述

定位到这个加密函数

buuctf - re 刷题记录 1-18_第15张图片

代码也看不懂,但是开头查看字符那里,有点像是base64加密

继续跟进一下

buuctf - re 刷题记录 1-18_第16张图片

大概率是base64了

str2 还经过了28行这里的移位,先还原回来,再进行解密即可,直接解密base64也是解不了的,@这种字符解不了

解密脚本

import base64
str = "e3nifIH9b_C@n@dH"

flag =''
for i in range(len(str)):
    flag+=chr(ord(str[i])-i)

data = base64.b64decode(flag)
print(data)

#b'{i_l0ve_you}'

9、不一样的flag

定位到关键代码

buuctf - re 刷题记录 1-18_第17张图片

buuctf - re 刷题记录 1-18_第18张图片

大概率是个迷宫题

从下面这段代码可以看出

buuctf - re 刷题记录 1-18_第19张图片

*1111

01000

01010

00010

1111#

构成如上这样一个迷宫,从*开始不能触碰1到#结束,然后输入1234分别代表上下左右

很了然了,直接输出

flag{222441144222}

10、SimpleRev

找到main函数,似乎没有什么用,大概就是输入一个值跳到一个关卡的意味

buuctf - re 刷题记录 1-18_第20张图片

关键代码应该是Decry() 定位到该函数 ,

将字符拼接好

unsigned __int64 Decry()
{
  char v1; // [rsp+Fh] [rbp-51h]
  int v2; // [rsp+10h] [rbp-50h]
  int v3; // [rsp+14h] [rbp-4Ch]
  int i; // [rsp+18h] [rbp-48h]
  int len; // [rsp+1Ch] [rbp-44h]
  char src[8]; // [rsp+20h] [rbp-40h] BYREF
  __int64 v7; // [rsp+28h] [rbp-38h]
  int v8; // [rsp+30h] [rbp-30h]
  __int64 v9[2]; // [rsp+40h] [rbp-20h] BYREF
  int v10; // [rsp+50h] [rbp-10h]
  unsigned __int64 v11; // [rsp+58h] [rbp-8h]

  v11 = __readfsqword(0x28u);
  *(_QWORD *)src = 'SLCDN';
  v7 = 0LL;
  v8 = 0;
  v9[0] = 'wodah';
  v9[1] = '\0';
  v10 = 0;
  text = (char *)join(key3, v9);                // text = killshadow
  strcpy(key, key1);
  strcat(key, src);                             // key1=ADSFKNDCLS
  v2 = 0;
  v3 = 0;
  getchar();
  len = strlen(key);
  for ( i = 0; i < len; ++i )
  {
    if ( key[v3 % len] > '@' && key[v3 % len] <= 'Z' )
      key[i] = key[v3 % len] + ' ';
    ++v3;
  }
  printf("Please input your flag:");
  while ( 1 )
  {
    v1 = getchar();
    if ( v1 == '\n' )
      break;
    if ( v1 == ' ' )
    {
      ++v2;
    }
    else
    {
      if ( v1 <= '`' || v1 > 'z' )
      {
        if ( v1 > '@' && v1 <= 'Z' )
        {
          str2[v2] = (v1 - '\'' - key[v3 % len] + 'a') % '\x1A' + 'a';
          ++v3;
        }
      }
      else
      {
        str2[v2] = (v1 - 39 - key[v3 % len] + 97) % 26 + 97;
        ++v3;
      }
      if ( !(v3 % len) )
        putchar(32);
      ++v2;
    }
  }
  if ( !strcmp(text, str2) )
    puts("Congratulation!\n");
  else
    puts("Try again!\n");
  return __readfsqword(0x28u) ^ v11;
}

最终结果是要str2同text做比较,已经得到text = killshadow和key=ADSFKNDCLS

然后通过代码的变化推算出str2,大概逻辑就是将key转化成小写,输入v1 然后经过转化生成str2[]

反过来想,我们输入是是字母,而且是大写字母,如果转化后满足与对应的text[]相等就是我们要输入的字符

代码

python

s = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'

key = 'adsfkndcls'
text = 'killshadow'

flag =''
for i in range(len(text)):
    str2=text[i]
    for j in s:
        if str2 == chr((ord(j) - 39 - ord(key[i % len(key)])+97)%26+97):
            flag+=j
print('flag{'+flag+'}')
#flag{KLDQCUDFZO}

11、Java逆向解密

直接进行分析

buuctf - re 刷题记录 1-18_第21张图片

python

list=[180, 136, 137, 147, 191, 137, 147, 191, 148, 136, 133, 191, 134, 140, 129, 135, 191, 65]

flag=''
for i in range(len(list)):
    flag+=chr(list[i]-ord('@')^32)

print('flag{'+flag+'}')
#flag{This_is_the_flag_!}

它这里是java,也用java写一写吧

package main;

public class main {
    public static void main(String[] args)
    {
        int[] list = {180, 136, 137, 147, 191, 137, 147, 191, 148, 136, 133, 191, 134, 140, 129, 135, 191, 65};
        String flag="";
        for(int i=0;i

12、[GXYCTF2019]luck_guy

buuctf - re 刷题记录 1-18_第22张图片

输入数字

buuctf - re 刷题记录 1-18_第23张图片

跟进patch_me(),如果数字为偶数,进入get_flag函数

buuctf - re 刷题记录 1-18_第24张图片

跟进get_flag()函数

buuctf - re 刷题记录 1-18_第25张图片

大概就是这些关键代码。接着分析,20、21行,有两个参数,f1=GXY{do_not_

f2指向的字符是s这里,大概是将两者拼接起来,那么关键点就在31行这一段16进制字符了

buuctf - re 刷题记录 1-18_第26张图片

观察到case5:8位数的变换,将s的值转化一下就是:0x7F,0x66,0x6F,0x60,0x67,0x75,0x63,0x69

f1 = 'GXY{do_not_'
list=[0x7F,0x66,0x6F,0x60,0x67,0x75,0x63,0x69][::-1]

flag=''
for i in range (8):
    if i%2==1:
        s=chr(list[i]-2)
    else:
        s=chr(list[i]-1)
    flag+=s
print(f1+flag)
#GXY{do_not_hate_me}

代码有点长还没看,做实验去了

14、findit

下载是一个apk文件,直接解压找到class.dex ,丢进jex反编译,找到主函数

buuctf - re 刷题记录 1-18_第27张图片

直接定位到主函数

package com.example.findit;

import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class MainActivity extends ActionBarActivity {
    /* access modifiers changed from: protected */
    @Override // android.support.v7.app.ActionBarActivity, android.support.v4.app.FragmentActivity
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        final EditText edit = (EditText) findViewById(R.id.widget2);
        final TextView text = (TextView) findViewById(R.id.widget1);
        final char[] a = {'T', 'h', 'i', 's', 'I', 's', 'T', 'h', 'e', 'F', 'l', 'a', 'g', 'H', 'o', 'm', 'e'};
        final char[] b = {'p', 'v', 'k', 'q', '{', 'm', '1', '6', '4', '6', '7', '5', '2', '6', '2', '0', '3', '3', 'l', '4', 'm', '4', '9', 'l', 'n', 'p', '7', 'p', '9', 'm', 'n', 'k', '2', '8', 'k', '7', '5', '}'};
        ((Button) findViewById(R.id.widget3)).setOnClickListener(new View.OnClickListener() {
            /* class com.example.findit.MainActivity.AnonymousClass1 */

            public void onClick(View v) {
                char[] x = new char[17];
                char[] y = new char[38];
                for (int i = 0; i < 17; i++) {
                    if ((a[i] < 'I' && a[i] >= 'A') || (a[i] < 'i' && a[i] >= 'a')) {
                        x[i] = (char) (a[i] + 18);
                    } else if ((a[i] < 'A' || a[i] > 'Z') && (a[i] < 'a' || a[i] > 'z')) {
                        x[i] = a[i];
                    } else {
                        x[i] = (char) (a[i] - '\b');
                    }
                }
                if (String.valueOf(x).equals(edit.getText().toString())) {
                    for (int i2 = 0; i2 < 38; i2++) {
                        if ((b[i2] < 'A' || b[i2] > 'Z') && (b[i2] < 'a' || b[i2] > 'z')) {
                            y[i2] = b[i2];
                        } else {
                            y[i2] = (char) (b[i2] + 16);
                            if ((y[i2] > 'Z' && y[i2] < 'a') || y[i2] >= 'z') {
                                y[i2] = (char) (y[i2] - 26);
                            }
                        }
                    }
                    text.setText(String.valueOf(y));
                    return;
                }
                text.setText("答案错了肿么办。。。不给你又不好意思。。。哎呀好纠结啊~~~");
            }
        });
    }

    public boolean onOptionsItemSelected(MenuItem item) {
        if (item.getItemId() == 2131034176) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
}

模仿代码写出解密

package main;

public class findit {
    public static void main(String[] args)
    {
        final char[] b = {'p', 'v', 'k', 'q', '{', 'm', '1', '6', '4', '6', '7', '5', '2', '6', '2', '0', '3', '3', 'l', '4', 'm', '4', '9', 'l', 'n', 'p', '7', 'p', '9', 'm', 'n', 'k', '2', '8', 'k', '7', '5', '}'};

        char[] y = new char[38];
        for (int i2 = 0; i2 < 38; i2++) {
            if ((b[i2] < 'A' || b[i2] > 'Z') && (b[i2] < 'a' || b[i2] > 'z')) {
                y[i2] = b[i2];
            } else {
                y[i2] = (char) (b[i2] + 16);
                if ((y[i2] > 'Z' && y[i2] < 'a') || y[i2] >= 'z') {
                    y[i2] = (char) (y[i2] - 26);
                }
            }
        }
        for(int j=0;j<38;j++){
            System.out.print(y[j]);
        }

    }
}
//flag{c164675262033b4c49bdf7f9cda28a75}

15、[BJDCTF2020]JustRE

打开后一个这软件

buuctf - re 刷题记录 1-18_第28张图片

ida看看,发现一个字符,但是%d%d这不知道是什么鬼,继续分析

buuctf - re 刷题记录 1-18_第29张图片

大概是点击19999次出flag??按照代码意思将19999和0填入%d%d BJD{1999902069a45792d233ac}

->flag{1999902069a45792d233ac}

buuctf - re 刷题记录 1-18_第30张图片

16、简单注册器

和findit类似,直接找主函数

buuctf - re 刷题记录 1-18_第31张图片

直接看验证部分就可以其实, 这种筛选部分直接可以不看,过滤不满足的字符然后跳转到retuen;

String xx = editview.getText().toString();

if (!(xx.length() == 32 && xx.charAt(31) == ‘a’ && xx.charAt(1) == ‘b’ && (xx.charAt(0) + xx.charAt(2)) - 48 == 56)) {
flag = 0;
}

package main;

public class 简单注册表 {
    public static void main(String[] args) {
        int flag = 1;
        if (flag == 1) {
            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;
            }
            System.out.print("flag{" + String.valueOf(x) + "}");
        }
    }
}
//flag{59acc538825054c7de4b26440c0999dd}

17、[GWCTF 2019]pyre

pyc文件,直接在线反编译成py,原理后面再学一下

#!/usr/bin/env python
# visit https://tool.lu/pyc/ for more information
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
    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']

解密:

code = ['\x1f','\x12','\x1d','(','0','4','\x01','\x06','\x14','4',',','\x1b','U','?','o','6','*',':','\x01','D',';','%','\x13']

l = len(code)
flag=''
for i in range(l-2,-1,-1):
    code[i]=chr(ord(code[i])^ord(code[i+1]))

for i in range(len(code)):
    flag+=chr((ord(code[i])-i)%128)

print(flag)
# GWHT{Just_Re_1s_Ha66y!}

18、[ACTF新生赛2020]easyre

UPX壳,脱去

buuctf - re 刷题记录 1-18_第32张图片

buuctf - re 刷题记录 1-18_第33张图片

然后IDA32打开,貌似有个什么加密

buuctf - re 刷题记录 1-18_第34张图片

定位到主函数

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char v4[12]; // [esp+12h] [ebp-2Eh] BYREF
  int v5[3]; // [esp+1Eh] [ebp-22h]
  char 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 )
    return 0;
  v5[0] = v7;
  v5[1] = v8;
  v5[2] = v9;
  for ( i = 0; i <= 11; ++i )
  {
    if ( v4[i] != _data_start__[*((char *)v5 + i) - 1] )    //v4[i]得与_data_start处理后相等
      return 0;
  }
  printf("You are correct!");
  return 0;
}

需要是以ASCTF{}包含一个文件,大概中间是12个字符,与“}|{zyxwvutsrqponmlkjihgfedcba`_^][ZYXWVUTSRQPONMLKJIHGFEDCBA@?>=”进行加密

找到那些字符

buuctf - re 刷题记录 1-18_第35张图片

第一次做这种,抄了个脚本

v4 = [42,70,39,34,78,44,34,40,73,63,43,64]
string = chr(0x7E)+"}|{zyxwvutsrqponmlkjihgfedcba`_^]\[ZYXWVUTSRQPONMLKJIHGFEDCBA@?>=<;:9876543210/.-,+*)(" + chr(0x27) + '&%$# !"'
flag=""

for i in v4:
    for j in range(1,len(string)):
        if i == ord(string[j]):
            flag+=chr(j+1)

print ("flag{"+flag+"}")
#flag{U9X_1S_W6@T?}

你可能感兴趣的:(CTF系列问题,#,re,re)