前言这节课,不管你是有了一定基础还是小白,都可以听,同时有一定基础不妨听听别人做题思路,一种题肯定不止一种解法,每个你都是新的脑回路!
什么是逆向,在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_水番正文的博客