Understand electronic forensics through a forensic analysis of nude chat software (competition question WP)

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.H5B8E45D3in 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-permissionwhich 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镜像进行挂载,具体操作可参考:

【电子取证:镜像仿真篇】Linux镜像仿真、E01镜像取证_电子取证 linux镜像仿真文件不是所有者-CSDN博客【电子取证:镜像仿真篇】Linux镜像仿真、E01镜像取证主要是Linux镜像仿真(DD、E01仿真相同),还介绍了特别特殊的一个情况,就是在虚拟磁盘里的镜像再挂载本地,出现的”磁盘占用“,导致无法成功仿真的问题!—【suy】文章目录【电子取证:镜像仿真篇】Linux镜像仿真、E01镜像取证一、FTK Imager 挂载镜像1、FTK Imager“可写”模式*"注意一"!!!二、新建VMware虚拟机1、选择客户端镜像系统2、磁盘类型选择“SATA”*"注意二"!!!3、本地磁盘*"注意三"!!!4、_电子取证 linux镜像仿真文件不是所有者https://blog.csdn.net/NDASH/article/details/109992377

虚拟机跑起来后,还有一个问题需要注意,就是运行之后需要密码登录,这里可以搜索相关系统的修改密码办法

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账号为

Guess you like

Origin blog.csdn.net/weixin_46175201/article/details/133299870