
कलाकृतियों का संग्रह उपकरण *nix प्रणालियों के लिए
fennec एक Rust में लिखा गया आर्टिफैक्ट संग्रह उपकरण है जिसका उपयोग *nix-आधारित सिस्टम पर घटना प्रतिक्रिया के दौरान किया जाता है। fennec आपको एक कॉन्फ़िगरेशन फ़ाइल लिखने की अनुमति देता है जिसमें आर्टिफैक्ट एकत्र करने का तरीका शामिल होता है।
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` : निर्दिष्ट कॉन्फ़िगरेशन फ़ाइल का उपयोग करें एम्बेडेड कॉन्फ़िगरेशन के बजाय
* `-f`, `--log-file` : लॉग फ़ाइल का डिफ़ॉल्ट नाम बदलें (डिफ़ॉल्ट: `fennec.log`)
* `-h`, `--help` : सहायता संदेश प्रिंट करें
* `-l`, `--log-level` : डिफ़ॉल्ट लॉग स्तर बदलें (डिफ़ॉल्ट: `info`)
* `-o`, `--output` : ज़िप फ़ाइल के लिए डिफ़ॉल्ट आउटपुट फ़ाइल नाम बदलें (डिफ़ॉल्ट: `{HOSTNAME}.zip`, जहाँ होस्टनाम रनटाइम पर मूल्यांकित मशीन होस्टनाम है)
* `--osquery-path` : osquery निष्पादन योग्य का पथ, यह मान निम्न शर्तों के आधार पर उपयोग किया जाएगा:
* यदि osquery बाइनरी `fennec` में एम्बेडेड है तो इसे निकालें और `--osquery-path` पर डंप करें
* यदि osquery `fennec` में एम्बेडेड नहीं है तो पथ `--osquery-path` में osquery बाइनरी का उपयोग करें
* `--output-format` : आउटपुट प्रारूप चुनें, समर्थित प्रारूप:
* jsonl : एक नई पंक्ति से अलग JSON ऑब्जेक्ट (डिफ़ॉल्ट)
* csv: कॉमा से अलग किए गए मान
* kjson: इस प्रारूप का उपयोग करें यदि आप परिणामी फ़ाइल को [Kuiper](https://github.com/DFIRKuiper/Kuiper) विश्लेषण प्लेटफ़ॉर्म पर अपलोड करना चाहते हैं।
* `-q`, `--quiet` : `stdout` पर लॉग प्रिंट न करें
* `--non-root`: Fennec को गैर-रूट अनुमतियों के साथ चलाएं। डिफ़ॉल्ट रूप से, Fennec को `root` अनुमतियों की आवश्यकता होती है और यदि रूट नहीं है तो यह त्रुटि संदेश के साथ बाहर निकल जाएगा।
* `--show-config` : एम्बेडेड कॉन्फ़िगरेशन प्रिंट करें फिर बाहर निकलें
* `--show-embedded` : एम्बेडेड फ़ाइलें दिखाएं
* `-t`, `--timeout` : प्रत्येक osquery क्वेरी आर्टिफैक्ट प्रकार के लिए सेकंड में टाइमआउट सेट करता है
* `-u`, `--upload-artifact` : आर्टिफैक्ट पैकेज को रिमोट सर्वर पर अपलोड करें। समर्थित प्रोटोकॉल:
* `s3` : आर्टिफैक्ट पैकेज को S3 बकेट में अपलोड करें
* `Format` : s3://<ACCESS_KEY>:<SECRET_ACCESS_KEY>@(http|https)://<HOSTNAME>:<PORT>/<BUCKET_NAME>:<PATH>
* `Example`: s3://minioadmin:minioadmin@http://192.168.100.190:9000/fennec:/
* `aws3` : आर्टिफैक्ट पैकेज को AWS S3 बकेट में अपलोड करें
* `Format` : aws3://<ACCESS_KEY>:<SECRET_ACCESS_KEY>@<AWS_REGOIN>.<BUCKET_NAME>:<PATH>
* `Example`: aws3://AKIAXXXXXXXXXXXXXXXXX:[email protected]:/
* `scp` : SCP प्रोटोकॉल का उपयोग करके सर्वर पर आर्टिफैक्ट पैकेज अपलोड करें
* `Format` : scp://`<USERNAME>`:`<PASSWORD>`@`<HOSTNAME>`:`<PORT>`:`<PATH>`
* `Example`: scp://testusername:[email protected]:22:/dev/shm
* `-V`, `--version` : `fennec` संस्करण प्रिंट करें फिर बाहर निकलें
## निर्भरताओं के साथ संकलन करें 👨💻
fennec `osquery` पर निर्भर करता है ताकि `query` प्रकार के आर्टिफैक्ट चलाए जा सकें। `deps` नामक निर्देशिका में वह फ़ाइल होती है जो लक्ष्य OS और आर्किटेक्चर के आधार पर बाइनरी में एम्बेड की जाएगी। संकलन से पहले नीचे दिए गए चरणों का पालन करें:
* आवश्यकतानुसार कॉन्फ़िगरेशन फ़ाइल `deps/<TARGET_OS>/fennec.yaml` को संशोधित करें
* नीचे दिए गए कमांडों में से एक का उपयोग करके बाइनरी बनाएं:
* dynamically linked: ```bash
cargo build --release
आप रिलीज़ अनुभाग में पूर्व-संकलित बाइनरी का भी उपयोग कर सकते हैं।
निम्नलिखित एक उदाहरण है जो Ubuntu 20 पर उसी कॉन्फ़िगरेशन के साथ चलाया गया है जो इस रेपो में है:

Kuiper समर्थित प्रारूप में डेटा आउटपुट करने के लिए Fennec को निम्नलिखित आर्गुमेंट के साथ निष्पादित करें:```bash sudo ./fennec --output-format kjson
या निम्नलिखित को कॉन्फ़िगरेशन के `args` अनुभाग में जोड़ें:```yaml
args:
- "--output-format"
- "kjson"
पुनः संकलित करें फिर निष्पादित करें:```bash sudo ./fennec
फिर परिणामी ज़िप फ़ाइल को Kuiper पर अपलोड करें, निम्नलिखित एक उदाहरण है:

## कॉन्फ़िगरेशन🔨
डिफ़ॉल्ट रूप से, पथ `deps/<TARGET_OS>/fennec.yaml` में कॉन्फ़िगरेशन संकलन के दौरान निष्पादन योग्य में एम्बेड किया जाएगा। कॉन्फ़िगरेशन YAML प्रारूप में है और इसमें दो खंड हैं:
### Args
इसमें निष्पादन योग्य को कमांड लाइन तर्कों के रूप में पारित किए जाने वाले तर्कों की एक सूची शामिल है, निम्नलिखित `args` खंड के लिए एक उदाहरण है जो आउटपुट प्रारूप को `jsonl` और लॉग फ़ाइल नाम को `fennec.log` पर सेट करेगा:```yaml
args:
- "--output-format"
- "jsonl"
- "--log-file"
- "fennec.log"
...
कमांड लाइन तर्कों का उपयोग निम्नलिखित प्राथमिकताओं में किया जाएगा:
एकत्रित किए जाने वाले आर्टिफैक्ट की सूची शामिल है। प्रत्येक आर्टिफैक्ट में निम्नलिखित फ़ील्ड होते हैं:
stdout को पार्स करने के लिए regex होता हैosquery SQL क्वेरी निष्पादित करें। सिस्टम पर सभी उपयोगकर्ताओं को प्राप्त करने के लिए निम्नलिखित उदाहरण आर्टिफैक्ट:```yaml artifacts:
#### आर्टिफैक्ट प्रकार: कलेक्शन
यह आर्टिफैक्ट प्रकार **paths** फील्ड में निर्दिष्ट फ़ाइलों/फ़ोल्डरों को एकत्र करता है। निम्नलिखित इस आर्टिफैक्ट प्रकार का एक उदाहरण है जो सिस्टम लॉग एकत्र करता है:```yaml
artifacts:
- name: logs
type: collection
description: "Collect system logs"
paths:
- '/var/log/**/*'
...
शेल कमांड इंटरप्रेटर का उपयोग करके निम्नलिखित प्राथमिकता में सिस्टम कमांड निष्पादित करें:
यह इस आर्टिफैक्ट प्रकार का एक उदाहरण है जो खराब लॉगिन प्राप्त करता है:```yaml artifacts:
यह आर्टिफैक्ट प्रकार `commands` सूची में कमांड्स को निष्पादित करेगा और `regex` फ़ील्ड में निर्दिष्ट रेगुलर एक्सप्रेशन का उपयोग करके `stdout` को पार्स करेगा। ध्यान दें कि regex केवल `stdout` स्ट्रीम पर संसाधित किया जाएगा, `stderr` पर नहीं। इसके अलावा, `regex` फ़ील्ड वैकल्पिक है। यहाँ `regex` फ़ील्ड के साथ और बिना इसके परिणामों का एक उदाहरण है:
##### बिना `regex` फ़ील्ड के```json
{
"line": 0,
"stdout": "root pts/1 2023-09-12T17:13:28+03:00 - 2023-09-12T17:13:28+03:00 (00:00)"
}
regex फ़ील्ड के साथ```json{ "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" }
#### कलाकृति प्रकार: Parse
यह कलाकृति प्रकार regex का उपयोग करके टेक्स्ट फ़ाइलों को पार्स करने और डेटा को संरचित प्रारूप में वापस लाने की क्षमता प्रदान करता है। नीचे दिया गया उदाहरण nginx एक्सेस लॉग को पार्स करता है और परिणामों को संरचित प्रारूप में लौटाता है:```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>.*?)"'
यह कॉन्फ़िगरेशन /var/log/nginx/access.* पथ में फ़ाइलों को पंक्ति दर पंक्ति पढ़ेगा और फ़ील्ड निकालने के लिए regex चलाएगा। यह आर्टिफैक्ट यह भी जाँचता है कि फ़ाइल gzip प्रारूप में है या नहीं, जिसका उपयोग पुराने लॉग्स को संपीड़ित करने के लिए किया जाता है ताकि स्थान बचाया जा सके, और उन्हें डीकंप्रेस करके पार्स करता है। regex को named captures प्रारूप में होना चाहिए जैसा कि rust regex library में दस्तावेज़ित किया गया है। निम्नलिखित पार्सिंग से पहले और बाद का एक उदाहरण nginx एक्सेस रिकॉर्ड है:
* पार्स किया गया रिकॉर्ड ```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"
}
This optional field can be used to change result field names and run post processing called modifiers on the field value. The below example will show the results for parsing nginx access record without maps:
* मूल रिकॉर्ड```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"
To change the field name `time` to `@timestamp` we add the following maps configuration to the artifact configurations:```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
उसी nginx access log पर कॉन्फ़िगरेशन के साथ संग्रह उपकरण चलाने के बाद हमें निम्नलिखित आउटपुट मिलता है:```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 आर्टिफैक्ट परिणामों के फ़ील्ड मान पर पोस्ट प्रोसेसिंग प्रदान करता है। उदाहरण के लिए दिनांक और समय को पुन: स्वरूपित करना। ऊपर दिए गए उदाहरण को जारी रखते हुए हम फ़ील्ड `@timestamp` में दिनांक और समय प्रारूप को `%Y-%m-%d %H:%M:%S` प्रारूप में बदल सकते हैं। इसे पूरा करने के लिए हम आर्टिफैक्ट कॉन्फ़िगरेशन में निम्नलिखित जोड़ सकते हैं:```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'
परिणामी रिकॉर्ड इस प्रकार दिखेगा:```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" }
उपलब्ध मॉडिफायर हैं:
| नाम | विवरण | input_time_format | output_time_format |
| ------------------------ | ------------------------------------------------------------ | -------------------------------------- | ------------------------------------------------------------ |
| epoch_to_iso | एपॉक टाइमस्टैम्प को कस्टम दिनांक और समय प्रारूप में बदलता है | N/A | आउटपुट दिनांक और समय प्रारूप निर्दिष्ट करें, डिफ़ॉल्ट `%Y-%m-%d %H:%M:%S` है |
| datetime_to_iso | दिनांक और समय को `input_time_format` प्रारूप से `output_time_format` प्रारूप में पुन: स्वरूपित करता है | इनपुट दिनांक और समय प्रारूप निर्दिष्ट करें | आउटपुट दिनांक और समय प्रारूप निर्दिष्ट करें, डिफ़ॉल्ट `%Y-%m-%d %H:%M:%S` है |
| time_without_year_to_iso | वर्ष रहित दिनांक और समय डेटा को `input_time_format` प्रारूप से `output_time_format` प्रारूप में स्वरूपित करता है | इनपुट दिनांक और समय प्रारूप निर्दिष्ट करें | आउटपुट दिनांक और समय प्रारूप निर्दिष्ट करें, डिफ़ॉल्ट `%Y-%m-%d %H:%M:%S` है |
| to_int | स्ट्रिंग डेटा (जैसे `command` और `parse` आर्टिफैक्ट प्रकार) को पूर्णांक (`i64` अर्थात साइन्ड 64-बिट पूर्णांक) में बदलता है। यह फ़ाइल आकार जैसे फ़ील्ड के लिए उपयोगी है ताकि हम अपनी पसंद के डेटा प्लेटफ़ॉर्म का उपयोग करके `size < 1024` जैसी जाँच कर सकें | N/A | N/A |
`time_without_year_to_iso` मॉडिफायर निम्नानुसार काम करता है:
* वर्तमान वर्ष जोड़ें, फिर जाँचें कि क्या पार्सर का समय वर्तमान समय से कम है; यदि हाँ, तो यह सही समय है
* अन्यथा यह पिछले वर्ष का है
यह मॉडिफायर मानता है कि लॉग **केवल** एक वर्ष के लिए हैं, इस मॉडिफायर का सावधानी से उपयोग करें
| OS विवरण | आर्किटेक्चर | सफलता? | विवरण |
|---|
| 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 को libc >= 2.12 की आवश्यकता है |
| Ubuntu 20.04 | aarch64 | ✅ | |
| MacOS Monterey v12.0.1 | x86_64 | ✅ | कॉन्फ़िगरेशन ट्यूनिंग आवश्यक है। यदि आपको MacOS आर्टिफैक्ट का अनुभव है तो योगदान करने में संकोच न करें |
| Oracle Linux Server 7.9 | x86_64 | ✅ |