第四届长安杯逆向分析部分

最近在学习逆向把之前打的一些比赛的逆向复盘一下

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  这个类分析类当中的加密逻辑^符号可以确认加密程序通过异或的方式进行加密

  1. 分析加密程序,其使用的非对称加密方式公钥后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://note.youdao.com/ynoteshare/index.html?id=78afde521af47956731c8185624110ec&type=note&_time=1667732405820#/

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

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值