Tuesday, March 6, 2007

FuzzXml

Ok si i was playing around the other day with a Jabber server written in java. I don't quite remember the name but it had a nice web configuration interface. I remember thinking "why not just throw some garbage at this little server of ours?" Yeah sounds like a nice idea! Lets proceede in python of course. First we know jabber is based on XML, second we know it can work without encryption. How much easier could it be? I made a list of all the xml files i could find in my home dir. From all the browsing on the net for this year and a half since i got this laptop i had a hell of alot of them. I did "cat" them all into one big.blob, then refined it with "strings" and the resulting pile of XML stored as good.blob.

serj@tokamak:~$ du -h good.blob
2.4M good.blob

Now all i need is a bit of python to make this work.

#!/usr/bin/env python

import sys
import time
import random
import socket
import string
import threading

def fuzzFile(file, iter, chunkLen):
f = open(file, 'r')
data = f.read()
f.close()

retStr = ""
for i in range(0, int(iter)):
x = random.randint(0,data.__len__());
retStr = retStr + str( data[ x : x+random.randint(0, int(chunkLen)) ] ) + "\n\n"
for i in range( 0, int(random.randint(0, 3)) ):
retStr = retStr + "\n"

return retStr


class FuzzAServer(threading.Thread):
def __init__(self, addr, port, file, iter, chunkLen):
threading.Thread.__init__(self, name="Producer")
self.addr = addr;
self.port = port;
self.file = file;
self.iter = iter;
self.chunkLen = chunkLen;

def run(self):
while 1:

try:
sox = socket.socket ( socket.AF_INET, socket.SOCK_STREAM )
sox.connect((self.addr,int(self.port)))

while sox.send(fuzzFile(self.file, self.iter, self.chunkLen)):
pass

sox.close()
except Exception, err:
print err

time.sleep(10)


class FuzzAClient(threading.Thread):
def __init__(self, addr, port, file, iter, chunkLen):
threading.Thread.__init__(self, name="Producer")
self.addr = addr;
self.port = int(port);
self.file = file;
self.iter = iter;
self.chunkLen = chunkLen;

def run(self):
while 1:

try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((self.addr, self.port))
s.listen(1)
conn, addr = s.accept()
print 'Connected by', addr
while 1:
data = conn.recv(1024)
print data,

if not data:
break


data = fuzzFile(self.file, self.iter, self.chunkLen)
print data

conn.send(data)

conn.close()
except Exception, err:
print err

s.shutdown(2)
s.close()

for i in range(0, 1000):
t = FuzzAServer(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5])
t.start()
# print "thread ", i




The idea is simple. Connect to the server build some random string of XML-ish garbage and send it back. And like this as fast as you can. And yeah lets spawn a couple of more in parallel.

As you can see i also included a server who can handle a client a time and send bad XML. I decided to test not just the server but the clients also.

The results? Well after about 10-30 seconds the java Jabber server eat about 1.2G ram and 98%cpu for more than 20 minutes (at least i killed it after 20 mins). The clients that i tested were examples from the XmlRpc++ library. The did handle the server without problems.

No comments: