2018-08-06 20:22:28 +00:00
|
|
|
"""
|
|
|
|
Basic tasks for FTP services
|
|
|
|
"""
|
2018-08-02 02:12:12 +00:00
|
|
|
|
|
|
|
import ftplib
|
|
|
|
|
2018-08-06 20:22:28 +00:00
|
|
|
from lib.exec import Task
|
2018-08-02 02:12:12 +00:00
|
|
|
|
2018-08-06 20:22:28 +00:00
|
|
|
class FTPConnectTask(Task): # pylint: disable=too-few-public-methods
|
|
|
|
"""Tries to connect FTP service with various credentials"""
|
2018-08-02 02:12:12 +00:00
|
|
|
def _process(self, item):
|
2018-08-06 20:22:28 +00:00
|
|
|
ftp = ftplib.FTP(host=item['data']['ip'], timeout=self.lcnf.get('timeout', 30))
|
2018-08-02 02:12:12 +00:00
|
|
|
try:
|
|
|
|
self._logger.debug('Trying anonymous login')
|
2018-08-06 20:22:28 +00:00
|
|
|
ftp.login()
|
|
|
|
except ftplib.error_perm as err:
|
|
|
|
self._logger.debug('Failed (%s)', err)
|
2018-08-02 02:12:12 +00:00
|
|
|
else:
|
2018-08-06 20:22:28 +00:00
|
|
|
self._logger.info('Succeeded with anonymous')
|
|
|
|
item['data']['username'] = 'anonymous'
|
|
|
|
item['data']['password'] = ''
|
|
|
|
return True
|
2018-08-02 02:12:12 +00:00
|
|
|
|
|
|
|
if self.lcnf.get('bruteforce', False):
|
2018-08-06 20:22:28 +00:00
|
|
|
self._logger.debug('Bruteforce enabled, loading usernames and passwords')
|
|
|
|
usernames = [line.rstrip() for line in open(self.lcnf.get('usernames'), 'r')]
|
|
|
|
passwords = [line.rstrip() for line in open(self.lcnf.get('passwords'), 'r')]
|
2018-08-02 02:12:12 +00:00
|
|
|
|
|
|
|
for username in usernames:
|
|
|
|
for password in passwords:
|
2018-08-06 20:22:28 +00:00
|
|
|
self._logger.debug('Checking %s', username + ':' + password)
|
2018-08-02 02:12:12 +00:00
|
|
|
try:
|
2018-08-06 20:22:28 +00:00
|
|
|
self._logger.debug('Sending NOOP')
|
|
|
|
ftp.voidcmd('NOOP')
|
|
|
|
except IOError as err:
|
|
|
|
self._logger.debug('IOError occured (%s), attempting to open new connection', err)
|
|
|
|
ftp = ftplib.FTP(host=item['data']['ip'], timeout=self.lcnf.get('timeout', 30))
|
2018-08-02 02:12:12 +00:00
|
|
|
try:
|
2018-08-06 20:22:28 +00:00
|
|
|
self._logger.debug('Trying to log in')
|
|
|
|
ftp.login(username, password)
|
|
|
|
except ftplib.error_perm as err:
|
|
|
|
self._logger.debug('Failed (%s)', err)
|
2018-08-02 02:12:12 +00:00
|
|
|
continue
|
|
|
|
else:
|
2018-08-06 20:22:28 +00:00
|
|
|
self._logger.info('Succeeded with %s', username + ':' + password)
|
|
|
|
item['data']['username'] = username
|
|
|
|
item['data']['password'] = password
|
|
|
|
return True
|
|
|
|
self._logger.info('Could not connect')
|
|
|
|
return False
|
|
|
|
|
|
|
|
class FTPListFilesTask(Task): # pylint: disable=too-few-public-methods
|
|
|
|
"""Executes NLST to list files on FTP"""
|
2018-08-02 02:12:12 +00:00
|
|
|
def _process(self, item):
|
2018-08-06 20:22:28 +00:00
|
|
|
ftp = ftplib.FTP(host=item['data']['ip'],
|
|
|
|
user=item['data']['username'],
|
|
|
|
passwd=item['data']['password'])
|
|
|
|
filelist = ftp.nlst()
|
2018-08-02 02:12:12 +00:00
|
|
|
try:
|
2018-08-06 20:22:28 +00:00
|
|
|
ftp.quit()
|
|
|
|
except ftplib.Error:
|
2018-08-02 02:12:12 +00:00
|
|
|
pass
|
|
|
|
|
2018-08-06 20:22:28 +00:00
|
|
|
item['data']['files'] = []
|
|
|
|
for filename in filelist:
|
|
|
|
item['data']['files'].append(filename)
|
|
|
|
return True
|
|
|
|
|
|
|
|
class FTPFilterFilesTask(Task): # pylint: disable=too-few-public-methods
|
|
|
|
"""Sets data.filter if FTP contains only junk"""
|
|
|
|
def _process(self, item):
|
|
|
|
junk_list = ['incoming', '..', '.ftpquota', '.', 'pub']
|
|
|
|
files = item['data']['files']
|
|
|
|
|
|
|
|
item['data']['filter'] = False
|
|
|
|
|
2018-08-02 02:12:12 +00:00
|
|
|
try:
|
2018-08-06 20:22:28 +00:00
|
|
|
if not files or files[0] == "total 0":
|
|
|
|
item['data']['filter'] = "Empty"
|
2018-08-02 02:12:12 +00:00
|
|
|
except IndexError:
|
|
|
|
pass
|
|
|
|
|
2018-08-06 20:22:28 +00:00
|
|
|
if 0 < len(files) <= len(junk_list): # pylint: disable=C1801
|
|
|
|
match_count = 0
|
|
|
|
for filename in junk_list:
|
|
|
|
if filename in files:
|
|
|
|
match_count += 1
|
|
|
|
if match_count == len(files):
|
|
|
|
item['data']['filter'] = "EmptyWithBloatDirs"
|
2018-08-02 02:12:12 +00:00
|
|
|
|
2018-08-06 20:22:28 +00:00
|
|
|
return True
|