Skip to content

Ivlyth/prsdata

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

30 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

跟流量相关的日常测试,就是 根据条件查找 pcap, 修改 pcap, 然后利用修改后的 pcap 执行某些软件命令的过程

1. 查找 pcap 通常可能用到的条件
  • 在指定的目录内查找
  • 按照 平均包大小 范围查找
  • 按照 PPS 范围查找
  • 按照 文件名称 模糊查找
  • 按照 包数量 范围查找
2. 修改 pcap 通常会用到的条件
  • 是否修改 pcap 内的 packet 时间, 修改到什么时候
  • 是否修改 pcap 内的 IP 地址, 修改到什么范围, 多大的范围
3. 执行命令通常会用到的内容
  • 命令执行主要是靠相关软件本身的命令行参数, 比如 zeek -r 支持从 pcap 读取数据工作, 此时最需要的就是待测 pcap 的路径
  • 有时候可能需要使用不同的 pcap 执行不同的命令, 且有先后顺序关系, 甚至中间需要进行一定时长的等待

基于以上分析, 抽象如下数据结构定义来描述上述概念:

1. 抽象 Finder, 用于定义如何查找 pcap
type Finder struct {
    // finder 的 ID, 默认是 default, 用于 Job 和 Command 引用
	Id              string   `mapstructure:"id"`
    // 从哪个目录查找
	Directory       string   `mapstructure:"directory"` // from user
    // 文件名的模式
	Patterns        []string `mapstructure:"patterns"`
    // 使用的 modifier 的 ID, 默认为 default
	ModifierId      string   `mapstructure:"modifier"`
	// pps 小于 xxx, 默认为 0 无限制
	PpsLE           float64  `mapstructure:"pps_le"`
    // pps 大于 xxx, 默认为 0 无限制
	PpsGE           float64  `mapstructure:"pps_ge"`
    // packet count 小于 xxx, 默认为 0 无限制
	PacketCountLe   int64    `mapstructure:"packet_count_le"`
    // packet count 大于 xxx, 默认为 0 无限制
	PacketCountGe   int64    `mapstructure:"packet_count_ge"`
    // avg packet size 小于 xxx, 默认为 0 无限制
	AvgPacketSizeLE float64  `mapstructure:"avg_packet_size_le"`
    // avg packet size 大于 xxx, 默认为 0 无限制
	AvgPacketSizeGE float64  `mapstructure:"avg_packet_size_ge"`
    
    // ModifierId 找到的 modifier
	modifier        *Modifier
}
2. 抽象 Modifier, 用于定义如何修改 pcap
type Modifier struct {
    // modifier 的 ID, 默认是 default, 用于 Finder 引用
	Id string `mapstructure:"id"`
    
    // 定义是否修改时间
	AdjustTime bool          `mapstructure:"adjust_time"`
    // 将时间修改到什么时候, 采用 go time.Duration 表示, 可以使用诸如 1h3m5s 等语法表示
	TimeOffset time.Duration `mapstructure:"time_offset"`
	
    // 是否要保持 IP, 默认是 false, 即 修改 IP
	KeepIp   bool `mapstructure:"keep_ip"`
    // 自定义客户端 IP 的 第 1 段
	C1       int  `mapstructure:"c1"`
    // 自定义客户端 IP 的 第 2 段
	C2       int  `mapstructure:"c2"`
    // 自定义客户端 IP 的 第 3 段
	C3       int  `mapstructure:"c3"`
    // 自定义客户端 IP 的 第 4 段
	C4       int  `mapstructure:"c4"`
    // 自定义服务端 IP 的 第 1 段
	S1       int  `mapstructure:"s1"`
    // 自定义服务端 IP 的 第 2 段
	S2       int  `mapstructure:"s2"`
    // 自定义服务端 IP 的 第 3 段
	S3       int  `mapstructure:"s3"`
    // 自定义服务端 IP 的 第 4 段
	S4       int  `mapstructure:"s4"`
    // 是否使用自定义的第 3 段
	UsePart3 bool `mapstructure:"use_part_3"`
    // 是否使用自定义的第 4 段
	UsePart4 bool `mapstructure:"use_part_4"`
}
3. 抽象 Command, 用于定义执行什么命令
type Command struct {
    // 命令的名称, 主要用于人可读
	Name      string        `mapstructure:"name"`
    // 要执行的命令, 包含必要的参数在内
	Command   string        `mapstructure:"command"`
    // 执行命令前 chroot 到指定目录, 可以为空
	Directory string        `mapstructure:"directory"`
    // 命令类型, 当前主要是两种类型: shell 和 pcap(默认值)
    // 区别是 pcap 类型的会使用 finder 找到的每一个 pcap 执行该命令(所以正常来讲, 命令内应该存在预定义变量占位符)
	Type      string        `mapstructure:"type"`
    // 命令执行的超时时间, 默认 30s, 允许自定义, 使用 1h2m3s 的语法
	Timeout   time.Duration `mapstructure:"timeout"`
    // 使用的 finder ID, 如果无定义从 Job 继承
	FinderId  string        `mapstructure:"finder"` // if not provide, use Job's
    
    // 所属任务
	job    *Job
    // FinderId 对应的 finder
	finder *Finder
}
4. 抽象 Job, 用于定义命令分组
type Job struct {
    // job 的 ID, 主要用于命令行筛选
	Id       string     `mapstructure:"id"`
    // job 的名称, 主要用于人可读
	Name     string     `mapstructure:"name"`
    // job 内的命令列表, 顺序执行
	Commands []*Command `mapstructure:"commands"`
    // 是否启用
	Enable   bool       `mapstructure:"enable"`
	// 使用的 Finder ID, 默认为 default
	FinderId string `mapstructure:"finder"`

	finder *Finder
}

model.jpg

配置文件

prsdata 支持从配置文件读取配置(可以无配置文件工作, 但是 Job 为内置硬编码, 仅可通过命令行修改 默认的 finder 和 modifier, 以及控制参数) 配置文件格式采用 YAML, 默认的配置路径为 ~/.prsdata.yml, 但是可以采用 -f 参数明确指定为其他路径

支持的参数列表如下:

[root@prs-sensor ~]# prsdata -h

Usage:
  prsdata [flags]

Flags:
  // 可以通过 -f 使用指定的配置文件
  -f, --config-file string           配置文件路径 (default "/root/.prsdata.yml")
  -C, --concurrency-jobs int         并发 job 数量 (default 6)
  -c, --concurrency-commands int     并发 command 数量 (default 6)
  // job 的循环执行次数
  -T, --test-times int               测试轮数 (default 1)
      --debug                        debug mode
  // 控制 prsdata 的最大运行时长, 通常配合 -T 使用
  -D, --duration duration            最大运行时长, 0 表示不限制, 可以使用诸如 1h3m5s 的表达式
  // 命令的执行超时时间, 可以在命令定义处使用 timeout 覆盖
  -S, --command-timeout duration     默认的单个命令执行时长 (default 30s)
  // prsdata 工作过程中产生的所有临时文件均保存在该处
  -w, --temporary-directory string   默认的临时文件夹 (default "/data/.prsdata/history/")
  // 仅打印 job 列表, 常用于调试配置文件内容
  -J, --just-show-jobs               仅打印加载的 job 列表
  // 仅打印加载到的 pcap 列表, 常用于测试配置的 finder 是否符合预期
  -j, --just-show-pcaps              仅打印加载的 pcap 列表
      --show-command                 打印正在执行的命令
      --show-stdout                  打印正在执行的命令及其输出
      --show-why                     展示 pcap 未被加载的原因
      --keep-data                    是否保留数据
  -O, --jobs strings                 仅执行指定的 ID 对应的 job, 逗号分割指定多个
      --daemon                       后台运行
      --pingback string              daemon 模式下的 pingback 地址, 请勿手动指定
  
  // 默认的 modifier 配置
  -a, --adjust-time                  adjust time or not (default true)
  -t, --time-offset duration         time offset
      --keep-ip                      keep ip or not
      --c1 int                       c1 (default 192)
      --c2 int                       c2 (default 168)
      --c3 int                       c3 (default 186)
      --c4 int                       c4 (default 11)
      --s1 int                       s1 (default 10)
      --s2 int                       s2 (default 132)
      --s3 int                       s3 (default 123)
      --s4 int                       s4 (default 22)
  -3, --use-part-3                   use part 3 or not
  -4, --use-part-4                   use part 4 or not
 
  // 默认的 finder 配置
  -d, --directory string             pcap search directory (default "/data/.prsdata/pcaps/")
  -p, --patterns strings             patterns for filter pcap
      --pps-le int                   pps less than or equal to given value
      --pps-ge int                   pps greater than or equal to given value
      --packet-count-le int          packet count less than or equal to given value
      --packet-count-ge int          packet count greater than or equal to given value
      --avg-packet-size-le int       avg packet size less than or equal to given value
      --avg-packet-size-ge int       avg packet size greater than or equal to given value
      
      // 以下用于配置使用到的相关工具路径(仅填写名称会使用 $PATH 环境变量进行查找)
      --bash string                  bash path (default "bash")
      --capinfos string              capinfos path (default "capinfos")
      --editcap string               editcap path (default "editcap")
      --tcpdump string               tcpdump path (default "tcpdump")
      --tcprewrite string            tcprewrite path (default "tcprewrite")
      --tcpprep string               tcpprep path (default "tcpprep")

  -V, --version                      show version
  -h, --help                         help for prsdata

对应的配置文件样例:

config:
  concurrency_jobs: 2
  concurrency_commands: 6
  test_times: 1
  duration: 0
  command_timeout: 30s
  debug: false

  tool:
    bash: bash
    capinfos: capinfos
    editcap: editcap
    tcpdump: tcpdump
    tcprewrite: tcprewrite
    tcpprep: tcpprep
    p426: p426

  modifier:
    adjust_time: true  # default is false, you must set it explicit
    time_offset: 0s
    keep_ip: false
    c1: 192
    c2: 168
    c3: 186
    c4: 11
    s1: 10
    s2: 132
    s3: 123
    s4: 22
    use_part_3: false
    use_part_4: false

  finder:
    directory: /data/.prsdata/pcaps/

jobs:
  - id: zeek
    name: zeek
    enable: true
    commands:
      - name: zeek
        command: /opt/zeek/bin/zeek -r {{.RelativePath}} -C /opt/zeek-scripts/tophant.entrypoint.zeek
        directory: "{{.FinderDirectory}}"

  - id: suricata
    name: suricata
    enable: true
    commands:
      - name: suricata
        command: /opt/suricata/bin/suricata -c /opt/suricata/etc/suricata/suricata.yaml -r {{.RelativePath}} -k none --runmode autofp
        directory: "{{.FinderDirectory}}"

  - id: fpc
    name: fpc
    enable: false
    commands:
      - name: moloch
        command: /data/moloch/bin/moloch-capture --insecure -c /data/moloch/etc/config.ini -r {{.RelativePath}}
        directory: "{{.FinderDirectory}}"

丰富的配置文件样例:

config:
  concurrency_jobs: 2
  concurrency_commands: 6
  test_times: 1
  debug: false
  duration: 0

  tool:
    bash: bash
    capinfos: capinfos
    editcap: editcap
    tcpdump: tcpdump
    tcprewrite: tcprewrite
    tcpprep: tcpprep

  modifier:
    adjust_time: true  # default is false, you must set it explicit
    time_offset: 0s
    keep_ip: false
    c1: 192
    c2: 168
    c3: 186
    c4: 11
    s1: 10
    s2: 132
    s3: 123
    s4: 22
    use_part_3: false
    use_part_4: false

  finder:
    directory: /data/.prsdata/pcaps/

modifiers:
  - id: pvs
    keep_ip: true
  - id: dga
    time_offset: 1h

finders:
  - id: pvs
    directory: /data/.prsdata/pcaps/pvs
    modifier: pvs

  - id: dga
    directory: /data/.prsdata/pcaps/dga
    modifier: dga

jobs:
  - id: zeek
    name: zeek pvs
    enable: true
    finder: pvs
    commands:
      - name: zeek
        command: /opt/zeek/bin/zeek -r {{.RelativePath}} -C /opt/zeek-scripts/tophant.entrypoint.zeek
        directory: "{{.FinderDirectory}}"

  - id: suricata
    name: suricata
    enable: true
    commands:
      - name: suricata
        # 因为 job 和 command 都没有定义明确定义 finder, 那么用的就是默认的 finder
        # finder: default
        command: /opt/suricata/bin/suricata -c /opt/suricata/etc/suricata/suricata.yaml -r {{.RelativePath}} -k none --runmode autofp
        directory: "{{.FinderDirectory}}"

      - name: test sleep
        command: sleep 1000
        timeout: 1002s

      - name: zeek dga
        finder: dga
        command: /opt/zeek/bin/zeek -r {{.RelativePath}} -C /opt/zeek-scripts/tophant.entrypoint.zeek
        directory: "{{.FinderDirectory}}"
命令模版

type 为 pcap 类型的 command, 其 command 内容可以包含预定义的变量. 预定义变量列表如下:

WorkingDirectory  - prsdata 本次的临时工作目录路径
FinderDirectory   - 当前 pcap 使用的 finder 对应的目录路径
PcapDirectory     - 当前 pcap 所在目录路径
RelativeDirectory - 当前 pcap 所在目录基于 WorkingDirectory 的相对路径信息
RelativePath      - 当前 pcap 路径基于 WorkingDirectory 的相对路径
Path              - 当前 pcap 的完整路径
BaseName          - 当前 pcap 的文件名称
Name              - 当前 pcap 不包含后缀的文件名称 
Ext               - 当前 pcap 的后缀信息

样例数据如下:

WorkingDirectory  - /data/.prsdata/history/prsdata-2020_09_29_17_19_31-14696
FinderDirectory   - /data/.prsdata/history/prsdata-2020_09_29_17_19_31-14696/finder-default
PcapDirectory     - /data/.prsdata/history/prsdata-2020_09_29_17_19_31-14696/finder-default/all-pcap/vulnerability/tunnel/dns_tunnel
RelativeDirectory - all-pcap/vulnerability/tunnel/dns_tunnel
RelativePath      - all-pcap/vulnerability/tunnel/dns_tunnel/dns_oob.pcap
Path              - /data/.prsdata/history/prsdata-2020_09_29_17_19_31-14696/finder-default/all-pcap/vulnerability/tunnel/dns_tunnel/dns_oob.pcap
BaseName          - dns_oob.pcap
Name              - dns_oob
Ext               - .pcap