1. Introduction
The File Transfer Protocol (FTP) is a plain-text
network protocol used to transfer files from a host to another over TCP.
FTP is based on the client-server architecture, and users may need to
authenticate using a username and password (in plain text) to connect to
the server. FTP also supports anonymous authentication, if a host
provides anonymous FTP access, a user typically connects to the server
by providing “anonymous” as username and email address as his password
but no verificantion is performed on that password.
2. FTP Authentication Basics
FTP has a very basic authentication mechanism based on
username and password. While authenticating, a little conversation
happens between the client and the server, and in Anonymous
authentication scenario, this conversation kinda looks like this:
view plainprint?- [client]: connects to a host on a port where the FTP service is running (typically, the port 21)
- [server]: “220 FTP Server is ready…\r\n”
- [client]: “USER anonymous\r\n”
- [server]: “331 User name okay, need password.”
- [client]: “PASS anon@\r\n”
- [server]: “230 User logged in, proceed.\r\n”
[+] 1xx: Positive Preliminary reply. The requested command is being processed, and the client should wait for another reply before proceeding sending commands.
[+] 2xx: Positive Completion reply. The requested command has been successfully processed.
[+] 3xx: Positive Intermediate reply. The sent command has been accepted and it needs more informations to get processed. the client should send these informations through a specified
command.
[+] 4xx: Transient Negative Completion reply. The sent command was not accepted for a temporary reason, and the client can request the same command later on.
[+] 5xx: Permanent Negative Completion reply. The command is rejected and the client should not send this command again.
[+] 6xx: Protected reply. Basicly, it’s a protected messages encoded in Base64 and the client need to decode it to get the real message.
More specifically, the status codes we’re interested on is:
view plainprint?
- 220: Service ready for new user.
- 331: User name okay, need password.
- 230: User logged in
- 430: Invalid username or password
This script scans random hosts for anonymous FTP login, each time it generates a random IP address and try to connect to it and do authentication process, then logs the results. After that, it moves on to the next host and scan it.
This cycle may take hours to get a one valid host that supports anonymous login, because the random IP addresses that it generates could be not online, or doesn’t run an FTP service, or it doesn’t allow anonymous login.
To get things more faster and efficient, we can use Thread Programming. A thread can executes the same code more than once at the same time. Which means that we can scan mutiple hosts for Anonymous FTP Login at the same time.
Python supports thread programming as well with a module called “threading”, more than that, it makes it easier for programmers to work with Threads.
To create a thread object we use the “Thread” method:
view plainprint?
- class threading.Thread(group=None,\
- target=function_to_be_executed,\
- name=thread_name,\
- args=(function_arguments),\
- kwargs={function_keyword_arguments})
[+] name: specify the thread name. by default, a unique name is assigned to it of the form “Thread-N”
[+] args: tuple of arguments will be passed to the called function
[+] kwargs: Dictionary of keyword arguments for the target function
After creating a thread object, we can execute it by calling the start method:
view plainprint?
- thread.start()
Examples:
[+] Example of a thread that doesn’t passes args:
view plainprint?
- import threading
- def ThreadFunction():
- “”” This function will be executed more than once at the same time “””
- print(“[+] Thread\n”)
- return
- n=int(input(“[+] How many thread you want to use: “))
- for i in range(n):
- t=threading.Thread(target=ThreadFunction)
- t.start()
view plainprint?
- [+] How many thread you want to use: 5
- [+] Thread
- [+] Thread
- [+] Thread
- [+] Thread
- [+] Thread
view plainprint?
- import threading
- def ThreadFunction(i):
- “”” This function will be executed more than once at the same time “””
- print(“[+] Thread #%d\n”%i)
- return
- n=int(input(“[+] How many thread you want to use: “))
- for i in range(n):
- t=threading.Thread(target=ThreadFunction, args=(i,)) # the comma should be assigned in case of passing one arg
- # to tell the interpreter that it’s a tuple not a simple varible
- t.start()
view plainprint?
- [+] How many thread you want to use: 5
- [+] Thread #0
- [+] Thread #1
- [+] Thread #2
- [+] Thread #3
- [+] Thread #4
4. The FTP Anonymous Login Scanner
As I mentioned before, this script do an Anonymous Login scan of random FTP hosts. It uses threads to scan multiple hosts at the same time in order to make the scan faster.
The help text of the script looks like this:
view plainprint?
- Usage: AnonFTP.py [options]
- Options:
- -h, –help show this help message and exit
- -n nHost Number of hosts
- -o FILE, –output=FILE
- File to save logs
- -v, –verbose Logs everything
- -t TIMEOUT, –timeout=TIMEOUT
- Timeout in seconds
- -m MAX, –maxthread=MAX
- Maximum thread number
[+] -n nHost: Number of hosts you want to scan
[+] -o FILE: Logs file
[+] -m MAX: This is very important option, you should specify the maximum number of threads. The value of this option depends on your computer!
Optional options:
[+] -v, –verbose: Specify this option when you want to include to outputs the hosts that doesn’t supports anonymous login
[+] -t TIMEOUT: the timeout of connecting to host. Specifying this option will make the scan more faster, the value depends on your internet speed
Screenshot of the script’s output:
The full script can be found on my github: AnonFTP.py
Tags:
Python for SysAdmin