最近在学习逆向把之前打的一些比赛的逆向复盘一下
41. 分析加密程序,编译该加密程序使用的语言是
die分析一下 可以看到是用python打包的exe
42.分析加密程序,它会加密哪些扩展名的文件?
使用pyinstxtractor进行将打包的exe解包成pyc文件
https://github.com/extremecoders-re/pyinstxtractor
将encrypt_file文件进行反编译
在线反编译https://www.toolnb.com/tools/pyc.html
找到加密逻辑这里
43.分析加密程序,是通过什么算法对文件进行加密的?
44.定位最后的加密函数xor_obj.encrypt 反过去捋一下 到xorcbc 这个类分析类当中的加密逻辑^符号可以确认加密程序通过异或的方式进行加密
- 分析加密程序,其使用的非对称加密方式公钥后5位为?
定位到对导入rsa公钥的部分
pubkey = '-----BEGIN PUBLIC KEY-----\nMIIBIzANBgkqhkiG9w0BAQEFAAOCARAAMIIBCwKCAQEAx5JF4elVDBaakgGeDSxI\nCO1LyyZ6B2TgR4DNYiQoB1zAyWPDwektaCfnvNeHURBrw++HvbuNMoQNdOJNZZVo\nbHVZh+rCI4MwAh+EBFUeT8Dzja4ZlU9E7jufm69TQS0PSseIiU/4Byd2i9BvIbRn\nHLFZvi/VXphGeW0qVeHkQ3Ll6hJ2fUGhTsuGLc1XXHfiZ4RbJY/AMnjYPy9CaYzi\nSOT4PCf/O12Kuu9ZklsIAihRPl10SmM4IRnVhZYYpXedAyTcYCuUiI4c37F5GAhz\nRDFn9IQ6YQRjlLjuOX8WB6H4NbnKX/kd0GsQP3Zbogazj/z7OM0Y3rv3T8mtF6/I\nkwIEHoau+w==\n-----END PUBLIC KEY-----\n'
45.被加密文档中,FLAG1的值是
同样的方式对decrypt文件进反编译
运行解密程序 需要输入密码
定位到 这个条件判断
得到解密的明文密码400803721
将加密后的文件导出和decrypt放到同一目录下
输入之前的密码会对其进行解密
得到解密后的docx文档 里面有flag1
46.恶意APK程序的包名为
法1雷电加载apk
法2:
Jadx反编译 查看xml文件
47.APK调用的与文件操作有关的权限包括
法一:
Xml文件 找到对应的权限
法二:
Apk messager分析可直接查看
48.解锁第一关所使用的FLAG2值为
查壳发现 是360加壳
雷电可以进行脱壳
脱壳出来搜索字符串 可以找到第一个flag
法二:
反编译 apk 定位到程序的主逻辑
搜索flag2也能找到
49.解锁第二关所使用的FLAG3值为
法一:fredia调试
分析代码逻辑 首先主activity进行了一个判断 注意这里的条件
i2 & 1
在mainactivity类当中的另一个方法找到相同的条 (i2 & 1) == 0
分析其中的app类
跳转到app类 这里加载了so文件
把so文件拖到ida当中进行分析
基本确认了调用so文件是进行加密
继续分析
Narive 从本地的so文件当中加载了解密和加密的方法
这里调用了解密的方法对密文进行解密
根据题目的逻辑 我们直接hook app类当中这个实例化对象得到的结果就能得到解密的密文。
由此可以得到hook的js文件
setImmediate(function () {
Java.perform(function () {
var app = Java.use("cn.forensix.cab.App"); // 指定类
var OooO0oo = app.class.getField("OooO0oo"); // 指定属性
var OooO0O0 = app.class.getField("OooO0O0").get(null); // 获取已实例化的对
象
console.log(OooO0oo.get(OooO0O0));
});
})
模拟器起一个 frida server服务
跑脚本就能得到最后的密文 frida -U -l hook.js "ZTuoExchange"
法二 新建一个安卓工程调用解密的函数直接进行输出
将so文件放到 jnilibs目录下
新建一个 mainactivity
//MainActivity.java
package cn.foresix.cab;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
System.out.println("welcome");
App.main();
setContentView(R.layout.activity_main);
}
}
打开一个未安装apk的模拟器运行即可。 这个apk会锁模拟器
50.解锁第三关所需的KEY值由ASCII可显示字符组成,请请分析获取该KEY值
定位到加密的方法
参考:
https://forensics.xidian.edu.cn/wiki/ChanganCup2022/
看一下加密逻辑
贴一个解密的脚本
class Main {
private static int[] OooO0oO = {1197727163, 1106668241, 312918615, 1828680913, 1668105995, 1728985987};
public static void main(String[] args) {
for (int n=0; n<6; n++) {
boolean flag = false;
for (int i = 0x20; i < 0x7f; i++) {
for (int j = 0x20; j < 0x7f; j++) {
for (int k = 0x20; k < 0x7f; k++) {
for (int l = 0x20; l < 0x7f; l++) {
long tmp = (long) (i << 16);
tmp |= (long) (j << '\b');
tmp |= (long) (k << 24);
tmp |= (long) l;
if (((OooO(tmp, 4294967296L)[0] % 4294967296L) + 4294967296L) % 4294967296L == ((long) OooO0oO[n])) {
System.out.print((char) i);
System.out.print((char) j);
System.out.print((char) k);
System.out.print((char) l);
flag = true;
break;
}
}
if (flag)
break;
}
if (flag)
break;
}
if (flag)
break;
}
}
}
public boolean OooO0O0(String str) {
if (str.length() != 24) {
return false;
}
long[] jArr = new long[6];
for (int i = 0; i < str.length() / 4; i++) {
int i2 = i * 4;
jArr[i] = (long) (str.charAt(i2) << 16);
jArr[i] = jArr[i] | ((long) (str.charAt(i2 + 1) << '\b'));
jArr[i] = jArr[i] | ((long) (str.charAt(i2 + 2) << 24));
jArr[i] = ((long) str.charAt(i2 + 3)) | jArr[i];
// PrintStream printStream = System.out;
// printStream.println("buildKey:i:" + i + ",value:" + jArr[i]);
}
try {
int[] iArr = {1197727043, 1106668192, 312918557, 1828680848, 1668105873, 1728985862};
Object[] objArr = {'x', '1', ':', 'A', 'z', '}'};
for (int i3 = 0; i3 < 6; i3++) {
if (((long) iArr[i3]) - jArr[i3] != ((long) ((Integer) objArr[i3]).intValue())) {
return false;
}
}
return true;
} catch (Exception unused) {
for (int i4 = 0; i4 < 6; i4++) {
if (((OooO(jArr[i4], 4294967296L)[0] % 4294967296L) + 4294967296L) % 4294967296L != ((long) this.OooO0oO[i4])) {
return false;
}
}
return true;
}
}
private static long[] OooO(long j, long j2) {
if (j == 0) {
return new long[]{0, 1};
}
long[] OooO = OooO(j2 % j, j);
return new long[]{((j2 / j) * OooO[0]) + OooO[1], OooO[0]};
}
}
得到最后的key