3.1. Extending Hydra
Hydra is a popular tool written by Van
Hauser (http://www.thc.org/) for
testing networked services for weak
username and
password combinations. This technique, commonly known as
brute-force testing, is valuable for
ensuring that network services and systems are not vulnerable to
password-guessing attacks due to weak username and password
combinations.
Although Hydra supports a number of different protocols for testing,
most likely you'll want to test services available
on your network that Hydra doesn't support. In this
section we will demonstrate how to add a module for testing Simple
Mail Transport Protocol (SMTP) authentication. You could use this to
determine if weak passwords exist in your email user base and close
this potential exposure before a spammer takes advantage of it.
Hydra is freely available for noncommercial use and for commercial
use with proper acknowledgment. You can download it from http://www.thc.org/thc-hydra/. The module
described in this section is included in Hydra Version 4.2.
3.1.1. Overview of Hydra
Hydra is a very popular tool primarily
because of the wide variety of protocols it supports and because its
parallel nature divides password-testing tasks among a user-definable
number of tasks.
As of Version 4.4, Hydra supports the following
protocols:
telnet | ftp | http |
https | http proxy | ldap |
SMB | SMBNT | Microsoft SQL |
mysql | rexec | socks5 |
VNC | pop3 | imap |
nntp | pcnfs | icq |
SAP/R3 | Cisco auth | Cisco enable |
SMTP auth | ssh2 | snmp |
cvs | Cisco AAA |
Hydra is primarily a command-line security-testing tool, and as such
you can call it from within recent versions of Nessus to perform
login (username) and password testing on services identified by
Nessus. In addition to using the tool
through Nessus, recent versions of Hydra also come with a graphical
GTK
user interface for platforms supporting the GTK toolkit.
3.1.2. Overview of SMTP Authentication
In this section we will demonstrate how to add
SMTP authentication protocol
support to Hydra. Mail servers commonly use SMTP authentication to
identify a user as being valid prior to accepting email for delivery.
A number of different standards for SMTP authentication exist, many
of which are not RFC standards. We are demonstrating an
authentication method using the
AUTH LOGIN method, as
shown in Example 3-1.
Example 3-1. An SMTP AUTH session
220-mail.xxxxxxxx.com ESMTP Exim 4.34 #1 Wed, 23 Jun 2004 17:35:13 -0700
EHLO mail.myserver.com
250-mail.xxxxxxxx.com Hello mail.myserver.com [192.168.0.156]
250-SIZE 52428800
250-PIPELINING
250-AUTH PLAIN LOGIN
250-STARTTLS
250 HELP
AUTH LOGIN
334 VXNlcm5hbWU6
bXl1c2VybmFtZQ==
334 UGFzc3dvcmQ6
bXlwYXNzd29yZA==
235 Authentication succeeded
The AUTH LOGIN authentication
method is well supported by many common SMTP servers, and as such, it
is a good protocol to use. The protocol is a simple process that uses
unencrypted credentials. Even though the protocol is insecure, a
number of mail servers support it in their default configurations as
a lowest-common-denominator protocol for SMTP authentication.
The protocol can be demonstrated by using the
telnet command to port 25 on an available mail
server. The mail server then responds with a connection message:
220-mail.xxxxxxxx.com ESMTP Exim 4.34 #1 Wed, 23 Jun 2004 17:35:13 -0700
The mail server responds with a header containing the
SMTP response code
220. Similar to the HTTP protocol, SMTP uses a numbered response code
system, as shown in Table 3-1.
Response code | Description |
---|---|
2xx; e.g., 220 (service ready) | Command accepted and processed |
3xx; e.g., 354 (start mail input) | Flow control message |
4xx; e.g., 421 (service not available) | Critical failure or transfer failure |
5xx; e.g., 500 (syntax error) | Errors with command |
In this case, the mail server (or more accurately, the
MTA, or Mail Transfer Agent) is running
the open source Exim service. Then we need to start an email session
with the mail server by using the
EHLO command with our Internet hostname, as
shown here:
250-mail.xxxxxxxx.com Hello mail.myserver.com [192.168.0.156]
250-SIZE 52428800
250-PIPELINING
250-AUTH PLAIN LOGIN
250-STARTTLS
250 HELP
The EHLO command informs the server that we want
to use the Extended Simple Mail Transfer Protocol
(ESMTP) and determines the SMTP extensions supported by the mail
server, including the types of authentication (if any) supported by
the server we are interrogating. The AUTH keyword
is followed by two different types of authentication, indicating that
this server supports both the
PLAIN and LOGIN
authentication methods. This command is important, as RFC-compliant
mail servers should respond with an error message such as
503 AUTH
command used
when not
advertised if the AUTH keyword
is used without a preceding EHLO command.
Then we send the mail server an
AUTH LOGIN command to
start the authentication process with the server:
AUTH LOGIN
334 VXNlcm5hbWU6
The AUTH LOGIN command instructs the server that
the client wants to begin SMTP authentication using the
LOGIN method. The server has responded with the
334 status code, and a Base64-encoded representation of the string
Username: to prompt the client to supply the
username. The client supplies the username for authentication encoded
using
Base64 encoding. The username used
here is myusername:
bXl1c2VybmFtZQ==
334 UGFzc3dvcmQ6
Then the server responds with a Base64-encoded representation of the
string Password: to prompt the client to supply
the password. The client supplies the password encoded using Base64
encoding. The password used in this example is
mypassword:
bXlwYXNzd29yZA==
235 Authentication succeeded
Providing the username and password supplied are correct, the server
responds with a 2xx status code. If the username and password
combination is incorrect the server responds with a 5xx response
code.
3.1.3. Adding Additional Protocols to Hydra
Hydra is structured in a very modular
way, and therefore adding support for an additional protocol requires
that Hydra support the defined module interface.
Each protocol is implemented in a file called
hydra-<service
name>.c containing a function
prototype:
void service_<service name> (unsigned long int ip, int sp, unsigned char options,
char *miscptr, FILE *fp, int port);
The options passed to the service function are outlined in Table 3-2.
Parameter | Description |
---|---|
ip | ip is the IP address of the target host. |
sp | sp is a socket used to read login (username) and password pairs for this task. |
options | options is for user options. Currently this is 0, or OPTION_SSL if the user has specified to use Secure Sockets Layer (SSL). |
miscptr | miscptr is a user-supplied additional parameter. This is for services that require more information than is supplied by default. Example modules using this parameter include the http, https, http-proxy, smbnt, ldap, cisco-enable, and SAP/R3 modules. |
fp | fp is a socket used to report found login (username) and password pairs for this task. |
port | If the user has defined a port to connect to, it is contained in port. This is used when services are run on nonstandard ports. |
Once the service file has been written, integrating the modules into
Hydra is simple:
Add the new
hydra-<service>
into the relevant areas within the Makefile.am
file.
Edit the hydra.c file to add a reference to the
new module. You can determine where to add this reference by
searching for the string ADD
NEW SERVICES
HERE.
Add default service ports into hydra.h.
Note that this will not add the new module into the
xhydra graphical interface. Also note that you
will need to patch this to support the ability to call the new
module.
3.1.4. Implementing SMTP-AUTH in Hydra
Every protocol Hydra supports needs to
define the following
variables and
include files:
#include "hydra-mod.h"
extern char *HYDRA_EXIT;
char *buf;
The hydra-mod.h include file defines the functions the
module accesses while running. The HYDRA_EXIT
string is a value returned by some Hydra functions. The
buf pointer is used
in hydra-smtpauth.c as a temporary buffer for
data received.
void
service_smtpauth(unsigned long int ip, int sp, unsigned char options,
char *miscptr, FILE * fp, int port)
{
int run = 1, next_run, sock = -1;
int myport = PORT_SMTPAUTH, mysslport = PORT_SMTPAUTH_SSL;
char *buffer = "EHLO hydra\r\n";
The run and next_run
variables are used to control the state of the testing session.
service_smtpauth follows a convention similar to many
of the other text-based protocols supported in Hydra, whereby it is
possible to connect and try multiple sets of credentials. The
run values are specified in Table 3-3.
run values | Description |
---|---|
1 | Connect or reconnect to the service port. |
2 | Run the password-testing function on the established connection. You can run this multiple times for one connection for this protocol. |
3 | Close the connection and exit gracefully. |
The sock variable is used to track the status
of the connection to the service. The
PORT_SMTPAUTH and
PORT_SMTPAUTH_SSL values have been added to the
hydra.h file, and they are the
ports SMTP runs on normally and when
run over SSL (ports 25 and 465, respectively). The
string buffer is the SMTP
EHLO command to be sent to the server.
/* keep track of socket for login/password */
hydra_register_socket(sp);
/* get the next login/password pair to test */
if (memcmp(hydra_get_next_pair( ), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0)
return;
The hydra_register_socket()function is required to register the
socket sp supplied to the module with the Hydra
functions used to obtain the login (username) and password pairs for
testing. Due to the parallelized structure of Hydra, each running
task obtains separate login (username) and password combinations to
optimize testing.
The hydra_get_next_pair(
) function is used to obtain the next
pair of credentials for testing. This function returns
HYDRA_EXIT on failure. These credentials are later
obtained as strings using the functions
hydra_get_next_login()
and hydra_get_next_password().
/* permanent loop keyed on the run variable */
while (1) {
switch (run) {
case 1: /* connect and service init function */
/* if we are already connected */
if (sock >= 0)
sock = hydra_disconnect(sock);
usleep(300000);
The run variable is used here in a
switch statement to control the state of the
connection to the server. The values used for the
run variable are shown in Table 3-3. This functionality ensures that if a
connection to the server is already in place, it is disconnected with
hydra_disconnect(). In this way, the module can ensure
that a new connection is made if an error occurs by ensuring the
run variable is set to 1.
/* determine port to connect to */
if ((options & OPTION_SSL) == 0) {
if (port != 0)
myport = port;
sock = hydra_connect_tcp(ip, myport);
port = myport;
} else {
if (port != 0)
mysslport = port;
sock = hydra_connect_ssl(ip, mysslport);
port = myport;
}
If the user has not specified the use of SSL, the module connects to
the default port for the service, or it connects to the user-defined
port if it has been supplied using hydra_connect_tcp(). If SSL has been specified, the
default SSL port is used unless the user has specified a custom port,
and the connection is made using hydra_connect_ssl()
. For protocols using
UDP, such as SNMP, Hydra also supports the
hydra_connect_udp() function.
/* see if connect succeeded */
if (sock < 0) {
hydra_report(stderr, "Error: Child with pid %d can't connect\n",
(int) getpid( ));
hydra_child_exit(1);
}
If the connection did not succeed, Hydra will print an error to
STDERR. The hydra_report( )
function is a synonym for
fprintf. The hydra_child_exit() function reports the exit status of
the child task, as in Table 3-4.
Value | Description |
---|---|
0 | Normal exit |
1 | Could not connect to the service |
2 | Application protocol error or service shutdown |
Once the connection is made, many protocols send some form of data as
a banner or to begin authentication.
/* consume any data waiting in buffer */
while (hydra_data_ready(sock)) {
if((buf = hydra_receive_line(sock)) == NULL)
exit(-1);
free(buf);
}
The hydra_data_ready() function returns regardless of whether
data is to be read from the connected socket. If data is to be read,
hydra_receive_line() reads the data in the receive buffer
from the socket, and the data is thrown away. This is done to ensure
that any banner messages are consumed from the buffer prior to any
other actions. Note that we free the buffer that was read. It is
important to perform this step on all data reads to avoid memory
leaks.
In addition to the hydra_receive_line( ) function,
Hydra also has the simpler hydra_recv(
) function that is useful if using a
binary protocol.
/* send EHLO command */
if (hydra_send(sock, buffer, strlen(buffer), 0) < 0)
exit(-1);
The hydra_send( ) function is used to send the
EHLO command to the server.
/* see if there was any response */
if ((buf = hydra_receive_line(sock)) == NULL)
exit(-1);
/* see if the LOGIN keyword is in the response */
if (strstr(buf, "LOGIN") == NULL) { /* check AUTH LOGIN supported */
hydra_report(stderr, "Error: SMTP AUTH LOGIN not supported: %s\n", buf);
hydra_child_exit(2);
exit(-1);
}
free(buf);
next_run = 2; /* run crack next */
break;
The buf buffer received in response to the
EHLO command is checked to see if it contains the
word LOGIN. This is done to validate whether the
server advertises the presence of the AUTH
LOGIN command. If the command is present, the
next_run value (and therefore the next value of
the run variable) is set to 2,
which initiates the testing process on the next cycle through the
loop.
case 2: /* run the cracking function */
next_run = start_smtpauth(sock, ip, port, options, miscptr, fp);
break;
Where the run variable is 2,
the connection has been established and the testing function is
started, as per Table 3-3.
case 3: /* clean exit */
/* if connected */
if (sock >= 0)
sock = hydra_disconnect(sock);
hydra_child_exit(0);
return;
Where the run variable is 3,
the socket is disconnected and the task exits cleanly, as per Table 3-3.
default:
hydra_report(stderr, "Caught unknown return code, exiting!\n");
hydra_child_exit(0);
exit(-1);
}
run = next_run; /* next step dependant on return from cracking function */
}
}
The service_smtpauth() function exits if the
start_smtpauth() function returns a value other than
1, 2, or 3.
This ensures that the simple state machine controlled by the
run variable is always in one of the three defined
statesconnecting/reconnecting, testing, or disconnecting.
Where the connection has been established successfully, and the
run variable is set to 2, the
service_smtpauth( ) function calls the
start_smtpauth( ) function to perform a single
testing instance.
int
start_smtpauth(int s, unsigned long int ip, int port, unsigned char options,
char *miscptr, FILE *fp)
Here the start_smtpauth( ) function is passed the
same values as those passed to the service_smtpauth(
) function. This function is not called from outside of
this module; however, the naming and structure throughout the
existing protocols supported in Hydra largely follow this convention.
char *empty = ";
char *login, *pass, buffer[300], buffer2[300];
/* get login and password from the pair fetched */
if (strlen(login = hydra_get_next_login( )) == 0)
login = empty;
if (strlen(pass = hydra_get_next_password( )) == 0)
pass = empty;
The hydra_get_next_login()
and hydra_get_next_password() functions are used to obtain the login (username) and
password pair to be used for this instance of testing. These
functions rely on the hydra_get_next_pair() function having been run to first read
the login and password pair from the internal socket.
/* consume any remaining data in the buffer */
while (hydra_data_ready(s) > 0) {
if ((buf = hydra_receive_line(s)) == NULL)
return (1);
free(buf); /* make sure we free memory we use */
}
Any data returned from the server remaining in the buffer is read and
thrown away. If an error occurs while reading data, the function
returns 1, which causes the
service_smtpauth(
) function to attempt to reconnect to
the server.
/* send AUTH LOGIN command */
sprintf(buffer, "AUTH LOGIN\r\n");
if (hydra_send(s, buffer, strlen(buffer), 0) < 0) {
return 1;
}
The AUTH LOGIN command is sent to start an
authentication attempt. If this fails, you should try to reconnect
again.
/* if no response received */
if ((buf = hydra_receive_line(s)) == NULL)
return 1;
/* make sure we got a 334 response code (asking for username) */
if (strstr(buf, "334") == NULL) {
hydra_report(stderr, "Error: SMTP AUTH LOGIN error: %s\n", buf);
free(buf);
return 3;
}
free(buf);
If the response from the mail server is something other than
334 VXNlcm5hbWU6, you have
experienced a protocol error, so you should exit. This might occur if
the mail server does not support the authentication method you are
attempting.
/* base64 encode the username - also making sure string is < 250 */
sprintf(buffer2, "%.250s", login);
hydra_tobase64((unsigned char *) buffer2);
sprintf(buffer, "%.250s\r\n", buffer2);
/* send the username */
if (hydra_send(s, buffer, strlen(buffer), 0) < 0) {
return 1;
}
Send the login (username) obtained from
hydra_get_next_login(). This is
Base64-encoded using
hydra_tobase64() . A
hydra_conv64( ) function exists for
Base64-encoding single characters, if required. Note that we are
ensuring that the user-supplied data is cut off at 250 characters to
avoid a potential buffer overflow issue.
/* if no response received */
if ((buf = hydra_receive_line(s)) == NULL)
return (1);
/* make sure we get a 334 - asking for password */
if (strstr(buf, "334") == NULL) {
hydra_report(stderr, "Error: SMTP AUTH LOGIN error: %s\n", buf);
free(buf);
return (3);
}
free(buf);
/* base64 encode the password */
sprintf(buffer2, "%.250s", pass);
hydra_tobase64((unsigned char *) buffer2);
sprintf(buffer, "%.250s\r\n", buffer2);
/* send the password */
if (hydra_send(s, buffer, strlen(buffer), 0) < 0) {
return 1;
}
/* if no response received */
if ((buf = hydra_receive_line(s)) == NULL)
return (1);
The password received from hydra_get_next_password()
is sent to the mail server the same
way in which the username was sent.
/* if authentication was successful */
if (strstr(buf, "235") != NULL) {
/* report the found credentials */
hydra_report_found_host(port, ip, "smtpauth", fp);
hydra_completed_pair_found( );
free(buf);
if (memcmp(hydra_get_next_pair( ), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0)
return 3;
return 1;
}
If the 235 Authentication
succeeded response is received
from the mail server, the successful login (username) and password
combination is reported using the hydra_report_found_host() function. The
hydra_completed_pair_found() function is used to communicate on the
internal socket that the current credentials were successful. Then
the hydra_get_next_pair() function fetches the next pair of
credentials for use and causes the module to exit cleanly if no
credential pairs remain.
free(buf);
/* otherwise, we''''re finished with this pair anyway */
hydra_completed_pair( );
if (memcmp(hydra_get_next_pair( ), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0)
return 3;
return 2;
}
If the authentication attempt was not successful, the completed
status of the pair is communicated using the
hydra_completed_pair() function. Then the
hydra_get_next_pair( ) function is used to fetch
the next pair, and causes the module to exit cleanly if no credential
pairs remain to be tested by this task.
3.1.5. Complete Source to hydra-smtpauth.c
The complete source to the SMTP authentication module as described
earlier in Section 3.1.4 is
contained in the
src/hydra-smtpauth.c file in the Hydra distribution in Versions
4.2 and above.
3.1.6. Quick Reference to Hydra Functions
Although
the SMTP authentication module highlighted most of the functionality
Hydra supplies for use in modules, we have not yet covered all of
Hydra''''s functionality. Because developer
documentation of the functions is not available for Hydra modules,
this section provides a quick reference to the Hydra functions
available as of Version 4.4.
In addition to the functions described next, Hydra also contains
files for supporting the MD4 and DES algorithms. These files are not
part of the Hydra module structure, and as such are not covered here.
void hydra_child_exit(int code)Exits the child task while signaling the exit status to Hydra
Valid values for code are shown in Table 3-4. Supply the value for code
as 0 for normal exit, 1 for no
connection possible, and 2 for protocol or service
error.
void hydra_register_socket(int sock)Registers the internal socket passed in by Hydra
hydra_register_socket( ) should be called with the
sp variable passed into the module.
char *hydra_get_next_pair( )Fetches the next pair of credentials for testing to an internal Hydra variable
The hydra_get_next_pair( ) function returns a
pointer to the next credential pair with the pair formatted as
login\0password. These can then be fetched cleanly
using hydra_get_next_login( ) and
hydra_get_next_password( ). The
hydra_get_next_pair( ) function returns
HYDRA_EXIT on failure, and
HYDRA_EMPTY where no value was supplied (for
example, when testing for blank passwords).
char *hydra_get_next_login( )Fetches the next login (username) string
This function returns a pointer to the login value fetched by the
hydra_get_next_pair( ) function.
char *hydra_get_next_password( )Fetches the next password string
This function returns a pointer to the password value fetched by the
hydra_get_next_pair( ) function.
void hydra_completed_pair( )Updates the status of the current pair to Hydra as not valid to the internal socket
This is run when the current pair does not appear to be a valid
login/password combination on the service being tested.
void hydra_completed_pair_found( )Updates Hydra with the status that the current pair is valid to the internal socket
This is run when the current pair has been found to be a valid
login/password combination on the service being tested.
void hydra_report_found(int port, char *svc, FILE *fp)Used to supply the credentials found for display
This function is used to output the found credentials to the user.
port is the port the service was tested on,
svc is the name of the service (commonly a literal
string such as smtpauth), and
fp is the fp value Hydra
supplied to the module.
void hydra_report_found_host (int port, unsigned int ip, char *svc, FILE *fp) Used to supply the credentials found for display, including the host IP address
This function is similar to hydra_report_found( ),
except the IP address of the server tested is displayed. It is used
to output the found credentials to the user. port
is the port the service was tested on, ip is the
IP address, svc is the name of the service
(commonly a literal string such as smtpauth), and
fp is the fp value Hydra
supplied to the module.
void hydra_report_found_host_msg (int port, unsigned int ip, char *svc, FILE *fp, char *msg)Used to supply the credentials found for display, including the host IP address and a message to be displayed to the user
This function is similar to hydra_report_found_host(), with the addition of a message to be displayed. It is
used to output the found credentials to the user.
port is the port the service was tested on,
ip is the IP address, svc is
the name of the service (commonly a literal string such as
smtpauth), fp is the
fp value Hydra supplied to the module, and
msg is a message to be displayed to the user.
int hydra_connect_tcp(unsigned long int host, int port)Used to make a connection to a service using TCP
This function makes a connection to the host defined by the IP
address host, on port port,
using TCP. host is the ip value
passed into the module, and the port value usually
is a standard port for the service; however, it also can be
user-defined. The function returns a socket value used in sending and
receiving operations, or -1 on error.
int hydra_connect_ssl(unsigned long int host, int port)Used to make a connection to a service using SSL.
This function makes a connection to the host defined by the IP
address host, on port port,
using SSL. host is the ip value
passed into the module, and the port value is
either the standard SSL port for the service, or user-defined. The
function returns a socket value used in sending and receiving
operations, or -1 on error.
int hydra_connect_udp(unsigned long int host, int port)Used to make a connection to a service using UDP
This function sets up a socket for communicating to the host defined
by the IP address host on port
port, using UDP. host is the
ip value passed into the module, and the
port value is either the standard port for the
service, or user-defined. The function returns a socket value used in
sending and receiving operations, or -1 on error.
int hydra_disconnect(int socket)Disconnects a socket opened by one of the Hydra connection functions
This function closes the socket supplied and returns
-1.
int hydra_data_ready_writing_timed(int socket, long sec, long usec)Checks whether the socket is ready to have data written to it
This function waits up to sec seconds and
usec microseconds to see if the socket
socket is available for writing. This function
returns a value greater than zero if the socket is ready for writing,
0 if the socket is not ready for writing, and
-1 on error.
int hydra_data_ready_writing(int socket)Checks whether the socket is ready to have data written to it
This function calls hydra_data_ready_writing_timed() to see if the socket socket is
available for writing. This function returns a value greater than
zero if the socket is ready for writing, 0 if the
socket is not ready for writing, and -1 on error.
int hydra_data_ready_timed(int socket, long sec, long usec)Checks whether the socket has data ready to be read
This function waits up to sec seconds and
usec microseconds to see if the socket
socket has data available for reading. This
function returns a value greater than zero if the socket has data for
reading, 0 if no data is available, and
-1 on error.
int hydra_data_ready(int socket)Checks whether the socket has data ready to be read
This function calls hydra_data_ready_timed( ) to
see if the socket socket has data to be read. This
function returns a value greater than zero if the socket has data for
reading, 0 if no data is available, and
-1 on error.
int hydra_recv(int socket, char *buf, int length)Receives data from the supplied socket
This function reads up to length data from the
socket socket into the buffer
buf. The function returns the amount of data read,
or -1 on error. No translation of any type is done
to the data received. This function should be used for binary
protocols, as hydra_receive_line( ) performs some
translation on data read.
char *hydra_receive_line(int socket)Receives data in a line-oriented mode from the supplied socket
This function attempts to read all data available from the socket
socket. It returns a pointer to a buffer which is
allocated within the function. These buffers should be deallocated
using a free( ) call after use to conserve memory
usage. All NULL characters in the data received are translated into
space characters (0x20).
int hydra_send(int socket, char *buf, int size, int options)Sends the supplied data on the supplied socket
This function sends the data in the buffer buf, of
length size, out on the socket defined by
socket. The options variable is
not commonly used (it is set to 0), but is the
flags variable for the underlying
socket''''s API send( ) command.
This function returns the amount of data sent, or
-1 on error.
int make_to_lower(char *buf)Converts the supplied buffer to lowercase
This function converts the buffer pointed to by
buf to lowercase. The function always returns
1.
unsigned char hydra_conv64(unsigned char in)Converts a single character to Base64 encoding
This function returns the Base64-encoded representation of the
character supplied to the function in the in
parameter, or 0 on error.
void hydra_tobase64(unsigned char *buf)Converts a string to Base64 encoding
This function converts the string pointed to by
buf to Base64 encoding. If an error occurs during
encoding, the value pointed to by buf is in an
undefined state.
void hydra_dump_asciihex(unsigned char *string, int length)Prints a hex and ASCII dump
This function takes the data in string, of length
length, and prints a hex and ASCII table to
standard output. This can be very useful for debugging a module under
development .