题目难度不大,毕竟是取证比赛,查查信息然后连蒙带猜也能做的差不多。
赛后从逆向的角度,对涉及到的几个程序再深入分析一下。
个人赛逆向部分#
exe#
- 在U盘中,你还发现了一个exe文件,但它被锁定,可能需要进行反编译以便进一步检查。参考
David_USB_8GB.e01,使用x64dbg的字符串搜索(String Search)功能,在Bitlocker.exe中查找哪个字符串最有可能与显示的登录状态有关?- 承上題,当找到控制登录成功的逻辑代码时,如何修改汇编代码来绕过检查,达到任意输入,都成功登录的效果?
Bitlocker.exe的正确用户登录名称是?Bitlocker.exe的正确登录密码是?- 当
Bitlocker.exe程序尝试显示登录结果(成功或失败)时,使用了哪一种途径来决定显示的消息?- 决定能否解密
Bitlocker Key的字节的内存偏移量(Memory Offset)(相对于基址"bitlocker.exe")是什么?- 决定能否解密
Bitlocker Key的内存偏移量(Memory Offset)后,应该如何利用它来进行解密?- 解密后的
Bitlocker Key是?
从U盘镜像中提取出这个Bitlocker.exe,先用DIE查一下,无壳,但要留意是GUI程序。

利用DIE自带的字符串功能也可以搜索到相关的字符串。(比IDA中的多了PE头、.text 节、.rsrc节的字符串)
程序的入口点恰好是WinMain函数,IDA打开后看这个函数的反编译伪码,只有简单的几行,除去最后的消息处理,只调用了两个函数:
sub_140001620:注册窗口类,这个窗口类在第二个函数中用于创建窗口。
sub_140001700:CreateWindowExA创建主窗口,保持update。
在窗口类的定义中可以发现回调函数v2.lpfnWndProc = sub_1400017C0,进入该函数分析

a2是uMsg参数,在windows.h中可以找到如下的宏定义。结合switch-case中的值可以推测功能
#define WM_CREATE 0x0001
#define WM_DESTROY 0x0002
#define WM_COMMAND 0x0111
主窗口创建时,产生WM_CREATE消息,调用sub_140001850创建一系列的子窗口句柄,体现为输入框,按钮等控件。退出主窗口时则产生WM_DESTROY消息。

重点放在command消息,也就是点击按钮时会调用sub_140001AE0。查看这个函数,发现最后用MessageBoxA来输出login结果,合理推测是对输入的用户名和密码进行检查。
伪码能直接看到两个字符串常量,分别对应Username和Password。代码部分类似memcmp逐个字符检查。
结果最终保存到v9中,通过if判断登录是否成功。对应的汇编是test + jnz,可以patch成jz来绕过检查。
后面sub_7FF7CB6F22A0函数还进行了hash,生成bitlocker key,通过MessageBox输出。但是如果直接运行的话输入正确只会显示Keep going那段话。在最后可以看到这段代码由硬编码的byte_7FF7CB6F808C常量控制跳转 (也就是题目中提到决定能否解密Bitlocker Key 的字节),必须要patch修改一下才能输出。
到这里已经梳理出程序的整个逻辑。由于程序会解密key,所以理想的做法就是两次patch来绕过拿key,和题目引导的整个流程一致,不太需要关心加解密的具体实现。否则可能还要分析加密的API及其参数来确定是何种加密方式。
团体赛逆向部分#
赛后检材直接删了,忘了把程序保存到本地。拿着当时的截图简单讲下思路吧
apk#
你现在査看Ben的笔记本电脑,并发现了APK文件。一般而言,APK的关键组成部分是什么?
参考
Ben_Laptop.zip内的Joshe Investment.apk,这个APK没有classes.dex文件,而是有smali文件,以下哪一个陈述是正确的?(A:这是一个經過反向工程製作的APK)Ben使用了哪个工具包生成恶意APK以控制受害者的设备?
确认哪个
.xml文件被特别添加为主活动(activity_main)的布局文件?确认被指定为主活动层(activity main layer)
.xml文件的公共ID?确认应用程序没有要求的权限?
ahmyth/mine/king/ahmyth/文件夹下的b.smali文件的主要功能是什么?在
ahmyth/mine/king/ahmyth/文件夹下的b.smali文件中,字节数组(Byte Array)在发送到服务器之前执行了哪一系列操作,最终的图像格式是?在
ahmyth/mine/king/ahmyth/文件夹下的b.smali文件中,图像在发送到服务器時的压缩比率是多少?在
ahmyth/mine/king/ahmyth/文件夹下的ConnectionManager.smali中,sendReqmethod的目的是什么?承上题,参考
Ben Laptop.zip内的Joshe Investment.apk,C2服务器的IP地址及端口号?
ahmyth/mine/king/ahmyth/文件夹下的g.smali文件中,MediaRecorder被初始化用于录音。如果setAudioSource()方法使用了错误的参数,会发生什么,且这将如何影响录音过程的功能?
ahmyth/mine/king/ahmyth/文件夹下的g.smali文件中,TimerTask用于在启动MediaRecorder后调度动作。TimerTask在这个过程中有什么作用?在
ahmyth/mine/king/ahmyth/文件夹下的h.smali文件中,methoda()和methodb()的主要功能有什么区别?在
ahmyth/mine/king/ahmyth/文件夹下的h.smali文件中,methodb()需要哪些参数?
在Ben的Laptop的镜像中,Joshe Investment.apk,jadx反编译后看到符号的混淆比较严重。
查看ahmyth包,这个应该是远控工具,主活动和主服务也在这个包里面。
在MainActivity中找SetContentView对应的layout,可以确定使用的布局xml文件,其id保存在R类中。
AndroidManifest.xml可以查到要求的权限。

接下来对apk的反编译代码进行分析。由于代码量较大且程序被误删掉,只浅析一下题目ahmyth/mine/king/ahmyth中提到的几个部分
b.smali#

onPictureTaken函数,推测与相机拍摄图像相关。先调用this.d释放camera实例,紧接着调用this.e(bArr)将字节数组解码成bitmap图像,再压缩成JEPG。压缩率是decodeByteArray.compress的第二个参数。整个JPEG图像以字节流写入json对象并发送。
ConnectionManager#
看到sendReq声明了一个b.a.b.e的实例对象,并用e.a().b()进行初始化。

分别查看二者的代码实现,在b.a.b.e中发现“connect”等关键词,推测与某个服务器建立连接。之后分析e.a.b,找到一串Base64编码过的字符串,解码后即为C2服务器的ip和端口。
g.smali#

TimerTask
h.smali#
逆向分析,发现sms
分析sendTextMessage参数
着重分析方法a和方法b
python#
在分析Ben的笔记本电脑时,你从调查人员那里获得了以下信息:在对一名被捕的犯罪集团成员进行审问时获得的情报显示,Ben对John心怀怨恨,因为John扣留了Ben的犯罪收益份额。因此,Ben加密了John的机密文件夹,以限制他的访问。参考
Ben_Laptop.zip,解密secretExcel.encrypted的第一步应该是什么?在加密文件
secretExcel.encrypted中,初始向量 (lnitial Vector)的值是什么?在加密文件
secretExcel.encrypted中,盐值(SALT)是什么?查看
encrypt.py代码,如果更改'PBKDF2'的'count'参数会产生什么影响?根据分析及计算后,解密
secrectExcel.encrypted所用的key具体值是什么?
同样在Ben的Laptop。这个和逆向关联可能不是很大,直接给了python源码,但是毕竟涉及到加解密。
找到encrypt.py,源代码如下:
import os
import sys
from Crypto.Cipher import AES
from Crypto.Protocol.KDF import PBKDF2
from Crypto.Random import get_random_bytes
from Crypto.Util.Padding import pad
def encrypt_file(file_path, password):
salt = get_random_bytes(32)
key = PBKDF2(password, salt, dkLen=32, count=100000000)
file_path = os.path.abspath(file_path)
output_dir = os.path.dirname(file_path)
folder_name = os.path.splitext(os.path.basename(file_path))[O]
encrypted_path = os.path.join(output_dir, f"{folder_name}.encrypted")
os.makedirs(os.path.dirname(encrypted_path), exist_ok=True)
with open(file_path, 'rb') as f_in, open (encrypted_path, 'wb') as f_out:
data f_in.read()
cipher = AES.new(key,AES.MODE_CBC)
f_out.write(cipher.iv)
f_out.write(salt)
encrypted_data = cipher.encrypt(pad(data,AES.block_size))
f_out.write(encrypted_data)
print(f"File encrypted successfully: {encrypted path}")
if __name__ == "__main__":
if len(sys.argv) != 3:
print("Usage: python encrypt.py <file_path> <password>")
sys.exit(1)
file_path = sys.argv[1]
password = sys.argv[2]
encrypt_file(file_path, password)
先基于PBKDF2算法生成伪随机密钥。查看crypto库的文档可以了解到该算法各个参数的作用,count参数代表迭代的次数,影响计算性能和安全性。
生成key之后进行AES-CBC加密。其中初始向量iv(16 bytes)和加盐salt(32 bytes)的值依次写入了加密文件的最前面。可以用十六进制编辑器提取出来。
反解出key再解密AES,恢复被加密的excel文件。
