NCTF2025
X1c@dM1n1$t
7d53ecd36a43d3d2
37e7dd633dcf8497
409EEC86B884A58B7E8A64E21AD3B8BB
x1login
过检测
首先我们先下载这个题目,因为我的手机开启了root权限所以直接退出了,这里我们直接看看这个,我第一想法是hook这个root检测和debugger检测
Java.perform(function() { |
这样就可以直接hook掉了这个检测,可以看到叫我们输入用户名和密码,这里看看逻辑吧,其实可以看出是一个动态加载的dex
这里给一下简单的API
动态加载的dex
InMemoryDexClassLoader
这是 Android 9(API 28)引入的一个类加载器,用于从内存中的字节数组加载 Dex 文件。代码中通过 new InMemoryDexClassLoader(ByteBuffer.wrap(...), getClassLoader())
来实现 Dex 的内存加载。使用这个 API 可以避免将 Dex 文件写入存储,从而减少被提取和逆向的风险。
自己实现的解密这些字符串
相当于字符串加密了,这里我们自己去调用这个native方法去实现解密就行(因为直接看native方法看不懂)
这里本地调用一下这个方法
var DecStr = Java.use('com.nctf.simplelogin.DecStr'); |
所以这个就是一个动态加载的这个check类,对于这种动态加载的类,我们的办法就是本地dump下这个动态加载的dex,然后去复制到sdcard,再给权限再去拖出来看
var InMemoryDexClassLoader = Java.use('dalvik.system.InMemoryDexClassLoader'); |
这里看出大致逻辑就是对用户名进行判断了,根据我们前面的frida主动调用解密可以得到明文,所以用户名很快就能得到,之后就差密码了,这里的密码的逻辑就是这个用户名进行md5加密再用密码一起传入这个Secure.doCheck方法
[*] Decrypted Username: X1c@dM1n1$t |
调用的就是native层的libnative.so文件了。
我们在导出表中没有看到这个doCheck方法,这里
看出应该是动态注册的方法,也看到了这个loaddex的方法,这里我们就看一下这个docheck方法吧
这里可以发现加密是Triple DES的加密的,这里我直接把这个密文拿去解密一直是不行的,后来才想到应该是大小端序的问题。
密钥应该就是我们输入的用户名经过md5加密后的字符串,用户名明文,可惜这里一直不行,后来想这个密钥是8字节,加密解密是不同的密钥,md5是16字节,那么我们按照8字节拆分
7d53ecd36a43d3d2
37e7dd633dcf8497
并且要是小端序,与之同时,我们的密文也要是小端序,每8字节
整理前的密文是409EEC86B884A58B7E8A64E21AD3B8BBDF4BFA1246453E52
所以整理的话密钥就是
d2d3436ad3ec537d9784cf3d63dde737d2d3436ad3ec537d
整理后的密文是
523E454612FA4BDFBBB8D31AE2648A7E8BA584B886EC9E40
就可以得到密码了,最后flag就是用户名_密码就行了。
Safe_program
第一次用超强9.0,这里的大致逻辑就先判断输入的格式和长度,之后进行加密,只不过这里调试就要飞,这里看看导出表发现有TLS回调函数,会在这个主函数加载之前就执行
发现有一个激起除零异常的函数,结合我们一调试就异常可以初步判断这个函数就是在反调试,这里直接apply patch是,改成强制跳转
这里可以看出就是SM4魔改的加密,因为直接用原版的解密方式是不行的,这里的方法就是去看,首先去出题人最喜欢的加密前后看看有没有其他的操作,比如对密钥进行异或,对明文数据进行异或,或者对加密的S盒进行替换,这里看出是对SM4的S盒进行的替换,我们其实可以先随便输入数据,然后调试去验证判断
这里的S盒是不一样的,密钥可以直接调试给出
|
|
运行就可以得到flag了
ezDos
拿到题目发现是16位的汇编程序,那就是考验汇编能力,这里需要十分细心
拿到之后先去除花指令,都是一些简单的永真永假跳转,可以随意过掉,这里直接看逻辑
通过这里的判断逻辑以及不相等就直接跳飞,可以看出这是判断输入的长度
这里不断push再加,可以判断出应该就是一个将1-256数据压入到栈中
cx的判断循环的次数
之后就是把这个取出,这其实就是rc4加密的魔改,这里取出的逻辑是遵循栈的先进后出,所以这里的s初始化就是256-0,和s盒的初始化是相反
这里其实可以去看这个数据区发现有字符串,其实就是密钥,这里除余这个字符串的长度可以判断除这里就是密钥的初始操作
这里因为它调用的函数对返回地址进行了改变,所以需要pop,这里的逻辑就是对密钥进行了位移操作,然后前面除的数字再去数组中找key
and就是除余256,所以这个很容易看出是rc4
这个也是魔改点
所以这里的魔改点就是s盒倒序,这个key的位移操作,以及这个s盒值加1
|