浅谈CTF逆向常见题型--P.Z

浅谈CTF逆向常见题型--P.Z

前言这节课,不管你是有了一定基础还是小白,都可以听,同时有一定基础不妨听听别人做题思路,一种题肯定不止一种解法,每个你都是新的脑回路!

什么是逆向,在CTF中,我们的目标就是找到出题人藏起来的flag,通过解密出题的人的正向,以此来得到flag,CTF中目标明确,就是弄清出题人的思路和考点,以此来完成题目。

语言的由来现在说下简单谈下机器码和汇编和C的关系,简单叙述下,这个十分重要,划重点,汇编和C就是逆向的根,一切都是从汇编开始,就是我们一开始的机器码再到汇编再到C语言。

机器语言首先,机器码,机器码是什么,其实就是01010101010,一连串的01010010就是一串指令,刚开始的指令,都是有本手册,用计算机的都是科学家,他们就是这样使用计算机的,而我们现在也经常需要看。

就比如你们都应该刷过杂项题,都会看到文件格式,那么就比如我们的一个exe文件,其实就是都是16进制。

汇编语言接着,汇编语言,一串0101010太麻烦了啊,于是就想着弄点人能懂的,那么现在我们假设0101010是加,那么在汇编语言中 0101010 = add,那么这样表达的语言就叫汇编语言。

机器语言对应的汇编语言

C语言于是最终,好几个汇编语言构成一个动作,就成了C语言。

诸如此类

工具概览本节课所用到的工具:

IDA反汇编软件(转汇编语言到C语言),逆向中主要使用工具

DBG动调常用工具

DIE日常查壳

签到类直接来实战,不多扯,首先讲下签到题,就算你之后的方向不是逆向,听完像一些真签到题在逆向中也能做。

举例题:Buuctf-easyre和2021ZJCTF决赛逆向签到题

Buuctf easyre0x00 日常查壳无壳64位

0x01 分析主函数通过左侧这个框找到main函数

scanf是输入函数,于是来到两个数判断是否相等(那么这题考点其实就是看你数据判断)

0x02 GetFlag!发现逻辑是判断第一个数是否和第二个数相等

2021 ZJCTF决赛逆向签到题0x00 日常查壳无壳64位

0x01 分析主函数

0x02 GetFlag!那么我们把enc里的数据拿出来,全部减50就可以拿到我们的input

1234enc = [0x76, 0x73, 0x85, 0x75, 0x86, 0x78, 0xAD, 0x6B, 0x97, 0x68, 0x98, 0x67, 0x64, 0x64, 0x62, 0x97, 0x68, 0x98, 0x6B, 0x6B, 0x96, 0x67, 0x62, 0x69, 0x95, 0x96, 0x65, 0x96, 0x6A, 0x69, 0x69, 0x65, 0x66, 0x97, 0x68, 0x98, 0x6A, 0x95, 0x68, 0xAF]for i in range(0, len(enc)): print(chr(enc[i] - 50), end = "")

GetFlag!

加壳类加壳,有压缩壳和加密壳,这节课简单讲讲压缩壳

简单看几眼这张图

Buuctf 新年快乐0x00 日常查壳upx壳 32位

有三种脱壳方法

upx软件直接脱注意原文件会给覆盖

异或类异或口诀,相同为0,不同为1

例如两个数,5和11,那么如何相同为0,不同为1呢

意为他们的转成二进制

5: 0101

11: 1011

14: 1110

对应位相同为0不同为1

注意异或是可逆的,自己把5 11 14三个数据相同为0不同为1,代一代就会很明白

Buuctf Xor0x00 日常查壳无壳64位

0x01 分析主函数一个异或加密

input[1] ^= input[0]

input[2] ^= einput[1]

input[3] ^= einput[2]

input[32] ^= einput[31]

每一位都是异或了前一位,

那么原来的input[32]怎么获得?就是再异或一遍einput[31],整条从后往前即可

0x02 GetFlag于是写个从后往前异或的脚本,注意第一位不用

1234567ef = "660A6B0C77264F2E4011780D5A3B55117019461F76224D23440E6706680F47324F00"ef = bytearray.fromhex(ef)for i in range(len(ef) - 1, 0, -1): ef[i] ^= ef[i - 1]for i in range(0, len(ef)): print(chr(ef[i]), end = "")

GetFlag!

PZCTF Xor0x00 日常查壳无壳64位

0x01 分析主函数就是分组异或

当下标为0 1 2 3什么都不异或

当到4 5 6 7就都异或input[0]

当到8 9 10 11就都异或input[0] input[1]

以此类推

0x02 GetFlag!思路:分段异或,那么逆回去,也是从尾到头再异或一遍即可

1234567891011s = [0x50, 0x5a, 0x43, 0x54, 0x16, 0x2b, 0x11, 0xf, 0x3b, 0x63,0x7e, 0x7e, 0x78, 0x2c, 0x16, 0x3a, 0x71, 0x2e, 0x2e, 0x6d, 0x72, 0x76]for i in range(len(s) - 1, -1, -1): # for j in range(int(i / 4) - 1, -1, -1): #不管是先异或 a b c还是 c b a都可以 for j in range(int(i / 4)): s[i] ^= s[j]for i in range(len(s)): print(chr(s[i]), end = "") # 当一个数异或多个数时 如 a ^ b ^ c ^ d = e # 那么当他要反过来推回来 不管是正着异或 e ^ b ^ c ^ d 还是倒过来 e ^ d ^ c ^ b 答案都为 a

绿城杯 easy_Re虽然是RC4加密(下周会讲),但其实也可以当成异或题

绿城杯-Reverse(逆向)-easy_Re 保姆级新手向_哔哩哔哩_bilibili

BugKu Ez_Fibon0x00 日常查壳upx壳 64位 直接-d脱掉即可

0x01 分析主函数重点在与那行 % 64的操作,是没法直接逆回来的,因为不知道减掉了多少个64,所以我们采用爆破法

本来是想给你们介绍三个方法,但是其实爆破法是最好理解,另两个有些场景不太好使用,现在我们掌握好爆破法,很多题都可以使用

0x02 GetFlag怎么爆破,就是构造每一位,如果我们的输入与加密数据吻合,那么就是正确的输入

1234567891011121314151617ef = [0x64, 0x79, 0x6E, 0x76, 0x46, 0x55, 0x7B, 0x6D, 0x40, 0x5E, 0x6D, 0x63, 0x74, 0x51, 0x6D, 0x56, 0x53, 0x7E, 0x77, 0x65, 0x6E, 0x72]fibon = [0 for i in range(22)]fibon[0] = 2 #构造斐波那契数列fibon[1] = 3for i in range(2, 22): fibon[i] = fibon[i - 1] + fibon[i - 2]for i in range(len(ef)): for f in range(0x40, 0x7F): #构造每一位可能的flag if ( (i & 1) != 0 ): tmp = (fibon[i] + i + f) % 64 + 64 else: tmp = (fibon[i] + i + f) % 64 + 64 if ( tmp == ef[i] ): #如何构造加密后与密文相同 print(chr(f), end = "") #就输出遍历到的值 break

GetFlag!

SMC类SMC是什么,在程序中就是一段代码需要动态解码

假设我们的数据本来是

ins[] = { 1, 2, 3, 4 },他们分别的指令是add sub mul div(只是假设)

当我们打开ida看,发现ins[] = { 11, 12, 13, 14 },那不就乱了是不是分析不了

但其实出题人在程序的开头有个解码函数将ins里的数据每个 - 10,当程序在运行的时候,数据又回到了 1 2 3 4

这就是SMC

穿山甲 SMC0x00 日常查壳

0x01 分析主函数这边即使SMC,还没解码的,可以发现上面for循环就是解码的代码,对401000的地址每个异或7

0x02 SMC于是我们直接在本地调试,让程序解码,这就是我们说的动调

可以发现还没有恢复,tab转成汇编,按u转为未定义数据,再按p形成结构函数,最后按F5反汇编

于是就恢复了

于是下面显而易见,四个一组四个一组进行操作

0x03 GetFlag!于是按着操作返回input即可

12345678v9 = [ 11, 9, 2, 7 ]v5 = [0x5E, 0x5C, 0x84, 0x66, 0x51, 0x60, 0xF6, 0x63, 0x7A, 0x56, 0xC2, 0x58, 0x72, 0x27, 0x60, 0x63, 0x6A, 0x41, 0xDE, 0x65, 0x2C, 0x18, 0x42, 0x7A]for i in range(0, len(v5), 4): print(chr(v5[i] - v9[i % 4]), end = "") print(chr(v5[i + 1] + v9[(i + 1) % 4]), end = "") print(chr(int(v5[i + 2] / v9[(i + 2) % 4])), end = "") print(chr(v5[i + 3] ^ v9[(i + 3) % 4]), end = "")

ACTF新生赛2020-Splendid_MineCraft两段SMC,更加刺激

文字版WP:

ACTF新生赛2020-Splendid_MineCraft - P.Z’s Blog

视频版WP:

ACTF新生赛2020-Splendid_MineCraft_bilibili

VM类VM题的核心!操作数和操作码

如jz 0511

jz就是操作码 0511就是操作数

GWCTF 2019-babyvmGWCTF 2019-babyvm - P.Z’s Blog

2021 深育杯 PressSangFor(深育杯)-Reverse(逆向) Press Write up_水番正文的博客

相关典藏

淘宝如何晒单(应该怎么做)
智家365app

淘宝如何晒单(应该怎么做)

📅 08-22 👁️‍🗨️ 9434
iOS18/17待机模式关闭教程,避免iPhone充电横放时出现横向时钟
365bet.com亚洲版

iOS18/17待机模式关闭教程,避免iPhone充电横放时出现横向时钟

📅 09-28 👁️‍🗨️ 3352
英語母音音標ɝ
智家365app

英語母音音標ɝ

📅 08-19 👁️‍🗨️ 824