Files
NetScaler_forensik/README.md
T

149 lines
6.0 KiB
Markdown
Raw Normal View History

# 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.