一、鉴定要求
- 检材硬盘的SHA256校验值。
- Windows账户“NJZhao”绑定的微软账号。
- 回收站中扩展名为“.pptx”的文件被删除前的路径。
- 检材电脑首次访问服务器中与“项目研发”相关内容的时间。
- 赵能嘉离职前(2023 年 7 月 10 日后)通过电子邮件发送文档的收件人的邮件地址。
- 通过“向日葵”软件远程连接检材的外网及内网IP地址。
- 检材外接U盘中创建并编辑过一个 Word 文档,给出该文档在 U 盘上的创建时间。
- 第7题 Word 文档最后一次被编辑时,修改后的内容(只列出修改部分)。
- 在检材未删除的文件中搜索同时满足包含“science”、包含“system”、 不包含“technology”、不包含“data”四个条件(关键词不含引号,不区分大小写)的文件,给出文件名。
- 将检材“\Users\NJZhao”目录下的未删除文件与样本哈希库进行对比,给出命中哈希库的文件数量(不去重)
二、工具
HashMyFiles v2.42
取证大师(版本V6.1.97919RTM)
AccessData FTK Imager 4.7.1.2
电子数据仿真取证系统(64位)V6.2.03882RTM
DBeaver Enterprise 22.0.0
三、答案及过程
1.检材硬盘的SHA256校验值。
答案:检材硬盘的SHA256校验值为6F88E3F7D18EE93D0BE109B9B02FD7131A70491F3A6CF5A8818EF84189741666
过程:
· 取证大师:虚拟磁盘挂载工具,以磁盘,只读模式挂载送检检材E01镜像。打开WinHex20.0,选择工具,打开磁盘,选中物理驱动器挂载的E01镜像生成的磁盘并点击确定。选择工具,计算哈希值(M),选择计算SHA-256(256bit),计算出检材硬盘的SHA256校验值为6F88E3F7D18EE93D0BE109B9B02FD7131A70491F3A6CF5A8818EF84189741666。
2.Windows账户“NJZhao”绑定的微软账号。
答案:Windows账户“NJZhao”绑定的微软账号为cnas-pt@hotmail.com
过程:
· 电子数据仿真取证系统:对送检硬盘镜像进行仿真,进入操作系统后,对此电脑点击右键,选择属性,再点击帐户,选中你的信息,发现Windows账户“NJZhao”绑定的微软账号为cnas-pt@hotmail.com。
3.回收站中扩展名为“.pptx”的文件被删除前的路径。
答案:回收站中扩展名为“.pptx”的文件被删除前的路径为“C:\Users\NJZhao\Downloads\13579\606936.pptx”
过程:
· 回收站删除记录1条,删除的文件名为“606936.pptx”,原始路径为“C:\Users\NJZhao\Downloads\13579\606936.pptx”
4.检材电脑首次访问服务器中与“项目研发”相关内容的时间。
答案:检材电脑首次访问服务器中与“项目研发”相关内容的时间为2023-07-12 16:44:02
过程:
· 取证大师:实时搜索关键字“项目研发”,搜索结果资源管理器痕迹中存在2条记录,最后访问时间均为“2023-07-12 16:44:02”
5.赵能嘉离职前(2023 年 7 月 10 日后)通过电子邮件发送文档的收件人的邮件地址。
答案:赵能嘉离职前(2023 年 7 月 10 日后)通过电子邮件发送文档的收件人的邮件地址为nlyz_a@163.com
过程:
· 电子数据仿真取证系统:对送检硬盘镜像进行仿真,进入操作系统后,点击开始菜单,选择邮件
· 进入邮件后选择已发送邮件,发现存在2023年7月12日发送给赵能嘉的邮件,点击邮件,找到内容为文档,点击收件人赵能嘉查看详情,邮件地址为nlyz_a@163.com。
6.通过“向日葵”软件远程连接检材的外网及内网IP地址。
答案:通过“向日葵”软件远程连接检材的外网(public)IP地址为223.167.224.166 ,内网(local)172.16.19.225
过程:
· 取证大师:路径“\Program Files\Oray\SunLogin\SunloginClient\log\”下找到向日葵日志文件“history.log”,该log为连接记录,2023-07-12 18:41:27记录了一次开始控制桌面的记录
· 路径“\Program Files\Oray\SunLogin\SunloginClient\log\”下发现存在向日葵详细连接记录文件“sunlogin_service.20230712-165919.log”,打开该文件并按照history.log中开始控制桌面的记录时间查找相对应时间的详细信息,发现存在记录远程连接检材的外网及内网IP地址,外网(public)IP地址为223.167.224.166 ,内网(local)172.16.19.225。
7.检材外接U盘中创建并编辑过一个 Word 文档,给出该文档在 U 盘上的创建时间。
答案:检材外接U盘中创建并编辑过一个 Word 文档,给出该文档在 U 盘上的创建时间为2023/7/14 9:39:43
过程:
· 取证大师:USB设备使用痕迹记录7条,其中挂载了一个SanDisk的U盘,挂载盘符为“D:”
· 最近访问的文档记录102条,筛选出完整路径为“D:”开头的最近访问的文档,发现3条文档记录,创建时间均为2023/7/14 9:39:43
8.第7题 Word 文档最后一次被编辑时,修改后的内容(只列出修改部分)。
答案:第7题 Word 文档最后一次被编辑时,修改后的内容(只列出修改部分)为“因甲方内部原因”
过程:
· 取证大师:文件分类中,找到Word文档193条记录,筛选出名称含“解除”的文件三个,根据创建时间、最后修改时间和删除状态分析,已删除的“解除劳动合同协议书.docx”为原始文件,删除状态为正常的“解除劳动合同协议书.docx”为最终保存文件,“解除劳动合同协议书.docx.C95E665F97FC34C16B681A11091AF66C.20230714103856408.wps”为创建的缓存备份文档
· 将已删除的“解除劳动合同协议书.docx”和删除状态为正常的“解除劳动合同协议书.docx”导出,并通过wps比较两个文档,经分析,修改后的内容(修改部分)为“因甲方内部原因”
9.在检材未删除的文件中搜索同时满足包含“science”、包含“system”、 不包含“technology”、不包含“data”四个条件(关键词不含引号,不区分大小写)的文件,给出文件名。
答案:在检材未删除的文件中搜索同时满足包含“science”、包含“system”、 不包含“technology”、不包含“data”四个条件(关键词不含引号,不区分大小写)的文件,满足条件的该文件名为322575.pptx,464081.pptx,469004.ppt,499269.docx
过程:
· 取证大师:实时搜索关键字“science”,搜索出89个文档,将89个文档全部导出至本地。使用脚本代码对该89个文档进行处理,筛选出包含“science”和“system”且不包含“technology”和“data”的文档为322575.pptx,464081.pptx,469004.ppt,499269.docx。使用“专业分析软件”对上述文件进行分析,均为未删除文件。
import tkinter as tk
from tkinter import filedialog
import os
import comtypes.client
from docx import Document
from pptx import Presentation
import csv
from openpyxl import load_workbook
import xlrd
import win32com.client
import warnings
import sys
# 不输出警告
warnings.simplefilter("ignore", category=UserWarning)
# 初始化满足条件的文件计数器
satisfying_file_count = 0
# 弹出选择目录文件夹
root = tk.Tk()
root.withdraw() # 隐藏主窗口
directory_path = filedialog.askdirectory()
# 检查是否选择了文件夹
if not directory_path:
print("未选择文件夹,程序退出。")
sys.exit()
# 打印选择的文件夹路径
print("选择的文件夹路径:", directory_path)
# 用户输入要包含的关键字,用英文逗号或竖线隔开表示全部包含或包含其中一个
while True:
keywords_include_input = input("请输入要包含的关键字,用英文逗号(全部包含)或竖线(包含其中一个)隔开,不可输入为空:").lower()
if not keywords_include_input.strip():
print("关键字不能为空,请重新输入。")
continue
break
# 处理关键字输入,支持逗号表示全部包含,竖线表示包含其中一个
if keywords_include_input == "default":
keywords_include = []
all_keywords_required = False
keywords_include_hint = "包含其中一个"
else:
if "|" in keywords_include_input:
keywords_include = keywords_include_input.split("|")
all_keywords_required = False
keywords_include_hint = "包含其中一个"
else:
keywords_include = keywords_include_input.split(",")
all_keywords_required = True
keywords_include_hint = "全部包含"
# 提示输入不包含关键字
exclude_input_prompt = "请输入不包含的关键字,用英文逗号(全部不包含)或竖线(不包含其中一个)隔开,不可输入为空:"
# 用户输入不包含关键字,处理空输入情况
while True:
keywords_exclude_input = input(exclude_input_prompt).lower()
if not keywords_exclude_input.strip():
print("关键字不能为空,请重新输入。")
continue
break
# 处理关键字输入,支持逗号表示全部不包含,竖线表示不包含其中一个
if keywords_exclude_input == "default":
keywords_exclude = []
all_keywords_exclude = False
keywords_exclude_hint = "不包含其中一个"
else:
if "|" in keywords_exclude_input:
keywords_exclude = keywords_exclude_input.split("|")
all_keywords_exclude = False
keywords_exclude_hint = "不包含其中一个"
else:
keywords_exclude = keywords_exclude_input.split(",")
all_keywords_exclude = True
keywords_exclude_hint = "全部不包含"
# 用户选择包含关系
while True:
condition_choice = input("请选择包含、不包含关键字之间关系: (0:需要全部满足,1:满足其中一个即可,默认为0):")
if condition_choice in ['0', '1', '']:
condition_choice = int(condition_choice) if condition_choice else 0
break
else:
print("无效的选择,请重新输入。")
# 判断方法
def meets_conditions(content):
content_str = " ".join(content).lower()
if all_keywords_required:
include = all(keyword in content_str for keyword in keywords_include)
else:
include = any(keyword in content_str for keyword in keywords_include)
if all_keywords_exclude:
exclude = all(keyword not in content_str for keyword in keywords_exclude)
else:
exclude = any(keyword not in content_str for keyword in keywords_exclude)
if condition_choice == 0:
return include and exclude
else:
return include or (not exclude)
# 提取PPTX文件内容
def extract_pptx_content(file_path):
content = []
try:
prs = Presentation(file_path)
for slide in prs.slides:
for shape in slide.shapes:
if hasattr(shape, "text"):
content.append(shape.text)
if shape.has_text_frame:
for paragraph in shape.text_frame.paragraphs:
content.append(paragraph.text)
for run in paragraph.runs:
content.append(run.text)
for slide_note in slide.notes_slide.notes_text_frame.paragraphs:
content.append(slide_note.text)
except Exception as e:
return str(e) # 返回错误消息
return content
# 提取PPT文件内容
def extract_ppt_content(file_path):
content = []
try:
powerpoint = comtypes.client.CreateObject("Powerpoint.Application")
presentation = powerpoint.Presentations.Open(file_path)
for slide in presentation.Slides:
for shape in slide.Shapes:
if shape.HasTextFrame:
if shape.TextFrame.HasText:
content.append(shape.TextFrame.TextRange.Text)
slide_notes = slide.NotesPage.Shapes.Placeholders(2).TextFrame.TextRange.Text
content.append(slide_notes)
presentation.Close()
powerpoint.Quit()
except Exception as e:
return str(e) # 返回错误消息
return content
# 提取DOCX文件内容
def extract_docx_content(file_path):
content = []
try:
doc = Document(file_path)
for paragraph in doc.paragraphs:
content.append(paragraph.text)
except Exception as e:
return str(e) # 返回错误消息
return content
# 提取DOC文件内容
def extract_doc_content(file_path):
content = []
try:
word = comtypes.client.CreateObject("Word.Application")
doc = word.Documents.Open(file_path)
for paragraph in doc.Paragraphs:
content.append(paragraph.Range.Text)
doc.Close()
word.Quit()
except Exception as e:
return str(e) # 返回错误消息
return content
# 提取XLSX文件内容
def extract_excel_content(file_path):
content = []
try:
workbook = load_workbook(file_path)
for sheet_name in workbook.sheetnames:
sheet = workbook[sheet_name]
for row in sheet.iter_rows():
for cell in row:
if cell.value:
content.append(str(cell.value))
except Exception as e:
return str(e) # 返回错误消息
return content
# 提取XLS文件内容
def extract_xls_content(file_path):
content = []
try:
workbook = xlrd.open_workbook(file_path)
for sheet in workbook.sheets():
for row_index in range(sheet.nrows):
row = sheet.row_values(row_index)
for cell in row:
content.append(str(cell))
except Exception as e:
return str(e) # 返回错误消息
return content
# 提取CSV文件内容
def extract_csv_content(file_path):
content = []
try:
with open(file_path, 'r', encoding='utf-8', newline='') as csv_file:
reader = csv.reader(csv_file)
for row in reader:
for cell in row:
content.append(cell)
except Exception as e:
return str(e) # 返回错误消息
return content
# 提取TXT文件内容
def extract_txt_content(file_path):
content = []
try:
with open(file_path, 'r', encoding='utf-8') as txt_file:
content = txt_file.readlines()
except Exception as e:
return str(e) # 返回错误消息
return content
# 提取RTF文件内容
def extract_rtf_content(file_path):
try:
word = win32com.client.Dispatch("Word.Application")
doc = word.Documents.Open(file_path)
content = doc.Content.Text
doc.Close()
word.Quit()
return content
except Exception as e:
return str(e) # 返回错误消息
# 排版分割
print("\n"
"--------------结果--------------"
"\n")
# 输出选择的条件
print(f"包含的关键字:{keywords_include_input}")
print(f"不包含的关键字:{keywords_exclude_input}")
# 包含、不包含关键字之间关系打印中文结果
if condition_choice == 0:
print("包含、不包含关键字之间关系: 需要全部满足")
else:
print("包含、不包含关键字之间关系: 满足其中任何一个条件即可")
# 遍历选择的目录中的文件
if directory_path:
for filename in os.listdir(directory_path):
file_path = os.path.join(directory_path, filename)
is_satisfying = False # 标记文件是否满足条件
# 根据文件类型提取内容
if filename.lower().endswith((".pptx", ".ppt")):
content = extract_pptx_content(file_path) if filename.lower().endswith(".pptx") else extract_ppt_content(
file_path)
elif filename.lower().endswith(".docx"):
content = extract_docx_content(file_path)
elif filename.lower().endswith(".doc"): # 新增对 .doc 文件的处理
content = extract_doc_content(file_path)
elif filename.lower().endswith((".xlsx", ".xls")):
content = extract_excel_content(file_path) if filename.lower().endswith(".xlsx") else extract_xls_content(
file_path)
elif filename.lower().endswith(".csv"):
content = extract_csv_content(file_path)
elif filename.lower().endswith(".txt"):
content = extract_txt_content(file_path)
elif filename.lower().endswith(".rtf"):
rtf_content = extract_rtf_content(file_path)
if not keywords_include or meets_conditions([rtf_content]):
print("满足条件的文件名:", filename)
satisfying_file_count += 1
is_satisfying = True
else:
continue
if not is_satisfying and (not keywords_include or meets_conditions(content)):
print("满足条件的文件名:", filename)
satisfying_file_count += 1
# 输出满足条件的文件总数
print("满足条件的文件总数:", satisfying_file_count)
10.将检材“\Users\NJZhao”目录下的未删除文件与样本哈希库进行对比,给出命中哈希库的文件数量(不去重)
答案:将检材“\Users\NJZhao”目录下的未删除文件与样本哈希库进行对比,命中哈希库的文件数量(不去重)为2351条
过程:
· AccessData FTK Imager:将“\Users\NJZhao”目录下的所有文件的校验值导出至“校验值.csv”,共有记录18383条
· 使用DBeaver访问解压至本地的备份哈希库文件“RDS_2023.06.1_modern_minimal.db”,发现存在哈希库表FILE,字段md5。新建表FTK-md5sha1,将“校验值.csv”中18383条记录导入至新建的表中
· 使用SQL语句SELECT COUNT(1) FROM "FTK-md5sha1" where MD5 in (SELECT md5 from FILE ),查询出“\Users\NJZhao”目录下的未删除文件哈希值命中哈希库哈希值的记录2351条,即检材“\Users\NJZhao”目录下的未删除文件与样本哈希库进行对比,命中哈希库的文件数量(不去重)2351条