
Ferramenta de coleta de artefatos para sistemas *nix
fennec é uma ferramenta de coleta de artefatos escrita em Rust para ser usada durante resposta a incidentes em sistemas baseados em *nix. fennec permite que você escreva um arquivo de configuração que contém como coletar artefatos.
fennec 0.4.1 AbdulRhman Alfaifi [email protected] Aritfact collection tool for *nix systems
USAGE: fennec [OPTIONS]
OPTIONS: -c, --config Sets a custom config file (Embedded : true)
-o, --output <FILE>
Sets output file name [default: ABDULRHMAN-PC.zip]
-l, --log-level <LEVEL>
Sets the log level [default: info] [possible values: trace, debug, info, error]
-f, --log-file <FILE>
Sets the log file name [default: fennec.log]
-u, --upload-artifact <CONFIG>...
Upload configuration string. Supported Protocols:
* s3 : Upload artifact package to S3 bucket (ex. minio)
* Format :
s3://<ACCESS_KEY>:<SECRET_ACCESS_KEY>@(http|https)://<HOSTNAME>:<PORT>/<BUCKET_NAME>:<PATH>
* Example (minio): s3://minioadmin:minioadmin@http://192.168.100.190:9000/fennec:/
* aws3 : Upload artifact package to AWS S3 bucket
* Format : aws3://<ACCESS_KEY>:<SECRET_ACCESS_KEY>@<AWS_REGOIN>.<BUCKET_NAME>:<PATH>
* Example: aws3://AKIAXXX:[email protected]:/
* scp : Upload artifact package to a server using SCP protocol
* Format : scp://<USERNAME>:<PASSWORD>@<HOSTNAME>:<PORT>:<PATH>
* Example: scp://testusername:[email protected]:22:/dev/shm
-q, --quiet
Do not print logs to stdout
-t, --timeout <SEC>
Sets osquery queries timeout in seconds [default: 60]
-h, --help
Print help information
--non-root
Run Fennec with non root permisions. This isn't recommended, most artifacts require root
permissions
--osquery-path <PATH>
Sets osquery path, if osquery is embedded it will be writen to this path otherwise the
path will be used to spawn osquery instance (Embedded : true) [default: ./osqueryd]
--output-format <FORMAT>
Sets output format [default: jsonl] [possible values: jsonl, csv, kjson]
--show-config
Show the embedded configuration file
--show-embedded
Show the embedded files metadata
-V, --version
Print version information
* `-c`, `--config` : Use o ficheiro de configuração especificado em vez da configuração incorporada
* `-f`, `--log-file` : Alterar o nome predefinido para o ficheiro de registo (predefinição: `fennec.log`)
* `-h`, `--help` : Imprimir mensagem de ajuda
* `-l`, `--log-level` : Alterar o nível de registo predefinido (predefinição: `info`)
* `-o`, `--output` : Alterar o nome predefinido do ficheiro de saída para o ficheiro zip (predefinição: `{HOSTNAME}.zip`, onde hostname é o nome do host da máquina avaliado em tempo de execução)
* `--osquery-path` : Caminho para o executável osquery. Este valor será usado com base nas seguintes condições:
* Se o binário osquery estiver incorporado no `fennec`, extraí-lo e despejá-lo no `--osquery-path`
* Se o osquery não estiver incorporado no `fennec`, então usar o binário osquery no caminho `--osquery-path`
* `--output-format` : Escolher o formato de saída. Formatos suportados:
* jsonl : Objetos JSON separados por nova linha (predefinição)
* csv: Valores separados por vírgulas
* kjson: Use este formato se pretender carregar o ficheiro resultante para a plataforma de análise [Kuiper](https://github.com/DFIRKuiper/Kuiper).
* `-q`, `--quiet` : Não imprimir registos para `stdout`
* `--non-root`: Executar Fennec com permissões não-root. Por predefinição, o Fennec requer permissões de `root` e sairá com uma mensagem de erro se não for root.
* `--show-config` : Imprimir a configuração incorporada e depois sair
* `--show-embedded` : Mostrar ficheiros incorporados
* `-t`, `--timeout` : Define o tempo limite em segundos para cada osquery no tipo de artefacto de consulta
* `-u`, `--upload-artifact` : Carregar pacote de artefactos para um servidor remoto. Protocolos suportados:
* `s3` : Carregar pacote de artefactos para bucket S3
* `Formato` : s3://<ACCESS_KEY>:<SECRET_ACCESS_KEY>@(http|https)://<HOSTNAME>:<PORT>/<BUCKET_NAME>:<PATH>
* `Exemplo`: s3://minioadmin:minioadmin@http://192.168.100.190:9000/fennec:/
* `aws3` : Carregar pacote de artefactos para bucket AWS S3
* `Formato` : aws3://<ACCESS_KEY>:<SECRET_ACCESS_KEY>@<AWS_REGOIN>.<BUCKET_NAME>:<PATH>
* `Exemplo`: aws3://AKIAXXXXXXXXXXXXXXXXX:[email protected]:/
* `scp` : Carregar pacote de artefactos para um servidor usando o protocolo SCP
* `Formato` : scp://`<USERNAME>`:`<PASSWORD>`@`<HOSTNAME>`:`<PORT>`:`<PATH>`
* `Exemplo`: scp://testusername:[email protected]:22:/dev/shm
* `-V`, `--version` : Imprimir a versão do `fennec` e depois sair
## Compilar com dependências 👨💻
o fennec depende do `osquery` para executar os artefactos do tipo `query`. O diretório chamado `deps` contém o ficheiro que será incorporado no binário dependendo do SO e arquitetura de destino. Antes de compilar, siga os passos abaixo:
* Modifique o ficheiro de configuração `deps/<TARGET_OS>/fennec.yaml` conforme necessário
* Compile o binário usando um dos comandos abaixo:
* ligado dinamicamente: ```bash
cargo build --release
Você também pode usar os binários pré-compilados na seção de releases.
O seguinte é um exemplo executado no Ubuntu 20 com as mesmas configurações deste repositório:

Para enviar dados para o formato suportado pelo Kuiper, execute o Fennec com o seguinte argumento:```bash sudo ./fennec --output-format kjson
ou adicione o seguinte à seção `args` na configuração:```yaml
args:
- "--output-format"
- "kjson"
recompile então execute:```bash sudo ./fennec
then upload the resulting zip file to Kuiper, the following is an example:

## Configuração🔨
Por padrão, a configuração no caminho `deps/<TARGET_OS>/fennec.yaml` será incorporada ao executável durante a compilação. A configuração está no formato YAML e possui duas seções:
### Args
contém uma lista de argumentos a serem passados para o executável como argumentos de linha de comando, a seguir está um exemplo para a seção `args` que definirá o formato de saída como `jsonl` e o nome do arquivo de log como `fennec.log`:```yaml
args:
- "--output-format"
- "jsonl"
- "--log-file"
- "fennec.log"
...
Os argumentos de linha de comando serão usados nas seguintes prioridades:
Contém uma lista de artefactos a serem recolhidos. Cada artefacto contém os seguintes campos:
stdout no caso de artefacto commandExecuta consultas SQL do osquery. O seguinte exemplo de artefacto para recuperar todos os utilizadores no sistema:```yaml artifacts:
#### Tipos de Artefato: Coleção
Este tipo de artefato coleta arquivos/pastas especificados no campo **paths**. A seguir está um exemplo deste tipo de artefato que coleta logs do sistema:```yaml
artifacts:
- name: logs
type: collection
description: "Collect system logs"
paths:
- '/var/log/**/*'
...
Execute comandos do sistema usando o interpretador de shell na seguinte ordem de prioridade:
Este é um exemplo deste tipo de artefato que recupera logins inválidos:```yaml artifacts:
Este tipo de artefato executará os comandos na lista `commands` e analisará a `stdout` usando a expressão regular especificada no campo `regex`. Observe que a regex será processada apenas no fluxo `stdout` e não no `stderr`. Além disso, o campo `regex` é opcional. Aqui está um exemplo dos resultados tanto usando o campo `regex` quanto sem ele:
##### Sem o campo `regex````json
{
"line": 0,
"stdout": "root pts/1 2023-09-12T17:13:28+03:00 - 2023-09-12T17:13:28+03:00 (00:00)"
}
{ "username": "root", "tty": "pts/1", "src_ip": null, "login_time": "2023-09-12 14:13:28", "logout_time": "2023-09-12T17:13:28+03:00", "duration": "00:00", "@timestamp": "2023-09-12 14:13:28" }
#### Tipos de Artefato: Parse
Este tipo de artefato fornece a capacidade de analisar arquivos de texto usando regex e retornar os dados em formato estruturado. O exemplo abaixo analisa logs de acesso do nginx e retorna os resultados em formato estruturado:```yaml
artifcats:
- name: nginx_access
type: parse
description: "Nginx access logs"
paths:
- /var/log/nginx/access.*
regex: '(?P<c_ip>[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}) - (?P<remote_user>[^ ]+) \[(?P<time>[0-9]{2}/[a-zA-Z]{3}/[0-9]{4}:[0-9]{2}:[0-9]{2}:[0-9]{2} \+[0-9]{4})\] "(?P<method>[A-Z]+)?[ ]?(?P<uri>.*?)[ ]?(HTTP/(?P<http_prot>[0-9\.]+))?" (?P<status_code>[0-9]{3}) (?P<body_bytes_sent>[0-9]+) "(?P<referer>.*?)" "(?P<user_agent>.*?)"'
Esta configuração lerá os ficheiros no caminho /var/log/nginx/access.* linha por linha e executará a regex para extrair campos. Este artefacto também verifica se o ficheiro está no formato gzip, que é utilizado para comprimir logs antigos para poupar espaço, e descomprime-os e analisa-os. A regex deve estar no formato de capturas nomeadas conforme documentado na biblioteca regex do Rust. Segue-se um exemplo de um registo de acesso nginx antes e depois da análise:
* registro analisado ```json
{
"c_ip": "192.168.133.70",
"remote_user": "-",
"time": "23/Jan/2022:19:14:37 +0000",
"method": "GET",
"uri": "/blog/",
"http_prot": "1.1",
"status_code": "200",
"body_bytes_sent": "2497",
"referer": "https://u0041.co/",
"user_agent": "Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0",
"full_path": "/var/log/nginx/access.log.9.gz"
}
Este campo opcional pode ser usado para alterar os nomes dos campos de resultado e executar pós-processamento chamado modificadores no valor do campo. O exemplo abaixo mostrará os resultados para analisar o registro de acesso do nginx sem maps:
* registro original```verilog
192.168.133.70 - - [23/Jan/2022:19:14:37 +0000] "GET /blog/ HTTP/1.1" 200 2497 "https://u0041.co/" "Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0"
Para alterar o nome do campo `time` para `@timestamp`, adicionamos a seguinte configuração de mapas às configurações de artefatos:```yaml
artifcats:
- name: nginx_access
type: parse
description: "Nginx access logs"
paths:
- /var/log/nginx/access.*
regex: '(?P<c_ip>[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}) - (?P<remote_user>[^ ]+) \[(?P<time>[0-9]{2}/[a-zA-Z]{3}/[0-9]{4}:[0-9]{2}:[0-9]{2}:[0-9]{2} \+[0-9]{4})\] "(?P<method>[A-Z]+)?[ ]?(?P<uri>.*?)[ ]?(HTTP/(?P<http_prot>[0-9\.]+))?" (?P<status_code>[0-9]{3}) (?P<body_bytes_sent>[0-9]+) "(?P<referer>.*?)" "(?P<user_agent>.*?)"'
maps:
- from: time #change field name from
to: '@timestamp' # to this name
Após executar a ferramenta de coleta com a configuração no mesmo log de acesso do nginx, obtemos a seguinte saída:```json { "c_ip": "192.168.133.70", "remote_user": "-", "@timestamp": "23/Jan/2022:19:14:37 +0000", "method": "GET", "uri": "/blog/", "http_prot": "1.1", "status_code": "200", "body_bytes_sent": "2497", "referer": "https://u0041.co/", "user_agent": "Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0", "full_path": "/var/log/nginx/access.log.9.gz" }
#### Modifiers
modifiers fornece pós-processamento no valor do campo dos resultados do artefato. Por exemplo, reformatar data e hora. Continuando no exemplo acima, podemos alterar o formato de data e hora no campo `@timestamp` para o formato `%Y-%m-%d %H:%M:%S`. Podemos adicionar o seguinte às configurações do artefato para conseguir isso:```yaml
artifacts:
- name: nginx_access
type: parse
description: "Nginx access logs"
paths:
- /var/log/nginx/access.*
regex: '(?P<c_ip>[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}) - (?P<remote_user>[^ ]+) \[(?P<time>[0-9]{2}/[a-zA-Z]{3}/[0-9]{4}:[0-9]{2}:[0-9]{2}:[0-9]{2} \+[0-9]{4})\] "(?P<method>[A-Z]+)?[ ]?(?P<uri>.*?)[ ]?(HTTP/(?P<http_prot>[0-9\.]+))?" (?P<status_code>[0-9]{3}) (?P<body_bytes_sent>[0-9]+) "(?P<referer>.*?)" "(?P<user_agent>.*?)"'
maps:
- from: time
to: "@timestamp"
modifier:
name: datetime_to_iso
parameters:
input_time_format: '%d/%b/%Y:%H:%M:%S %z'
output_time_format: '%Y-%m-%d %H:%M:%S'
O registro resultante será assim:```json { "c_ip": "192.168.133.70", "remote_user": "-", "@timestamp": "2022-01-23 19:14:37", "method": "GET", "uri": "/blog/", "http_prot": "1.1", "status_code": "200", "body_bytes_sent": "2497", "referer": "https://u0041.co/", "user_agent": "Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0", "full_path": "/var/log/nginx/access.log.9.gz" }
Os modificadores disponíveis são:
| Nome | Detalhes | input_time_format | output_time_format |
| ------------------------ | ------------------------------------------------------------ | -------------------------------------- | ------------------------------------------------------------ |
| epoch_to_iso | Converte timestamp epoch para formato de data e hora personalizado | N/A | especifique o formato de data e hora de saída, o padrão é `%Y-%m-%d %H:%M:%S` |
| datetime_to_iso | Reformata data e hora do formato `input_time_format` para o formato `output_time_format` | especifique o formato de data e hora de entrada | especifique o formato de data e hora de saída, o padrão é `%Y-%m-%d %H:%M:%S` |
| time_without_year_to_iso | Formata data e hora sem dados de ano do formato `input_time_format` para o formato `output_time_format` | especifique o formato de data e hora de entrada | especifique o formato de data e hora de saída, o padrão é `%Y-%m-%d %H:%M:%S` |
| to_int | Converte dados de string (como tipos de artefato `command` e `parse`) para inteiros (`i64`, ou seja, inteiro de 64 bits com sinal). Isso é útil para campos como o tamanho do arquivo, para que possamos fazer verificações como `tamanho < 1024` usando a plataforma de dados de nossa escolha | N/A | N/A |
O modificador `time_without_year_to_iso` funciona da seguinte forma:
* Adiciona o ano atual e verifica se o tempo do analisador é menor que o tempo atual; se for, então é o tempo correto
* caso contrário, é o ano anterior
Este modificador assume que os logs são de **APENAS** um ano, use este modificador com cautela
| Detalhes do SO | Arquitetura | Sucesso? | Detalhes |
|---|
| Ubuntu 20.04.3 LTS | x86_64 | ✅ | |
| Ubuntu 19.04 | x86_64 | ✅ | |
| Ubuntu 18.04.6 LTS | x86_64 | ✅ | |
| Ubuntu 17.04 | x86_64 | ✅ | |
| Ubuntu 16.04.7 LTS | x86_64 | ✅ | |
| Ubuntu 15.10 | x86_64 | ✅ | |
| Ubuntu 14.04.6 LTS | x86_64 | ✅ | |
| Ubuntu 13.04 | x86_64 | ✅ | |
| Ubuntu 12.04.5 LTS | x86_64 | ✅ | |
| CentOS 8.4.2105 | x86_64 | ✅ | |
| CentOS 7.9.2009 | x86_64 | ✅ | |
| CentOS 6.10 | x86_64 | ✅ | |
| CentOS 5.11 | x86_64 | ❌ | osquery requer libc >= 2.12 |
| Ubuntu 20.04 | aarch64 | ✅ | |
| MacOS Monterey v12.0.1 | x86_64 | ✅ | ajustes de configuração são necessários. Se você tem experiência em artefatos MacOS sinta-se à vontade para contribuir |
| Oracle Linux Server 7.9 | x86_64 | ✅ |