Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switched to requests library #7

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
170 changes: 89 additions & 81 deletions serializekiller.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
#!/usr/bin/env python
#-------------------------------------------------------------------------------
# ------------------------------------------------------------------------------
# Name: SerializeKiller
# Purpose: Finding vulnerable vulnerable servers
# Purpose: Finding vulnerable java servers
#
# Author: (c) John de Kroon, 2015
# Version: 1.0.2
#-------------------------------------------------------------------------------
# ------------------------------------------------------------------------------

import subprocess
import threading
import time
import socket
import sys
import argparse
import urllib2
import ssl
import requests
import re

from socket import error as socket_error
from datetime import datetime
Expand All @@ -26,59 +26,47 @@
parser.add_argument('file', nargs='?', help='File with targets')
args = parser.parse_args()


def nmap(host, *args):
global shellCounter
global threads
global target_list

# are there any ports defined for this host?
# All ports to enumerate over for jboss, jenkins, weblogic, websphere
port_list = ['80', '81', '443', '444', '1099', '5005',
'7001', '7002', '8080', '8081', '8083', '8443',
'8880', '8888', '9000', '9080', '9443', '16200']

# Are there any ports defined for this host?
if not target_list[host]:
found = False
cmd = 'nmap --host-timeout 5 --open -p 5005,8080,9080,8880,7001,7002,16200 '+host
cmd = 'nmap --host-timeout 5 --open -p %s %s' % (','.join(port_list), host)
try:
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
out, err = p.communicate()
if "5005" in out:
if websphere(host, "5005"):
found = True
if "8880" in out:
if websphere(host, "8880"):
found = True
if "7001" in out:
if weblogic(host, 7001):
found = True
if "16200" in out:
if weblogic(host, 16200):
found = True
if "8080" in out:
if jenkins(host, "8080"):
found = True
if jboss(host, 8080):
found = True
if "9080" in out:
if jenkins(host, "9080"):

for this_port in port_list:
if websphere(host, this_port) or weblogic(host, this_port) or jboss(host, this_port) or jenkins(host, this_port):
found = True
if found:
shellCounter += 1
except ValueError:
print " ! Something went wrong on host: "+host
except ValueError, v:
print " ! Something went wrong on host: %s: %s" % (host, v)
return
else:
for port in target_list[host]:
if websphere(host, port) or weblogic(host, port) or jenkins(host, port) or jboss(host, port):
shellCounter += 1
return


def websphere(url, port, retry=False):
try:
ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE
output = urllib2.urlopen('https://'+url+":"+port, context=ctx, timeout=8).read()
output = requests.get('https://'+url+":"+port, timeout=8)
if "rO0AB" in output:
print " - (possibly) Vulnerable Websphere: "+url+" ("+port+")"
return True
except urllib2.HTTPError, e:
except requests.exceptions.HTTPError, e:
if e.getcode() == 500:
if "rO0AB" in e.read():
print " - (possibly) Vulnerable Websphere: "+url+" ("+port+")"
Expand All @@ -87,19 +75,20 @@ def websphere(url, port, retry=False):
pass

try:
output = urllib2.urlopen('http://'+url+":"+port, timeout=3).read()
output = requests.get('http://'+url+":"+port, timeout=3)
if "rO0AB" in output:
print " - (possibly) Vulnerable Websphere: "+url+" ("+port+")"
return True
except urllib2.HTTPError, e:
except requests.exceptions.HTTPError, e:
if e.getcode() == 500:
if "rO0AB" in e.read():
print " - (possibly) Vulnerable Websphere: "+url+" ("+port+")"
return True
except:
pass

#Used this part from https://github.com/foxglovesec/JavaUnserializeExploits


# Used this part from https://github.com/foxglovesec/JavaUnserializeExploits
def weblogic(url, port):
try:
server_address = (url, int(port))
Expand All @@ -111,64 +100,89 @@ def weblogic(url, port):

try:
data = sock.recv(1024)
print "[debug] Received weblogic data:", data
except socket.timeout:
return False

sock.close()
if "HELO" in data:
print " - Vulnerable Weblogic: "+url+" ("+str(port)+")"
return True
return False
# CGP: https://github.com/nmap/nmap/blob/master/scripts/weblogic-t3-info.nse
# weblogic_version = string.match(result, "^HELO:(%d+%.%d+%.%d+%.%d+)%.")
if weblogic_vulnerable(data):
print " - Vulnerable Weblogic: "+url+" ("+str(port)+")"
return True
else:
return False
else:
return False
except socket_error:
return False

#Used something from https://github.com/foxglovesec/JavaUnserializeExploits
def weblogic_vulnerable(data):
# Very cheap hack
affected_versions = ['10.3.6.0', '12.1.2.0', '12.1.3.0', '12.2.1.0']
m = re.findall(r"[0-9]+(?:\.[0-9]+){3}", data)[0]
print "[debug] Found Weblogic version:", m
if m in affected_versions:
return True

return False


# Used something from https://github.com/foxglovesec/JavaUnserializeExploits
def jenkins(url, port):
# CGP: Check the Jenkins Remote API here:
# https://wiki.jenkins-ci.org/display/JENKINS/Remote+access+API
JENKINS_FIRST_PATCHED_VERSION = 1.638
try:
cli_port = False
ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE
try:
output = urllib2.urlopen('https://'+url+':'+port+"/jenkins/", context=ctx, timeout=8).info()
cli_port = int(output['X-Jenkins-CLI-Port'])
except urllib2.HTTPError, e:
output = requests.get('https://'+url+':'+port+"/jenkins/", timeout=8)

# Perform version detection before anything else
jenkins_version = float(output.headers['X-Jenkins'])
if jenkins_version >= JENKINS_FIRST_PATCHED_VERSION:
print "[DEBUG] Patched version of Jenkins (%.3f). Moving on..." % jenkins_version
return False

cli_port = int(output['X-Jenkins-CLI-Port'])
except requests.exceptions.HTTPError, e:
if e.getcode() == 404:
try:
output = urllib2.urlopen('https://'+url+':'+port, context=ctx, timeout=8).info()
cli_port = int(output['X-Jenkins-CLI-Port'])
output = requests.get('https://'+url+':'+port, timeout=8)
cli_port = int(output.headers['X-Jenkins-CLI-Port'])
except:
pass
except:
pass
except:
print " ! Could not check Jenkins on https. Maybe your SSL lib is broken."
pass
if cli_port == False:

if not cli_port:
try:
output = urllib2.urlopen('http://'+url+':'+port+"/jenkins/", timeout=8).info()
cli_port = int(output['X-Jenkins-CLI-Port'])
except urllib2.HTTPError, e:
output = requests.get('http://'+url+':'+port+"/jenkins/", timeout=8)
cli_port = int(output.headers['X-Jenkins-CLI-Port'])
except requests.exceptions.HTTPError, e:
if e.getcode() == 404:
try:
output = urllib2.urlopen('http://'+url+':'+port, timeout=8).info()
cli_port = int(output['X-Jenkins-CLI-Port'])
output = requests.get('http://'+url+':'+port, timeout=8).info()
cli_port = int(output.headers['X-Jenkins-CLI-Port'])
except:
return False
except:
return False
#Open a socket to the CLI port

# Open a socket to the CLI port
try:
server_address = (url, cli_port)
sock = socket.create_connection(server_address, 5)

# Send headers
headers = '\x00\x14\x50\x72\x6f\x74\x6f\x63\x6f\x6c\x3a\x43\x4c\x49\x2d\x63\x6f\x6e\x6e\x65\x63\x74'
sock.send(headers)

data1 =sock.recv(1024)
data1 = sock.recv(1024)
if "rO0AB" in data1:
print " - Vulnerable Jenkins: "+url+" ("+str(port)+")"
return True
Expand All @@ -181,42 +195,43 @@ def jenkins(url, port):
pass
return False

def jboss(url, port, retry = False):

def jboss(url, port, retry=False):
try:
ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE
output = urllib2.urlopen('https://'+url+':'+port+"/invoker/JMXInvokerServlet", context=ctx, timeout=8).read()
output = requests.get('https://'+url+':'+port+"/invoker/JMXInvokerServlet", timeout=8)
except:
try:
output = urllib2.urlopen('http://'+url+':'+port+"/invoker/JMXInvokerServlet", timeout=8).read()
output = requests.get('http://'+url+':'+port+"/invoker/JMXInvokerServlet", timeout=8)
except:
#OK. I give up.
# OK. I give up.
return False

if "\xac\xed\x00\x05" in output:
print " - Vulnerable JBOSS: "+url+" ("+port+")"
return True
return False


def urlStripper(url):
url = str(url.replace("https:", ''))
url = str(url.replace("http:", ''))
url = str(url.replace("\r", ''))
url = str(url.replace("\n", ''))
url = str(url.replace("\n", ''))
url = str(url.replace("/", ''))
return url


def read_file(filename):
f = open(filename)
content = f.readlines()
f.close()
return content


def worker():
global threads
content = read_file(args.file)

for line in content:
if ":" in line:
item = line.strip().split(':')
Expand All @@ -235,24 +250,23 @@ def worker():
for host in target_list:
current += 1
while threading.active_count() > threads:
print " ! We have more threads running than allowed. Current: {} Max: {}.".format(threading.active_count(),
threads)
print " ! We have more threads running than allowed. Current: {} Max: {}.".format(threading.active_count(), threads)
if threads < 100:
threads+=1
threads += 1
sys.stdout.flush()
time.sleep(2)
print " # Starting test {} of {} on {}.".format(current, total_jobs, host)
sys.stdout.flush()
threading.Thread(target=nmap, args=(host, False, 1)).start()

#we're done!
# We're done!
while threading.active_count() > 2:
print " # Waiting for everybody to come back. Still {} active.".format(threading.active_count() - 1)
sys.stdout.flush()
time.sleep(4)

print
print " => scan done. "+str(shellCounter)+" vulnerable hosts found."
print " => Scan done. "+str(shellCounter)+" vulnerable hosts found."
print "Execution time: "+str(datetime.now() - startTime)
exit()

Expand All @@ -261,12 +275,6 @@ def worker():
print "Start SerializeKiller..."
print "This could take a while. Be patient."
print

try:
ssl.create_default_context()
except:
print " ! WARNING: Your SSL lib isn't supported. Results might be incomplete."
pass

target_list = {}
shellCounter = 0
Expand Down