基础逆向分析学习
本文整理 Android 注册逻辑、Java 解密、ELF 与 Windows 程序等基础逆向分析题目的思路和脚本。
基本函数
char *strcat(char *dest, const char *src) 把 src 所指向的字符串追加到 dest 所指向的字符串的结尾。
简单注册器
刚接触到安卓逆向,用jdx打开apk包发现注册逻辑

编写exp:
1 | x = list('dd2940c04462b4dd7c450528835cca15') |
获得flag为flag{59acc538825054c7de4b26440c0999dd}
JAVA逆向解密

看 Encrypt()的逻辑,flag作为参数传入
1 | for (char c : arr) { |
这是加密的主要逻辑
逆向一下加密逻辑就是
c = result ^ 32 - ord(‘@’)
后面使用KEY来做对比
所以编写脚本
1 | KEY = [180, 136, 137, 147, 191, 137, 147, 191, 148, 136, 133, 191, 134, 140, 129, 135, 191, 65] |
flag{This_is_the_flag_!}
luck_guy
解压之后先查壳,发现无壳,是ELF64位文件

将luck_guy拖进IDA中分析

发现是switch-case函数,逐个分析一下每一个case
case1的作用是先将s设置为空,将f1和f2都链接在s之后,那么s可能就是要找的flag,点击了一下f1,发现了f1的值

case2和case3 都是输出,先不管
case4这里给了 s = ‘\x7Ffoguci' ,刚开始查文件时候说了是ELF64文件,所以它存储的时候是小端存储,但是在IDA的显示中会变为大端存储,所以需要把s逆置一下,也就是s = icugof,然后会把s插入f2之后
Case5是对f2进行处理,这个循环的含义是如果j为奇数,就把f2 - 2,如果是偶数,就把f2 - 1
所以可以猜想一下,case4 -> case5 -> case1 就可以得到flag
编写脚本走一圈
1 | f1 =list('GXY{do_not_') |
得到flag
GXY{do_not_hate_me}
刮开有奖
先查壳,没什么有效信息

直接丢IDA,看到DIalogFunc直接跟进去

这里大概就能看到加密的主体了,将这些东西都修复了就变成这样了

第一点,输入字符的长度必须是8
第二点,下面的这些变量肯定是和flag有关
跟进sub_4010f0函数

发现函数是升序的快速排序,给函数更一下名
那么意思就是将上面的变量进行升序排序
1 | key = list("ZJSECaNH3ng") |
再往下看sub_401000函数,跟进去

观察函数逻辑,发现是base64加密,跟进去byte_407830中,看一下base64表是没有变的
在主函数的逻辑中,v4 v5都是被base64加密之后的变量
最后看if的判断条件

排序后的元素为3CEHJNSZagn
1️⃣v7[0]表示的是第一个元素 也就是3 ,string[0] = v7[0] + 34
2️⃣v10代表的是第五个元素 对应的也就是J
3️⃣逆运算一下 string[2] = (3 * v8 + 141) / 4,这里的v8是第三个元素,也就是E
4️⃣逆运算一下 string[3] = 2 * (v13 / 9) * 4,这里的v13是第八个元素 ,也就是Z
5️⃣6️⃣都是做比较,将ak1w和V1Ax base64解密一下再做比较,因为上面说过了 v4 v5都是base64加密之后的变量,解密之后为ak1w -> jMp V1Ax -> WP1
从上往下求一下
1 | key = "3CEHJNSZagn" |
得到UJWP,因为已知长度是8,上面两个字符串base64解密后为jMp和 WP1,做一下比较可以得到WP1在前面
所以flag为flag{UJWP1jMp}
[BJDCTF2020]JustRE
进去之后查看字符串,发现一个和flag很像的东西,跟进去

发现点击次数为19999输出flag,再往下看format,把19999和0带入进去得到flag
flag{1999902069a45792d233ac}
rome
1 | miwen = ['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', '}'] |
[GWCTF 2019]pyre
拿到题目反编译后得到这样的python代码

分析第二个循环一下能够知道,反着算就行,code的最后一位是不变的
由于最后一位code[i + 1]没变,从后往前走,code[i + 1] ^ code [i]得到的就是异或前的code[i]
从后往前异或完得到的就是num
然后分析第一个循环
num = (input[i] + i) % 128
反着算就是flag
num = (input[i] - i) % 128
编写exp
1 | code = ['\x1f','\x12','\x1d','(','0','4','\x01','\x06','\x14','4',',','\x1b','U','?','o','6','*',':','\x01','D',';','%','\x13'] |