├── .gitignore ├── LICENSE ├── Makefile ├── README.md ├── Tasks.todo ├── Vagrantfile ├── bin └── EMPTY ├── gitbook ├── .gitignore ├── README.md ├── SUMMARY.md ├── afl-fuzzing │ ├── fuzzing-primitives.md │ ├── getting-started-afl.md │ ├── imagemagick-fuzzing.md │ ├── images │ │ ├── afl1.png │ │ └── ssrv_crash.png │ ├── libgit2-fuzzing.md │ ├── libtiff-fuzzing.md │ ├── parallel-fuzzing.md │ ├── persistent-mode-fuzzing.md │ └── tools-suite.md ├── environment-setup │ ├── afl-setup-test.md │ └── fuzzer-vm-setup.md ├── extra │ └── extra-references.md ├── images │ └── bsides.png ├── introduction │ ├── README.md │ ├── images │ │ ├── abhisek.png │ │ └── ashfaq.png │ └── terminologies.md ├── threat-modelling │ └── threat-modelling-for-vulnerability-research.md └── winafl │ └── qh-fuzzing.md └── src ├── hello-vulnerable-world.c ├── int20.c ├── ssrv.c └── vuln3.c /.gitignore: -------------------------------------------------------------------------------- 1 | .vagrant 2 | bin/* 3 | !bin/EMPTY 4 | src/*.o 5 | scratch 6 | a.out 7 | 8 | ubuntu-xenial-16.04-cloudimg-console.log 9 | ubuntu-bionic-18.04-cloudimg-console.log 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Abhisek Datta 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | CC := afl-clang 2 | CFLAGS := -D_FORTIFY_SOURCE=0 3 | LDFLAGS := 4 | BIN_DIR := bin 5 | 6 | hello-vulnerable-world: src/hello-vulnerable-world.o 7 | $(CC) -o $(BIN_DIR)/hello-vulnerable-world src/hello-vulnerable-world.o $(LDFLAGS) 8 | 9 | hello-integer-world: src/hello-integer-world.o 10 | $(CC) -o $(BIN_DIR)/hello-integer-world src/hello-integer-world.o $(LDFLAGS) 11 | 12 | all: hello-vulnerable-world hello-integer-world 13 | 14 | .PHONY: clean 15 | clean: 16 | -rm -rf src/*.o 17 | -find $(BIN_DIR)/ -type f -not -name 'EMPTY' -print0 | xargs -0 rm -- 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AFL Fuzzing Workshop 2 | BSides Delhi 2019 - https://bsidesdelhi.in 3 | 4 | ## Prerequisite 5 | 6 | * VirtualBox 7 | * Vagrant 8 | * NodeJS (To start local Gitbook server) 9 | 10 | ## Getting Started 11 | 12 | Clone this repository 13 | 14 | ``` 15 | git clone https://github.com/abhisek/afl-fuzzing-workshop 16 | ``` 17 | 18 | Switch to repository directory 19 | 20 | ``` 21 | cd afl-fuzzing-workshop 22 | ``` 23 | 24 | Install `Gitbook` cli 25 | 26 | ``` 27 | sudo npm install -g gitbook-cli 28 | ``` 29 | 30 | Start local Gitbook server to following workshop content 31 | 32 | ``` 33 | cd gitbook 34 | gitbook serve 35 | ``` 36 | 37 | Navigate to `http://localhost:4000` -------------------------------------------------------------------------------- /Tasks.todo: -------------------------------------------------------------------------------- 1 | BSides Delhi 2019 Workshop Courseware: 2 | Selected Talk Category: Workshop (3 Hours) 3 | 4 | Setup and Introduction: 5 | Get everyone to setup their VM and have clarity on intent and objective of the workshop 6 | ☐ Intent and object of the workshop 7 | ☐ VM setup using Vagrant and Virtual Box 8 | 9 | Getting started with Fuzzing using AFL: 10 | Get everyone to be familiar with various use-cases of AFL 11 | ☐ Hello World Fuzzing 12 | ☐ Simple buffer overflow 13 | ☐ Simple integer overflow 14 | ☐ Simple format string 15 | ☐ Simple use-after-free 16 | ☐ AFL use-cases 17 | ☐ Single instance fuzzing 18 | ☐ Multi instance fuzzing (distributed) 19 | ☐ AFL Tools 20 | 21 | Targeted Fuzzing: 22 | Get everyone to start thinking in terms of a vulnerability researcher 23 | ☐ Introduction to Threat Modelling 24 | ☐ What to fuzz in a software 25 | ☐ Creating fuzz target 26 | ☐ Measuring fuzzer effectiveness through Coverage analysis 27 | ☐ Improving fuzzer effectiveness 28 | 29 | Demo: 30 | ☐ Vulnerability Discovery using WinAFL 31 | 32 | Vulnerability Discovery Hackathon: 33 | Get everyone to find vulnerabilities in real-life software (Github) -------------------------------------------------------------------------------- /Vagrantfile: -------------------------------------------------------------------------------- 1 | # -*- mode: ruby -*- 2 | # vi: set ft=ruby : 3 | Vagrant.configure("2") do |config| 4 | config.vm.box = "ubuntu/bionic64" 5 | config.vm.network "private_network", ip: "192.168.33.100" 6 | # config.vm.network "public_network" 7 | 8 | config.vm.provider "virtualbox" do |vb| 9 | vb.memory = "2048" 10 | end 11 | 12 | config.vm.provision "shell", inline: <<-SHELL 13 | apt-get update 14 | DEBIAN_FRONTEND=noninteractive apt-get install -y build-essential wget gdb clang cmake openssl libssl-dev 15 | mkdir /tmp/afl-install && cd /tmp/afl-install 16 | wget -O afl-latest.tgz https://github.com/google/AFL/archive/v2.56b.tar.gz 17 | tar xzvf afl-latest.tgz 18 | rm -rf afl-latest.tgz 19 | cd AFL-* 20 | make 21 | cd llvm_mode 22 | LLVM_CONFIG=/usr/bin/llvm-config-6.0 make 23 | cd .. && make install 24 | 25 | cd /tmp 26 | wget https://gitlab.com/akihe/radamsa/uploads/a2228910d0d3c68d19c09cee3943d7e5/radamsa-0.6.c.gz 27 | gzip -d radamsa-0.6.c.gz 28 | sudo gcc -o /usr/local/bin/radamsa radamsa-0.6.c 29 | 30 | echo 'kernel.core_pattern = core' | sudo tee -a /etc/sysctl.conf 31 | sysctl -p 32 | SHELL 33 | end 34 | -------------------------------------------------------------------------------- /bin/EMPTY: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abhisek/afl-fuzzing-workshop/ccfba17233beade802902c7e71d20b36139d8cb3/bin/EMPTY -------------------------------------------------------------------------------- /gitbook/.gitignore: -------------------------------------------------------------------------------- 1 | _book 2 | -------------------------------------------------------------------------------- /gitbook/README.md: -------------------------------------------------------------------------------- 1 | # Software Vulnerability Discovery Using Static Analysis and Fuzzing 2 | 3 | ![](images/bsides.png) 4 | -------------------------------------------------------------------------------- /gitbook/SUMMARY.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | 3 | * [Welcome](README.md) 4 | 5 | ## Introduction 6 | 7 | * [Introduction](introduction/README.md) 8 | 9 | 10 | ## Environment Setup 11 | 12 | * [Fuzzer VM Setup](environment-setup/fuzzer-vm-setup.md) 13 | * [Taking AFL for a Ride](environment-setup/afl-setup-test.md) 14 | 15 | ## Fuzzing with AFL 16 | 17 | * [Fuzzing Primitives](afl-fuzzing/fuzzing-primitives.md) 18 | * [Getting Started with AFL](afl-fuzzing/getting-started-afl.md) 19 | * [Persistent Mode Fuzzing](afl-fuzzing/persistent-mode-fuzzing.md) 20 | * [Parallel Fuzzing](afl-fuzzing/parallel-fuzzing.md) 21 | * [AFL Tools Suite](afl-fuzzing/tools-suite.md) 22 | 23 | ## Fuzzing Example 24 | 25 | 26 | * [Fuzzing libtiff](afl-fuzzing/libtiff-fuzzing.md) 27 | * [Fuzzing libgit2](afl-fuzzing/libgit2-fuzzing.md) 28 | * [Fuzzing on Windows with WinAFL](winafl/qh-fuzzing.md) 29 | 30 | ## Threat Modelling 31 | 32 | * [Threat Modelling for Vulnerability Research](threat-modelling/threat-modelling-for-vulnerability-research.md) 33 | 34 | ## Extra 35 | 36 | * [Extra and References](extra/extra-references.md) -------------------------------------------------------------------------------- /gitbook/afl-fuzzing/fuzzing-primitives.md: -------------------------------------------------------------------------------- 1 | # Fuzzing Primitives 2 | 3 | ## What is the purpose of fuzzing? 4 | 5 | > Fuzzing or fuzz testing is an automated software testing technique that involves providing invalid, unexpected, or random data as inputs to a computer program. 6 | 7 | In most real-world scenario, a fuzzing process consist of a set of tools (fuzzer) and a program (fuzz target) and a workflow such as below for the fuzzer: 8 | 9 | 1. Generates random, valid or invalid input 10 | 2. Executes target program with generated input 11 | 3. Monitors target program execution for possible fault (e.g. crash) 12 | 4. Observes runtime behavior which may influence fuzzer input generation 13 | 5. Log everything, especially input data and process state during a crash 14 | 15 | ## Fuzzer Types 16 | 17 | * Generation 18 | * Mutation 19 | * Evolutionary 20 | 21 | > There are many other types, with new names being invented on a regular basis. 22 | 23 | ## Fuzzer Components 24 | 25 | ### Fuzz Target 26 | 27 | The program being tested for fault by feeding generated input. 28 | 29 | ### Code Coverage Analyser 30 | 31 | A program that can monitor execution of target process and identify [Basic Blocks](https://en.wikipedia.org/wiki/Basic_block) executed for a given input. 32 | 33 | This allows a guided or smart fuzzer to generate input with increased code coverage, thereby automatically improving the effectiveness of the fuzzing processs. 34 | 35 | ### Corpus 36 | 37 | List of input files fed in to a fuzzer to mutate on. 38 | 39 | ### Fault Detection 40 | 41 | A program, usually a debugger that can monitor a target program and detect and log faults. 42 | 43 | ### Memory Analyser 44 | 45 | External tools (e.g. Valgrind) or compiler injected instrumention (e.g. ASAN/MSAN) that can detect a variety of memory related security vulnerabilities at runtime. 46 | 47 | ## Reference 48 | 49 | * https://llvm.org/docs/LibFuzzer.html 50 | * https://gitlab.com/akihe/radamsa 51 | * https://en.wikipedia.org/wiki/Fuzzing 52 | * https://llvm.org/docs/LibFuzzer.html -------------------------------------------------------------------------------- /gitbook/afl-fuzzing/getting-started-afl.md: -------------------------------------------------------------------------------- 1 | # Getting Started with AFL 2 | 3 | > All the activities in this document are performed within the Fuzzer VM 4 | 5 | ## What is AFL? 6 | 7 | > American fuzzy lop is a security-oriented fuzzer that employs a novel type of compile-time instrumentation and genetic algorithms to automatically discover clean, interesting test cases that trigger new internal states in the targeted binary. 8 | 9 | ## First Fuzz 10 | 11 | We will fuzz the program `hello-vulnerable-world.c` available in `src` directory in the repo. 12 | 13 | We start by compiling the target program using `afl-gcc` 14 | 15 | ``` 16 | cd /vagrant/src/ 17 | afl-gcc hello-vulnerable-world.c 18 | ``` 19 | 20 | Create the input and output directories 21 | 22 | ``` 23 | mkdir -p /tmp/h1/input /tmp/h1/output 24 | ``` 25 | 26 | Create random input corpus 27 | 28 | ``` 29 | openssl rand 1024 > /tmp/h1/input/rand 30 | ``` 31 | 32 | Start the fuzzing process 33 | 34 | ``` 35 | afl-fuzz -i /tmp/h1/input/ -o /tmp/h1/output/ -- ./a.out 36 | ``` 37 | 38 | > The above program receives input from STDIN. File inputs through command line argument can be passed using `@@` special marker. 39 | 40 | Fuzzer status view indicates a crash within a few seconds of fuzzing process 41 | 42 | ![](images/afl1.png) 43 | 44 | List the mutated input that resulted in crash 45 | 46 | ``` 47 | ls -al /tmp/h1/output/crashes/ 48 | ``` 49 | 50 | Manually reproduce a crash using one of the mutated files in the above directory 51 | 52 | ``` 53 | export f=$(ls /tmp/h1/output/crashes/ |head -n 1) 54 | cat /tmp/h1/output/crashes/$f | ./a.out 55 | ``` 56 | 57 | ## Am I doing it right? 58 | 59 | One of things about finding bugs continuously is to ensure incremental improvement in fuzzing strategy. That means, when you start the fuzzing process, you must have the means to measure effectiveness of the current strategy. 60 | 61 | This can be done using basic coverage analysis i.e. measure the code coverage ratio (or percentage) observed during fuzzing within a reasonable time period. If this is very less, then we must look into better strategy for fuzzing. 62 | 63 | ## Coverage Guided Fuzzing 64 | 65 | > American Fuzzy Lop is a brute-force fuzzer coupled with an exceedingly simple but rock-solid instrumentation-guided genetic algorithm. It uses a modified form of edge coverage to effortlessly pick up subtle, local-scale changes to program control flow. 66 | 67 | ``` 68 | Simplifying a bit, the overall algorithm can be summed up as: 69 | 70 | 1) Load user-supplied initial test cases into the queue, 71 | 72 | 2) Take next input file from the queue, 73 | 74 | 3) Attempt to trim the test case to the smallest size that doesn't alter 75 | the measured behavior of the program, 76 | 77 | 4) Repeatedly mutate the file using a balanced and well-researched variety 78 | of traditional fuzzing strategies, 79 | 80 | 5) If any of the generated mutations resulted in a new state transition 81 | recorded by the instrumentation, add mutated output as a new entry in the 82 | queue. 83 | 84 | 6) Go to 2. 85 | ``` 86 | 87 | > http://lcamtuf.coredump.cx/afl/README.txt 88 | 89 | ### Static Analysis of Fuzz Target 90 | 91 | [Basic Block](https://en.wikipedia.org/wiki/Basic_block) count in a program can be used as an indicator to measure coverage during fuzzing. However, a process consists of a main binary and associated shared libraries. In such a case, we need to identify the basic block count in the fuzz target i.e. the library or program that contains our target code. 92 | 93 | ## Reference 94 | 95 | * [http://lcamtuf.coredump.cx/afl/QuickStartGuide.txt](http://lcamtuf.coredump.cx/afl/QuickStartGuide.txt) 96 | * [http://lcamtuf.coredump.cx/afl/README.txt](http://lcamtuf.coredump.cx/afl/README.txt) -------------------------------------------------------------------------------- /gitbook/afl-fuzzing/imagemagick-fuzzing.md: -------------------------------------------------------------------------------- 1 | # Fuzzing ImageMagick 2 | 3 | Obtain source code and extract 4 | 5 | ``` 6 | wget -O imagemagick.tar.gz \ 7 | https://github.com/ImageMagick/ImageMagick/archive/7.0.8-68.tar.gz 8 | 9 | tar xzvf imagemagick.tar.gz 10 | cd ImageMagick-7.0.8-68 11 | ``` 12 | 13 | Set compiler to `AFL` 14 | 15 | ``` 16 | export CC=afl-clang-fast 17 | export CXX=afl-clang-fast++ 18 | ``` 19 | 20 | Build and compile 21 | 22 | ``` 23 | ./configure --prefix=/opt/ImageMagick-AFL 24 | make 25 | sudo make install 26 | ``` 27 | 28 | At this point, ImageMagick libraries and binaries are installed in `/opt/ImageMagick-AFL`. 29 | 30 | Create input and output directory for fuzzer 31 | 32 | ``` 33 | mkdir -p /tmp/magick/input /tmp/magick/output 34 | ``` 35 | 36 | Seed the input directory to random file samples 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /gitbook/afl-fuzzing/images/afl1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abhisek/afl-fuzzing-workshop/ccfba17233beade802902c7e71d20b36139d8cb3/gitbook/afl-fuzzing/images/afl1.png -------------------------------------------------------------------------------- /gitbook/afl-fuzzing/images/ssrv_crash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abhisek/afl-fuzzing-workshop/ccfba17233beade802902c7e71d20b36139d8cb3/gitbook/afl-fuzzing/images/ssrv_crash.png -------------------------------------------------------------------------------- /gitbook/afl-fuzzing/libgit2-fuzzing.md: -------------------------------------------------------------------------------- 1 | # Fuzzing LibGit2 2 | 3 | We will fuzz `libgit2` as a real-life target. The reason for choosing this target is due to ready availability of stub code meant for fuzzing with `libFuzzer` i.e. a `fuzz target`. This can easily be re-purposed for fuzzing with AFL. For other targets, we need to re-purpose the program or write a new program using interesting functions if the target is a shared library. 4 | 5 | Source: [https://github.com/libgit2/libgit2](https://github.com/libgit2/libgit2) 6 | 7 | Start by cloning `libgit2` locally 8 | 9 | ``` 10 | git clone --depth=1 https://github.com/libgit2/libgit2 11 | ``` 12 | 13 | For fuzzing with AFL, we have to slightly re-purpose `fuzzers/standalone_driver.c` to read input from `STDIN` instead of from a corpus directory. 14 | 15 | ```c 16 | #include 17 | 18 | #include "git2.h" 19 | #include "futils.h" 20 | #include "path.h" 21 | 22 | extern int LLVMFuzzerTestOneInput(const unsigned char *data, size_t size); 23 | extern int LLVMFuzzerInitialize(int *argc, char ***argv); 24 | 25 | int main(int argc, char **argv) 26 | { 27 | if (git_libgit2_init() < 0) { 28 | fprintf(stderr, "Failed to initialize libgit2\n"); 29 | exit(1); 30 | } 31 | 32 | LLVMFuzzerInitialize(&argc, &argv); 33 | while (__AFL_LOOP(1000)) { 34 | char buf[1024]; 35 | int n = 0; 36 | 37 | memset(buf, 0, sizeof(buf)); 38 | n = read(0, buf, sizeof(buf) - 1); 39 | 40 | if (n > 0) 41 | LLVMFuzzerTestOneInput((const unsigned char *) buf, n); 42 | } 43 | 44 | git_libgit2_shutdown(); 45 | return 0; 46 | } 47 | ``` 48 | 49 | Build `libgit2` with our modified fuzz target using `afl-clang-fast` to leverage persistent mode fuzzing. 50 | 51 | ``` 52 | mkdir build && cd build 53 | cmake -D BUILD_FUZZERS:BOOL=ON \ 54 | -D USE_STANDALONE_FUZZERS:BOOL=ON \ 55 | -D CMAKE_C_COMPILER=afl-clang-fast \ 56 | -D CMAKE_CXX_COMPILER=afl-clang-fast++ \ 57 | .. 58 | cmake --build . 59 | ``` 60 | 61 | Start the fuzzing process by following the steps below: 62 | 63 | 1. Create input and output directory 64 | 65 | ``` 66 | mkdir -p fuzzing/input fuzzing/output 67 | ``` 68 | 69 | 2. Create input data. For this we will just use a part of the pack file from `.git` 70 | 71 | ``` 72 | cp ../.git/... 73 | ``` 74 | 75 | 3. Start the fuzzer 76 | 77 | ``` 78 | afl-fuzz -i fuzzing/input -o fuzzing/output -m 512 -t 100 -- \ 79 | ./fuzzer/objects_fuzzer 80 | ``` -------------------------------------------------------------------------------- /gitbook/afl-fuzzing/libtiff-fuzzing.md: -------------------------------------------------------------------------------- 1 | # Fuzzing libtiff 2 | 3 | Install required dependencies 4 | 5 | ``` 6 | sudo apt-get install zlib1g-dev 7 | ``` 8 | 9 | Start by downloading and extracting the sources 10 | 11 | ``` 12 | wget http://download.osgeo.org/libtiff/tiff-4.0.9.tar.gz 13 | tar xzvf tiff-4.0.9.tar.gz 14 | cd tiff-4.0.9 15 | ``` 16 | 17 | Set appropriate compiler environment variables 18 | 19 | ``` 20 | export CC=afl-clang-fast 21 | export CXX=afl-clang-fast++ 22 | ``` 23 | 24 | Build libtiff with AFL compiler wrapper 25 | 26 | ``` 27 | ./configure --prefix=/opt/libtiff 28 | make 29 | sudo make install 30 | ``` 31 | 32 | Create input, output directories and seed input with sample TIFF files. Test the fuzzing process using the command line below 33 | 34 | ``` 35 | afl-fuzz -i /tmp/tiff/input/ -o /tmp/tiff/output/ -- /opt/libtiff/bin/tiff2ps @@ 36 | ``` -------------------------------------------------------------------------------- /gitbook/afl-fuzzing/parallel-fuzzing.md: -------------------------------------------------------------------------------- 1 | # Parallel or Distributed Fuzzing 2 | 3 | AFL can be used for parallel fuzzing using a shared volume. [See here](http://lcamtuf.coredump.cx/afl/README.txt) for more information. 4 | 5 | ## Parallel Fuzzing 6 | 7 | AFL can run multiple fuzzer instance in a system with a shared `output` directory for synchronising across multiple instance of the fuzzer. 8 | 9 | More information: 10 | https://github.com/mirrorer/afl/blob/master/docs/parallel_fuzzing.txt 11 | 12 | 13 | ## Distributed Fuzzing 14 | 15 | [AFL in the Cloud](https://github.com/abhisek/afl-in-the-cloud) is a PoC implementation of running parallel fuzzing in AWS cloud with automated provisioning. -------------------------------------------------------------------------------- /gitbook/afl-fuzzing/persistent-mode-fuzzing.md: -------------------------------------------------------------------------------- 1 | # Fuzzing in Persistent Mode 2 | 3 | ## Introduction 4 | 5 | [Detailed](http://lcamtuf.blogspot.com/2015/06/new-in-afl-persistent-mode.html) description of fuzzing in *Persistent Mode*. 6 | 7 | Example program 8 | 9 | ```c 10 | main() { 11 | while(__AFL_LOOP(1000)) { 12 | char buf[100]; 13 | int n = 0; 14 | 15 | memset(buf, 0, sizeof(buf)); 16 | n = read(0, buf, sizeof(buf)); 17 | 18 | target_function(buf, n) 19 | } 20 | } 21 | ``` 22 | 23 | > Forking is expensive as it involves creating process context and its associated data structure. To optimize further, AFL supports in-process fuzzing where appropriate instrumentation code is generated to re-run the fuzz target with mutated input. `__AFL_LOOP` provides an indicator to AFL on each iteration of in-process fuzzing. 24 | 25 | **Note:** For this to work, `afl-clang-fast` or `afl-clang-fast++` wrapper along with LLVM `clang` has to be used to build the fuzz target. 26 | 27 | ## Hands-on Exercise 28 | 29 | Fuzz `ssrv.c` using AFL and identify the vulnerability. 30 | 31 | ## Solution 32 | 33 | The target program is a network service which needs to be re-purposed to be able to fuzz with AFL. We apply the following patch to fuzz it with AFL in *Persistent Mode* 34 | 35 | ```diff 36 | diff --git a/src/ssrv.c b/src/ssrv.c 37 | index 56f3701..e633542 100644 38 | --- a/src/ssrv.c 39 | +++ b/src/ssrv.c 40 | @@ -143,5 +143,14 @@ int srv_init() 41 | 42 | int main(int argc, char **argv) 43 | { 44 | - return srv_init(); 45 | + // return srv_init(); 46 | + while(__AFL_LOOP(1000)) { 47 | + char buf[1024]; 48 | + int n = 0; 49 | + 50 | + memset(buf, 0, sizeof(buf)); 51 | + n = read(0, buf, sizeof(buf) - 1); 52 | + 53 | + process_msg(-1, buf); 54 | + } 55 | ``` 56 | 57 | Compile the fuzz target 58 | 59 | ``` 60 | afl-clang-fast ./ssrv.c 61 | ``` 62 | 63 | Create input and output directory 64 | 65 | ``` 66 | mkdir -p /tmp/ss/input /tmp/ss/output 67 | ``` 68 | 69 | Generate input corpus 70 | 71 | ``` 72 | openssl rand -hex 1024 > /tmp/ss/input/rand 73 | ``` 74 | 75 | Start the fuzzing 76 | 77 | ``` 78 | afl-fuzz -i /tmp/ss/input/ -o /tmp/ss/output/ -- ./a.out 79 | ``` 80 | 81 | To improve the effectiveness of the fuzzing process, create a dictionary with following content 82 | 83 | ``` 84 | sep="\x200" 85 | cmd_echo="echo" 86 | nullb="\x00" 87 | data="AAAAA" 88 | ``` 89 | 90 | Restart the fuzzing process with custom dictionary 91 | 92 | ``` 93 | afl-fuzz -i /tmp/ss/input/ -o /tmp/ss/output/ -x /tmp/ss.dict -- ./a.out 94 | ``` 95 | 96 | Fuzzer status after crash 97 | 98 | ![](images/ssrv_crash.png) -------------------------------------------------------------------------------- /gitbook/afl-fuzzing/tools-suite.md: -------------------------------------------------------------------------------- 1 | # AFL Tools Suite 2 | 3 | ## afl-fuzz 4 | 5 | The main fuzzer 6 | 7 | ## Compiler Wrappers 8 | 9 | * afl-gcc 10 | * afl-g++ 11 | * afl-clang 12 | * afl-clang++ 13 | * afl-clang-fast 14 | * afl-clang-fast++ 15 | 16 | The compiler wrappers inject instrumentation code at compile time. 17 | 18 | ## afl-cmin 19 | 20 | Corpus minimizer 21 | 22 | ## afl-tmin 23 | 24 | Test case minimizer used to minimize a test case that generated a crash 25 | 26 | ## afl-whatsup 27 | 28 | Status check tool, useful during parallel fuzzing 29 | 30 | ## afl-analyze 31 | 32 | Analyze and guess the structure of input file format based on code coverage at runtime -------------------------------------------------------------------------------- /gitbook/environment-setup/afl-setup-test.md: -------------------------------------------------------------------------------- 1 | # Taking AFL for a Ride 2 | 3 | > All the activities in this document are performed within the Fuzzer VM 4 | 5 | Compile damn vulnerable programs: 6 | 7 | ``` 8 | cd /vagrant 9 | make 10 | ``` 11 | 12 | Lets fuzz `hello-vulnerable-world` 13 | 14 | ``` 15 | mkdir -p /tmp/hello-vulnerable-workspace/input 16 | mkdir -p /tmp/hello-vulnerable-workspace/output 17 | dd if=/dev/urandom of=/tmp/hello-vulnerable-workspace/input/input.dat bs=1024 count=1 18 | ``` 19 | 20 | Start fuzzer 21 | 22 | ``` 23 | afl-fuzz \ 24 | -i /tmp/hello-vulnerable-workspace/input \ 25 | -o /tmp/hello-vulnerable-workspace/output \ 26 | -- ./bin/hello-vulnerable-world 27 | ``` -------------------------------------------------------------------------------- /gitbook/environment-setup/fuzzer-vm-setup.md: -------------------------------------------------------------------------------- 1 | # Environment Setup 2 | 3 | ## Requirements 4 | 5 | * Vagrant 6 | * Virtualbox 7 | 8 | ## Setup 9 | 10 | Create virtual machine with AFL installed 11 | 12 | ``` 13 | vagrant up 14 | ``` 15 | 16 | SSH into the VM 17 | 18 | ``` 19 | vagrant ssh 20 | ``` 21 | 22 | > Everything else is done inside the VM 23 | 24 | -------------------------------------------------------------------------------- /gitbook/extra/extra-references.md: -------------------------------------------------------------------------------- 1 | # Extra 2 | 3 | * [AFL Training](https://github.com/mykter/afl-training) 4 | * [Clang LibFuzzer](https://llvm.org/docs/LibFuzzer.html) 5 | * [Address Sanitizer](https://github.com/google/sanitizers/wiki/AddressSanitizer) -------------------------------------------------------------------------------- /gitbook/images/bsides.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abhisek/afl-fuzzing-workshop/ccfba17233beade802902c7e71d20b36139d8cb3/gitbook/images/bsides.png -------------------------------------------------------------------------------- /gitbook/introduction/README.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | ## Intent of the Workshop 4 | 5 | The intent of the workshop is to introduce participants familiar with vulnerability assessment and penetration testing to the art of discovering software vulnerability through static code analysis and fuzzing. 6 | 7 | The workshop will provide a getting started experience and discussion space for anybody interested in navigating source code to identify potential attack surfaces, which in turn can be fuzzed in a targeted manner to discover potential vulnerabilities. 8 | 9 | Familiarity with reading C/C++ is preferred. Ability to read and understand other people's code (in any language) is highly recommended for participants. 10 | 11 | ## Objective of the Workshop 12 | 13 | Every individual who fully participate in the workshop should be able to 14 | 15 | 1. Setup a Virtual Machine using `Vagrantfile` with an [AFL](http://lcamtuf.coredump.cx/afl/) fuzzing environment 16 | 2. Gain hands-on experience of various use-cases supported by [AFL](http://lcamtuf.coredump.cx/afl/) 17 | 3. Get started to fuzzing for discovering vulnerabiliteis 18 | 4. Perform a basic *Threat Modelling* exercise before fuzzing 19 | 5. Fuzzing of real-life open source software 20 | 21 | ## About Trainer 22 | 23 | | Trainer | Details | 24 | | ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | 25 | | ![Abhisek Datta](images/abhisek.png) | Name : Abhisek Datta
Twitter : [@abh1sek](https://twitter.com/abh1sek)
LinkedIn: [Abhisek Datta](https://www.linkedin.com/in/abh1sek/)
Github: [https://github.com/abhisek](https://github.com/abhisek) | 26 | | ![Ashfaq Ansari](images/ashfaq.png) | Name : Ashfaq Ansari
Twitter : [@HackSysTeam](https://twitter.com/HackSysTeam)
Github: [https://github.com/hacksysteam](https://github.com/hacksysteam) | 27 | -------------------------------------------------------------------------------- /gitbook/introduction/images/abhisek.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abhisek/afl-fuzzing-workshop/ccfba17233beade802902c7e71d20b36139d8cb3/gitbook/introduction/images/abhisek.png -------------------------------------------------------------------------------- /gitbook/introduction/images/ashfaq.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abhisek/afl-fuzzing-workshop/ccfba17233beade802902c7e71d20b36139d8cb3/gitbook/introduction/images/ashfaq.png -------------------------------------------------------------------------------- /gitbook/introduction/terminologies.md: -------------------------------------------------------------------------------- 1 | # Terminologies 2 | 3 | ## Threat Model 4 | 5 | ## Fuzzer 6 | 7 | ## Fuzz Target 8 | 9 | ## Coverage Analysis -------------------------------------------------------------------------------- /gitbook/threat-modelling/threat-modelling-for-vulnerability-research.md: -------------------------------------------------------------------------------- 1 | # Threat Modelling 2 | 3 | ## Terminologies 4 | 5 | * Threat 6 | * Vulnerability 7 | * Exploit 8 | * Risk 9 | 10 | ## What is Threat Modeling? 11 | 12 | * Threat modeling is an in-depth approach for analyzing the security of an application 13 | * It allows the reviewer to see where the entry points to the application are (i.e. the attack surfaces) 14 | * The associated threats with each entry point (i.e. attack vectors) 15 | * Design and adopt various counter measures and mitigation strategies to enhance security of the application 16 | 17 | ## Objective for Threat Modeling 18 | 19 | To gain insight to inner working of the application and its various components 20 | 21 | ## High-level Steps for Threat Modeling 22 | 23 | 1. Decompose the Application 24 | 2. Determine and rank threats 25 | 3. Determine counter measures and mitigations 26 | 27 | ## A Basic Threat Model 28 | 29 | A basic threat model can be prepared to gain insight about a target application before fuzzing by answering questions as below: 30 | 31 | ### What are the primary assets in the application? 32 | 33 | List what are the critical information that needs to be protected by the application and its infrastructure. 34 | 35 | ### Who are the attackers 36 | 37 | List who are potential attackers. Example 38 | 39 | 1. Anonymous external user 40 | 2. Registered external user 41 | 3. Local user 42 | 4. Etc. 43 | 44 | ### What are the attack surfaces 45 | 46 | Example: 47 | 48 | 1. Primary web portal 49 | 2. Support portal 50 | 3. Chat system 51 | 4. Etc. 52 | 53 | ### What are the security controls implemented in the application 54 | 55 | Example: 56 | 57 | 1. SSL/TLS 58 | 2. Authentication 59 | 3. Authorization 60 | 4. Sandbox 61 | 5. Etc. 62 | 63 | ### How can they attack 64 | 65 | List potential scenarios using which critical information can be breached. 66 | 67 | ## Reference 68 | 69 | * https://www.owasp.org/index.php/Application_Threat_Modeling 70 | * https://www.amazon.in/Threat-Modeling-Designing-Adam-Shostack-ebook/dp/B00IG71FAS 71 | * https://docs.threatdragon.org 72 | * https://www.microsoft.com/en-us/securityengineering/sdl/threatmodeling 73 | 74 | -------------------------------------------------------------------------------- /gitbook/winafl/qh-fuzzing.md: -------------------------------------------------------------------------------- 1 | # Fuzzing Quick Heal using WinAFL 2 | 3 | Fuzzing closed source application is not as easy as fuzzing application whose source code is available. 4 | 5 | Quick Heal is a closed source AV scanner made in India. This AV has lots of services and drivers installed in the system. Each can pose security risk. However, in this workshop we are interested in fuzzing the file parsers in this particular AV. 6 | 7 | Quick Heal installs **Core Scanning Server (SAPISSVC.EXE)** as a **SYSTEM** service. The Quick Heal GUI uses **IPC** to communicate with **SAPISSVC.EXE** service. 8 | 9 | ## How do we fuzz it now? 10 | 11 | **SAPISSVC.EXE** runs as SYSTEM. We can't attach debugger to it easily. After some reversing of the main **SCANNER.EXE** (GUI application), I figured out that if the service is not not responding or dead, then the **SCANNER.EXE** with load the scanning engine and then continue scanning the file. 12 | 13 | ## Fuzzing SCANNER.EXE 14 | 15 | Now we know that it's easy to fuzz **SCANNER.EXE**. But is it efficient enough to fuzz it using AFL/WinAFL? 16 | 17 | Short answer not really. Then, how to fuzz it? 18 | 19 | 20 | ## Write custom Quick Heal client 21 | 22 | Writing a custom client for an application whose source code nor debugging symbols are available, it's really hard and requires extensive reverse engineering. 23 | 24 | I reached out to QuickHeal to see if they can provide me **qhscan** binary. **qhscan** is the command line scanner for Linux. But they asked to give my address, phone number and email so that their sales team can contact me and then provide me **quick heal for linux**. I declined this offer. 25 | 26 | Quick Heal provides a scanning SDK (**SCANSDK.DLL**) which is utilized by the **SCANNER.EXE** and other command line scanners they provide. As this is a SDK, the important functions are exported. 27 | 28 | ```bash 29 | ashfaq@hacksys:~$ cat dump-exports.py 30 | import os 31 | import sys 32 | import pefile 33 | 34 | if __name__ == "__main__": 35 | filename = sys.argv[1] 36 | pe = pefile.PE(filename, fast_load=True) 37 | pe.parse_data_directories(directories=pefile.DIRECTORY_ENTRY["IMAGE_DIRECTORY_ENTRY_EXPORT"]) 38 | 39 | print "Dumping exports for: {0}".format(os.path.basename(filename)) 40 | print "" 41 | 42 | exports = [e.name for e in pe.DIRECTORY_ENTRY_EXPORT.symbols] 43 | 44 | for export in exports: 45 | print export 46 | ``` 47 | 48 | ```bash 49 | ashfaq@hacksys:~/Shared$ python dump-exports.py SCANSDK.DLL 50 | Dumping exports for: SCANSDK.DLL 51 | 52 | GetAWStatus 53 | GetQHOptions 54 | GetSSStatus 55 | QHAppCtlCloseFile 56 | QHAppCtlDeinit 57 | QHAppCtlGetFileType 58 | QHAppCtlGetOptions 59 | QHAppCtlGetVersionInfo 60 | QHAppCtlInit 61 | QHAppCtlOpenFile 62 | QHAppCtlScanFile 63 | QHAppCtlScanFileEx 64 | QHAppCtlScanFileExForRS 65 | QHAppCtlSetOptions 66 | QHAppCtlSetOptionsForRS 67 | QHAppcApplySignatures 68 | QHAppcLoadSignatures 69 | QHAppcReloadSignatures 70 | QhCleanBoot 71 | QhCleanFile 72 | QhCleanFileEx 73 | QhCleanFileExForMobile 74 | QhCleanFileForMobile 75 | QhCleanFileGen 76 | QhCloseFile 77 | QhCloseFileForMobile 78 | QhCreateMimeObject 79 | QhDeinitScan 80 | QhDeinitScanForSAS 81 | QhDeleteMimeObject 82 | QhGetAPIVersion 83 | QhGetAPIVersionEx 84 | QhGetAVStamp 85 | QhGetAVStampEx 86 | QhGetActionForCommandLineW 87 | QhGetFileType 88 | QhGetFileTypeForMobile 89 | QhGetFileTypeForSAS 90 | QhGetOptions 91 | QhGetOptionsForSAS 92 | QhGetQuarantineUploadDecisionW 93 | QhGetUpdateState 94 | QhInitScan 95 | QhInitScanForSAS 96 | QhIsAccessDeniedAppExcludedW 97 | QhIsCriticalAppInfectedW 98 | QhIsHiddenProcessExcludedW 99 | QhIsKindOfWorm 100 | QhLoadBootScanner 101 | QhOpenFile 102 | QhOpenFileForMobile 103 | QhOpenFileForSAS 104 | QhReloadSignatures 105 | QhResetFPTFlags 106 | QhScanBoot 107 | QhScanBuffer 108 | QhScanBufferEx 109 | QhScanBufferForSAS 110 | QhScanFile 111 | QhScanFileEx 112 | QhScanFileExForMobile 113 | QhScanFileForMobile 114 | QhScanMBR 115 | QhScanMessage 116 | QhScanSSMemDS 117 | QhScanSectorBuffer 118 | QhScanURL 119 | QhSetCallBack 120 | QhSetCallBackForMobile 121 | QhSetCallbackForSAS 122 | QhSetMessageString 123 | QhSetMessageStringForSAS 124 | QhSetOptions 125 | QhSetOptionsForSAS 126 | QhSetProcessInfoForSAS 127 | QhUnloadBootScanner 128 | QhUpdatesArrived 129 | ``` 130 | 131 | Using old school debugging techniques, I figured out the API call sequence that is required to load the scanning engine and scan a file. 132 | 133 | ``` 134 | scansdk!QhInitScanForSAS 135 | scansdk!QhSetCallbackForSAS 136 | scansdk!QhOpenFileForSAS 137 | scansdk!QhGetFileTypeForSAS 138 | scansdk!QhScanFileEx 139 | scansdk!QhCloseFile 140 | scansdk!QhDeinitScanForSAS 141 | ``` 142 | 143 | Another big challenge in reversing an application is to figure out the data structures. As I have been doing RE stuff from a long time, it did not take much time to figure out the data structures. Few snipped data structures are listed below. 144 | 145 | ```c 146 | typedef struct _INITSCAN_1 { 147 | SHORT Size; 148 | ... 149 | CHAR QuickHealDir[0x100]; 150 | CHAR TempDir[0x100]; 151 | ... 152 | } INITSCAN_1, *PINITSCAN_1; 153 | 154 | typedef struct _INITSCAN_2 { 155 | ... 156 | DWORD CurrentPid; 157 | ... 158 | } INITSCAN_2, *PINITSCAN_2; 159 | 160 | typedef struct _CALLBACK_PARAM_1 { 161 | ... 162 | CHAR DetectionDescription[50]; 163 | ... 164 | } CALLBACK_PARAM_1, *PCALLBACK_PARAM_1; 165 | ``` 166 | 167 | ``` 168 | C:\Users\hacksys\Desktop\qhscan>qhscan.exe C:\61f67cf6f474351517e3b48cdd247f8255 169 | 892f48680ba52f6d6b8bf6c5d4b1d0.pdf 170 | 171 | 8 8 8""""8 ""8"" 172 | 8 8 eeeee eeee e e 8 e e eeeee 8 eeee eeeee eeeeeee 173 | 8eee8 8 8 8 8 8 8 8eeeee 8 8 8 " 8e 8 8 8 8 8 8 174 | 88 8 8eee8 8e 8eee8e 88 8eeee8 8eeee 88 8eee 8eee8 8e 8 8 175 | 88 8 88 8 88 88 8 e 88 88 88 88 88 88 8 88 8 8 176 | 88 8 88 8 88e8 88 8 8eee88 88 8ee88 88 88ee 88 8 88 8 8 177 | 178 | Quick Heal Scanner Client 179 | CloudFuzz Technolabs Pvt. Ltd. 180 | 181 | [+] Loading ScanSDK 182 | [+] DLL: C:\Program Files\Quick Heal\Quick Heal AntiVirus Pro\SCANSDK.DL 183 | L 184 | [+] Handle: 0x71070000 185 | [+] Resolving ScanSDK APIs 186 | [+] Scanning: C:\61f67cf6f474351517e3b48cdd247f8255892f48680ba52f6d6b8bf6c5d4b1d 187 | 0.pdf 188 | [+] QhScanFileEx 189 | [+] Infected: JS/Pdfcm.AQ 190 | [+] [Unrepairable] 191 | 192 | C:\Users\hacksys\Desktop\qhscan> 193 | ``` 194 | 195 | ## Fuzzing using WinAFL 196 | 197 | As the custom client is ready to scan the files for us. It's a matter of few commands to start WinAFL and start fuzzing. 198 | 199 | ### Minset 200 | 201 | ``` 202 | winafl-cmin.py -v -D C:\Users\hacksys\Desktop\DynamoRIO\bin32 -t 100000 -i C:\Users\hacksys\Desktop\av -o C:\Users\hacksys\Desktop\minset -covtype edge -coverage_module SCANSDK.DLL -coverage_module platform.qvd -coverage_module filesdk.qvd -coverage_module ggstub.dll -coverage_module onlnmf.dll -coverage_module diskapi.dll -coverage_module bdsitf.dll -coverage_module infori.dll -coverage_module FileWrap.dll -coverage_module registry.dll -coverage_module opsitf.dll -coverage_module catitf.dll -coverage_module disasm.qvd -coverage_module dataproc.qvd -coverage_module qhpicln.dll -coverage_module engncore.qvd -coverage_module pescan.qvd -coverage_module pepoly.qvd -coverage_module arcvsdk.qvd -coverage_module lzesdk.qvd -coverage_module heurscan.qvd -coverage_module npesdk.qvd -coverage_module boot.qvd -coverage_module miscscan.qvd -coverage_module webcat.dll -coverage_module qhkill.qvd -target_module qhscan.exe -target_method ScanFile -nargs 1 -w 4 -- C:\Users\hacksys\Desktop\qhscan\qhscan.exe @@ 203 | ``` 204 | 205 | ### Fuzzing 206 | 207 | ``` 208 | afl-fuzz.exe -M master0 -i F:\minset -o F:\fuzz -D C:\Users\hacksys\Desktop\DynamoRIO\bin32 -t 20000 -- -covtype edge -coverage_module SCANSDK.DLL -coverage_module platform.qvd -coverage_module filesdk.qvd -coverage_module ggstub.dll -coverage_module onlnmf.dll -coverage_module diskapi.dll -coverage_module bdsitf.dll -coverage_module infori.dll -coverage_module FileWrap.dll -coverage_module registry.dll -coverage_module opsitf.dll -coverage_module catitf.dll -coverage_module disasm.qvd -coverage_module dataproc.qvd -coverage_module qhpicln.dll -coverage_module engncore.qvd -coverage_module pescan.qvd -coverage_module pepoly.qvd -coverage_module arcvsdk.qvd -coverage_module lzesdk.qvd -coverage_module heurscan.qvd -coverage_module npesdk.qvd -coverage_module boot.qvd -coverage_module miscscan.qvd -coverage_module webcat.dll -coverage_module qhkill.qvd -target_module qhscan.exe -target_method ScanFile -nargs 1 -- F:\qhscan.exe @@ 209 | ``` 210 | 211 | ``` 212 | afl-fuzz.exe -S slave0 -i - -o F:\fuzz -D C:\Users\hacksys\Desktop\DynamoRIO\bin32 -t 20000 -- -covtype edge -coverage_module SCANSDK.DLL -coverage_module platform.qvd -coverage_module filesdk.qvd -coverage_module ggstub.dll -coverage_module onlnmf.dll -coverage_module diskapi.dll -coverage_module bdsitf.dll -coverage_module infori.dll -coverage_module FileWrap.dll -coverage_module registry.dll -coverage_module opsitf.dll -coverage_module catitf.dll -coverage_module disasm.qvd -coverage_module dataproc.qvd -coverage_module qhpicln.dll -coverage_module engncore.qvd -coverage_module pescan.qvd -coverage_module pepoly.qvd -coverage_module arcvsdk.qvd -coverage_module lzesdk.qvd -coverage_module heurscan.qvd -coverage_module npesdk.qvd -coverage_module boot.qvd -coverage_module miscscan.qvd -coverage_module webcat.dll -coverage_module qhkill.qvd -target_module qhscan.exe -target_method ScanFile -nargs 1 -- F:\qhscan.exe @@ 213 | ``` 214 | -------------------------------------------------------------------------------- /src/hello-vulnerable-world.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | static 7 | int do_vuln() 8 | { 9 | unsigned char buf[32]; 10 | int fd = STDIN_FILENO; 11 | int ret, n; 12 | 13 | n = 0; 14 | ret = read(fd, (void*) &n, 2); 15 | 16 | if((n <= 0) || (n > 256)) 17 | return -1; 18 | 19 | memset(buf, 0, sizeof(buf)); 20 | ret = read(fd, buf, n); 21 | 22 | if(ret <= 0) 23 | return -1; 24 | 25 | printf("Read %d bytes from input stream\n", n); 26 | return 0; 27 | } 28 | 29 | int main(int argc, char **argv) 30 | { 31 | return do_vuln(); 32 | } 33 | -------------------------------------------------------------------------------- /src/int20.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int do_stuff() 7 | { 8 | unsigned char buf[32]; 9 | int fd = STDIN_FILENO; 10 | int ret, n; 11 | 12 | ret = read(STDIN_FILENO, (void*) &n, sizeof(n)); 13 | if (ret < 4) 14 | return -1; 15 | 16 | if (n > sizeof(buf)) 17 | return -1; 18 | 19 | ret = read(STDIN_FILENO, (void*) buf, n); 20 | if (ret <= 0) 21 | return -1; 22 | 23 | printf("Read %d bytes from stdin\n", ret); 24 | return 0; 25 | } 26 | 27 | int main(int argc, char **argv) 28 | { 29 | return do_stuff(); 30 | } 31 | 32 | -------------------------------------------------------------------------------- /src/ssrv.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | void str_strip(char *n) 13 | { 14 | char *p = n + strlen(n) - 1; 15 | while(p >= n) { 16 | if((*p != ' ') && (*p != '\n') && (*p != '\r')) 17 | break; 18 | 19 | *p-- = '\0'; 20 | } 21 | } 22 | 23 | // format: type:msg 24 | void process_msg(int sock, char *buffer) 25 | { 26 | char eb[100]; 27 | char *cmd_err = "Error - unsupported command\n"; 28 | char *p = buffer; 29 | char *t = NULL; 30 | 31 | t = strchr(buffer, ' '); 32 | if(t) 33 | *t++ = '\0'; 34 | 35 | if(strcmp(p, "echo") != 0) { 36 | send(sock, cmd_err, strlen(cmd_err), 0); 37 | return; 38 | } 39 | 40 | memset(eb, 0, sizeof(eb)); 41 | sprintf(eb, "echo: %s\n", t); 42 | 43 | send(sock, eb, strlen(eb), 0); 44 | } 45 | 46 | void handle_client(int sock) 47 | { 48 | char buffer[8192]; 49 | 50 | char *prompt = "fash$ "; 51 | char *msg_timeout = "Your connection is being timed out.\n"; 52 | 53 | fd_set rfds; 54 | struct timeval tv; 55 | 56 | send(sock, prompt, strlen(prompt), 0); 57 | 58 | FD_ZERO(&rfds); 59 | FD_SET(sock, &rfds); 60 | 61 | tv.tv_sec = 10; 62 | tv.tv_usec = 0; 63 | 64 | if(select(sock + 1, &rfds, NULL, NULL, &tv) < 0) 65 | return; 66 | 67 | if(!FD_ISSET(sock, &rfds)) { 68 | send(sock, msg_timeout, strlen(msg_timeout), 0); 69 | return; 70 | } 71 | 72 | memset(buffer, 0x00, sizeof(buffer)); 73 | if(recv(sock, buffer, sizeof(buffer) - 1, 0) > 0) 74 | process_msg(sock, buffer); 75 | } 76 | 77 | void child_handler(int signo) 78 | { 79 | printf("Child exit (%d)\n", signo); 80 | } 81 | 82 | void segv_handler(int signo) 83 | { 84 | printf("SIGSEGV (%d)\n", signo); 85 | exit(EXIT_FAILURE); 86 | } 87 | 88 | void abrt_handler(int signo) 89 | { 90 | printf("SIGABRT (%d)\n", signo); 91 | exit(EXIT_FAILURE); 92 | } 93 | 94 | int srv_init() 95 | { 96 | struct sockaddr_in sin; 97 | struct sockaddr_in cin; 98 | int srv_fd, cln_fd; 99 | int tmp; 100 | int sop; 101 | 102 | srv_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 103 | assert(srv_fd > 0); 104 | 105 | sop = 1; 106 | setsockopt(srv_fd, SOL_SOCKET, SO_REUSEADDR, (void*) &sop, sizeof(sop)); 107 | 108 | sin.sin_addr.s_addr = inet_addr("0.0.0.0"); 109 | sin.sin_port = htons(9000); 110 | sin.sin_family = AF_INET; 111 | 112 | assert(!bind(srv_fd, (struct sockaddr*) &sin, sizeof(sin))); 113 | listen(srv_fd, 100); 114 | 115 | //signal(SIGCHLD, child_handler); 116 | signal(SIGCHLD, SIG_IGN); 117 | 118 | while(1) { 119 | tmp = sizeof(cin); 120 | cln_fd = accept(srv_fd, (struct sockaddr*) &cin, &tmp); 121 | if(cln_fd < 0) 122 | continue; 123 | 124 | printf("Received client from %s:%d\n", (char*) inet_ntoa(cin.sin_addr), ntohs(cin.sin_port)); 125 | if(!fork()) { 126 | printf("Processing client: pid: %d socket: %d\n", getpid(), cln_fd); 127 | 128 | //signal(SIGSEGV, segv_handler); 129 | //signal(SIGABRT, abrt_handler); 130 | 131 | close(srv_fd); 132 | handle_client(cln_fd); 133 | 134 | shutdown(cln_fd, SHUT_RDWR); 135 | close(cln_fd); 136 | 137 | exit(0); 138 | } 139 | 140 | close(cln_fd); 141 | } 142 | } 143 | 144 | int main(int argc, char **argv) 145 | { 146 | return srv_init(); 147 | } 148 | -------------------------------------------------------------------------------- /src/vuln3.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | struct functions { 7 | void (*hi)(); 8 | void (*bye)(); 9 | }; 10 | 11 | void func_hi() 12 | { 13 | printf("Hello world\n"); 14 | } 15 | 16 | void func_bye() 17 | { 18 | printf("Bye bye world\n"); 19 | } 20 | 21 | int main(int argc, char **argv) 22 | { 23 | char buf[512]; 24 | char *ptr = NULL; 25 | int count; 26 | int flag; 27 | struct functions *f = NULL; 28 | char *ebuf = malloc(256); 29 | assert(ebuf != NULL); 30 | 31 | while(fgets(buf, sizeof(buf) - 1, stdin)) { 32 | count = *((int*)buf + 10); 33 | flag = *((int*)buf + 10); 34 | 35 | if(flag == 100) { 36 | f = (struct functions*) malloc(sizeof(*f)); 37 | assert(f != NULL); 38 | f->hi = (void*) func_hi; 39 | f->bye = (void*) func_bye; 40 | } 41 | 42 | if(flag == 200) { 43 | ptr = (char*) malloc(count); 44 | assert(ptr != NULL); 45 | fgets(ptr, count - 1, stdin); 46 | } 47 | 48 | if(flag == 50) { 49 | if(f) { 50 | f->hi(); 51 | f->bye(); 52 | 53 | free(f); 54 | f = NULL; 55 | } 56 | 57 | if(ptr) { 58 | free(ptr); 59 | ptr = NULL; 60 | } 61 | } 62 | 63 | if(flag == 300) { 64 | if(ptr) 65 | strcpy(ebuf, ptr); 66 | } 67 | } 68 | } 69 | --------------------------------------------------------------------------------