身处各地,交流不畅,沟通效果不好,需要处理这个问题,尤其是检材二,没有发现其中的启动脚本,导致绕弯太多
背景
案情背景:某地警方接到受害人报案称其在某虚拟币交易网站遭遇诈骗,该网站号称使用”USTD币“购买所谓的"HT币”,受害人充值后不但“HT币”无法提现、交易,而且手机还被恶意软件锁定勒索。警方根据受害人提供的虚拟币交易网站调取了对应的服务器镜像并对案件展开侦查。
1. 检材1的SHA256值为
计算镜像哈希或者磁盘哈希都算正确
结果为9FFA17C4366660942FA79289DB797FAEBBA3E32C603574FF2B578A404AF11666
2. 分析检材1,搭建该服务器的技术员IP地址是多少?用该地址解压检材2
仿真进入检材一系统后,输入命令 last
即可查看
或者通过分析镜像,查看登录日志得到
结果为172.16.80.100
3. 检材1中,操作系统发行版本号为
可以直接查看文件/etc/centos-release
查看
也可以在系统输入命令lsb_release -a
或者通过分析软件查看
结果为CentOS Linux release 7.5.1804
4. 检材1系统中,网卡绑定的静态IP地址为
输入命令ifconfig
查看
或者直接查看网卡配置
或者查看分析软件
结果为172.16.80.133
5. 检材1中,网站jar包所存放的目录是(答案为绝对路径,如“/home/honglian/”)
通过查看历史命令并过滤关键字jar来找到,命令history |grep jar
,发现经常进入目录/web/app/
结果为/web/app/
6. 检材1中,监听7000端口的进程对应文件名为
虚拟机中查看太不方便,可以利用ssh连接,有一个小技巧,仿真后不要修改原来的网卡配置,直接新增一个网卡,这样也方便了网站重构,尤其是站库分离的网站,原来的ip配置不动,可以更轻松地重构出网站。
检材中一键启动服务的shell脚本被恶意删除
因此可以通过历史命令,将所有jar包一一启动起来,然后查看端口监听情况
不过通过对检材二的分析,发现在D盘中,还保存有脚本start_web.sh
,还能看到一份建站笔记,和另一个脚本
可以看到网站重构需要先启动后端,才能启动前端,而检材1中的内容是前端部分
那么先去接着看检材二,搞到建材三的解压密码,看看情况
结果为cloud.jar
7. 检材1中,网站管理后台页面对应的网络端口为(答案填写阿拉伯数字,如“100”)
单独启动admin.jar
或者重构后登录,发现后台端口是9090
结果为9090
网站重构后,页面有一个apk的二维码,扫描过后得到链接
结果为https://pan.forensix.cn/f/c45ca511c7f2469090ad/?dl=1
9. 检材1中,网站管理后台页面调用的用户表(admin)里的密码字段加密方式为?
网站后台是利用admin-api.jar
,对这个jar包进行逆向分析,可以看到加密方式是MD5
结果为md5
10. 分析检材1,网站管理后台登录密码加密算法中所使用的盐值是
定位这个md5Key
结果为XehGyeyrVgOV4P8Uf70REVpIw3iVNwNs
检材2:根据IP地址落地及后续侦查,抓获了搭建网站的技术员,扣押了其个人电脑并制作镜像“检材2”,分析所有掌握的检材回答下列问题
11. 检材2中,windows账户Web King的登录密码是
通过分析软件,可以看到,火眼会直接碰撞密码哈希,其他软件需要获取哈希去在线网站查询结果
如果没有自动化分析的软件,那么可以通过x-ways
导出用户的SAM
和SYSTEM
注册表文件,利用mimikatz
获取到用户的NTML
哈希值,然后查询解密
结果为135790
12. 检材2中,除检材1以外,还远程连接过哪个IP地址?并用该地址解压检材3
查看xshell的连接记录,可以发现
也可以直接查看xshell保存的会话文件,并且可以通过程序解析会话文件得到链接服务器的密码,在github中有项目提供解密程序
结果为172.16.80.128
13. 检材2中,powershell中输入的最后一条命令是
powershell会在用户目录\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadLine
下保存历史命令文件,查看该文件可以找到最后使用的命令
结果为ipconfig
14. 检材2中,下载的涉案网站源代码文件名为
通过分析程序可以看到Chrome下载记录中下载的文件
仿真进入系统也能在下载文件夹中看到文件
在重构出网站前台后,就能知道源码文件
结果为ZTuoExchange_framework-master.zip
15. 检材2中,网站管理后台root账号的密码为
使用分析程序查看,在谷歌浏览器保存了账号和密码
当然也可以通过其他浏览器取证工具获取
结果为root
16. 检材2中,技术员使用的WSL子系统发行版本是(答案格式如下:windows 10.1)
仿真过后通过命令wsl -l
可以获取到
或者通过分析程序发现,命令都是在20.04
中输入的
结果为Ubuntu 20.04
17. 检材2中,运行的数据库服务版本号是(答案格式如下:10.1)
通过分析程序查看,可以看到版本号
结果为8.0.30
18. 上述数据库debian-sys-maint用户的初始密码是
mysql的debian-sys-maint
的初始密码保存在mysql目录的配置文件debian.cnf
中
数据库是在wsl子系统中运行的,因此需要定位到子系统目录C:\Users\Web King\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu20.04LTS_79rhkp1fndgsc\LocalState\rootfs
找到/etc/mysql/debian.cnf
,查看密码
结果为ZdQfi7vaXjHZs75M
19. 检材3服务器root账号的密码是
通过分析程序可以看到ssh的历史命令,得到密码
结果为h123456
检材3:根据网站前端和技术员个人电脑上的线索,发现了网站后端所在的服务器IP并再次调证取得“检材3”,分析所有掌握的检材回答下列问题
20. 检材3中,监听33050端口的程序名(program name)为
查看历史命令发现,除了一键启动的脚本,还使用到了docker
启动docker后发现监听端口的程序就是docker
结果为docker-proxy
网站重构
现在我们拥有两台服务器的启动脚本
被删除的数据库b1
将数据进行上传,然后按照顺序启动脚本将网站重构,将start_web.sh
上传至检材一的/web/app
下,将start.sh
上传至检材三的/web
下,将b1
数据库文件上传至检材三的/data/mysql/db
下
查看历史记录发现,检材三还需要启动docker,利用的是docker-compose
,目录位置在/data/mysql
先启动利用命令docker-compose up -d
启动docker,启动时需要注意权限
启动检材三的脚本
启动检材一的脚本
启动后查看端口监听情况
通过3000
端口成功访问到前台页面
通过7000
端口成功访问到后台页面
同时需要注意,上图中的验证码无法加载,因为请求的地址仍然是172网段的地址
因此需要修改网卡配置,将vm的虚拟网卡也配置成同网段的ip,才能加载出来
21. 除MySQL外,该网站还依赖以下哪种数据库
分析admin-api.jar
时,可以看到还使用了redis
和mongodb
结果为redis|mongodb
22. 检材3中,MySQL数据库root账号的密码是
分析admin-api.jar
时,可以看到
结果为shhl7001
23. 检材3中,MySQL数据库在容器内部的数据目录为
利用docker命令进入到容器中docker exec -it mysql57 bash
或者使用命令docker inspect 8eda4cb0b452
结果为/var/lib/mysql
24. 涉案网站调用的MySQL数据库名为
分析admin-api.jar
时,可以看到
结果为b1
25. 勒索者在数据库中修改了多少个用户的手机号?(答案填写阿拉伯数字,如“15”)
使用之前获取到的数据库地址、端口和密码,连接到数据库,查看数据库的general_log
发现了日志地址为/var/lib/mysql/b58cd2cdce3d.log
,同时要注意这个数据库是运行在容器里的
导出这个日志进行分析docker cp mysql57:/var/lib/mysql/8eda4cb0b452.log /web
题目关键词为修改,我们要知道在mysql中所有操作都会被保存在general_log
中,修改需要执行的语句则是update
,可以看到手机号是存在member
表
那么在日志中搜索update `b1`.`member`
即可
结果为3
26. 勒索者在数据库中删除的用户数量为(答案填写阿拉伯数字,如“15”)
与上题同理,搜索delete from `b1`.`member`
结果为28
27. 还原被破坏的数据库,分析除技术员以外,还有哪个IP地址登录过管理后台网站?用该地址解压检材4
网站重构后,在网站中会有系统日志
或者可以进行猜测,前几个检材的解压ip的网段都是172.16.80.0
,我们在/web
全局搜索172.16.80.
,过滤出几个ip,挨个进行尝试
又或者可以通过这个网段的形式,制造字典暴力破解
结果为172.16.80.197
28. 还原全部被删改数据,用户id为500的注册会员的HT币钱包地址为
利用sql语句查询SELECT address,member_id FROM `member_wallet` WHERE member_id=500
结果为cee631121c2ec9232f3a2f028ad5c89b
29. 还原全部被删改数据,共有多少名用户的会员等级为'LV3'(答案填写阿拉伯数字,如“15”)
还原全部被删改数据,在第26题中,我们找到了被删除的用户id,发现是从973
到1000
的连号,定位到insert
语句,在vsc
中可以很方便地选择并复制,当然要注意,多条语句执行需要加上;
粘贴到数据库执行
在网站后台上找到LV3
和LV2
的用户,从而确定用户id去查看会员在数据库表中的具体值
利用sql查询select * from member where id in (389,828)
,可以看到字段member_grade_id
的值是多少,会员等级就是多少
接下来直接进行统计select count(*) from member where member_grade_id=3
结果为164
30. 还原全部被删改数据,哪些用户ID没有充值记录(答案填写阿拉伯数字,多个ID以逗号分隔,如“15,16,17”)
通过分析,发现member_transaction
是充值记录表,联合member
表查询出未充值过的用户
使用sql语句select id from member where id not in (select distinct(member_id) from member_transaction)
得到结果
切忌直接从member_wallet
表中查询,这次是碰巧,没有人把币花得正正好好变成0,但实际中什么情况都能出现,这毕竟是人造的数据
结果为318,989
31. 还原全部被删改数据,2022年10月17日总计产生多少笔交易记录?(答案填写阿拉伯数字,如“15”)
使用sql语句SELECT count(*) FROM `member_transaction` where create_time>="2022-10-17 00:00:00" and create_time<"2022-10-18 00:00:00"
从member_transaction
表中查询
32. 还原全部被删改数据,该网站中充值的USDT总额为(答案填写阿拉伯数字,如“15”)
使用sql语句select sum(amount) from member_transaction
查询到
结果为408228
检材4.根据前期侦查分析,通过技术手段找到了幕后老板,并对其使用的安卓模拟器“检材4”进行了固定。分析所有掌握的检材,回答下列问题
33. 嫌疑人使用的安卓模拟器软件名称是
npbk是今年三所刚出过的模拟器的备份文件,使用到的模拟器是夜神模拟器,后缀名一搜就可以搜到
结果为夜神模拟器
34. 检材4中,“老板”的阿里云账号是
目前来讲,手机部分的题,还是用分析程序比较好,千万不要自己平白花费气力去解密数据库、解析内容,从npbk中导出vmdk,使用分析程序解析
在微信和嫌疑人聊天时透露自己的阿里云账号
结果为forensixtech1
35. 检材4中安装的VPN工具的软件名称是
夜神模拟器直接恢复备份就可以看到桌面应用
或者查看程序列表
结果为v2rayNG
36. 上述VPN工具中记录的节点IP是
在模拟器中直接打开查看
或者从分析程序查看
结果为38.68.135.18
37. 检材4中,录屏软件安装时间为
从模拟器中导出录屏apk,根据包名比对
结果为2022/10/19 10:50:27
38. 上述录屏软件中名为“s_20221019105129”的录像,在模拟器存储中对应的原始文件名为
在/data/data/com.jiadi.luping/databases
下有数据库记录,导出数据库并查看
或者你不知道要查看数据库,可以根据哈希值来过滤,首先在录屏软件中导出文件,然后在模拟器的文件管理中可以看到这个视频的md5值为5056910ea1e1dcae0212b1493710f90f
我们在x-ways
中为镜像进行磁盘快照,计算所有文件的md5值
然后根据视频的md5值进行过滤,就可以得到文件名
结果为0c2f5dd4a9bc6f34873fb3c0ee9b762b98e8c46626410be7191b11710117a12d
39. 上述录屏软件登录的手机号是
从数据库中查看
或者根据录屏软件中提示的手机号开头或结尾,直接在x-ways
中搜索
结果为18645091802
40. 检材4中,发送勒索邮件的邮箱地址为
通过分析程序查看
结果为skterran@163.com
分析所有掌握的检材,找到勒索邮件中被加密的文档和对应的加/解密程序,并回答下列问题
41. 分析加密程序,编译该加密程序使用的语言是
如第6
题所示,在检材二中有加解密程序和加密后的文档,其实图标已经出卖了这俩文件,程序就是Python
实在不行还可以用ida查看字符串,可以发现很明显的python特征
结果为Python
42. 分析加密程序,它会加密哪些扩展名的文件?
使用ida继续查看字符串,可以发现打包程序是PyInstaller
可以利用pyinstxtractor.py
脚本来解包
反编译后可以看到文件encrypt_file_1
,就是pyc文件,但是无法直接反编译,因为他的文件头对不上,需要修改
将struct
的前12个字节复制到encrypt_file_1
的前面,并将这个文件添加pyc
后缀
这之后使用uncompyle6
进行反编译
这时候可以看到代码中要加密的文件的格式
结果为.txt|.jpg|.xls|.docx
43. 分析加密程序,是通过什么算法对文件进行加密的?
代码中有一段异或加密函数
可以看到实际上加密文件的就是异或加密,而RSA加密的是随机产生的密钥
结果为异或
44. 分析加密程序,其使用的非对称加密方式公钥后5位为?
代码中直接看到
结果为u+w==
45. 被加密文档中,FLAG1的值是(FLAG为8位字符串,如“FLAG9:QWERT123”)
同样的操作反编译decrypt_file.exe
,直接在代码中看到了密码
使用密码进行解密
看到flag
结果为TREFWGFS
分析所有掌握的检材,找到报案人描述的加密勒索apk程序,分析并回答下列问题
46. 恶意APK程序的包名为
通过第8
题得到的链接下载apk并分析,jadx
打开看到包名
结果为cn.forensix.changancup
47. APK调用的权限包括
继续查看AndroidManifest.xml
,得到权限
结果为READ_EXTERNAL_STORAGE|WRITE_EXTERNAL_STORAGE
48. 解锁第一关所使用的FLAG2值为(FLAG为8位字符串,如需在apk中输入FLAG,请输入完整内容,如输入"FLAG9:QWERT123")
利用雷电进行一键脱壳,脱壳时注意不要给予软件root权限
,否则容易拿不到dex
脱壳后反编译dex查看代码,看到app直接显示flag2
那就先搜索FLAG2
,可以直接看到结果
结果为MATSFRKG
49. 解锁第二关所使用的FLAG3值为(FLAG为8位字符串,如需在apk中输入FLAG,请输入完整内容,如输入"FLAG9:QWERT123")
定位到第二关的代码
发现是个解密
通过OooO0O0.OooO0O0()
处理后丢到so里进行解密
整理一下发现解密后的值返回给了this.OooO0oo
这个值被在cn.forensix.cab.A
类中被定义
仔细观察发现,最后比较的就是App
类中声明的变量OooO0oo
的值,而App
类中又声明了一个App
类的变量OooO0O0
尝试利用frida
脚本进行hook
,执行frida -U -l hook.js "ZTuoExchange"
来进行hook,同样注意不能给root权限
,因为软件会把adb杀掉
代码如下
setImmediate(function () {
Java.perform(function () {
//hook类cn.forensix.cab.App
var clazz = Java.use("cn.forensix.cab.App");
//拿到App中的属性
var OooO0oo = clazz.class.getField("OooO0oo");
//获取已经实例化好的App类型的属性
var OooO0O0 = clazz.class.getField("OooO0O0").get(null);
//获取OooO0O0的OooO0oo的值
console.log("FLAG3:" + OooO0oo.get(OooO0O0));
});
})
执行结果如下
结果为TDQ2UWP9
50. 解锁第三关所需的KEY值由ASCII可显示字符组成,请请分析获取该KEY值
分析第三关的代码,发现是针对输入的字符串,分成6组,每组进行处理后和保存好的数据进行比较,全部通过比较后就能进行解密
题目中给出了很明确的提示,密码由全部可显示的ASCII
码组成,在标准的ASCII
表中,可打印的字符的编码范围是33-126
,在代码中是对分为6组的数组依次判断,也就是说我们可以通过每4位
爆破的方式,组成全部的密码
代码如下
public class Test{
static int[] OooO0oO = {1197727163, 1106668241, 312918615, 1828680913, 1668105995, 1728985987};
public 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]};
}
public static void main(String[] args) {
String res = "";
for (int i = 0; i < 6; i++) {
//4层循环遍历4位字符串
for (int a1 = 33; a1 < 127; a1++) {
for (int a2 = 33; a2 < 127; a2++) {
for (int a3 = 33; a3 < 127; a3++) {
for (int a4 = 33; a4 < 127; a4++) {
long tmp = (long) (a1 << 16);
tmp = tmp | ((long) (a2 << '\b'));
tmp = tmp | ((long) (a3 << 24));
tmp = ((long) a4) | tmp;
if (((OooO(tmp, 0x100000000L)[0] % 0x100000000L) + 0x100000000L) % 0x100000000L == ((long) OooO0oO[i])) {
res += (char)a1;
res += (char)a2;
res += (char)a3;
res += (char)a4;
//获取到当前密码后,跳出4层循环
a1 = a2 = a3 = a4 = 128;
}
}
}
}
}
}
System.out.println(res);
}
}
运行结果
结果为a_asd./1imc2)dd1234]_+=+