THC Hydra: Auditing passwords

As we have said previously, the Cyber Security world is full of useful tools to perform different task. At the end of the day, pentesters are usually very proficient with some of them, the ones they use in daily day basis but, at least, they know or they have tried some of the others. Even similar tools or tools that apparently do the same task, sometimes have slightly different behaviors that can be the difference between success or fail in a pentest.

The tool we are going to see today is called THC Hydra. THC Hydra is a tool that will help us to test the strength of our passwords auditing remote authentication services.

As an example, I am going to use the same set up I used in the Ncrack article before. If you do not know what I am talking about, you can follow this link to my previous article.

After we have our service running in our virtual machine, and we have checked the machine and the service are available, we can execute the “hydra” command.

Just a few notes before test our service.

You can execute the command to obtain information about how to execute the tool:

hydra

You will see that multiple flags are listed, and the most interesting part is the list of services that are supported by the tool. As an important note, I must say that the number of services supported by the tool depends on the kind of compilation and installation we have done. There are a few libraries or dependencies we need to install before THC Hydra to have support for all types of services.

To follow this example, it is enough if you have install the tool with the “libssh” support.

Now, let’s continue. As you have seen in the help description for the tool, there are multiple flags we can use, but for this test, we are going to focus in the next flags:

  • -l LOGIN or -L FILE: It allows us to give to the tool a user or a list of users.
  • -p PASS or -P FILE: It allows us to give to the tool a password or a list of passwords.
  • service: The service we want to test. In our case “ssh”

Now, following the appropriate syntax, we can execute the next command:

hydra -l fjavierm -P password.txt ssh://192.168.0.38

This is going to show us the result:

Hydra v8.4 (c) 2017 by van Hauser/THC - Please do not use in military or secret service organizations, or for illegal purposes.

Hydra (http://www.thc.org/thc-hydra) starting at 2017-04-02 08:26:38
[WARNING] Many SSH configurations limit the number of parallel tasks, it is recommended to reduce the tasks: use -t 4
[DATA] max 3 tasks per 1 server, overall 3 tasks, 3 login tries (l:1/p:3), ~1 try per task
[DATA] attacking service ssh on port 22
[22][ssh] host: 192.168.0.38 login: fjavierm password: pa$$w0rd
1 of 1 target successfully completed, 1 valid password found
Hydra (http://www.thc.org/thc-hydra) finished at 2017-04-02 08:26:41

As we can see, we have been able to find the weak password.

THC Hydra: Auditing passwords

Machine learning branches

In machine learning we can find three main different branches where we can classify the algorithms:

  • Supervised learning.
  • Unsupervised learning.
  • Reinforcement learning.

Supervised learning

In supervised algorithms you know the input and the output that you need from your model. You do not know how the output is achieved from the input data or how are the inner relations among you data, but definitely know the output data.

As an example, we can take a magazine publication that it has the subscription data of a determinate number of customers or old customers, let’s say 100.000 customers. The company in charge of the magazine knows that half of these customers (50.000) have cancelled their subscriptions and the other half (50.000) are still subscribed, and they want a model to predict what customers will cancel their subscriptions.

We know the input: customers subscription data, and the output: cancelled or not.

We can then build our training data set with 90.000 customers data. Half of them cancelled and half of them still active. We will train our system with this training set. And after that we will try to predict the result for the other 10.000 we left outside the training data to check the accuracy of our model.

Unsupervised learning

In unsupervised learning algorithms you do not know what is the output of your model, you maybe know there is some kind of relation or correlation in your data but, maybe, the data is too complex to guess.

In this kind of algorithms, you normalize your data in ways that it can be compared and you wait for the model to find some of these relationships. One of the special characteristics of these models is that, while the model can suggest different ways to categorize or order your data, it is up to you to make further research on these to unveil something useful.

For example, we can have a company selling a huge number of products and they want to improve their system to target customers with useful advertisement campaigns. We can give to our algorithm the customers data and the algorithms can suggest some relations: age range, location, …

Reinforcement learning

In reinforcement learning algorithms, they do not receive immediately the reward for their actions, and they need to accumulate some consecutive decision to know if the actions/decisions are or not correct. In this scenario, there is no supervisor, the feedback about the decision is delayed and agent’s actions affect the subsequent data it receives.

One example of this, it can be the chess game, where the algorithm is going to be taking decisions but, till the end of the game, it is not going to be able to know if these decisions were correct or not and, obviously, previous decisions affect subsequent decisions.

Machine learning branches

Git Bash: Shell prompt customization

What is it?

Git Bash for Windows is not just bash compiled for Windows. It is a package that contains bash, which is a command-line shell, and a collection of other, separate *nix utilities which you can run using the shell, compiled for Windows, and a new command-line interface terminal window called mintty.

You can download it from here.

Shell prompt customization

If we want to customize the shell prompt according to our preferences, we just need to edit the file “git-prompt.sh”. In a Windows x64 system, we can find it in:

C:\Program Files\Git\etc\profile.d\git-prompt.sh

Now we just need to play a little bit with the different options available.

As an example, the version I am using right now looks like that:

TITLEPREFIX='Bash Prompt (Git for Windows) =>'

PS1='\[\033]0;$TITLEPREFIX:${PWD//[^[:ascii:]]/?}\007\]' # set window title
PS1="$PS1"'\[\033[32m\]'       # change to green
PS1="$PS1"'\w'                 # current working directory
if test -z "$WINELOADERNOEXEC"
then
    GIT_EXEC_PATH="$(git --exec-path 2>/dev/null)"
    COMPLETION_PATH="${GIT_EXEC_PATH%/libexec/git-core}"
    COMPLETION_PATH="${COMPLETION_PATH%/lib/git-core}"
    COMPLETION_PATH="$COMPLETION_PATH/share/git/completion"
    if test -f "$COMPLETION_PATH/git-prompt.sh"
    then
        . "$COMPLETION_PATH/git-completion.bash"
        . "$COMPLETION_PATH/git-prompt.sh"
        PS1="$PS1"'\[\033[36m\]'  # change color to cyan
        PS1="$PS1"'`__git_ps1`'   # bash function
    fi
fi
PS1="$PS1"'\[\033[0m\]'        # change color
PS1="$PS1"'$ '                 # prompt: always $
MSYS2_PS1="$PS1"               # for detection by MSYS2 SDK's bash.basrc
Git Bash: Shell prompt customization

Design patterns: Abstract Factory

This is a creational pattern, as it is used to control class instantiation. The abstract factory pattern is used to provide a client with a set of related or dependant objects. The set of objects created by the factory is determined at run-time according to the selection of concrete factory class.

Provides a level of indirection that abstracts the creation of families of related or dependent objects without directly specifying their concrete classes. The factory object has the responsibility for providing creation services for the entire platform family. Clients never create platform objects directly, they ask the factory to do that for them.

This mechanism makes exchanging product families easy because the specific class of the factory object appears only once in the application – where it is instantiated. The application can wholesale replace the entire family of products simply by instantiating a different concrete instance of the abstract factory.

Elements involved:

  • AbstractFactory: This is an abstract base class for the concrete factory classes that will generate new sets of related objects. A method is included for each type of object that will be instantiated.
  • ConcreteFactory: Inheriting from the AbstractFactory class, the concrete factory classes override the methods that generate the suite of objects required by the client.
  • AbstractProduct: This abstract class is the base class for the types of object that a factory can create. One base type exists for each of the distinct types of product required by the client.
  • ConcreteProduct: Multiple subclasses of the ConcreteProduct classes are defined, each containing specific functionality. Objects of these classes are generated by the abstract factory to populate the client.
  • Client: This class uses the factories to generate a family of related objects. In the UML diagram, the client has two private fields that hold instances of the abstract product classes.

We should use the Abstract Factory design pattern when:

  • the system needs to be independent from the way the products it works with are created.
  • the system is or should be configured to work with multiple families of products.
  • a family of products is designed to work only all together.
  • the creation of a library of products is needed, for which is relevant only the interface, not the implementation, too.

Let´s see some code:

public abstract class AbstractFactory {
    public abstract AbstractProduct createProduct();
}
public abstract class AbstractProduct {
    public abstract void operation1();
    public abstract void operation2();
}
public class ConcreteFactory1 extends AbstractFactory {
    @Override
    public AbstractProduct createProduct() {
        return new ConcreteProduct1();
    }
}
public class ConcreteFactory2 extends AbstractFactory {
    @Override
    public AbstractProduct createProduct() {
        return new Product2();
    }
}
public class ConcreteProduct1 extends AbstractProduct {
    public ConcreteProduct1() {
        System.out.println("Creating product 1...");
    }

    @Override
    public void operation1() {
        System.out.println("Executing ConcreteProduct1::operation1...");
    }

    @Override
    public void operation2() {
        System.out.println("Executing ConcreteProduct1::operation2...");
    }
}
public class ConcreteProduct2 extends AbstractProduct {
    public ConcreteProduct2() {
        System.out.println("Creating product 2...");
    }

    @Override
    public void operation1() {
        System.out.println("Executing Product2::operation1...");
    }

    @Override
    public void operation2() {
        System.out.println("Executing Product2::operation2...");
    }
}
public enum ProductType {
    PRODUCT_1,
    PRODUCT_2
}
public class FactoryMaker {

    public static AbstractFactory getFactory(final ProductType productType) {
        final AbstractFactory abstractFactory;

        switch (productType) {
            case PRODUCT_1:
                abstractFactory = new ConcreteFactory1();
                break;

            case PRODUCT_2:
                abstractFactory = new ConcreteFactory2();
                break;

            default:
                throw new IllegalArgumentException("The product type does not exist.");
        }

        return abstractFactory;
    }
}
public class Client {

    public static void main(String[] args) {
        Arrays.stream(ProductType.values())
            .forEach(productType -> {
                AbstractFactory abstractFactory = FactoryMaker.getFactory(productType);
                AbstractProduct product = abstractFactory.createProduct();

                product.operation1();
                product.operation2();
            });
    }
}

The output after the execution should be something like that:

Creating product 1...
Executing ConcreteProduct1::operation1...
Executing ConcreteProduct1::operation2...
Creating product 2...
Executing Product2::operation1...
Executing Product2::operation2...

You can find the code in my GitHub repository “design-apperns“.

Design patterns: Abstract Factory

Error Prone

We, as a developers, sometimes, make mistakes or add bugs to our code without realizing. For this reason static analyzers are a handy tool to apply during our builds or during our code verification processes.

One of these tools is Error Prone.

Error Prone is Google’s Java bug detection and static analysis tool. It is integrated into the Java compiler and catches bugs at compile time. It supports plugin checks for project-specific enforcement.

Basically, it is a tool created by Google for code analysis and error detection for the Java language. It is integrated inside the compiler and tries to detect bugs in compilation time.

But, let’s see and example. Imagine we have a program with the next line of code:

String.format("Param A: {}, param B: {}, param C: {}", paramA, paramB, paramC);

Obviously, it is not correct and the error comes from, maybe, a transformation between a previous log message to a different kind of message. The compiler is not going to complain because it is a string message and it is not a syntax error. But, the truth is there is an error.

When we try to compile the program with Error Prone, we are going to receive a compilation error message like this:

error: [FormatString] extra format arguments: used 0, provided 3
String.format("Param A: {}, param B: {}, param C: {}", paramA, paramB, paramC);
             ^
(see http://errorprone.info/bugpattern/FormatString)

We can see clearly and without any doubts there is an error. Even, a link to the error description is provided.

The proper code should be:

String.format("Param A: %s, param B: %s, param C: %s", paramA, paramB, paramC);

The easiest way to start using the tool, it is to add the maven plugin to our pom.xml file:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.3</version>
    <configuration>
        <compilerId>javac-with-errorprone</compilerId>
        <forceJavacCompilerUse>true</forceJavacCompilerUse>
        <source>8</source>
        <target>8</target>
    </configuration>
    <dependencies>
        <dependency>
            <groupId>org.codehaus.plexus</groupId>
            <artifactId>plexus-compiler-javac-errorprone</artifactId>
            <version>2.8.1</version>
        </dependency>
        <dependency>
            <groupId>com.google.errorprone</groupId>
            <artifactId>error_prone_core</artifactId>
            <version>2.0.19</version>
        </dependency>
    </dependencies>
</plugin>

For more options, just go to the installation instructions page.

The project is open source and you can see all the code in the official repository: error-prone.

I am not saying that it is going to solve all your problems but, at least, it is another tool to increase our code quality and avoid silly mistakes.

Error Prone

Publishing to GitHub

GitHub is a web-based Git or version control repository and Internet hosting service. As a developers, I am quite sure that all of you know the platform.

Every-time we start a new project, even if it is just something for us, it is a good idea to use a version control system. Here is where Git and GitHub can help us.

There are two easy ways to create and upload our project to a repository.

The first way, it is to create the repository in GitHub, and after that clone in our machine the created repository and start writing our code. This is the simplest way. Doing it in this way, our local repository is already connected to the remote repository and we just need to start committing things. The clone command, assuming the account name is “fjavierm” and the repository name is “myproject”,  is:

git clone https://github.com/fjavierm/myproject.git

Te second way, it is when we already have a project in our local machine and we want to add the project to a repository. In this case, we need to perform a few more steps.

1. We need to create the repository under our GitHub account. In this case, my account is “fjavierm” and my repository is going to be “myproject”.

2. In our local machine, in our local project folder, we need to initiate the git repository. This will add a folder “.git”:

git init

3. We can check the status of the available files:

git status

This instruction will show us the files that we can add to the repository to commit. In this step, it deserves to pay special attention to the files that we do not want to add and, maybe, it is a good idea to create the files “.gitignore” and “README.md”

4. Add the files to the repository:

git add .

5. Commit the added files adding a descriptive message. Usually, issue number and description, or something meaningful.:

git commit -m "Starting the project."

6. Connect our local repository with our remote repository:

git remote add origin https://github.com/fjavierm/myproject.git

7. Check we have perform the previous step properly:

git remote -v

8. Push our changes to the remote repository:

git push -u origin master

With these few instructions we should have available all our code in the GitHub repository.

Publishing to GitHub

SSH access with Ncrack

The cybersecurity field has thousands of tools we can use to check the security of our systems. One category of tools we can find is the password crackers. In this group, we can find Ncrack. Ncrack defines itself as a high-speed network authentication cracker.

Ncrack is a high-speed network authentication cracking tool. It was built to help companies secure their networks by proactively testing all their hosts and networking devices for poor passwords. Security professionals also rely on Ncrack when auditing their clients. Ncrack was designed using a modular approach, a command-line syntax similar to Nmap and a dynamic engine that can adapt its behaviour based on network feedback. It allows for rapid, yet reliable large-scale auditing of multiple hosts.

Ncrack’s features include a very flexible interface granting the user full control of network operations, allowing for very sophisticated bruteforcing attacks, timing templates for ease of use, runtime interaction similar to Nmap’s and many more. Protocols supported include RDP, SSH, HTTP(S), SMB, POP3(S), VNC, FTP, SIP, Redis, PostgreSQL, MySQL, and Telnet.

Let´s try to do a little demo. Previously, we need a few things:

  • A remote system to audit. It can be a real system or a virtual machine. In my case, I am going to use a Debian VM with a SSH server installed.
  • Ncrack installed in our machine. There are versions available for different systems like Windows, Linux and Mac OS.
  • We need two dictionaries. One with a list of users we want to use and, the second one with a list of passwords to use to audit the system.

Firsts thing, let´s try the connectivity with the system we want to audit:

~# ping -c 1 192.168.0.38
PING 192.168.0.38 (192.168.0.38): 56 data bytes
64 bytes from 192.168.0.38: icmp_seq=0 ttl=64 time=0.382 ms

--- 192.168.0.38 ping statistics ---
1 packets transmitted, 1 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 0.382/0.382/0.382/0.000 ms

The next step should be to check if the SSH port is available in the remote system. For this purpose, we can use a tool like Nmap.

~# nmap -sV 192.168.0.38

Starting Nmap 7.40 ( https://nmap.org ) at 2017-03-25 10:09 GMT
Nmap scan report for 192.168.0.38
Host is up (0.00094s latency).
Not shown: 992 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 6.7p1 Debian 5+deb8u3 (protocol 2.0)
80/tcp open tcpwrapped
110/tcp open tcpwrapped
111/tcp open rpcbind 2-4 (RPC #100000)
143/tcp open tcpwrapped
443/tcp open tcpwrapped
993/tcp open imaps?
995/tcp open pop3s?
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 6.45 seconds

And, finally, let´s audit our external system using Ncrack. We are going to use a few flags to execute the Ncrack tool:

  • -p: Allows us to specify the port we want to audit.
  • -U: Allows us to specify a file with the list of users.
  • -P: Allows us to specify a file with the list of passwords.
~# ncrack -p 22 -U users.txt -P passwords.txt 192.168.0.38

Starting Ncrack 0.5 ( http://ncrack.org ) at 2017-03-25 10:11 GMT

Discovered credentials for ssh on 192.168.0.38 22/tcp:
192.168.0.38 22/tcp ssh: 'fjavierm' 'pa$$w0rd'

Ncrack done: 1 service scanned in 18.02 seconds.

Ncrack finished.

And, let´s double check the credentials are working properly:

~# ssh 192.168.0.38
fjavierm@192.168.0.38's password: 

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Sat Mar 25 10:07:52 2017 from 192.168.0.15
fjavierm@debian:~$

As we can see, now, we have access to the remote system exploiting a weak password.

There are some countermeasures that we can implement to fix this problem, one of them is to establish a strong password policy.

SSH access with Ncrack