12. Security-analysis tools
[!ref] Full details in the User Manual, "Security-analysis tools".
12.1 Constraints
- Only usable inside the workspace's
samples/subdirectory. exec-type tools are hard-disabled insamples/and not configurable.- Analysis tools never modify the sample itself; the
samples/directory is writable (sample drops andsec.pcap_stream_extractoutput land on disk).
12.1.1 Sample drop entry points
| Entry | Behaviour |
|---|---|
| "+" at bottom-left of input box | System multi-file dialog → land in <workspace>/samples/ |
| User cancel | Silently ignored, no error |
| Duplicate names | Auto-suffix timestamp; no overwrite |
| No active workspace | Button greyed; click shows "No active workspace" |
Backend transparently handles local and remote workspaces.
12.2 Tools (16 total)
| Tool | Purpose |
|---|---|
sec.hash |
Multi-algorithm hash (md5 / sha1 / sha256 / sha512 etc.) |
sec.entropy |
Shannon entropy (total + per-block) |
sec.hexdump |
xxd-style hex + ASCII |
sec.strings |
Extract ASCII + UTF-16LE strings |
sec.ioc_extract |
Extract IOCs (IP / URL / domain / email / hashes incl SHA-512 / BTC·ETH·XMR / CVE / MAC / registry / paths); refangs first, paginated (see §12.6) |
sec.pe_parse |
PE / PE+ (sections, imports, exports, entry, subsystem) |
sec.elf_parse |
ELF (sections, dynamic deps, symbols, build-id) |
sec.macho_parse |
Mach-O (incl. FAT / universal) |
sec.imphash |
Mandiant-style PE imphash |
sec.disasm |
Linear disassembly (architecture auto-sniffed) |
sec.decompile |
LLM-assisted C / Java pseudo-code |
sec.pcap_info |
PCAP overview + top-N flows |
sec.pcap_stream_list |
Enumerate all TCP/UDP/ICMP flows in a PCAP with stable ids |
sec.pcap_stream_extract |
Dump a flow's L7 payload to a workspace path |
sec.pcap_extract |
DNS / HTTP / TLS ClientHello SNI field extraction |
sec.yara_scan |
YARA rule scan (default build is stub) |
12.3 sec.hash
| Arg | Type | Default | Description |
|---|---|---|---|
path |
string | — | Required |
algorithms |
array | [md5, sha1, sha256] |
One of md5, sha1, sha256, sha384, sha512, sm3 |
12.4 sec.entropy
| Arg | Type | Default | Description |
|---|---|---|---|
path |
string | — | Required |
block_size |
int | 4096 | 0 = no blocks |
12.5 sec.strings
| Arg | Type | Default | Description |
|---|---|---|---|
path |
string | — | Required |
min_len |
int | 6 | Minimum length |
encodings |
array | [ascii, utf16le] |
|
limit |
int | 4096 soft / 256 KiB hard |
12.6 sec.ioc_extract
Auto-refangs first (hxxp://, 1.2.3[.]4, evil[.]com, foo(dot)bar), then matches over printable strings (cuts binary noise). IPs are net.ParseIP-validated and tagged (private/loopback/link_local/multicast/cgnat/unspecified), MACs are no longer misparsed as IPv6, and domains are public-suffix-validated (drops kernel32.dll-style). Deduplicated per value with count and tags (including defanged). Paginated like sec.strings (limit and byte_limit, whichever is tighter; on truncated=true read next_offset / per_kind_capped / hint).
| Arg | Type | Default | Description |
|---|---|---|---|
path |
string | — | Required |
kinds |
array | All | See below; empty = all |
max_per_kind |
int | 200 (max 5000) | Max unique hits per kind; capped kinds listed in per_kind_capped |
max_bytes |
int | 128 MiB | Max bytes to scan |
offset |
int | 0 | Full-set 0-based continuation index (use prior next_offset) |
limit |
int | 500 (max 5000) | Per-call items cap |
byte_limit |
int | 4096 (hard 262144) | Per-call return-bytes cap, whole-item granularity |
defang_output |
bool | false | Render values defanged (evil[.]com / hxxp://…) for safe display |
exclude_private |
bool | false | Drop non-public IPs (kept and tagged by default) |
context |
bool | false | Include a short surrounding-text snippet per hit |
Kinds:
| Name | Meaning |
|---|---|
ipv4 / ipv6 |
IP addresses (with classification tags) |
url / domain / email |
Links / domains (public-suffix-validated) / email |
md5 / sha1 / sha256 / sha512 |
Hashes |
btc / eth / xmr |
Bitcoin / Ethereum / Monero wallet addresses |
cve |
CVE ids |
mac |
MAC addresses |
registry |
Windows registry keys |
path_win / path_unix |
Path strings |
Extraction is a candidate indicator, not a verdict — corroborate before acting.
12.7 sec.pe_parse / sec.elf_parse / sec.macho_parse
| Arg | Type | Default | Description |
|---|---|---|---|
path |
string | — | Required |
sections |
bool | true | Sections list |
imports |
bool | true | Imports (PE) / dynamic deps (ELF) |
exports |
bool | true | Exports |
signatures |
bool | false | Signatures / cert chain |
12.8 sec.disasm
| Arg | Type | Default | Description |
|---|---|---|---|
path |
string | — | Required |
arch |
enum | auto |
auto / x86 / x86_64 / arm / arm64 / ppc64 |
start |
int / hex | File entry | Start VA / offset |
length |
int | 4096 | Bytes to disassemble |
12.9 sec.decompile
| Arg | Type | Default | Description |
|---|---|---|---|
path |
string | — | Required |
target |
enum | c |
c / java |
function |
string | Entry | Function name or start address |
Privacy:
sec.decompilesends the relevant disassembly to the decompilation model; only use when the sample is safe to transmit.
12.10 sec.pcap_info / sec.pcap_stream_list / sec.pcap_stream_extract / sec.pcap_extract
| Tool | Args | Description |
|---|---|---|
sec.pcap_info |
path |
Total packets / start-end times / protocol mix / top-N flows |
sec.pcap_stream_list |
path, limit (default 200, max 2000), offset, sort_by (first_ts (default) / packets / bytes) |
Paginated list of TCP/UDP/ICMP flows; id is always the chronological global id, stable across pages and sort orders, and can be passed straight to sec.pcap_stream_extract |
sec.pcap_stream_extract |
path, stream_id, out_path (relative to workspace root; can land outside samples/) |
Dump the flow's L7 payload to a file |
sec.pcap_extract |
path, protocol (dns / http / tls_sni), limit |
Protocol-aware field extraction; returns IOCs (IPs etc.) |
v1 does single-packet inspection only; no TCP reassembly.
12.11 sec.yara_scan
| Arg | Type | Default | Description |
|---|---|---|---|
path |
string | — | Required |
rules |
string | Built-in | Rule file (relative path) or built-in set name |
timeout_ms |
int | 60_000 | Kill on timeout |
12.12 sec.ontology.* — Security domain fact layer (v1, local workspace)
| Tool | Args | Description |
|---|---|---|
sec.ontology.record |
facts: [{s, p, o, source?}] |
Write SPO triples. Single-valued predicates (version / license / severity / auth) supersede; multi-valued (depends_on / has_cve / exposes / listens / affects) accumulate |
sec.ontology.query |
s?, p?, o? (empty = wildcard) |
Pattern query; e.g. {p:"has_cve"} lists all CVEs, {s:"pkg:lodash"} lists everything about lodash |
sec.ontology.reachable |
start, predicate |
Multi-hop traversal along a transitive predicate from start; for transitive-dependency / attack-surface blast-radius |
Entity naming: prefer typed prefixes (pkg:lodash / svc:api / cve:CVE-2021-23337) so cross-class queries don't collide. SSOT persistence: facts live in the workspace and survive conversation compaction.
12.13 Software bill of materials (SBOM) tools — supply-chain vulnerability scanning
sbom.* are workspace tools (they act on the project's dependency manifests, not limited to samples/); 5 in total. Result files land in the workspace's .avlcode/ directory by default. Related settings: §6.16.
| Tool | Use |
|---|---|
sbom.generate |
Scan dependency manifests to build an SBOM (default CycloneDX 1.5 JSON) |
sbom.convert |
Convert freely between CycloneDX / SPDX / DSDX / SWID |
sbom.audit |
Audit against OSV for known vulns, flagging CVE / KEV / CVSS severity |
sbom.vex |
Converge vulns by symbol-level reachability; emit OpenVEX |
sbom.dbsync |
Maintain the local offline OSV DB (air-gap) |
12.13.1 sbom.generate
| Param | Type | Default | Notes |
|---|---|---|---|
path |
string | workspace root | Scan root (relative to workspace) |
format |
string | cyclonedx |
cyclonedx / spdx / dsdx / swid; append -xml for XML (e.g. cyclonedx-xml), dsdx-tag for DSDX native tag-value |
output |
string | .avlcode/sbom.<format>.<ext> |
Output path (relative to scan root) |
- Ecosystems (
Ecosystemconstants): go · npm (incl. yarn Berry / pnpm v5) · cargo · pypi · maven · gem · composer · nuget · swift · pub · conan · conda · hex · cocoapods · cran · hackage · julia; Deno manifests also supported. - Manifest scanning recurses subdirectories and falls back to manifest-file parsing when a lock is missing; npm/pypi/conan: first matching lock wins, maven reads all three; drops first-party false positives, handles Go
replace/exclude, keeps version comparison faithful. - A missing manifest skips that ecosystem; all missing yields a 0-component BOM (not an error); output is deterministic / reproducible (no timestamps / random serial; components sorted).
- The audit does per-ecosystem fallback, adds precision notes for Maven/Gradle/pip/Conda/Conan/npm, spells out unaudited ecosystems, and includes exploitability notes.
- Returns:
format/encoding/component_count/ecosystems/bom_path/components(preview, max 50) /truncated.
12.13.2 sbom.convert
| Param | Type | Default | Notes |
|---|---|---|---|
input |
string | — | required, SBOM file to convert (relative to workspace) |
to |
string | — | required, target format (same syntax as format) |
from |
string | auto-detect | Source-format override |
output |
string | <input>.<to>.json |
Output path |
Converts via a canonical intermediate model (N readers + N writers); preserves components / purls / licenses / hashes / dependency relationships; fields the target can't hold are dropped per rule (DSDX has no hashes; SWID hashes not mapped). Format × encoding matrix: CycloneDX(1.5) JSON+XML, SPDX(2.3) JSON+RDF/XML, DSDX JSON+XML+native, SWID JSON+XML — all readable and writable.
12.13.3 sbom.audit
| Param | Type | Default | Notes |
|---|---|---|---|
path |
string | workspace root | Scan root |
mode |
enum | auto |
auto (offline DB if present, else online) / online (api.osv.dev) / offline (local snapshot) |
output |
string | .avlcode/sbom.audit.json |
Report path |
Matches against OSV; CVE = first CVE-… alias; KEV from <config>/kev.json. Severity from CVSS vectors: v2 (AV:/AC:/Au:) / v3 (CVSS:3) / v4 (CVSS:4.0, official MacroVector lookup); bands critical ≥9 / high ≥7 / medium ≥4 / low >0; a record's own GHSA qualitative band wins when present. Sorted worst-first, KEV on top. Returns: source / components_scanned / vulnerable / total_vulns / by_severity / kev_count / report_path / findings (preview, max 30) / truncated.
12.13.4 sbom.vex
| Param | Type | Default | Notes |
|---|---|---|---|
path |
string | workspace root | Scan root |
mode |
enum | auto |
Same source as audit |
output |
string | .avlcode/sbom.vex.json |
OpenVEX output |
lsp_confirm |
bool | false | Use the language server to confirm at least one real reference per package (needs the server installed; spawns it); default off — pure offline import scan, air-gap friendly |
detail |
bool | false | Include findings_detail (for the App-side LLM convergence) |
Runs audit, then deterministic symbol-level reachability analysis. Statuses: affected / not_affected / under_investigation / fixed; not_affected carries a machine-readable justification (vulnerable_code_not_present / vulnerable_code_not_in_execute_path / component_not_present / inline_mitigations_already_exist). Reachability scan caps: ≤4000 files, ≤256 KiB/file, skipping .git / node_modules / vendor / target / dist / build etc. Go converges to not_affected directly from OSV affected symbols; other ecosystems default to "referenced → affected, unreferenced → under_investigation" (never auto-marking not_affected) and can be narrowed via lsp_confirm or App-side symbol match. Sorted affected > under_investigation > fixed > not_affected.
12.13.5 sbom.dbsync
| Param | Type | Default | Notes |
|---|---|---|---|
action |
enum | status |
status (local-only — record counts / freshness) / sync (fetch OSV dumps over network) / import (offline import) / kev (refresh KEV) |
ecosystems |
string[] | auto-detect | sync ecosystems to fetch; empty = auto-detect from the workspace manifests |
path |
string | workspace root | sync auto-detect scan root |
zip_path |
string | — | import required: local OSV ecosystem zip (relative to workspace) |
osv_eco |
string | — | import required: the OSV ecosystem name the zip is for (e.g. npm / PyPI / Go) |
13 ecosystems have OSV offline-dump coverage (SyncableEcosystems); conan / conda / CocoaPods have no offline DB (online audit only). import errors if zip_path or osv_eco is missing.
12.14 Cloud threat-intelligence tools (VirusTotal / GTI)
Two tool groups, independently gated, both configured under Settings → Security (see §6.17).
Sentinel hash scan sec.vtai_* (bound to the "auto-scan interception · Sentinel" config, via vtGuard):
| Tool | Params | Notes |
|---|---|---|
sec.vtai_check_hash |
hash (required, MD5/SHA1/SHA256) |
Hash-only intel lookup, no upload; returns verdict/malicious/total/label/source/link; errors if no backend configured |
sec.vtai_scan |
path (required), force (bool) |
Uploads a high-risk file for a full scan; RegisterUploadRequired — visible to the LLM only when "upload scan" or local YARA is on, else degrades to a hash lookup |
sec.vtai_register |
display_name? / human_alias? / bio? / contact_email? |
Triggers VirusTotal AI registration; actually completed via the settings consent flow (RegisterVTAI) |
sec.vtai_status |
— | Returns enabled/monitor/auto_scan/mode/source/public_handle/cache_size, etc. |
Full intelligence vt.* (gated by the full_tools policy, coexists with Sentinel):
| Tool | Key params | Gating |
|---|---|---|
vt.lookup |
indicators[] / indicator, type? (file/url/domain/ip), relationship? |
Free, read-only (master switch only) |
vt.api |
resource? / id? / relationship? / action? / path? / method (default GET) / query{} / body{} / raw? |
Reads by default; writes via query_only, Premium/GTI endpoints via enable_paid_features |
vt.submit |
url? / file? / rescan? / wait? / confirm? |
Write; blocked by query_only; file upload ≤ 32 MB, needs confirm=true when confirm_sample_upload is on; wait polls up to 180 s |
vt.download |
hash (req), save_to (req) |
Premium (enable_paid_features) |
vt.feeds |
type, time (YYYYMMDDhhmm/hh, UTC), save_to (all req) |
Premium; T-60 min delay |
vt.hunt |
op (retrohunt_*/notifications/rulesets), id? / rules? / corpus? / limit? / cursor? |
Premium; async |
full_tools policy:
- Fields:
enabled/query_only(default on) /enable_paid_features(default off) /confirm_sample_upload(default on) /api_base. Check()order: not enabled →ErrDisabled; write + query-only →ErrQueryOnly; non-public tier + paid off →ErrPaidDisabled; tiers (public/premium/gti) are enforced remotely by VT (403).- Enabling requires
KeyUsable(ciphertext decrypts to non-empty), else it errors at enable time. - Responses default to a
Summarize()compact summary (namescap 8,tagscap 12);raw=truereturns raw; timeouts: api/lookup/hunt/submit 30 s, download/feeds 5 min.
