Hydra Custom Modules
Learn how to create and modify custom protocol modules for Hydra
This guide explains how to create and modify custom protocol modules for Hydra. Custom modules allow you to extend Hydra's capabilities to support new protocols or modify existing ones to handle non-standard implementations.
Understanding Hydra's Module System
Hydra uses a modular architecture where each protocol is implemented as a separate module. These modules are written in C and are part of the Hydra source code. Each module implements a standard interface that Hydra uses to interact with the protocol.
When to Create Custom Modules
Consider creating a custom module when:
- You need to test a proprietary or custom authentication protocol
- An existing protocol implementation has unique characteristics not supported by Hydra
- You want to add support for a new protocol
- You need to modify an existing module to handle specific edge cases
Module Development Prerequisites
Before creating a custom module, you'll need:
Set Up Development Environment
Install the necessary development tools:
# Debian/Ubuntu
sudo apt install build-essential git libssl-dev pkg-config
# Fedora/RHEL
sudo dnf install gcc gcc-c++ git openssl-devel pkgconfig
Get Hydra Source Code
Clone the Hydra repository:
git clone https://github.com/vanhauser-thc/thc-hydra.git
cd thc-hydra
Understand Module Structure
Examine existing modules in the source code:
ls -l hydra-*.c
Each file named hydra-[protocol].c
contains the implementation for a specific protocol.
Module Structure
A Hydra module consists of the following key components:
- Module Registration: Information about the module name, port, and flags
- Connection Functions: Code to establish and manage connections
- Authentication Functions: Code to perform authentication attempts
- Cleanup Functions: Code to release resources
Here's a simplified example of a module structure:
void module_register() {
register_module(MODULE_NAME, MODULE_PORT, MODULE_OPTIONS);
}
int start_module(int s, char *ip, int port, unsigned char options, char *miscptr, FILE *fp) {
// Initialize connection
}
int send_module(int s, char *ip, char *user, char *pass, char *miscptr, FILE *fp) {
// Send authentication attempt
}
void service_module(char *ip, int sp, unsigned char options, char *miscptr, FILE *fp, int port, char *hostname) {
// Main service function
}
void stop_module() {
// Cleanup resources
}
Creating a Basic Custom Module
Let's walk through creating a simple custom module for a fictional protocol:
Module Template
Start by creating a new file named hydra-custom.c
:
#include "hydra-mod.h"
// Module information
extern char *HYDRA_EXIT;
char *buf;
// Module registration
void module_register() {
register_module(MODULE_NAME, MODULE_PORT, MODULE_OPTIONS);
}
// Connection initialization
int start_module(int s, char *ip, int port, unsigned char options, char *miscptr, FILE *fp) {
// Initialize connection
return 0;
}
// Authentication attempt
int send_module(int s, char *ip, char *user, char *pass, unsigned char options, char *miscptr, FILE *fp) {
// Send authentication attempt
return 0;
}
// Main service function
void service_module(char *ip, int sp, unsigned char options, char *miscptr, FILE *fp, int port, char *hostname) {
// Main service logic
}
// Cleanup function
void stop_module() {
// Cleanup resources
}
This template includes all the required functions for a Hydra module.
Modifying Existing Modules
Instead of creating a new module, you can modify an existing one to handle special cases:
Identify the Module
Find the module you want to modify:
# For example, to modify the SSH module
cp hydra-ssh.c hydra-ssh-custom.c
Make Your Changes
Edit the module file to implement your changes. Common modifications include:
- Changing authentication message formats
- Adding support for additional authentication methods
- Modifying response parsing
- Adding custom headers or parameters
Update Registration
Change the module registration to avoid conflicts:
// Change from
register_module("ssh", 22, 0);
// To
register_module("ssh-custom", 22, 0);
Integrate and Compile
Update the Makefile and hydra.c as described earlier, then compile.
Advanced Module Techniques
Handling Multi-Step Authentication
Some protocols require multiple steps for authentication:
int send_module(int sock, char *ip, char *user, char *pass, unsigned char options, char *miscptr, FILE *fp) {
// Step 1: Send username
snprintf(buffer, sizeof(buffer), "USER %s\r\n", user);
if (hydra_send(sock, buffer, strlen(buffer), 0) < 0) return 1;
buf = hydra_receive_line(sock);
if (buf == NULL) return 1;
// Check for username acceptance
if (!strstr(buf, "Password:")) {
free(buf);
return 1;
}
free(buf);
// Step 2: Send password
snprintf(buffer, sizeof(buffer), "PASS %s\r\n", pass);
if (hydra_send(sock, buffer, strlen(buffer), 0) < 0) return 1;
buf = hydra_receive_line(sock);
if (buf == NULL) return 1;
// Check for success
if (strstr(buf, "Login successful")) {
hydra_report_found_host(port, ip, "custom", fp);
hydra_completed_pair_found();
free(buf);
return 1;
}
// Failed login
hydra_completed_pair();
free(buf);
return 2;
}
Handling Binary Protocols
For binary protocols, you'll need to use raw data handling:
int send_module(int sock, char *ip, char *user, char *pass, unsigned char options, char *miscptr, FILE *fp) {
unsigned char buffer[1024];
int length = 0;
// Create binary packet header
buffer[0] = 0x01; // Protocol version
buffer[1] = 0x03; // Authentication request
// Add username length and data
buffer[2] = strlen(user);
memcpy(buffer + 3, user, strlen(user));
length = 3 + strlen(user);
// Add password length and data
buffer[length] = strlen(pass);
memcpy(buffer + length + 1, pass, strlen(pass));
length += 1 + strlen(pass);
// Send binary packet
if (hydra_send(sock, (char *)buffer, length, 0) < 0) return 1;
// Receive binary response
int bytes_read = recv(sock, buffer, sizeof(buffer), 0);
if (bytes_read <= 0) { return 1; }
// Check response code (assuming first byte is status)
if (buffer[0] == 0x00) {
hydra_report_found_host(port, ip, "custom", fp);
hydra_completed_pair_found();
return 1;
}
hydra_completed_pair();
return 2;
}
Testing and Debugging Modules
To test and debug your custom module:
Enable Debug Output
Run Hydra with verbose output:
./hydra -l admin -p password -V -d custom://192.168.1.100
The -d
flag enables debug output, which shows all communication.
Use a Test Server
Create a simple server that implements your protocol for testing:
import socket
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(('0.0.0.0', 12345))
server.listen(5)
print("Server listening on port 12345")
while True:
client, addr = server.accept()
print(f"Connection from {addr}")
# Send welcome message
client.send(b"Welcome to test server\r\n")
# Receive authentication
data = client.recv(1024).decode('utf-8').strip()
print(f"Received: {data}")
# Check credentials
if data == "AUTH admin password":
client.send(b"SUCCESS\r\n")
else:
client.send(b"FAILED\r\n")
client.close()
Use GDB for Debugging
For more complex issues, use GDB:
gdb --args ./hydra -l admin -p password custom://127.0.0.1
Set breakpoints in your module:
(gdb) break hydra-custom.c:100
(gdb) run
Contributing Modules Back to Hydra
If you've created a useful module, consider contributing it back to the Hydra project:
- Ensure your code follows Hydra's coding style
- Add proper documentation and comments
- Test thoroughly with various inputs
- Submit a pull request on GitHub with a clear description of your module
Next Steps
Now that you understand how to create custom Hydra modules, explore the following topics:
- Protocol-Specific Guides - Detailed guides for specific protocols
- Best Practices - Learn best practices for effective and ethical use of Hydra