Initial release: offline NetScaler triage with Sigma rules and MIT license
This commit is contained in:
commit
711c42b270
52 files changed
+61222
No files matched your search
@@ -0,0 +1,149 @@
|
||||
# NetScaler Triage
|
||||
|
||||
Offline forensic triage for Citrix NetScaler ADC and Gateway logs. Point it at a
|
||||
folder or archive to find suspicious requests, public indicators, encoded
|
||||
payloads, update records and related events across logs.
|
||||
|
||||
Original inputs are not modified. Payloads are decoded as data, never executed
|
||||
or downloaded. A finding is an investigation lead, **not proof of compromise**.
|
||||
|
||||
## Quick start
|
||||
|
||||
Requires **Python 3.14 or newer**.
|
||||
|
||||
```sh
|
||||
git clone https://tea.karlcom.de/karl/NetScaler_forensik.git
|
||||
cd NetScaler_forensik
|
||||
python3 -m venv .venv
|
||||
source .venv/bin/activate
|
||||
python -m pip install .
|
||||
netscaler-triage ./logs.7z
|
||||
```
|
||||
|
||||
On Windows PowerShell, create and activate the environment with:
|
||||
|
||||
```powershell
|
||||
py -3.14 -m venv .venv
|
||||
.venv\Scripts\Activate.ps1
|
||||
python -m pip install .
|
||||
netscaler-triage .\logs.7z
|
||||
```
|
||||
|
||||
Installation may require internet access. Analysis runs offline.
|
||||
|
||||
## Everyday use
|
||||
|
||||
```sh
|
||||
# Unpacked logs, an archive, or multiple appliance exports
|
||||
netscaler-triage ./logs
|
||||
netscaler-triage export.tar.gz
|
||||
netscaler-triage ./appliance-a ./appliance-b export.zip
|
||||
|
||||
# Discover inputs in the current directory
|
||||
netscaler-triage
|
||||
|
||||
# Encrypted archive: prompt for a password without displaying it
|
||||
netscaler-triage export.7z --password
|
||||
```
|
||||
|
||||
ZIP (including ZipCrypto/AES), TAR, TAR.GZ/TGZ, GZIP and 7z inputs are supported,
|
||||
including nested archives within preparation limits. Unsupported formats are
|
||||
reported. `--password VALUE` is also supported, but can expose the password in
|
||||
shell history or process listings. Passwords are not stored in results.
|
||||
|
||||
The tool prints the result directory. Use `--output PATH` to choose a new one;
|
||||
existing results are not overwritten. Appliance grouping is inferred from
|
||||
directories; review the preparation manifest for unusual export layouts.
|
||||
|
||||
## Read the results
|
||||
|
||||
| File | Purpose |
|
||||
| --- | --- |
|
||||
| `summary.json` | Processing status, counts and incomplete coverage |
|
||||
| `findings.jsonl` | Events, source lines, matching rules and decoding explanations |
|
||||
| `IOCS.csv` | Exact SIEM search values and separate defanged display values |
|
||||
| `updates.jsonl` | Installation and software-version evidence |
|
||||
| `correlations.jsonl` | Related events on the same appliance; temporal candidates, not causal proof |
|
||||
| `coverage.json` | Per-file coverage and errors |
|
||||
| `input_manifest.json` | Original relative paths and SHA-256 checksums |
|
||||
| `preparation_manifest.json` | Archive preparation and appliance grouping |
|
||||
|
||||
The output also includes an SQLite event index, effective configuration and
|
||||
indicator/hash hit files. JSONL contains one JSON object per line. URL/Base64
|
||||
decoding retains original values, transformation steps, checksums and errors.
|
||||
An installer command alone does not establish successful patch completion.
|
||||
|
||||
## Add indicators and Sigma rules
|
||||
|
||||
Put your packs in a directory and validate them before scanning:
|
||||
|
||||
```sh
|
||||
netscaler-triage rules --config ./my-rules
|
||||
netscaler-triage ./logs --config ./my-rules
|
||||
```
|
||||
|
||||
Directories load Sigma YAML, JSON, CSV and TXT recursively. Repeat `--config`
|
||||
to combine packs. No Python changes are needed to add an IP, path or rule.
|
||||
For example, an IOC CSV can contain:
|
||||
|
||||
```csv
|
||||
type,value,status,source,description
|
||||
ipv4,192.0.2.42,reference_only,local-review,Investigate matching events
|
||||
path,/example/suspicious-file,reference_only,local-review,Check file context
|
||||
```
|
||||
|
||||
These are synthetic examples. Use original, non-defanged values for matching.
|
||||
TXT accepts one value per line; unambiguous IP addresses, SHA-256 hashes, URLs
|
||||
and Unix paths are inferred. Other values remain literal strings.
|
||||
|
||||
Sigma is parsed with pySigma and evaluated locally using the subset documented
|
||||
in [RULES.txt](RULES.txt). Unsupported features fail explicitly. Sigma metadata
|
||||
does not bypass detection conditions. Rule packs are data, not executable plugins.
|
||||
|
||||
Defaults include 47 Sigma rules and 246 public reference indicators. Attribution
|
||||
and limitations are recorded in [THREAT_INTELLIGENCE.txt](THREAT_INTELLIGENCE.txt)
|
||||
and [config/threat_intel.json](config/threat_intel.json). This is a dated reference
|
||||
collection, not a promise of exhaustive intelligence or zero false positives.
|
||||
|
||||
Keep confidential packs in `private/`, excluded from Git and release archives.
|
||||
Load them explicitly. Never put customer logs or generated findings in a public
|
||||
repository. Examples under [examples/](examples/) use synthetic data.
|
||||
|
||||
## Limits and interpretation
|
||||
|
||||
- Exit `0`: configured processing completed; **not** a clean-system verdict.
|
||||
- Exit `2`: an error or incomplete processing; inspect `summary.json`.
|
||||
- Missing years/timezones are not guessed. See [README.txt](README.txt) for time configuration.
|
||||
- Binary appliance logs may need an external decoder. Decode failures can also come from ordinary text.
|
||||
- Damaged inputs and regex timeouts are reported. Archive path traversal, unsafe links and exhausted quotas stop preparation.
|
||||
- Processing uses one worker, incremental reads and disk-backed SQLite. There is no hard process-wide RAM/CPU quota or automatic resume.
|
||||
- Default limits: 2 GiB preparation budget, 100,000 archive entries, depth 3, 1 MiB per line and 512 MiB expanded per log file. Advanced options can raise limits.
|
||||
|
||||
Tests were executed on macOS/ARM64. Windows and Linux instructions are provided,
|
||||
but those platforms have not yet been validated in the recorded test environment.
|
||||
|
||||
## Help and development
|
||||
|
||||
```sh
|
||||
netscaler-triage --help
|
||||
netscaler-triage scan --help-all
|
||||
netscaler-triage decode payload.txt
|
||||
netscaler-triage inventory ./logs
|
||||
|
||||
uv sync --locked
|
||||
uv run python -W error -m unittest discover -s tests
|
||||
uv run mypy
|
||||
uv run ruff check src tests typing_stubs
|
||||
uv run ruff format --check src tests typing_stubs
|
||||
uv build
|
||||
```
|
||||
|
||||
See [README.txt](README.txt) for the detailed plain-text manual and
|
||||
[VALIDATION.txt](VALIDATION.txt) for test scope and known coverage limits.
|
||||
|
||||
## License
|
||||
|
||||
Project code is licensed under the [MIT License](LICENSE.txt).
|
||||
Third-party dependencies and referenced external materials retain their own
|
||||
licenses. Source attribution does not imply affiliation with Citrix or the
|
||||
referenced researchers, and does not relicense their original publications.
|
||||
Reference in new issue
Block a user