Earlier this week, we open-sourced a tool we rely on for dynamic binary analysis: Manticore! Manticore helps us quickly take advantage of symbolic execution, taint analysis, and instrumentation to analyze binaries. Parts of Manticore underpinned our symbolic execution capabilities in the Cyber Grand Challenge. As an open-source tool, we hope that others can take advantage of these capabilities in their own projects.
We prioritized simplicity and usability while building Manticore. We used minimal external dependencies and our API should look familiar to anyone with an exploitation or reversing background. If you have never used such a tool before, give Manticore a try.
Two interfaces. Multiple use cases.
Manticore comes with an easy-to-use command line tool that quickly generates new program “test cases” (or sample inputs) with symbolic execution. Each test case results in a unique outcome when running the program, like a normal process exit or crash (e.g., invalid program counter, invalid memory read/write).
The command line tool satisfies some use cases, but practical use requires more flexibility. That’s why we created a Python API for custom analyses and application-specific optimizations. Manticore’s expressive and scriptable Python API can help you answer questions like:
- At point X in execution, is it possible for variable Y to be a specified value?
- Can the program reach this code at runtime?
- What is a program input that will cause execution of this code?
- Is user input ever used as a parameter to this libc function?
- How many times does the program execute this function?
- How many instructions does the program execute if given this input?
In our first release, the API provides functionality to extend the core analysis engine. In addition to test case generation, the Manticore API can:
- Abandon irrelevant states
- Run custom analysis functions at arbitrary execution points
- Concretize symbolic memory
- Introspect and modify emulated machine state
Manticore is one of the primary tools we use for binary analysis research. We used an earlier version as the foundation of our symbolic execution vulnerability hunting in the Cyber Grand Challenge. We’re using it to build a custom program analyzer for DARPA LADS.
In the month leading up to our release, we solicited ideas from the community on simple use cases to demonstrate Manticore’s features. Here are a few of our favorites:
- Eric Hennenfent solved a simple reversing challenge. He presented two solutions: one using binary instrumentation and one using symbolic execution.
- Yan and Mark replaced a variable with a tainted symbolic value to determine which specific comparisons user input could influence.
- Josselin Feist generated an exploit using only the Manticore API. He instrumented a binary to find a crash and then determined constraints to call an arbitrary function with symbolic execution.
- Cory Duplantis solved a reversing challenge from Google CTF 2016. His script is a great example of how straightforward it is to solve many CTF challenges with Manticore.
Finally, a shoutout to Murmus who made a video review of Manticore only 4 hours after we open sourced it!
It’s easy to get started
With other tools, you’d have to spend time researching their internals. With Manticore, you have a well-written interface and an approachable codebase. So, jump right in and get something useful done sooner.
Grab an Ubuntu 16.04 VM and:
# Install the system dependencies sudo apt-get update && sudo apt-get install z3 python-pip -y python -m pip install -U pip # Install manticore and its dependencies git clone https://github.com/trailofbits/manticore.git && cd manticore sudo pip install --no-binary capstone .
You have installed the Manticore CLI and API. We included a few examples in our source repository. Let’s try the CLI first:
# Build the examples cd examples/linux make # Use the Manticore CLI to discover unique test cases manticore basic cat mcore_*/*1.stdin | ./basic cat mcore_*/*2.stdin | ./basic
“Basic” is a toy example that reads user input and prints one of two statements. Manticore used symbolic execution to explore `basic` and discovered the two unique inputs. It puts sample inputs it discovers into “stdin” files that you can pipe to the binary. Next, we’ll use the API:
# Use the Manticore API to count executed instructions cd ../script python count_instructions.py ../linux/helloworld
The count_instructions.py script uses the Manticore API to instrument the `helloworld` binary and count the number of instructions it executes.
Let us know what you think!
If you’re interested in reverse engineering, binary exploitation, or just want to want to learn about CPU emulators and symbolic execution, we encourage you to play around with it and join #manticore on our Slack for discussion and feedback. See you there!