Enumerates program capabilities and malicious behaviors using fragment analysis.
- Analyzes binaries from any architecture - arm64, amd64, riscv, ppc64, sparc64
- Supports scripting languages such as bash, PHP, Perl, Ruby, NodeJS, and Python
- Integrates YARA forge for rules by Avast, Elastic, FireEye, Google, Nextron, and others.
- 12,000+ rules that detect everything from ioctl's to malware
- Tuned for especially excellent performance with Linux programs
- Diff-friendly output in Markdown, JSON, YAML outputs
- CI/CD friendly
- Does not attempt to process archive files (jar, zip, apk)
- Minimal rule support for Windows and Java (help wanted!)
- go 1.21+
- yara 4.3+
If you don't have it already, install yara. Something like this should work:
brew install yara || sudo apt install libyara-devel || sudo dnf install yara-devel || sudo pacman -S yara
Then install libcapz:
go install github.com/chainguard-dev/bincapz@latest
To inspect a binary, pass it as an argument to dump a list of predicted capabilities:
bincapz /bin/ping
There are flags for controlling output (see the Usage section) and filtering out rules. Here's the --format=markdown
output:
RISK | KEY | DESCRIPTION |
---|---|---|
meta | entitlements | com.apple.private.network.management.data.development |
com.apple.security.network.client | ||
com.apple.security.network.server | ||
meta | format | macho |
1/LOW | net/hostname/resolve | resolves network hosts via name |
1/LOW | net/icmp | iCMP (Internet Control Message Protocol), aka ping |
1/LOW | net/interface/get | get network interfaces by name or index |
1/LOW | net/interface/list | list network interfaces and their associated addresses |
1/LOW | net/ip | access the internet |
1/LOW | net/ip/multicast/send | send data to multiple nodes simultaneously |
1/LOW | net/ip/resolve | resolves network hosts via IP address |
1/LOW | net/ip/send/unicast | send data to the internet |
1/LOW | net/socket/connect | initiate a connection on a socket |
1/LOW | net/socket/receive | receive a message from a socket |
1/LOW | net/socket/send | send a message to a socket |
1/LOW | process/userid/set | set real and effective user ID of current process |
2/MED | combo/net/scan_tool | may scan networks: "connect |
gethostbyname | ||
port | ||
scan | ||
socket" | ||
2/MED | net/ip/string | converts IP address from byte to string |
Behaviors are sorted by lowest to highest risk: this binary doesn't have anything particularly exciting about it. If you want to only show output for the most suspicious behaviors, use --min-level=3
, which shows only "HIGH" or "CRITICAL" risk behaviors.
Let's say you are a company that is sensitive to supply-chain compromises. You want to make sure an update doesn't introduce unexpected capability changes. There's a --diff
mode for that:
bincapz -diff old_ffmpeg.dylib new_ffmpeg.dylib
Here is a result using the 3CX compromise as a test case. Each of the lines that beginsl with a "+" represent a newly added capability.
RISK | KEY | DESCRIPTION |
---|---|---|
+1/LOW | compression/gzip | works with gzip files |
+1/LOW | env/HOME | looks up the HOME directory for the current user |
+1/LOW | fs/lock/update | apply or remove an advisory lock on a file |
+1/LOW | kernel/dispatch/semaphore | uses Dispatch Semaphores |
+1/LOW | kernel/hostname/get | gets the hostname of the machine |
+1/LOW | net/http/accept/encoding | able to decode multiple forms of HTTP responses (example: gzip) |
+1/LOW | random/insecure | generate random numbers insecurely |
+1/LOW | sync/semaphore/user | uses semaphores to synchronize data between processes or threads |
+2/MED | exec/pipe | uses popen to launch a program and pipe output to/from it |
+2/MED | fs/permission/modify | modifies file permissions |
+2/MED | net/http/cookies | able to access HTTP resources using cookies |
+2/MED | net/url/request | requests resources via URL |
+2/MED | ref/path/hidden | references a hidden file that can be generated dynamically: "%s/.main_storage" |
+2/MED | shell/arbitrary_command/dev_null | runs arbitrary commands redirecting output to /dev/null |
+4/CRIT | 3P/godmoderules/iddqd/god/mode | detects a wide array of cyber threats, from malware and ransomware to advanced persistent threats (APTs), by Florian Roth |
+4/CRIT | 3P/signature_base/3cxdesktopapp/backdoor | detects 3CXDesktopApp MacOS Backdoor component, by X__Junior (Nextron Systems) |
+4/CRIT | 3P/signature_base/nk/3cx | detects malicious DYLIB files related to 3CX compromise, by Florian Roth (Nextron Systems) |
+4/CRIT | 3P/signature_base/susp/xored | detects suspicious single byte XORed keyword 'Mozilla/5.0' - it uses yara's XOR modifier and therefore cannot print the XOR key, by Florian Roth |
+4/CRIT | 3P/volexity/iconic | detects the MACOS version of the ICONIC loader., by [email protected] |
If you like to do things the hard way, you can also store the JSON output and diff the keys by hand:
bincapz --format=json <file> | jq '.Files.[].Behaviors | keys'
--all
: Ignore nothing, show all--data-files
: include files that are detected to as non-program (binary or source) files--diff
: show capability drift between two files--format
string: Output type. Valid values are: json, markdown, simple, terminal, yaml (default "terminal")--ignore-tags
string: Rule tags to ignore--min-level
: minimum suspicion level to report (1=low, 2=medium, 3=high, 4=critical) (default 1)--omit-empty
: omit files that contain no matches--third-party
: include third-party rules, which may have licensing restrictions (default true)
bincapz automates the same steps that almost any security analyst performs when faced with an unknown binary: a cursory strings
inspection. It does this using a library of 12,000+ YARA rules, including some that read byte streams and decrypt XOR/BASE64 data.
While this seems absurdly simple, it is exceptionally effective, as every binary leaves traces of its capabilities in its contents, particularly on UNIX platforms. These fragments are typically libc
or syscall
references or error codes. Due to the C-like background of many scripting languages such as PHP or Perl, the same fragment detection rules often apply.
Mostly because fragment analysis is so effective. Capability analysis through reverse engineering is challenging to get right, particularly for programs that execute other programs, such as malware that executes /bin/rm
. Capability analysis through reverse engineering that supports a wide array of file formats also requires significant engineering investment.
The most exciting malware only triggers when the right conditions are met. Nation-state actors in particular are fond of time bombs and locale detection. bincapz will enumerate the capabilities, regardless of conditions.
Sometimes you don't have it! Sometimes your CI/CD infrastructure is the source of compromise. Source-code-based capability analysis is also complicated for polyglot programs, or programs that execute external binaries, such as /bin/rm
.
bincapz alerns when an obfuscated or packed binary is detected. Depending on the packer used, fragment analysis may still work to a lesser degree. For the full story, we recommend unpacking binaries first.
Much of bincapz's functionality is inspired by https://github.com/mandiant/capa. While capa is a fantastic tool, it only works on x86-64 binaries (ELF/PE), and does not work for macOS programs, arm64 binaries, or scripting languages. https://karambit.ai/ and https://www.reversinglabs.com/ offer capability analysis through reverse engineering as a service. If you require more than what bincapz can offer, such as Windows binary analysis, you should check them out.
If you find malware that bincapz
doesn't surface suspicious behaviors for, send us a patch! All of the rules are defined in YARA format, and can be found in the rules/
folder.
If you get this error at installation:
ld: warning: search path '/opt/homebrew/Cellar/yara/4.5.0/lib' not found
ld: library 'yara' not found
You'll need to install the yara
C library:
brew install yara || sudo apt install libyara-devel || sudo dnf install yara-devel || sudo pacman -S yara