winter2020 / oo7

oo7, a binary analysis tool to defend against Spectre vulnerabilities
Other
32 stars 3 forks source link

Failing compile BAP #8

Open taehyun9203 opened 2 years ago

taehyun9203 commented 2 years ago

Hi, i want to implement this code in my system but i face the problem during compiling the bap.


#=== ERROR while compiling bap-llvm.2.0.0 =====================================#
# context     2.1.0 | linux/x86_64 | ocaml-base-compiler.4.05.0 | https://opam.ocaml.org#f2aede02
# path        ~/.opam/4.05.0/.opam-switch/build/bap-llvm.2.0.0
# command     ~/.opam/opam-init/hooks/sandbox.sh build make
# exit-code   2
# env-file    ~/.opam/log/bap-llvm-637206-4f7a9d.env
# output-file ~/.opam/log/bap-llvm-637206-4f7a9d.out
### output ###
# [...]
# /usr/lib/llvm-10/include/llvm/MC/MCDisassembler/MCDisassembler.h:77:3: note: 'getInstruction' declared here
#   virtual DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
#   ^
# lib/bap_llvm/llvm_disasm.cpp:460:62: error: too few arguments to function call, expected 5, have 4
#             printer->printInst(&mcinst, stream, "", *sub_info);
#             ~~~~~~~~~~~~~~~~~~                               ^
# /usr/lib/llvm-10/include/llvm/MC/MCInstPrinter.h:82:3: note: 'printInst' declared here
#   virtual void printInst(const MCInst *MI, uint64_t Address, StringRef Annot,
#   ^
# 3 errors generated.
# Command exited with code 1.
# make: *** [Makefile:8: build] Error 1

<><> Error report <><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
┌─ The following actions failed
│ λ build bap-llvm 2.0.0
``

I thought that the reason is that mismatching the version of bap-llvm.

Could you help me to solve the this problem?

my system use llvm-10 and is running on Ubuntu 20.04
ivg commented 2 years ago

This repository is a snapshot of the tool as it was published so it is no longer updated to the latest versions of llvm or bap. When it was released, LLVM 10 didn't even exist :) And BAP was of version 1.5. Therefore, if you want to get exactly this version you will have to use a virtual machine with an older version of llvm. To be honest, I can't recollect the upper bound of llvm in BAP 1.5.0 (it was many years ago).

The static analysis part of this plugin is part of bap-toolkit and is available under the MIT license, so if you want you can use it (see the spectre tool). It should be compatible with the rest of the oo7 tool, so if you want to continue experimenting with this tool or even build something on top of it, I would suggest you to use the latest available version of BAP, which is 2.4.0 or even use the development branch 2.5.0-alpha. You can either install it using the README instructions (note that you need opam 2.0 for that) or use the available docker images of bap or even bap-toolkit.

If you have any questions on BAP, feel free to drop our chat in gitter.

taehyun9203 commented 2 years ago

Thanks for answering my question. I have more question about the spectre code. I have motivation which uses your tool to find another new spectre gadget in applications using my spectre gadget. Is it possible to modify spectre code in bap and find another gadget not only spectre-v1?

ivg commented 2 years ago

Sure, it should be possible, if this variant is statically detectable. You can modify the plugin and the PR back is very welcome. And I will happily advise you, in case you will get stuck :)

taehyun9203 commented 2 years ago

I get the incident from the well-know spectre-v1 (Spectre paper). how to exactly parse the incidents? I use the incidents_profile.py in this project but the result is not clear like README.md in this project. Could you give me advise how to get the result clearly? the result is here

@branches: 37
@S1: 0 (0.000%)
@S2: 0 (0.000%)
@S2_avg_dis: 0
@S3: 0 (0.000%)
@S3_avg_dis: 0
ivg commented 2 years ago

This script was written by @winter2020 to post-process the results of static analysis. So I can't give you more insights on it than you probably already have. Let me explain the general picture how it works.

On the high level. The static analysis microexecutes a binary using BAP's microexecutor1 called Primus. During the execution, Primus emits observations when something interesting happens. There are lots of observations available in Primus2. An interesting class of observations is called incident, and it is reported whenever we suspect some kind of weakness in the binary. The bap-toolkit repository contains a plethora of tools, each reporting a different kind of incidents, like use-after-free or spectre. So let's focus the spectre vulnerability and how BAP detects it.

After BAP finishes analyzing the binary, you can post-process the incidents file (the file that contains the record of observations) to find all incidents of the spectre vulnerability. The post-processing is not really needed as the ddtbd analysis (bap) is able to detect this vulnerability, using the following decision rule,

      <L1>: when <c> branch _
      <L2>: load <i> -> <j>
      <L3>: load <j> -> _ \/ store <j>
      distance (<L1>,<L2>) < SEW
      distance (<L1>,<L3>) < SEW
      <c> is-data-dependent-on <untrusted-input>
      <i> is-data-dependent-on <untrusted-input>
      <j> is-data-dependent-on <i> \/ <j> is-ctrl-dependent-on <i>
      <i> is-program-dependent-on <c>
      -------------------------------------------
      spectre-pattern (L1, L2, L3)

This rule searches for three observations,

  1. a branch with a tainted3 condition, which is denoted by the following observation in the incidents file,
    (spectre-hypot-init (<id> (S1 (cond <L1>) (taint <tid>))))
  2. a load (memory read) from a tainted address <i> that is program dependent on the condition, which is denoted with the following observation in the incidents file,
    (spectre-hypot-partial (<id> (S2 (taint <tid>) (cond <L1>) (load <L2>))))
  3. and finally a load or a store (memory write) from an address <j> which is program dependent on <i>, which is denoted in the incidents file with the following observation,
    (spectre-path (<val> (<id> (S3 (cond <L1>) (load <L2>) (last <L3>)))))

Nearly forgot, and the distance between L1, L2, and L3 should be less than the speculative execution window. So once we found all three parts that satisfy our condition we report the spectre-pattern incident, which looks like this

(incident (spectre-pattern <id> <cond-id> <load-id> <last-id>))

Which is used in our incident tracking system to identify the full provenance of the spectre pattern, those <*id> point to the inicident-location observations, each containing a full execution trace. So that we can load this incidents file in IDA and check it and step through the trace.

I hope you now get a more or less clear picture of the analysis. And if you have a file, run bap on it. You can use the bap-toolkit docker image (or install bap and do make && make install in the bap-toolkit repository), then just do,

bap ./exe --recipe=spectre

where exe is your testing artifact, and the grep for spectre-path in the incidents file, e.g.,

ivg@pippin:~/factory/oo7/toy$ grep spectre-path incidents 
(spectre-path (1:63u#3426 (7 (S3 (cond 4005c8) (load 4005cf) (last 4005de)))))

This output says that the toy binary from this repo is vulnerable to spectre, and the addresses correspond to the location of the branch, first and the second load/store correspondingly.


1) A microexecutor is like an emulator that is able to execute arbitrary pieces of a binary instead of the whole binary. The microexecutor initializes inputs with random data. To increase coverage, it mutates branch conditions, which may lead to unsound results, since we will be visiting infeasible paths.

2) Think of them as probes in linux perf.

3) We use tainting analysis to test which variables are under adversary control. So when I say tainted, read "possibly controllable by adversary"

taehyun9203 commented 2 years ago

Thank you for giving helpful advice.

In oo7, I find incidents and check the vulnerability in the files.

However when i run the toy code in my bap-tool using bap environment, i can not get the same result :( (spectre-path (1:63u#3426 (7 (S3 (cond 4005c8) (load 4005cf) (last 4005de)))))

I think i wrongly install the bap and bap install.

I spent many times to install bap and bap install following the README.md over 10times but maybe i still miss something....

I try to do myself to make similar result you mentioned in here :)

ivg commented 2 years ago

Hey @taehyun9203, are you still struggling with getting it to work? If so then consider using docker to get reproducible results. There are detailed instructions in the readme how to use docker, but here is a quick start,

  1. make sure that you have the latest version of bap,
    docker pull binaryanalysisplatform/bap
  2. go to the bap-toolkit folder and build the toolkit image,
    docker build -t bap-tookit .
  3. go to the folder with your test file, e.g., with the toy, and run the toolkit container,
    docker run -it --rm -v $(pwd):/bap-toolkit bap-toolkit bap test --recipe=spectre
  4. check that you have the spectre vulnerability detected,
    grep S3 incidents
  5. modify the code of the tool to your taste and got to step 2.