Fuzzing. Symbolic Execution =========================== We talk about securing software by program analysis. We discuss about fuzzing techniques and symbolic execution, their advantages and disadvantages and about hybrid approaches. Slides for this session: * slides_ .. _slides: http://elf.cs.pub.ro/sis/res/10-fuzzing-symex.pdf .. _`session task archive`: http://elf.cs.pub.ro/sis/res/10-fuzzing-symex.tar Tasks ----- We higly recommen you use teams of 2 or 3 to work on the tutorials. Setup ^^^^^ For the AFL and KLEE tutorial, you require access to a pre-configured environment. These environments use Docker, both for `AFL `_ and `KLEE `_. You can either: - Download a Virtual Machine that is already configured to use Docker to run the `AFL` and `KLEE` containers - Install Docker on your local machine and configure the `AFL` and `KLEE` containers Depending on which method you want to use, skip to the matching section below: Virtual Machine """"""""""""""" The easiest way is to use the ``SIS - Fuzzing`` virtual machine. This virtual machine has Docker installed and it also has the `AFL` and `KLEE` containers configured. Download the virtual machine (in OVA format) using Bittorrent. Use `this Bittorrent file `_. The virtual machine is rather large (5.4GB the OVA file, 13GB the unpacked virtual machine); be sure you have disk space. Import the OVA file in VMware or VirtualBox. Once you start the virtual machine, use the username ``student`` and password ``student``. Then start and access the AFL and KLEE Docker instances as the following snippet explains: .. code-block:: student@sis-fuzzing:~$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES student@sis-fuzzing:~$ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES f2d5777932b3 klee/klee:2.1 "/bin/bash" 8 minutes ago Exited (0) 5 minutes ago klee 5275c2d2c1ed afltraining "entrypoint.sh" 19 minutes ago Exited (137) 14 minutes ago afl student@sis-fuzzing:~$ docker start afl afl student@sis-fuzzing:~$ docker start klee klee student@sis-fuzzing:~$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES f2d5777932b3 klee/klee:2.1 "/bin/bash" 8 minutes ago Up 4 seconds 0.0.0.0:23000->22/tcp klee 5275c2d2c1ed afltraining "entrypoint.sh" 20 minutes ago Up 7 seconds 0.0.0.0:22000->22/tcp afl student@sis-fuzzing:~$ docker exec -it klee /bin/bash klee@f2d5777932b3:~$ ls klee_build klee_src klee@f2d5777932b3:~$ exit student@sis-fuzzing:~$ ssh fuzzer@localhost -p 22000 fuzzer@localhost's password: Welcome to Ubuntu 20.04.1 LTS (GNU/Linux 4.15.0-130-generic x86_64) * Documentation: https://help.ubuntu.com * Management: https://landscape.canonical.com * Support: https://ubuntu.com/advantage Last login: Tue Jan 12 09:52:37 2021 from 172.17.0.1 -bash: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8) fuzzer@5275c2d2c1ed:~$ ls AFLplusplus workshop fuzzer@5275c2d2c1ed:~$ logout .. important:: The password for the AFL Docker container is ``afl``. No password is required for the KLEE Docker container. Local Docker Installation """"""""""""""""""""""""" Otherwise you can do your own setup using Docker. If that is the case, do the following steps. #. (Skip this if Docker is already installed) Install Docker. .. code-block:: bash sudo apt-get update sudo apt-get install -y apt-transport-https ca-certificates curl gnupg-agent software-properties-common curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" sudo apt-get update sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose sudo service docker start sudo usermod -aG docker $USER sudo newgrp docker You may need to reautenticate the current user. #. Install the AFL Docker container, by following the `AFL instructions `_. .. code-block:: bash docker pull ghcr.io/mykter/fuzz-training:latest docker run -d --name afl --privileged -p 2222:2222 -e PASSMETHOD=env -e PASS=afl ghcr.io/mykter/fuzz-training ssh fuzzer@localhost -p 2222 # use password afl sudo ~/AFLplusplus/afl-system-config #. Install the KLEE Docker container, by followint the `KLEE instructions `_. The important bit is: .. code-block:: bash docker pull klee/klee:2.3 docker run -d --name klee --rm -ti --ulimit='stack=-1:-1' klee/klee:2.3 docker exec -it klee /bin/bash Fuzzing with AFL ^^^^^^^^^^^^^^^^ We will go through the `AFL tutorial `_. Just as the README suggests, we will go over the `quickstart` and `harness` exercises. First, log into the AFL Docker container. Then go inside the ``workshop/`` folder. Then go the ``quickstart/`` folder and follow the `instructions `_. After launching `afl-fuzz` make sure to take a look at `understanding the status screen `_. Once you have some crashes being detected, you can move on to the next step. You can test the crashes in the ``out/crashes/``: .. code-block:: bash ./vulnerabable < out/crashes/ Create a new folder with inputs and use that. Now create your own test file, with an obvious issue / vulnerability (such as a buffer overflow). And build that with AFL support and test / fuzz it using AFL. Now go through the ``harness/`` folder. Follow the instructions. Go through as many challenges in the ``challenges/`` folder as you can. Symbolic Execution with KLEE ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ We will go through the `KLEE tutorials `_. Go through the tutorials in order: ``First tutorial``, ``Second tutorial``, ``Using symbolic environment``. Clone the `official repo `_ to have access to the `examples/` directory. Use the directory to work on the exercises. The latest version of the container has `clang` installed in `/usr/lib/llvm-11/bin/clang`. This path is not included in the `PATH` variable. You can either include it manually or call `clang` with the full path. Extra: Fuzzing with driller ^^^^^^^^^^^^^^^^^^^^^^^^^^^ **BONUS**: Traditional fuzzers are not able to generate inputs that pass complex string comparisons, magic numbers, etc. Even if a grey-box fuzzer like ``libFuzzer`` knows the coverage state and drives the test generation to uncovered paths, this approach won't determine proper value for complex compares. In this situation, a mix system is used. This approach knows the set of paths where execution can reach only one branch of the comparison during multiple tests. We say that the fuzzer is ``blocked`` in certain instruction pointers. To unblock the code discovery, symbolic execution is used. In this lab we experiment this situation with ``driller`` (https://github.com/shellphish/driller). Take a look on how it works in ``this example`` (https://github.com/shellphish/driller/blob/master/README.md). From `session task archive`_, access ``hard-to-fuzz`` subfolder and inspect ``fuzzy`` using a static analyzer. #. Run ``fuzzy-fuzzer`` to see whether issues are found in reasonable time. #. Write a Driller script to detect the deep-hidden vulnerability. ``Driller`` is installed in this virtual machine (https://repository.grid.pub.ro/cs/hexcellents/sss/SSS%20-%20Ubuntu%2014.04.1%2064-bit.ova). To start driller virtual environment, run ``workon driller``. Be patient! Pay attention to how ``crash-me`` reads input!