reverse-skills-max: initial public release (restored, redacted, hardened)
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
Apache License 2.0 — see the repository root LICENSE file for the full text.
|
||||
|
||||
Copyright the AnalystAIPack contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
@@ -0,0 +1,88 @@
|
||||
---
|
||||
name: analyzing-golang-malware-internals
|
||||
description: 'Analyzes Go-compiled malware by recovering function names from the pclntab, detecting
|
||||
the Go build/version string, and listing embedded package paths to overcome stripped symbols.
|
||||
Activates for requests to analyze Go malware, recover Go function names, or identify a Golang
|
||||
binary build.'
|
||||
domain: cybersecurity
|
||||
subdomain: reverse-engineering
|
||||
tags:
|
||||
- reverse-engineering
|
||||
- golang
|
||||
- symbol-recovery
|
||||
- pclntab
|
||||
- stripped-binaries
|
||||
version: 1.0.0
|
||||
author: analyst-ai-pack
|
||||
license: Apache-2.0
|
||||
mitre_attack:
|
||||
- T1027
|
||||
- T1587.001
|
||||
- T1059
|
||||
d3fend:
|
||||
- D3-SDA
|
||||
- D3-DA
|
||||
references:
|
||||
- 'Go runtime pclntab format (Go source: runtime/symtab.go) — https://go.dev/src/runtime/symtab.go'
|
||||
- 'Go binary build info (debug/buildinfo) — https://pkg.go.dev/debug/buildinfo'
|
||||
---
|
||||
|
||||
# Analyzing Golang Malware Internals
|
||||
|
||||
## When to Use
|
||||
|
||||
- You have a Go-compiled binary (often large, statically linked) and standard symbol recovery
|
||||
fails because user symbols are stripped.
|
||||
- You need function names from the pclntab, the Go version, and embedded package/module paths.
|
||||
|
||||
**Do not use** this for non-Go binaries — confirm the Go build signature first. This skill reads
|
||||
the binary statically and executes nothing.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- The Go binary (read inertly).
|
||||
|
||||
## Safety & Handling
|
||||
|
||||
- Read bytes statically; treat strings as untrusted data.
|
||||
|
||||
## Workflow
|
||||
|
||||
### Step 1: Confirm it is Go and get the version
|
||||
|
||||
```bash
|
||||
python scripts/analyst.py info sample.bin
|
||||
```
|
||||
|
||||
Looks for the `Go build ID`, the `go1.x` version string, and `runtime.` references.
|
||||
|
||||
### Step 2: Recover function names from pclntab
|
||||
|
||||
The pclntab (preceded by a magic like `\xfb\xff\xff\xff`/`\xf0\xff\xff\xff` across Go versions)
|
||||
contains function name strings; extract `main.*`, package-qualified, and `runtime.*` names.
|
||||
|
||||
### Step 3: Enumerate package paths
|
||||
|
||||
List embedded import/module paths (`github.com/...`, vendored deps) to fingerprint capabilities
|
||||
and third-party libraries.
|
||||
|
||||
### Step 4: Map and document
|
||||
|
||||
Map suspicious packages (networking, crypto, exec) to behavior and ATT&CK.
|
||||
|
||||
## Validation
|
||||
|
||||
- The Go build signature/version is confirmed before deeper parsing.
|
||||
- Recovered names include plausible `main.*`/package-qualified functions.
|
||||
- Package paths are real module paths, not random strings.
|
||||
|
||||
## Pitfalls
|
||||
|
||||
- pclntab magic differs across Go versions; try the known set.
|
||||
- Obfuscators (garble) rename symbols and strip build info — names may be hashed.
|
||||
- Confusing vendored library code with the author's `main` package.
|
||||
|
||||
## References
|
||||
|
||||
- See [`references/api-reference.md`](references/api-reference.md) for the analyzer.
|
||||
- Go pclntab/buildinfo references (linked in frontmatter).
|
||||
@@ -0,0 +1,38 @@
|
||||
# API Reference: Analyzing Golang Malware Internals
|
||||
|
||||
## Overview
|
||||
|
||||
`scripts/analyst.py` confirms a Go build (build ID / `go1.x` / `runtime.main`), detects pclntab
|
||||
magic markers, and recovers Go function names and package import paths from printable strings,
|
||||
mapping notable packages to capabilities. It reads bytes statically and executes nothing. This is
|
||||
a heuristic scan, not a full pclntab structure parser.
|
||||
|
||||
## Dependencies
|
||||
|
||||
| Package | Version | Purpose |
|
||||
|---------|---------|---------|
|
||||
| (stdlib) | — | regex, JSON, file IO |
|
||||
|
||||
## Core functions
|
||||
|
||||
### `info(path)`
|
||||
Returns Go detection, versions, pclntab magics present, recovered functions, package paths, and
|
||||
capabilities.
|
||||
|
||||
## Heuristics
|
||||
|
||||
- Go detection: `Go build ID`, `go1.x`, `runtime.main`.
|
||||
- pclntab magics: `\xfb\xff\xff\xff`, `\xfa…`, `\xf0…`, `\xf1…` (across Go versions).
|
||||
- Functions: `main.*`, `runtime.*`, `net.*`, `crypto.*`, `os/exec.*`, `syscall.*`.
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
python scripts/analyst.py info sample.bin
|
||||
```
|
||||
|
||||
## Sources
|
||||
|
||||
- Go runtime pclntab format (runtime/symtab.go) — https://go.dev/src/runtime/symtab.go
|
||||
- Go build info (debug/buildinfo) — https://pkg.go.dev/debug/buildinfo
|
||||
- Go RE techniques (pclntab name recovery, garble obfuscation) from public Go-malware research
|
||||
@@ -0,0 +1,62 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Analyze a Go-compiled binary: confirm Go build, recover names, list package paths.
|
||||
|
||||
Detects the Go build signature/version, scans printable strings for Go function/package names
|
||||
(main.*, runtime.*, github.com/... import paths), and reports likely capabilities. Reads bytes
|
||||
statically; executes nothing. This is a heuristic string/pclntab-marker scan, not a full pclntab
|
||||
parser.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import re
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
ASCII_RE = re.compile(rb"[\x20-\x7e]{3,}")
|
||||
RE_GOVER = re.compile(rb"go1\.\d+(?:\.\d+)?")
|
||||
PCLNTAB_MAGICS = [b"\xfb\xff\xff\xff", b"\xfa\xff\xff\xff", b"\xf0\xff\xff\xff",
|
||||
b"\xf1\xff\xff\xff"]
|
||||
RE_FUNC = re.compile(r"^(?:main|runtime|net|crypto|os/exec|syscall)[./][\w./*()]+")
|
||||
RE_PKG = re.compile(r"(?:github\.com|gitlab\.com|golang\.org|gopkg\.in)/[\w./-]+")
|
||||
|
||||
CAP_PKGS = {
|
||||
"net/http": "HTTP networking", "net": "raw networking", "crypto/aes": "AES crypto",
|
||||
"os/exec": "process execution", "syscall": "direct syscalls",
|
||||
"golang.org/x/sys": "low-level OS access",
|
||||
}
|
||||
|
||||
|
||||
def info(path: str) -> dict:
|
||||
data = Path(path).read_bytes()
|
||||
strings = [m.decode("latin-1", "ignore") for m in ASCII_RE.findall(data)]
|
||||
blob = "\n".join(strings)
|
||||
is_go = b"Go build ID" in data or bool(RE_GOVER.search(data)) or b"runtime.main" in data
|
||||
versions = sorted({m.decode() for m in RE_GOVER.findall(data)})
|
||||
funcs = sorted({s for s in strings if RE_FUNC.match(s)})[:200]
|
||||
pkgs = sorted(set(RE_PKG.findall(blob)))[:100]
|
||||
caps = sorted({desc for pkg, desc in CAP_PKGS.items() if pkg in blob})
|
||||
pcln = [m.hex() for m in PCLNTAB_MAGICS if m in data]
|
||||
return {
|
||||
"is_go_binary": is_go,
|
||||
"go_versions": versions,
|
||||
"pclntab_magics_present": pcln,
|
||||
"recovered_functions": funcs,
|
||||
"package_paths": pkgs,
|
||||
"capabilities": caps,
|
||||
}
|
||||
|
||||
|
||||
def main(argv: list[str] | None = None) -> int:
|
||||
parser = argparse.ArgumentParser(description="Analyze a Go binary")
|
||||
sub = parser.add_subparsers(dest="cmd", required=True)
|
||||
p = sub.add_parser("info")
|
||||
p.add_argument("file")
|
||||
args = parser.parse_args(argv)
|
||||
print(json.dumps(info(args.file), indent=2))
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Reference in New Issue
Block a user