BUUCTF-RE-0x04

本文解析了多个CTF赛事中的逆向工程挑战题,包括easyre、pyre及JustRE等,详细介绍了使用工具如OllyDbg、X64dbg、IDA等进行脱壳分析、逆向算法及动态调试的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


title: BUUCTF-RE-0x04
date: 2021-05-10 19:58:34
tags:

刷题记录。狗头~~

[ACTF新生赛2020]easyre

首先看题

image-20210508200441970

啥都没有,下载下来看见有两个运行文件,有一个是可以使用的。

image-20210508200528241

查壳

image-20210508201646648

UPX壳,因为会脱压缩壳了。所以就脱吧,没有用脱壳机。

放入OllyDbg脱壳失败了,地址直接是乱的。然后放入的是X64dbg脱得壳,这个就很明显。

使用ESP定律把壳脱了。然后修复之后,可以运行了。

放入IDA然后简单分析之后就做不来了。发现这些数据可能有问题。

image-20210508201516376

然后查看思考,可能是我脱壳没有脱干净。可是直接使用脱壳机脱得壳反汇编的结果也是一样的。所以可能就是这样的。前面显示的是一个读不懂的函数,然后后面的比较应该是进行比较。可是跟flag好像没啥关系,也跟输入的内容没啥关系。所以这里就有点不是很懂了。

image-20210509203151403

# 主要的一个函数的解析
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]

  sub_401A10();                                 // 不知道这是个啥
  qmemcpy(v4, "*F'\"N,\"(I?+@", sizeof(v4));
  printf("Please input:");
  scanf("%s", v6);                              // ACTF{}
  if ( v6[0] != 'A' || v6[1] != 'C' || v6[2] != 'T' || v6[3] != 'F' || v6[4] != '{' || v10 != '}' )                     //这里的字符是手动改变过的
    return 0;
  v5[0] = v7;
  v5[1] = v8;
  v5[2] = v9;
  for ( i = 0; i <= 11; ++i )
  {
    if ( v4[i] != byte_402000[*((char *)v5 + i) - 1] )// v4 = 数组[flag[i] -1]

      return 0;
  }
  printf("You are correct!");
  return 0;
}

后来查看文档,有搜索python字符串里面需要转义字符,就是需要斜杠来加入到字符串里面。所以将V4写成这样才对

# 原来的v4
v4  = "*F'\"N,\"(I?+@"
# 改一下
v4  = "*F\'\"N,\"(I?+@"
然后就是12个字符了,不过有点奇怪的是为什么IDA显示说是char【15】,而只有14个呀,所以可能数据末尾可能是有换行符的吧。暂时这么猜想的。

接下来,就开始写逆向的算法。

可能是因为python不熟的缘故,所以算法最后的结果如下。然后中间还有一个就是在使用Shift+E将数据到处的时候,好像不知道怎么就把其中一个空格给删不见了。这个就有点奇特了。

flag

# easyre
v4  = "*F\'\"N,\"(I?+@"

# list = "~}|{zyxwvutsrqponmlkjihgfedcba`_^]\[ZYXWVUTSRQPONMLKJIHGFEDCBA@?>=<;:9876543210/.-,+*)(\x27&%$# ! \""
list = "~}|{zyxwvutsrqponmlkjihgfedcba`_^]\[ZYXWVUTSRQPONMLKJIHGFEDCBA@?>=<;:9876543210/.-,+*)(\x27&%$# !\""


flag =""

for i in v4:
    temp = list.find(i)+1
    flag += chr(temp)

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

这个之间踩得坑还是挺多的。

OK,解决了。

image-20210509211027072

[GWCTF 2019]pyre


工具和环境

uncompyle6     #一个将pyc文件还原成py文件的工具
python3        #看着代码,把他写出来

小知识点

做完之后,看见的知识点应该考察的是算法逆向过程中的异或运算。即一个数两次异或得到自己本身。

题目

image-20210504211730053

[GWCTF 2019]pyre

得到的 flag 请包上 flag{} 提交。

下载

下载得到的是一个pyc的文件,所以就使用uncompyle6 将这个编译的文件,反汇编得到py文件

源码如下

# uncompyle6 version 3.7.4
# Python bytecode 2.7 (62211)
# Decompiled from: Python 3.7.8 (tags/v3.7.8:4b47a5b6ba, Jun 28 2020, 08:53:46) [MSC v.1916 64 bit (AMD64)]
# Embedded file name: encode.py
# Compiled at: 2019-08-19 21:01:57
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']

算法逆向(python3)

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

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

# print(code)
flag = ""

for i in range(l):
    num = ord(code[i]) - i
    if num <0:
        num+=128;
    flag +=chr(num)

print(flag)
# GWHT{Just_Re_1s_Ha66y!}

得到flag

GWHT{Just_Re_1s_Ha66y!}

因为题目要求提交flag形式的。所以还要改一下

flag{Just_Re_1s_Ha66y!}

这下对了。

简单的注册器

工具及环境

jadk_v1.2.0   #用来反汇编apk文件
python      #计算出flag
ApkScan-PKID.jar     #查壳工具

题目

image-20210504204322436

要求

简单注册器
生活中难免会有需要使用一些付费的程序,但是没有绿色版怎么办?只能自己逆向看看注册程序的代码是什么逻辑了。 注意:得到的 flag 请包上 flag{} 提交

下载

下载后看见是一个APK,所以尝试着查下壳。

查壳

用了查壳的软件没有查到壳。

image-20210504204708410

使用jadx反汇编查看(这个工具感觉是非常友好的软件),在这个上面的安卓应用反汇编的更强吧。

image-20210504204938750

进入主函数就看见了我们需要的东西。所以接下来。就照着这个写就好了。

python3写的

str = "dd2940c04462b4dd7c450528835cca15"
# 将str转化为list可以使用下标来处理。
list = []
for j in str:
    list.append(j)
x = list   # 处理了之后,就用原来的函数来处理
x[2] =  chr(ord(x[2])+ ord(x[3]) - 50 )
x[4] =  chr(ord(x[2])+ ord(x[5]) - 48);
x[30] = chr(ord(x[31])+ ord(x[9]) - 48);
x[14] = chr(ord(x[27])+ ord(x[28]) - 97);

for i in range(0,16):
    s = x[31-i]
    x[31-i] = x[i]
    x[i] = s

str2 = "".join(list)   # 处理完之后,将原来的改成字符串打印输出
flag = ''
flag = flag+"flag{"+str2+"}"
print(flag)
# print(x)

然后运行就出来了。

flag

flag{59acc538825054c7de4b26440c0999dd}

[BJDCTF2020]JustRE


工具以及环境

Exeinfo PE        # 查壳

题目及描述

[BJDCTF2020]JustRE

得到的 flag 请包上 flag{} 提交。来源:
https://github.com/BjdsecCA/BJDCTF2020

下载 attachment.exe

查壳

image-20210504212511647

没有壳那么我们就考虑使用IDA和OD

因为这里是32位的程序,先使用IDA32.

逆向过程

通过搜索字符串,然后发现字符串。

image-20210504221757874

双击到达那里,然后选中后右键选择。

image-20210504221818456

image-20210504221929231

确定后点击确定。

可以猜出大概是这个意思。

image-20210504221547639

Flag

BJD{1999902069a45792d233ac}

然后在BUUCTF里面需要将格式修改一下变成 
flag{1999902069a45792d233ac}

知识点

这个使用动态调试的时候电脑死机了。所以就静态调试搞出来了。大概需要我们点击19999次。

image-20210504223136059

总结

BJD{1999902069a45792d233ac}
所以
flag{1999902069a45792d233ac}

<think>好的,我现在需要处理用户关于BUUCTF中[BJDCTF2020]JustRE题目的动态调试问题,使用x64dbg工具。首先,我得先回忆一下这个题目的基本情况。可能是一个逆向工程题目,需要分析一个可执行文件,找出flag。用户希望了解如何使用x64dbg进行动态调试来解题。 首先,我需要确定用户的需求。他们可能已经尝试过静态分析但遇到了困难,或者想通过动态调试来观察程序运行时的行为,比如寄存器、内存变化,或者找到关键函数的位置。接下来,我应该考虑这个题目的常见解法,可能涉及输入验证、字符串解密、或者某些特定的反调试技巧。 用户提到的是x64dbg,所以这是一个Windows平台下的64位程序。可能需要检查是否有加壳,但通常CTF题目不会太复杂,可能只是简单的混淆或直接验证。我需要引导用户进行步骤,比如加载程序,设置断点,分析字符串,跟踪输入处理流程。 首先,步骤应该是准备环境:下载题目文件,安装x64dbg,可能还需要准备一些输入样本,比如测试字符串。然后打开x64dbg,加载程序,运行到入口点。接着,寻找关键函数,可能通过字符串参考,比如程序输出的提示信息,或者错误信息,找到引用这些字符串的代码位置,设置断点。 在动态调试过程中,用户需要观察程序执行时的寄存器状态、栈变化、内存数据。例如,输入可能被处理后与某个预设值比较,或者在内存中进行某种运算,如异或、加减等。这时候需要跟踪这些操作,找到flag生成的部分。 可能的挑战包括处理反调试技术,比如检测调试器存在,导致程序行为异常。这时候需要指导用户如何绕过,比如修改标志位,或者使用插件。但CTF题目可能不会涉及太复杂的反调试,所以可能不需要这些步骤。 另外,可能需要分析程序的输入处理函数。比如,用户输入被读取后存放在某个缓冲区,之后经过一系列操作,与正确flag进行比较。这时候需要找到比较的位置,查看比较的数据,可能直接得到flag或需要进一步解密。 可能的错误点:用户可能没有正确设置断点,或者在错误的位置分析代码。需要提醒他们在关键函数(如main函数,或获取输入的函数)设置断点,并逐步执行,观察程序流程。 总结步骤可能包括:加载程序,定位关键字符串,回溯到引用处,设置断点,运行程序,输入测试数据,跟踪处理过程,分析内存或寄存器中的值,从而找到flag。 需要确保回答结构清晰,分步骤说明,同时注意LaTeX格式的正确使用,尤其是行内数学表达式和独立公式的格式。例如,在提到内存地址时,可能需要用$...$包裹,如地址0x401000应写作$0x401000$。如果有数学运算,如异或操作,用$...$包含,例如$x \oplus 0x12$。 另外,确保使用中文回答,避免专业术语过于晦涩,必要时进行解释。比如,解释断点是什么,如何设置,寄存器窗口的作用等。 最后,可能需要验证答案的正确性,比如在动态调试后得到的字符串是否符合flag格式,如BJD{...},并提醒用户常见的flag格式,避免遗漏。</think>以下是针对BUUCTF题目**[BJDCTF2020]JustRE**使用x64dbg进行动态调试的详细步骤: --- ### 一、准备工作 1. **下载题目文件** 从BUUCTF平台下载`JustRE.exe`(通常为32/64位Windows可执行文件)。 2. **安装x64dbg** 确保安装最新版x64dbg(含x64和x86调试器),本题可能为32位程序,需启动`x32dbg`。 3. **准备测试输入** 题目可能需要输入字符串,准备测试值如`123456`或`BJD{test}`。 --- ### 二、初步静态分析 1. **检查程序行为** 直接运行程序,观察输出(如提示输入、错误信息等)。 2. **查找关键字符串** 使用x64dbg的字符串搜索功能(`Ctrl+A`分析代码后,`右键 -> 搜索 -> 所有模块 -> 字符串`),定位如`"Wrong!"`、`"Correct!"`或`flag`相关字符串。 - 例:若发现字符串`"Please input your flag:"`,记录其地址(如`$0x404000$`)。 --- ### 三、动态调试步骤 1. **加载程序** - 打开x64dbg,拖拽`JustRE.exe`到窗口,或通过`文件 -> 打开`加载。 - 程序暂停在入口点(`EntryPoint`),按`F9`运行至程序初始化完成。 2. **定位关键函数** - **方法1**:通过字符串引用回溯 双击找到的提示字符串(如`"Wrong!"`),跳转到其代码引用位置,向上查找函数头部(`push ebp`),按`F2`在此处设断点。 - **方法2**:跟踪输入函数 在`GetDlgItemTextA`(获取输入内容)或`strcmp`(字符串比较)等API设断点,触发后回溯调用栈。 3. **分析输入处理逻辑** - 触发输入框后,输入测试字符串(如`123456`),程序暂停在输入处理函数。 - **单步执行**:按`F7`逐指令跟踪,观察: - **寄存器变化**:如`EAX`存储返回值,`ECX`可能为循环计数器。 - **内存操作**:如`[ebp-0x10]`可能存储输入内容,`mov`、`xor`等指令处理数据。 - **关键操作示例**: ```assembly ; 输入字符与固定值异或 XOR AL, 0x12 ; 比较处理后的值与预设值 CMP [EDI], AL JNZ WRONG_LABEL ``` 4. **提取Flag** - **直接获取**:若发现内存中存在完整Flag(如`BJD{...}`),直接复制。 - **计算推导**:若为逐字符处理,记录预设值(如`0x45`)及操作(如`XOR 0x12`),反推原始字符: $$ \text{原始字符} = \text{预设值} \oplus \text{操作数} $$ 例:$0x45 \oplus 0x12 = 0x57 \rightarrow \text{字符'W'}$。 --- ### 四、注意事项 1. **反调试绕过** 若程序检测调试器(如`IsDebuggerPresent`),在x64dbg中: - 修改相关标志位(`右键 -> 断点 -> 硬件断点 -> 删除`)。 - 使用插件(如`ScyllaHide`)隐藏调试器。 2. **函数调用约定** 注意`stdcall`或`cdecl`约定,正确分析参数传递(如`push`顺序)。 --- ### 五、答案示例 假设调试发现输入字符需与`0x12`异或,预设值为`[0x45, 0x36, ...]`,则: 1. 计算每个字符:$0x45 \oplus 0x12 = 0x57$('W'),$0x36 \oplus 0x12 = 0x24$('$')... 2. 组合结果得到Flag:`BJD{...}`。 --- 通过以上步骤,可逐步定位关键验证逻辑并提取Flag。实际调试中需结合程序具体行为调整策略。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值