Back to File Analyzer APITry this endpoint in the playground →
Static File Analysis
POST
/v1/file/analyzeSubmit a script file for heuristic static analysis. Detects malicious patterns, extracts indicators of compromise, identifies obfuscation techniques, maps findings to MITRE ATT&CK, and produces a confidence-scored verdict — all without executing the file.
Permission
file:read
Credits
5 per request
Plans
All plans
Max Size
5 MB
Request
Send the file as multipart/form-data. Do not set Content-Type manually — let your HTTP client set the correct boundary.
# Multipart form-data upload # Field: file (required) — the script file to analyze
| Field | Type | Required | Description |
|---|---|---|---|
| file | File | Yes | The script file to analyze. Maximum size: 5 MB. See supported file types below. |
Supported File Types
The static analyzer accepts text-based script files only. Binary files are rejected.
| Extension | Type |
|---|---|
| .ps1 | PowerShell scripts |
| .vbs / .vbe | VBScript (plain and encoded) |
| .js / .jse | JScript / JavaScript (plain and encoded) |
| .hta | HTML Applications |
| .wsf / .wsh | Windows Script Files |
| .bat / .cmd | Batch files |
| .sct | Windows Scriptlet / COM Scriptlet |
| .txt | Plain text (script content) |
Response
{
"data": {
"file_name": "suspicious.ps1",
"file_size": 4312,
"file_type": "ps1",
"mime_type": "text/x-powershell",
"sha256": "e3b0c44298fc1c149afbf4c8996fb924...",
"entropy": 4.87,
"entropy_assessment": "moderate — consistent with obfuscated script",
"verdict": {
"level": "malicious",
"score": 82,
"summary": "PowerShell script with high-confidence malicious indicators including encoded payload download, credential access, and persistence via registry.",
"recommended_actions": [
"Quarantine immediately",
"Investigate process execution history",
"Check for registry persistence keys"
]
},
"findings": [
{
"id": "ps1-encoded-download",
"category": "payload_delivery",
"severity": "critical",
"title": "Encoded Download Cradle",
"description": "Script uses IEX with encoded command to download and execute remote payload.",
"evidence": "IEX ([System.Text.Encoding]::Unicode.GetString([System.Convert]::FromBase64String(...)))",
"line": 14,
"mitre_technique": "T1059.001"
},
{
"id": "ps1-registry-persistence",
"category": "persistence",
"severity": "danger",
"title": "Registry Run Key Persistence",
"description": "Writes to HKCU\\Run to establish persistence on user login.",
"evidence": "Set-ItemProperty -Path 'HKCU:\\Software\\Microsoft\\Windows\\CurrentVersion\\Run'",
"line": 31,
"mitre_technique": "T1547.001"
}
],
"extracted_scripts": [
{
"language": "powershell",
"content": "...",
"start_line": 1,
"end_line": 45
}
],
"iocs": [
{
"type": "url",
"value": "https://evil[.]example[.]com/payload.bin",
"defanged": "https://evil[.]example[.]com/payload.bin",
"context": "Download cradle at line 14"
},
{
"type": "domain",
"value": "evil[.]example[.]com",
"defanged": "evil[.]example[.]com",
"context": "C2 domain extracted from download URL"
}
],
"obfuscation": {
"score": 71,
"indicators": [
"Base64-encoded payload",
"String concatenation to hide keywords",
"Variable name randomization"
]
},
"metadata": {
"script_languages": ["powershell"],
"has_embedded_scripts": false,
"uses_activex": false,
"uses_wmi": false,
"uses_powershell": true,
"uses_network": true,
"uses_filesystem": true,
"uses_registry": true,
"attempts_persistence": true,
"attempts_evasion": true
}
},
"meta": {
"request_id": "req_a1b2c3d4-...",
"credits_used": 5,
"credits_remaining": 495,
"processing_time_ms": 312
}
}| Field | Type | Description |
|---|---|---|
| data.file_name | string | Original filename as submitted |
| data.file_size | number | File size in bytes |
| data.file_type | string | Detected script type (e.g. ps1, vbs, js) |
| data.mime_type | string | MIME type of the file |
| data.sha256 | string | SHA-256 hash of the file content |
| data.entropy | number | Shannon entropy score (0–8); higher values may indicate obfuscation or packing |
| data.entropy_assessment | string | Human-readable interpretation of the entropy value |
| data.verdict.level | string | "clean", "suspicious", "malicious", or "highly_malicious" |
| data.verdict.score | number | Aggregate risk score from 0 (safe) to 100 (critical) |
| data.verdict.summary | string | Human-readable summary of the verdict and detected behaviors |
| data.verdict.recommended_actions | string[] | List of recommended analyst actions based on findings |
| data.findings | array | Individual detection findings with id, category, severity, title, description, evidence, optional line number, and optional MITRE technique |
| data.extracted_scripts | array | Embedded script blocks with language, content, and line range |
| data.iocs | array | Extracted indicators: type, value, defanged form, and context |
| data.obfuscation.score | number | Obfuscation severity score from 0 (none) to 100 (heavy) |
| data.obfuscation.indicators | string[] | List of detected obfuscation techniques |
| data.metadata | object | Boolean flags for script capabilities: network, filesystem, registry, ActiveX, WMI, PowerShell, persistence, evasion |
| meta.request_id | string | Unique request identifier for support and debugging |
| meta.credits_used | number | Credits consumed (always 5) |
| meta.credits_remaining | number | Remaining credit balance after this request |
| meta.processing_time_ms | number | Server-side processing time in milliseconds |
Code Examples
cURL
curl -X POST https://api.dfir-lab.ch/v1/file/analyze \ -H "Authorization: Bearer sk-dfir-your-key-here" \ -F "file=@suspicious.ps1"
Python
import requests
with open("suspicious.ps1", "rb") as f:
response = requests.post(
"https://api.dfir-lab.ch/v1/file/analyze",
headers={"Authorization": "Bearer sk-dfir-your-key-here"},
files={"file": ("suspicious.ps1", f, "application/octet-stream")},
)
data = response.json()
result = data["data"]
verdict = result["verdict"]
print(f"Verdict: {verdict['level']} (score: {verdict['score']}/100)")
print(f"SHA-256: {result['sha256']}")
print(f"Entropy: {result['entropy']:.2f} ({result['entropy_assessment']})")
print(f"Findings: {len(result['findings'])}")
print(f"IOCs extracted: {len(result['iocs'])}")
for finding in result["findings"]:
print(f" [{finding['severity'].upper()}] {finding['title']}")
if finding["mitre_technique"]:
print(f" MITRE: {finding['mitre_technique']}")
print(f"Credits used: {data['meta']['credits_used']}")Important Notes
- Static analysis does not execute the file. It uses heuristic pattern matching against known malicious constructs. For execution-based analysis, use the Deep Analysis endpoint with
analysis_type: "dynamic". - Binary files are rejected with
400 binary_file. Only text-based script files are accepted. - Results are returned synchronously. The endpoint blocks until analysis is complete (typically under 500 ms for files under 5 MB).
- IOC values in the response are defanged (brackets inserted in domains and URLs) to prevent accidental navigation.