{"id":18838070,"url":"https://github.com/ivlyth/prsdata","last_synced_at":"2025-04-14T06:22:50.493Z","repository":{"id":75143480,"uuid":"299572588","full_name":"Ivlyth/prsdata","owner":"Ivlyth","description":"find, modify and replay with pcap","archived":false,"fork":false,"pushed_at":"2021-11-18T05:53:22.000Z","size":223,"stargazers_count":6,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-27T20:11:18.423Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Ivlyth.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2020-09-29T09:46:45.000Z","updated_at":"2022-05-04T21:15:33.000Z","dependencies_parsed_at":"2023-07-12T21:45:45.535Z","dependency_job_id":null,"html_url":"https://github.com/Ivlyth/prsdata","commit_stats":null,"previous_names":["mythren/prsdata"],"tags_count":22,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ivlyth%2Fprsdata","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ivlyth%2Fprsdata/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ivlyth%2Fprsdata/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ivlyth%2Fprsdata/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Ivlyth","download_url":"https://codeload.github.com/Ivlyth/prsdata/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248831062,"owners_count":21168395,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-08T02:37:51.823Z","updated_at":"2025-04-14T06:22:50.469Z","avatar_url":"https://github.com/Ivlyth.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"跟流量相关的日常测试，就是 根据条件查找 pcap, 修改 pcap, 然后利用修改后的 pcap 执行某些软件命令的过程\n\n##### 1. 查找 pcap 通常可能用到的条件\n- 在指定的目录内查找\n- 按照 平均包大小 范围查找\n- 按照 PPS 范围查找\n- 按照 文件名称 模糊查找\n- 按照 包数量 范围查找\n\n##### 2. 修改 pcap 通常会用到的条件\n- 是否修改 pcap 内的 packet 时间, 修改到什么时候\n- 是否修改 pcap 内的 IP 地址, 修改到什么范围, 多大的范围\n\n##### 3. 执行命令通常会用到的内容\n- 命令执行主要是靠相关软件本身的命令行参数, 比如 zeek -r 支持从 pcap 读取数据工作, 此时最需要的就是待测 pcap 的路径\n- 有时候可能需要使用不同的 pcap 执行不同的命令， 且有先后顺序关系, 甚至中间需要进行一定时长的等待\n\n#### 基于以上分析, 抽象如下数据结构定义来描述上述概念:\n\n##### 1. 抽象 Finder, 用于定义如何查找 pcap\n```go\ntype Finder struct {\n    // finder 的 ID, 默认是 default, 用于 Job 和 Command 引用\n\tId              string   `mapstructure:\"id\"`\n    // 从哪个目录查找\n\tDirectory       string   `mapstructure:\"directory\"` // from user\n    // 文件名的模式\n\tPatterns        []string `mapstructure:\"patterns\"`\n    // 使用的 modifier 的 ID, 默认为 default\n\tModifierId      string   `mapstructure:\"modifier\"`\n\t// pps 小于 xxx, 默认为 0 无限制\n\tPpsLE           float64  `mapstructure:\"pps_le\"`\n    // pps 大于 xxx, 默认为 0 无限制\n\tPpsGE           float64  `mapstructure:\"pps_ge\"`\n    // packet count 小于 xxx, 默认为 0 无限制\n\tPacketCountLe   int64    `mapstructure:\"packet_count_le\"`\n    // packet count 大于 xxx, 默认为 0 无限制\n\tPacketCountGe   int64    `mapstructure:\"packet_count_ge\"`\n    // avg packet size 小于 xxx, 默认为 0 无限制\n\tAvgPacketSizeLE float64  `mapstructure:\"avg_packet_size_le\"`\n    // avg packet size 大于 xxx, 默认为 0 无限制\n\tAvgPacketSizeGE float64  `mapstructure:\"avg_packet_size_ge\"`\n    \n    // ModifierId 找到的 modifier\n\tmodifier        *Modifier\n}\n```\n\n##### 2. 抽象 Modifier, 用于定义如何修改 pcap\n```go\ntype Modifier struct {\n    // modifier 的 ID, 默认是 default, 用于 Finder 引用\n\tId string `mapstructure:\"id\"`\n    \n    // 定义是否修改时间\n\tAdjustTime bool          `mapstructure:\"adjust_time\"`\n    // 将时间修改到什么时候, 采用 go time.Duration 表示, 可以使用诸如 1h3m5s 等语法表示\n\tTimeOffset time.Duration `mapstructure:\"time_offset\"`\n\t\n    // 是否要保持 IP, 默认是 false, 即 修改 IP\n\tKeepIp   bool `mapstructure:\"keep_ip\"`\n    // 自定义客户端 IP 的 第 1 段\n\tC1       int  `mapstructure:\"c1\"`\n    // 自定义客户端 IP 的 第 2 段\n\tC2       int  `mapstructure:\"c2\"`\n    // 自定义客户端 IP 的 第 3 段\n\tC3       int  `mapstructure:\"c3\"`\n    // 自定义客户端 IP 的 第 4 段\n\tC4       int  `mapstructure:\"c4\"`\n    // 自定义服务端 IP 的 第 1 段\n\tS1       int  `mapstructure:\"s1\"`\n    // 自定义服务端 IP 的 第 2 段\n\tS2       int  `mapstructure:\"s2\"`\n    // 自定义服务端 IP 的 第 3 段\n\tS3       int  `mapstructure:\"s3\"`\n    // 自定义服务端 IP 的 第 4 段\n\tS4       int  `mapstructure:\"s4\"`\n    // 是否使用自定义的第 3 段\n\tUsePart3 bool `mapstructure:\"use_part_3\"`\n    // 是否使用自定义的第 4 段\n\tUsePart4 bool `mapstructure:\"use_part_4\"`\n}\n```\n\n##### 3. 抽象 Command, 用于定义执行什么命令\n```go\ntype Command struct {\n    // 命令的名称, 主要用于人可读\n\tName      string        `mapstructure:\"name\"`\n    // 要执行的命令, 包含必要的参数在内\n\tCommand   string        `mapstructure:\"command\"`\n    // 执行命令前 chroot 到指定目录, 可以为空\n\tDirectory string        `mapstructure:\"directory\"`\n    // 命令类型, 当前主要是两种类型: shell 和 pcap(默认值)\n    // 区别是 pcap 类型的会使用 finder 找到的每一个 pcap 执行该命令(所以正常来讲, 命令内应该存在预定义变量占位符)\n\tType      string        `mapstructure:\"type\"`\n    // 命令执行的超时时间, 默认 30s, 允许自定义, 使用 1h2m3s 的语法\n\tTimeout   time.Duration `mapstructure:\"timeout\"`\n    // 使用的 finder ID, 如果无定义从 Job 继承\n\tFinderId  string        `mapstructure:\"finder\"` // if not provide, use Job's\n    \n    // 所属任务\n\tjob    *Job\n    // FinderId 对应的 finder\n\tfinder *Finder\n}\n```\n\n##### 4. 抽象 Job, 用于定义命令分组\n```go\ntype Job struct {\n    // job 的 ID, 主要用于命令行筛选\n\tId       string     `mapstructure:\"id\"`\n    // job 的名称, 主要用于人可读\n\tName     string     `mapstructure:\"name\"`\n    // job 内的命令列表, 顺序执行\n\tCommands []*Command `mapstructure:\"commands\"`\n    // 是否启用\n\tEnable   bool       `mapstructure:\"enable\"`\n\t// 使用的 Finder ID, 默认为 default\n\tFinderId string `mapstructure:\"finder\"`\n\n\tfinder *Finder\n}\n```\n\n![model.jpg](./model.jpg)\n\n#### 配置文件\nprsdata 支持从配置文件读取配置(可以无配置文件工作, 但是 Job 为内置硬编码, 仅可通过命令行修改 默认的 finder 和 modifier, 以及控制参数)\n配置文件格式采用 YAML, 默认的配置路径为 ~/.prsdata.yml, 但是可以采用 `-f` 参数明确指定为其他路径\n\n支持的参数列表如下:\n\n```text\n[root@prs-sensor ~]# prsdata -h\n\nUsage:\n  prsdata [flags]\n\nFlags:\n  // 可以通过 -f 使用指定的配置文件\n  -f, --config-file string           配置文件路径 (default \"/root/.prsdata.yml\")\n  -C, --concurrency-jobs int         并发 job 数量 (default 6)\n  -c, --concurrency-commands int     并发 command 数量 (default 6)\n  // job 的循环执行次数\n  -T, --test-times int               测试轮数 (default 1)\n      --debug                        debug mode\n  // 控制 prsdata 的最大运行时长, 通常配合 -T 使用\n  -D, --duration duration            最大运行时长, 0 表示不限制, 可以使用诸如 1h3m5s 的表达式\n  // 命令的执行超时时间, 可以在命令定义处使用 timeout 覆盖\n  -S, --command-timeout duration     默认的单个命令执行时长 (default 30s)\n  // prsdata 工作过程中产生的所有临时文件均保存在该处\n  -w, --temporary-directory string   默认的临时文件夹 (default \"/data/.prsdata/history/\")\n  // 仅打印 job 列表, 常用于调试配置文件内容\n  -J, --just-show-jobs               仅打印加载的 job 列表\n  // 仅打印加载到的 pcap 列表, 常用于测试配置的 finder 是否符合预期\n  -j, --just-show-pcaps              仅打印加载的 pcap 列表\n      --show-command                 打印正在执行的命令\n      --show-stdout                  打印正在执行的命令及其输出\n      --show-why                     展示 pcap 未被加载的原因\n      --keep-data                    是否保留数据\n  -O, --jobs strings                 仅执行指定的 ID 对应的 job, 逗号分割指定多个\n      --daemon                       后台运行\n      --pingback string              daemon 模式下的 pingback 地址, 请勿手动指定\n  \n  // 默认的 modifier 配置\n  -a, --adjust-time                  adjust time or not (default true)\n  -t, --time-offset duration         time offset\n      --keep-ip                      keep ip or not\n      --c1 int                       c1 (default 192)\n      --c2 int                       c2 (default 168)\n      --c3 int                       c3 (default 186)\n      --c4 int                       c4 (default 11)\n      --s1 int                       s1 (default 10)\n      --s2 int                       s2 (default 132)\n      --s3 int                       s3 (default 123)\n      --s4 int                       s4 (default 22)\n  -3, --use-part-3                   use part 3 or not\n  -4, --use-part-4                   use part 4 or not\n \n  // 默认的 finder 配置\n  -d, --directory string             pcap search directory (default \"/data/.prsdata/pcaps/\")\n  -p, --patterns strings             patterns for filter pcap\n      --pps-le int                   pps less than or equal to given value\n      --pps-ge int                   pps greater than or equal to given value\n      --packet-count-le int          packet count less than or equal to given value\n      --packet-count-ge int          packet count greater than or equal to given value\n      --avg-packet-size-le int       avg packet size less than or equal to given value\n      --avg-packet-size-ge int       avg packet size greater than or equal to given value\n      \n      // 以下用于配置使用到的相关工具路径(仅填写名称会使用 $PATH 环境变量进行查找)\n      --bash string                  bash path (default \"bash\")\n      --capinfos string              capinfos path (default \"capinfos\")\n      --editcap string               editcap path (default \"editcap\")\n      --tcpdump string               tcpdump path (default \"tcpdump\")\n      --tcprewrite string            tcprewrite path (default \"tcprewrite\")\n      --tcpprep string               tcpprep path (default \"tcpprep\")\n\n  -V, --version                      show version\n  -h, --help                         help for prsdata\n```\n\n对应的配置文件样例:\n\n```yaml\nconfig:\n  concurrency_jobs: 2\n  concurrency_commands: 6\n  test_times: 1\n  duration: 0\n  command_timeout: 30s\n  debug: false\n\n  tool:\n    bash: bash\n    capinfos: capinfos\n    editcap: editcap\n    tcpdump: tcpdump\n    tcprewrite: tcprewrite\n    tcpprep: tcpprep\n    p426: p426\n\n  modifier:\n    adjust_time: true  # default is false, you must set it explicit\n    time_offset: 0s\n    keep_ip: false\n    c1: 192\n    c2: 168\n    c3: 186\n    c4: 11\n    s1: 10\n    s2: 132\n    s3: 123\n    s4: 22\n    use_part_3: false\n    use_part_4: false\n\n  finder:\n    directory: /data/.prsdata/pcaps/\n\njobs:\n  - id: zeek\n    name: zeek\n    enable: true\n    commands:\n      - name: zeek\n        command: /opt/zeek/bin/zeek -r {{.RelativePath}} -C /opt/zeek-scripts/tophant.entrypoint.zeek\n        directory: \"{{.FinderDirectory}}\"\n\n  - id: suricata\n    name: suricata\n    enable: true\n    commands:\n      - name: suricata\n        command: /opt/suricata/bin/suricata -c /opt/suricata/etc/suricata/suricata.yaml -r {{.RelativePath}} -k none --runmode autofp\n        directory: \"{{.FinderDirectory}}\"\n\n  - id: fpc\n    name: fpc\n    enable: false\n    commands:\n      - name: moloch\n        command: /data/moloch/bin/moloch-capture --insecure -c /data/moloch/etc/config.ini -r {{.RelativePath}}\n        directory: \"{{.FinderDirectory}}\"\n\n```\n\n丰富的配置文件样例:\n\n```yaml\nconfig:\n  concurrency_jobs: 2\n  concurrency_commands: 6\n  test_times: 1\n  debug: false\n  duration: 0\n\n  tool:\n    bash: bash\n    capinfos: capinfos\n    editcap: editcap\n    tcpdump: tcpdump\n    tcprewrite: tcprewrite\n    tcpprep: tcpprep\n\n  modifier:\n    adjust_time: true  # default is false, you must set it explicit\n    time_offset: 0s\n    keep_ip: false\n    c1: 192\n    c2: 168\n    c3: 186\n    c4: 11\n    s1: 10\n    s2: 132\n    s3: 123\n    s4: 22\n    use_part_3: false\n    use_part_4: false\n\n  finder:\n    directory: /data/.prsdata/pcaps/\n\nmodifiers:\n  - id: pvs\n    keep_ip: true\n  - id: dga\n    time_offset: 1h\n\nfinders:\n  - id: pvs\n    directory: /data/.prsdata/pcaps/pvs\n    modifier: pvs\n\n  - id: dga\n    directory: /data/.prsdata/pcaps/dga\n    modifier: dga\n\njobs:\n  - id: zeek\n    name: zeek pvs\n    enable: true\n    finder: pvs\n    commands:\n      - name: zeek\n        command: /opt/zeek/bin/zeek -r {{.RelativePath}} -C /opt/zeek-scripts/tophant.entrypoint.zeek\n        directory: \"{{.FinderDirectory}}\"\n\n  - id: suricata\n    name: suricata\n    enable: true\n    commands:\n      - name: suricata\n        # 因为 job 和 command 都没有定义明确定义 finder, 那么用的就是默认的 finder\n        # finder: default\n        command: /opt/suricata/bin/suricata -c /opt/suricata/etc/suricata/suricata.yaml -r {{.RelativePath}} -k none --runmode autofp\n        directory: \"{{.FinderDirectory}}\"\n\n      - name: test sleep\n        command: sleep 1000\n        timeout: 1002s\n\n      - name: zeek dga\n        finder: dga\n        command: /opt/zeek/bin/zeek -r {{.RelativePath}} -C /opt/zeek-scripts/tophant.entrypoint.zeek\n        directory: \"{{.FinderDirectory}}\"\n\n```\n\n##### 命令模版\ntype 为 pcap 类型的 command, 其 command 内容可以包含预定义的变量. 预定义变量列表如下:\n\n```go\nWorkingDirectory  - prsdata 本次的临时工作目录路径\nFinderDirectory   - 当前 pcap 使用的 finder 对应的目录路径\nPcapDirectory     - 当前 pcap 所在目录路径\nRelativeDirectory - 当前 pcap 所在目录基于 WorkingDirectory 的相对路径信息\nRelativePath      - 当前 pcap 路径基于 WorkingDirectory 的相对路径\nPath              - 当前 pcap 的完整路径\nBaseName          - 当前 pcap 的文件名称\nName              - 当前 pcap 不包含后缀的文件名称 \nExt               - 当前 pcap 的后缀信息\n```\n\n样例数据如下:\n\n```\nWorkingDirectory  - /data/.prsdata/history/prsdata-2020_09_29_17_19_31-14696\nFinderDirectory   - /data/.prsdata/history/prsdata-2020_09_29_17_19_31-14696/finder-default\nPcapDirectory     - /data/.prsdata/history/prsdata-2020_09_29_17_19_31-14696/finder-default/all-pcap/vulnerability/tunnel/dns_tunnel\nRelativeDirectory - all-pcap/vulnerability/tunnel/dns_tunnel\nRelativePath      - all-pcap/vulnerability/tunnel/dns_tunnel/dns_oob.pcap\nPath              - /data/.prsdata/history/prsdata-2020_09_29_17_19_31-14696/finder-default/all-pcap/vulnerability/tunnel/dns_tunnel/dns_oob.pcap\nBaseName          - dns_oob.pcap\nName              - dns_oob\nExt               - .pcap\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fivlyth%2Fprsdata","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fivlyth%2Fprsdata","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fivlyth%2Fprsdata/lists"}