Home Deliverance Fuzzing File Descriptors
Post

Deliverance Fuzzing File Descriptors

Fuzzing Script

File Descriptors

A file descriptor identifies where a file is opened in a computer system’s memory. File descriptors are most commonly used for reading and writing to files, usually on disk. They do, however, have other uses such as pipes, interprocess communication, a given program’s standard input, output and error streams, etc. On Linux, which will be our host operating system for this whitepaper, each open file is represented in the program as a pointer, and in procfs as a symbolic link to the open file or device in /proc/pidnumber/fd/ as a number. You can for example view your shell’s currently open file descriptors by typing

1
find /proc/self/fd
.

Why Fuzz File Descriptors?

In short, programs sometimes are not written with error checking to make sure the input from a file (or stream, or other spawned process, or standard in) is the type of input that it was expecting. If there are little or no checks, that program will usually encounter a fault when, for example, too much data is copied into a buffer. Fuzzing allows us to quickly and autonomously search for bugs and sometimes vulnerabilities. I call it “brute force vulnerability assessment”, and it is a powerful tool I always employ while searching for bugs. I usually let a fuzzer run on its own while doing other things, like reading the program’s code!

The Fuzzer Source

This is actually pretty short, and not very complex at all.

The most current version of this script can be found on github.

#!/usr/bin/bash
# Marshall Whittaker / oxagast
# A small file descriptor fuzzer.
# IMPORTANT: This will trash things around the system, do not run unless it's contained in a VM.
#
# Deliverance
# noun
#  1. the action of being rescued or set free.
#
# Useage: ./deliverance.sh [progname] [buf size optional]
# Useage: ./deliverance.sh firefox 512
# Note: Some processes will spin off other processes, for example with skype, you need to use
# skypeforlinux as the program name to fuzz, as that is how it shows up in ps/pgrep.

pn=$1;

fuzz () {
  rm open_fd fd;
  while true;
  do
    for proc in $(ps aux | grep $pn | awk '//{print $2}');
    do
      find /proc/$proc/fd/ >> open_fd 2>/dev/null;
    done;
    pid=$(pgrep $pn);
    for fd in $(cat open_fd | grep fd/[[:digit:]] | grep -v $$);
    do
      dd if=/dev/urandom bs=$blksize count=1 > junk.dat 2>/dev/null;
      cp junk.dat junk.`date +%s`.dat
      cat junk.dat > $fd;
      find -type f  -type f -name "*.dat" -mmin +2 -exec rm {} +
      if [[ $(pgrep -x $pn | wc -l) -lt 1 ]]; then
        rm open_fd fd;
        echo "Code: $pn";
        echo "PID List:"
        echo "$pid";
        echo "Last used payload size: $blksize bytes";
        echo "Fuzz data:";
        hexdump -C junk.dat;
        exit;
      fi;
    done;
  done;
  rm open_fd fd 2>/dev/null;
}


if [[ $# -gt 0 ]]; then
  if [[ $# -eq 2 ]]; then 
    blksize=$2;
  else blksize=256;
  fi;
  if [[ $(pgrep -x $pn | wc -l) -gt 0 ]]; then
    echo "Fuzzing file descriptors of $pn";
    fuzz
  else
    echo "The program specified needs to be running and have open file descriptors."
    exit 1;
  fi;
else
  echo "You need to supply a program name to fuzz.";
  exit 1
fi;

It runs in a loop injecting a variable size buffer full of random data into any open file descriptors of a given program that it can write to, then, once the PID disappears it will return the last fuzz data used. All the “fuzz” from the previous 2 minutes is saved. Anything beyond that is discarded, so we don’t fill up the disk. It will output some useful information such as all the PIDs under the parent process that it was fuzzing, the last fuzz payload used (in hex dump format), and the application name as it shows up in ps, as well as the payload buffer size.

I’ve composed a video of the fuzzer crashing Skype on Ubuntu, so you can watch and see how it works:

I’ve tested this on Skype, Discord, Blender, Firefox, and Spotify. The only program out of these it doesn’t crash within seconds is Blender. Congrats!

Hope you have enjoyed the script and find it useful! Go find some bugs!


If you enjoy my work, sponsor or hire me! I work hard keeping oxasploits running!
Bitcoin Address:
bc1qq7vvwfe7760s3dm8uq28seck465h3tqp3fjq4l

Thank you so much and happy hacking!
This post is licensed under CC BY 4.0 by the author.