Skip to content

Commit

Permalink
Banners uniformly implemented
Browse files Browse the repository at this point in the history
  • Loading branch information
strictlymike committed Aug 15, 2017
1 parent dfcfa15 commit de6a896
Show file tree
Hide file tree
Showing 4 changed files with 189 additions and 203 deletions.
38 changes: 21 additions & 17 deletions fakenet/configs/default.ini
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,23 @@ BlackListPortsUDP: 67, 68, 137, 138, 443, 1900, 5355
# * DNSResponse - IP address to respond with for A record DNS queries. (DNSListener)
# * NXDomains - A number of DNS requests to ignore to let the malware cycle through
# all of the backup C2 servers. (DNSListener)
# * Banner - FTPListener, IRCListener: FTP or IRC banner to display.
# Valid settings are any banner string, or !<key> where
# <key> is a valid key in the BANNERS dictionary within
# FTPListener.py or IRCListener.py, or !random to
# randomize among the banners in the BANNERS dictionary.
# The default value if none is specified is !generic,
# which selects the banner in the BANNERS dictionary going
# by that key. Banner string may specify the following
# escapes/insertions:
# %(servername)s - ServerName setting value
# %(tz)s - Time zone, currently hard-coded to 'UTC'
# * ServerName - FTPListener, IRCListener: FTP or IRC server name for
# insertion into selected default banners or into a
# user-specified banner string. Valid settings are any
# hostname string, !hostname to insert the actual hostname
# of the system, or !random to generate a random hostname
# between 1 and 15 characters (inclusive).

[Forwarder]
Enabled: False
Expand Down Expand Up @@ -246,22 +263,8 @@ Listener: FTPListener
UseSSL: No
FTProot: defaultFiles/
PasvPorts: 60000-60010
###############################################################################
# FTP Listener Optional Configuration
#
# The following optional settings control FTP banner behavior:
#
# * Banner - FTP banner to display. Valid settings are any banner
# string, !<key> where <key> is in FTP_BANNERS within
# listeners/FTPListener.py, or !random to randomize among
# the default banners.
# * Hostname - FTP hostname for insertion into selected default
# banners. Valid settings are any hostname string,
# !hostname to insert the actual hostname of the system,
# or !random to generate a random hostname between 3 and
# 13 characters (inclusive).
Banner: !ncftpd
Hostname: !hostname
Banner: !generic
ServerName: !gethostname

[FTPListenerPASV]
Enabled: True
Expand All @@ -274,7 +277,8 @@ Port: 6667
Protocol: TCP
Listener: IRCListener
UseSSL: No
ServerName: localhost
Banner: !generic
ServerName: !gethostname
Timeout: 30

[TFTPListener]
Expand Down
58 changes: 53 additions & 5 deletions fakenet/listeners/BannerFactory.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,67 @@
import random
import socket
import string
import datetime

class BannerFactory():
def banner(self, config, bannerlist):
banner = config.get('banner', '!generic')
servername = config.get('servername', socket.gethostname())
def genBanner(self, config, bannerdict, defaultbannerkey='!generic'):
"""Select and format a banner.
Supported banner escapes:
!<key> - Use the banner whose key in bannerdict is <key>
!random - Use a random banner from bannerdict
!generic - Every listener supporting banners must have a generic
insertions = {'servername': servername, 'tz': 'UTC'}
Banners can include literal '\n' or '\t' tokens (slash followed by the
letter n or t) to indicate that a newline or tab should be inserted.
Banners can include %(servername)s or %(tz)s to insert the servername
or time zone (hard-coded to 'UTC' as of this writing).
If the user does not specify a banner, then '!generic' is used by
default, resulting in bannerdict['generic'] being used. If the user
specifies a bang escape e.g. '!iis-6', then the banner keyed by that
name will be used. If the user specifies '!random' then a random banner
will be chosen from bannerdict.
Because some banners include the servername as an insertion string,
this method also retrieves that configuration value and incorporates
a couple of similar escape sequences:
!random - Randomized servername with random length between 1-15
!gethostname - Use the real hostname
"""

banner = config.get('banner', defaultbannerkey)
servername = config.get('servername', 'localhost')

if servername.startswith('!'):
servername = servername[1:]
if servername.lower() == 'random':
servername = self.randomizeHostname()
elif servername.lower() == 'gethostname':
servername = socket.gethostname()
else:
raise ValueError('ServerName config invalid escape: !%s' %
(servername))

if banner.startswith('!'):
banner = banner[1:]
banner = bannerlist[banner]
if banner.lower() == 'random':
banner = random.choice(bannerdict.keys())
elif banner not in bannerdict:
raise ValueError('Banner config escape not a valid banner key')

banner = bannerdict[banner]

insertions = {'servername': servername, 'tz': 'UTC'}

banner = datetime.datetime.now().strftime(banner)
banner = banner % insertions
banner = banner.replace('\\n', '\n').replace('\\t', '\t')

return banner

def randomizeHostname(self):
valid_hostname_charset = (string.ascii_letters + string.digits + '-')
n = random.randint(1, 15)
return ''.join(random.choice(valid_hostname_charset) for _ in range(n))
Loading

0 comments on commit de6a896

Please sign in to comment.