[code autolinks=”false”]
#######################################################################
# Unified diff (patch file) to modify Dionaea’s http.py module #
# to enable it to recognise and download from URLs in a wget/curl/ #
# lwp-download command line contained within ShellShock exploits #
# #
# Application instructions #
# [from the parent directory of Dionaea’s source directory] #
# [it will patch ./dionaea/modules/python/scripts/http.py ] #
# patch -p0 < dionaea-shellshock.diff #
# #
# dionaea-shellshock.diff v2015.01.26 #
# http://malwaremusings.com/supporting-files/dionaea-shellshock-diff/ #
#######################################################################
— ./dionaea/modules/python/scripts/http.py.dist 2015-01-26 11:39:21.541750572 +1100
+++ ./dionaea/modules/python/scripts/http.py 2015-01-26 11:34:13.000000000 +1100
@@ -37,6 +37,7 @@
import urllib.parse
import re
import tempfile
+import traceback
logger = logging.getLogger(‘http’)
logger.setLevel(logging.DEBUG)
@@ -89,6 +90,75 @@
self.max_request_size = max_request_size * 1024
+
+ ###
+ # process_headers(): look for ShellShock exploit
+ ###
+
+ def process_headers(self):
+ try:
+ allheaders = self.header.headers
+
+ #
+ # remember URLs that we’ve already created an incident for
+ #
+ submittedurls = []
+
+ for i in allheaders:
+ #
+ # convert the arrays of bytes to strings
+ #
+ headername = str(i,encoding="utf-8")
+ headerval = str(allheaders[i],encoding="utf-8")
+
+ #
+ # check for ShellShock exploit
+ #
+ if re.match("\(\) {[ ][^}]*;[ ]*}[ ]*;",headerval):
+ #print("— ShellShock —")
+ #print(i + b": " + allheaders[i])
+
+ #
+ # we have shellshock. extract URLs from wget/curl/lwp-download command lines
+ #
+ urlmatch = re.findall("(?:wget|curl|lwp-download)(?: |(?: [^;\"]* ))((?:(?:https?|ftp)://)?(?:[0-9A-Za-z]+\.){2,}[0-9A-Za-z]+(?:/[^ ;\\\"]*)*)",str(allheaders[i]))
+
+ #
+ # for each URL that we extracted
+ # the ‘?:’ modifier means that we don’t get all of the grouped bits returned, but just any matching URLs
+ #
+ for dlurl in urlmatch:
+ #
+ # check that we haven’t already created an incident for it
+ #
+ if not (dlurl in submittedurls):
+ #print(" Found URL: %s" % dlurl)
+
+ #
+ # create a Dionaea download offer incident
+ #
+ i = incident("dionaea.download.offer")
+
+ #
+ # link it to this connection, and set the URL
+ #
+ i.con = self
+ i.url = dlurl
+
+ #
+ # do stuff with it
+ #
+ i.report()
+
+ #
+ # append the URL to a list of URLs that we’ve already submitted
+ # this stops us from creating multiple download offers for the same URL
+ # if it appears more than one in a single HTTP request (it often does)
+ #
+ submittedurls.append(dlurl)
+ except:
+ traceback.print_exc()
+
def handle_origin(self, parent):
self.root = parent.root
self.rwchunksize = parent.rwchunksize
@@ -116,6 +186,7 @@
header = data[0:eoh]
data = data[soc:]
self.header = httpreq(header)
+ self.process_headers()
self.header.print()
if self.header.type == b’GET’:
[/code]