小白研究生入学1:如何快速写一个数据集处理脚本

————————————————————————————————————————

阅前提示:

本文针对于刚入学的研究生同学。如果你本科阶段基本上没有什么科研经验,也很少编码(例如知道Python,会用一点,但是完全不熟悉),导师丢过来一个数据集要预处理,但是看不懂数据集,或者看懂了不会写预处理的脚本。

本文在此抛砖引玉,教你如何使用AI来写一个预处理脚本。

PS:博主很菜,本文不涉及任何高深的知识。

————————————————————————————————————————

 一、数据集及其介绍

以atlasv2这个数据集为例

ATLASv2数据集在原始ATLAS数据集的基础上进行了扩展,主要包含三类日志数据:Windows安全审计系统日志、Firefox浏览器日志以及通过WireShark捕获的DNS日志。相较于原数据集,ATLASv2引入了更高质量的背景噪声,并增加了额外的日志来源,如Sysmon日志和通过VMware Carbon Black Cloud跟踪的事件。这个扩展旨在提供更全面和详细的攻击检测数据,支持深入分析和研究多种攻击场景。

数据集介绍:[2401.01341] ATLASv2: ATLAS Attack Engagements, Version 2 (arxiv.org)
其中一条数据如下,其实就是一系列的日志数据。

{"type":"endpoint.event.filemod","process_guid":"7DMF69PK-05debeef-000009b8-00000000-1d8984c85f4a992","parent_guid":"7DMF69PK-05debeef-000001e0-00000000-1d8984c83839290","backend_timestamp":"2022-07-19 07:26:53 +0000 UTC","org_key":"7DMF69PK","device_id":98483951,"device_name":"WIN-32-H1","device_external_ip":"130.126.255.183","device_os":"WINDOWS","device_group":"","action":"ACTION_FILE_CREATE | ACTION_FILE_MOD_OPEN | ACTION_FILE_OPEN_WRITE | ACTION_FILE_OPEN_SET_ATTRIBUTES","schema":1,"device_timestamp":"2022-07-19 07:24:57.2128941 +0000 UTC","process_terminated":false,"process_reputation":"REP_RESOLVING","parent_reputation":"REP_RESOLVING","process_pid":2488,"parent_pid":480.0,"process_publisher":[{"name":"Cortado AG","state":"FILE_SIGNATURE_STATE_SIGNED | FILE_SIGNATURE_STATE_VERIFIED"}],"process_path":"c:\\program files\\vmware\\vmware tools\\tpautoconnsvc.exe","parent_path":"c:\\windows\\system32\\services.exe","process_hash":["7bc6e9df892edd7e09c544b598fa5eb3","3e2b444059769eda3d0ca96ca7f8bf49f81193a370d37045b64098ce2c1707ae"],"parent_hash":["5f1b6a9c35d3d5ca72d6d6fdef9747d6","d7bc4ed605b32274b45328fd9914fb0e7b90d869a38f0e6f94fb1bf4e9e2b407"],"process_cmdline":"\"C:\\Program Files\\VMware\\VMware Tools\\TPAutoConnSvc.exe\"","parent_cmdline":"C:\\Windows\\system32\\services.exe","process_username":"NT AUTHORITY\\SYSTEM","sensor_action":"ACTION_ALLOW","event_origin":"EDR","filemod_hash":["",""],"filemod_name":"c:\\windows\\system32\\spool\\drivers\\w32x86\\tp ps driver 642d4d86fc304982923cb27485a07b19.ppd","regmod_name":null,"modload_name":null,"modload_count":null,"modload_effective_reputation":null,"modload_hash":null,"modload_md5":null,"modload_publisher":null,"modload_sha256":null,"process_duration":null,"target_cmdline":null,"remote_port":null,"remote_ip":null,"local_port":null,"local_ip":null,"netconn_domain":null,"netconn_inbound":null,"netconn_protocol":null,"netconn_community_id":null,"childproc_name":null,"childproc_hash":null,"childproc_pid":null,"childproc_guid":null,"childproc_username":null,"childproc_publisher":null,"childproc_reputation":null,"crossproc_name":null,"crossproc_guid":null,"crossproc_hash":null,"crossproc_action":null,"crossproc_publisher":null,"crossproc_reputation":null,"crossproc_target":null,"scriptload_count":null,"scriptload_reputation":null,"scriptload_effective_reputation":null,"scriptload_publisher":null}

二、任务要求 

依据OPM溯源模型,将该数据集处理成为,源节点,目标节点,边的溯源图数据。

//如果你从未接触过溯源相关的东西,在刚看到这个数据集的时候,有可能会很迷茫。再加上如果你在本科阶段很少写代码,那么这可能就是一个艰巨的任务。

三、分析数据集

 //我这里分别使用的ChatGPT 4o mini和Kimi来完成接下的几步。(注意Kimi在内网内,目前可以免费使用;ChatGPT 4o mini需要一点魔法上网的技巧,当然它可以免注册免费使用,不要被淘宝上付费的骗了)

 1.ChatGPT 4o mini

问1:让AI帮我们初步分析一下数据集,找出我们需要关注的位置,也帮我们更好地理解该数据集

答1:

问2:进一步找到具体的数据项

答2:

问3:因为我这个数据集的type类型不止有filemod这种,所以我这里还让它给我写了一个找出所有类型的代码

答3:

import json

# 读取数据集文件
def read_json_file(filename):
    types_set = set()
    with open(filename, 'r') as file:
        for line in file:
            record = json.loads(line)
            event_type = record.get('type')
            if event_type:
                types_set.add(event_type)
    return types_set

# 主程序
if __name__ == "__main__":
    filename = 'dataset.json'  # 替换为实际的数据集文件名
    unique_types = read_json_file(filename)
    
    # 打印所有唯一的type类型
    for event_type in unique_types:
        print(event_type)

PS:在本文的末尾,我会附上Windows上配置anaconda环境的方法,以及针对于很少跑Python代码的宝宝,附上如何跑AI输出的这些脚本的注意事项。

问4:我让ChatGPT写了一个输出找到该类型的第一条数据(因为数据太多了,自己找有些时候那种占比很低的类型找不到)。这个地方的type可以更换成别的,都很好用的。

答4:

import json

def find_first_filemod_entry(filename):
    with open(filename, 'r') as file:
        for line in file:
            record = json.loads(line)
            if record.get('type') == 'endpoint.event.filemod':
                return record
    return None

# 主程序
if __name__ == "__main__":
    filename = 'dataset.json'  # 替换为实际的数据集文件名
    first_filemod_entry = find_first_filemod_entry(filename)
    
    if first_filemod_entry:
        print(json.dumps(first_filemod_entry, indent=4))
    else:
        print("No 'endpoint.event.filemod' type found in the dataset.")

2.Kimi(用它的原因是,它目前不要钱,灵动AI用来写一些脚本其实也还行,但是要钱)

//问法还是和上面一样的,我这里只截取Kimi的回答

答1:

答2:(这条我觉得Kimi答的更好一点)

答3:

import json
from collections import Counter

# 假设数据集是一个名为 dataset.json 的文件
filename = 'dataset.json'

# 读取JSON数据
with open(filename, 'r') as file:
    data = json.load(file)

# 初始化计数器
type_counter = Counter()

# 遍历数据集中的每个条目
for item in data:
    # 增加对应类型的计数
    type_counter[item['type']] += 1

# 打印每种类型及其数量
for type, count in type_counter.items():
    print(f"Type: {type}, Count: {count}")

答4:

import json

# 假设数据集是一个名为 dataset.json 的文件
filename = 'dataset.json'

# 读取JSON数据
with open(filename, 'r') as file:
    data = json.load(file)

# 初始化一个标志变量,用于标记是否已经找到第一条符合条件的数据
found = False

# 遍历数据集中的每个条目
for item in data:
    # 检查条目的类型是否为 endpoint.event.filemod
    if item.get('type') == 'endpoint.event.filemod':
        # 输出找到的第一条符合条件的数据
        print(json.dumps(item, indent=4))
        # 设置标志变量为 True
        found = True
        break  # 找到后即退出循环

# 如果没有找到符合条件的数据,则打印提示信息
if not found:
    print("No data found with type 'endpoint.event.filemod'.")

 四、数据预处理程序

1.ChatGPT 4o mini

问1:我们依据上一步的分析,具体地告诉AI,我需要处理成为的数据集是怎样的

答1:

import json
import uuid
from urllib.parse import quote

def process_record(record):
    # 处理 `type` 为 `endpoint.event.filemod` 的记录
    if record.get('type') != 'endpoint.event.filemod':
        return None
    
    # 提取字段
    src_uuid = record.get('process_guid')
    src_name = record.get('process_path')
    dst_name = record.get('filemod_name')
    
    # 处理 dst_name 成为 UUID 形式
    # 这里使用 UUID 的哈希作为示例,实际情况下可能需要根据具体需求处理
    dst_uuid = str(uuid.uuid5(uuid.NAMESPACE_DNS, dst_name))
    
    # 提取 `action` 并获取第一项
    actions = record.get('action', '').split(' | ')
    operation_type = actions[0] if actions else None
    
    # 截取 `backend_timestamp` 到秒
    backend_timestamp = record.get('backend_timestamp', '')
    timestamp = backend_timestamp.split('.')[0]  # 截取到秒
    
    # 构造结果字典
    processed_record = {
        'src_uuid': src_uuid,
        'src_name': src_name,
        'dst_name': dst_name,
        'dst_uuid': dst_uuid,
        'operation_type': operation_type,
        'timestamp': timestamp
    }
    
    return processed_record

def preprocess_jsonl_file(input_filename, output_filename):
    with open(input_filename, 'r') as infile, open(output_filename, 'w') as outfile:
        for line in infile:
            record = json.loads(line)
            processed_record = process_record(record)
            if processed_record:
                outfile.write(json.dumps(processed_record) + '\n')

# 主程序
if __name__ == "__main__":
    input_filename = 'input_dataset.jsonl'  # 替换为实际的数据集文件名
    output_filename = 'processed_dataset.jsonl'  # 替换为处理后数据的文件名
    preprocess_jsonl_file(input_filename, output_filename)

在有了脚本后,就可以更换一下,input_filename和output_filename跑了。

2.Kimi

问1:同上

答1:

import json
import uuid
from datetime import datetime

# 假设数据集是一个名为 dataset.jsonl 的文件
filename = 'dataset.jsonl'

# 打开文件并逐行读取
with open(filename, 'r') as file:
    for line in file:
        # 将每行的JSON字符串转换为字典
        data = json.loads(line)
        
        # 检查数据类型是否为 endpoint.event.filemod
        if data.get('type') == 'endpoint.event.filemod':
            # 提取所需的信息
            src_uuid = data.get('process_guid')
            src_name = data.get('process_path').replace('\\', '\\\\')  # 转义反斜杠
            dst_name = data.get('filemod_name')
            operation_type = data.get('action').split(' | ')[0] if data.get('action') else None
            timestamp = data.get('backend_timestamp').split('.')[0]  # 截取到秒

            # 将文件名处理成uuid形式
            dst_uuid = str(uuid.uuid5(uuid.NAMESPACE_DNS, dst_name))

            # 打印提取和处理后的信息
            print(f"src_uuid: {src_uuid}")
            print(f"src_name: {src_name}")
            print(f"dst_uuid: {dst_uuid}")
            print(f"dst_name: {dst_name}")
            print(f"operation_type: {operation_type}")
            print(f"timestamp: {timestamp}")
            print("-" * 40)  # 分隔线

问2:因为Kimi答的脚步,输出的样式不是我想要的,所以这里我追加一问,试图驯服。

答2:

import json
import uuid
from datetime import datetime

# 假设数据集是一个名为 dataset.jsonl 的文件
filename = 'dataset.jsonl'
output_filename = 'processed_data.csv'

# 打开输出文件并准备写入
with open(output_filename, 'w') as outfile:
    # 写入CSV文件的标题行
    csv_header = "src_uuid,src_name,dst_uuid,dst_name,operation_type,timestamp\n"
    outfile.write(csv_header)

    # 打开数据集文件并逐行读取
    with open(filename, 'r') as file:
        for line in file:
            # 将每行的JSON字符串转换为字典
            data = json.loads(line)
            
            # 检查数据类型是否为 endpoint.event.filemod
            if data.get('type') == 'endpoint.event.filemod':
                # 提取所需的信息
                src_uuid = data.get('process_guid')
                src_name = data.get('process_path')
                dst_name = data.get('filemod_name')
                operation_type = data.get('action').split('|')[0] if data.get('action') else ''
                timestamp = datetime.strptime(data.get('backend_timestamp'), "%Y-%m-%d %H:%M:%S %z").strftime("%Y-%m-%d %H:%M:%S")

                # 将文件名处理成uuid形式作为dst_uuid
                dst_uuid = str(uuid.uuid5(uuid.NAMESPACE_DNS, dst_name))

                # 构建CSV行数据
                csv_row = f"{src_uuid},{src_name},{dst_uuid},{dst_name},{operation_type},{timestamp}\n"
                
                # 写入处理后的数据到CSV文件
                outfile.write(csv_row)

print(f"Data has been processed and saved to {output_filename}")

五、结果分析

1.ChatGPT 4o mini(PS:这是我之前跑的ChatGPT给的代码,和这个博客中的略有区别,但大体相同,在写博客的时候,存数据集的那个移动硬盘不在身边,所以Kimi的没有测试)

src_name,src_uuid,dst_name,dst_uuid,action,timestamp
c:\program files\vmware\vmware tools\tpautoconnsvc.exe,7DMF69PK-05debeef-000009b8-00000000-1d8984c85f4a992,c:\windows\system32\spool\drivers\w32x86\tp ps driver 642d4d86fc304982923cb27485a07b19.ppd,639f300d-a182-5f56-9154-e0cd0bbd5f4a,ACTION_FILE_CREATE,2022-07-19 07:24:57.2128941 +0000 UTC
c:\windows\system32\spoolsv.exe,7DMF69PK-05debeef-0000055c-00000000-1d8984c843f9f45,c:\windows\system32\spool\drivers\w32x86\3\new\tp ps driver 642d4d86fc304982923cb27485a07b19.ppd,4684e834-7f6b-5834-acd0-a8c8f1668bd6,ACTION_FILE_CREATE,2022-07-19 07:24:57.227895 +0000 UTC
c:\windows\system32\spoolsv.exe,7DMF69PK-05debeef-0000055c-00000000-1d8984c843f9f45,c:\windows\system32\spool\drivers\w32x86\3\new\tp ps driver 642d4d86fc304982923cb27485a07b19.ppd,4684e834-7f6b-5834-acd0-a8c8f1668bd6,ACTION_FILE_MOD_OPEN,2022-07-19 07:24:57.228895 +0000 UTC
c:\windows\system32\spoolsv.exe,7DMF69PK-05debeef-0000055c-00000000-1d8984c843f9f45,c:\windows\system32\spool\drivers\w32x86\3\new\tp ps driver 642d4d86fc304982923cb27485a07b19.ppd,4684e834-7f6b-5834-acd0-a8c8f1668bd6,ACTION_FILE_RENAME,2022-07-19 07:24:57.228895 +0000 UTC

附录(IF 你并不知道如何在Windows上跑Python代码)

我这里使用的anaconda(Anaconda 是一个开源的 Python 和 R 语言的发行版,专为数据科学和机器学习工作流设计。它包括了 Python 解释器、常用的数据科学库(如 NumPy、Pandas、SciPy、Matplotlib)、以及 Conda 包管理器。)

Windows上安装anaconda的方法(下载下安装包,然后安装……这个很简单的,注意的是,anaconda自身是带有Python解释器的,就不大需要再安装Python了,当然如果你要用的Python和anaconda自带的版本不同的话,就要考虑再安装)

官网下载地址:Download Anaconda Distribution | Anaconda

实在不会可以参考这个:手把手教你如何在 Windows 安装 Anaconda - 哔哩哔哩 (bilibili.com)

一些注意事项和我个人使用的时候是怎么弄的(不一定是最好的方法)

1.我应该怎么用anaconda?

一般来说我是直接使用它那个命令行Anaconda Powershell Prompt(如果你要切换目录之类的操作,最好以管理员身份运行),进去后,它刚开始是全黑的,enter一下就好了

然后cd到你存放脚本的目录,python  你的脚本.py 就能够用了

当然我们一般不在base下面跑,一般会create一个环境来跑,像这样:

这个创建环境的过程,一般问啥你就y(yes)就行了

创建好了就是这个样子:

进入我的环境,括号里的内容从base变成了你的环境名就成功了

2.我应该怎么跑我的脚本,报错说缺包怎么办?

假设你不知道要安装什么包,这个时候可以询问AI

例如:

问1:

答1:

因此我们进入我们创建的test环境后,再输出这行指令就行了,具体地为:
 

conda activate test
conda install tqdm

结束

假设这篇文章能够帮助到你,这会让我十分高兴。

06-07 1396
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值