Skip to content

Instantly share code, notes, and snippets.

@dev-zzo
Last active August 18, 2016 14:54
Show Gist options
  • Select an option

  • Save dev-zzo/6dfa94de914616edd5aa21a8d18d2d4d to your computer and use it in GitHub Desktop.

Select an option

Save dev-zzo/6dfa94de914616edd5aa21a8d18d2d4d to your computer and use it in GitHub Desktop.
MAGNETO!!!!
import socket
import time
import sys
import http
import magneto
def run_test(target, id):
print
print "* * * * * Starting next test"
try:
print "Connecting..."
s = socket.create_connection(target)
print "Connected."
except socket.error as e:
print "Connection failed."
return False
ctx = magneto.Context(
hostname="abc.net",
uri="/",
collaborator="http://enemy.com/ping",
)
payload = http.generate(ctx)
print payload
s.sendall(payload)
print "Receiving..."
try:
data = s.recv(1024)
print "Received:"
print data
except socket.error:
print "RX timed out -- the device is likely having issues."
with open("%s_%d_%d.txt" % (target[0], target[1], id), "w") as fp:
fp.write(payload)
finally:
s.close()
target = (sys.argv[0], int(sys.argv[1]))
id = 0
while True:
run_test(target, id)
id += 1
"""
HTTP grammar using MAGNETO!!!
"""
from magneto import *
MAX_LENGTH = 1024
CRLF = "\r\n"
WS = " "
HTTP_DATE = "Fri, 31 Dec 1999 23:59:59 GMT"
METHODS = [
"GET",
"POST",
"HEAD",
"PUT",
"DELETE",
"OPTIONS",
"TRACE",
"CONNECT",
"INVALIDMETHOD",
]
URI = Choice([
Variable("uri"),
RandomString(max=4096, prefix="/")
])
HTTP_VERSION = [ "HTTP", "/", Choice(["1.0", "1.1"]) ]
REQUEST = [ Choice(METHODS), WS, URI, WS, HTTP_VERSION, CRLF ]
# https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
HEADERNAME_ACCEPT_CHARSET = "Accept-Charset"
HEADERNAME_ACCEPT_LANGUAGE = "Accept-Language"
HEADERNAME_ACCEPT_ENCODING = "Accept-Encoding"
HEADERNAME_IF_NONE_MATCH = "If-None-Match"
HEADERNAME_PRAGMA = "Pragma"
HEADERNAME_X_REQUESTED_WITH = "X-Requested-With"
HEADERNAME_CONTENT_TYPE = "Content-Type"
HEADERNAME_CONTENT_LENGTH = "Content-Length"
HEADER_SEPARATOR = [ ":", WS ]
HTTP_CREDENTIALS = Choice([
[ "Basic", WS, RandomString(max=1024, prefix="admin:", encoding="base64") ],
[ "Basic", WS, RandomString(max=1024, suffix=":password", encoding="base64") ],
])
MEDIA_TYPE = [
"audio",
"text",
"image",
RandomString()
]
MEDIA_SUBTYPE = [
"*",
"plain",
"html",
"jpeg",
RandomString()
]
ACCEPT_MEDIA = Choice([
"*/*",
[ Choice(MEDIA_TYPE), "/", Choice(MEDIA_SUBTYPE) ],
])
HTTP_HOST = [
Variable("hostname"),
RandomString(max=MAX_LENGTH, suffix=".com"),
]
HEADER_ACCEPT = [
"Accept", HEADER_SEPARATOR,
LeftRecursion([ ", ", ACCEPT_MEDIA ], ACCEPT_MEDIA),
CRLF,
]
HEADER_AUTHORIZATION = [
"Authorization", HEADER_SEPARATOR,
HTTP_CREDENTIALS,
CRLF,
]
HEADER_CACHE_CONTROL = [
"Cache-Control", HEADER_SEPARATOR,
Choice([
"max-age=0",
"max-stale=0",
"no-cache",
"no-store",
]),
CRLF,
]
HEADER_CONNECTION = [
"Connection", HEADER_SEPARATOR,
Choice([
"close",
"keep-alive",
]),
CRLF,
]
HEADER_COOKIE = [
"Cookie", HEADER_SEPARATOR,
Choice([
[ RandomString(max=MAX_LENGTH), "=", RandomString(max=MAX_LENGTH) ],
]),
CRLF,
]
HEADER_FROM = [
"From", HEADER_SEPARATOR,
Choice([
"[email protected]",
RandomString(max=MAX_LENGTH),
]),
CRLF,
]
HEADER_HOST = [
"Host", HEADER_SEPARATOR,
Choice(HTTP_HOST),
CRLF,
]
HEADER_IF_MATCH = [
"If-Match", HEADER_SEPARATOR,
'"', RandomString(max=MAX_LENGTH), '"',
CRLF,
]
HEADER_IF_MODIFIED_SINCE = [
"If-Modified-Since", HEADER_SEPARATOR,
HTTP_DATE,
CRLF,
]
HEADER_IF_NONE_MATCH = [
"If-None-Match", HEADER_SEPARATOR,
'"', RandomString(max=MAX_LENGTH), '"',
CRLF,
]
HEADER_IF_UNMODIFIED_SINCE = [
"If-Unmodified-Since", HEADER_SEPARATOR,
HTTP_DATE,
CRLF,
]
HEADER_MAX_FORWARDS = [
"Max-Forwards", HEADER_SEPARATOR,
RandomInteger(max=1<<24),
CRLF,
]
HEADER_PROXY_AUTHORIZATION = [
"Proxy-Authorization", HEADER_SEPARATOR,
HTTP_CREDENTIALS,
CRLF,
]
HEADER_RANGE = [
"Range", HEADER_SEPARATOR,
"bytes",
"=",
RandomInteger(0, 1<<24),
"-",
Choice([ "", RandomInteger(0, 1<<24) ]),
CRLF,
]
HEADER_REFERRER = [
"Referer", HEADER_SEPARATOR,
Choice([
"http://idontexist.com/",
Variable("collaborator"),
RandomString(max=MAX_LENGTH),
]),
CRLF,
]
HEADER_USER_AGENT = [
"User-Agent", HEADER_SEPARATOR,
Choice([
"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:47.0) Gecko/20100101 Firefox/47.0",
"Mozilla/5.0 (Windows NT 10.0; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0",
RandomString(min=25, max=MAX_LENGTH),
]),
CRLF,
]
HEADERS = [
HEADER_ACCEPT,
HEADER_AUTHORIZATION,
HEADER_CACHE_CONTROL,
HEADER_CONNECTION,
HEADER_COOKIE,
HEADER_FROM,
HEADER_HOST,
HEADER_IF_MATCH,
HEADER_IF_MODIFIED_SINCE,
HEADER_IF_NONE_MATCH,
HEADER_IF_UNMODIFIED_SINCE,
HEADER_MAX_FORWARDS,
HEADER_PROXY_AUTHORIZATION,
HEADER_RANGE,
HEADER_REFERRER,
HEADER_USER_AGENT,
]
grammar = [ REQUEST, Multiple(Choice(HEADERS), 2, 10), CRLF ]
def generate(context):
tokens = expand(grammar, context)
return ''.join([str(token) for token in tokens])
if __name__ == '__main__':
ctx = Context(
hostname="abc.net",
collaborator="http://enemy.com/ping",
)
print generate(ctx)
# EOF
"""
MAGNETO, aka grammar-based generator of random shit
"""
import random
import base64
#
# Expression classes
#
class Expression(object):
"Base class for all grammar elements"
def expand(self, context):
raise NotImplementedError()
class RandomValue(Expression):
"Represents a randomly generated value"
pass
class RandomString(RandomValue):
"Represents a randomly generated string"
UPALPHA = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
LWALPHA = "abcdefghijklmnopqrstuvwxyz"
MIXALPHA = UPALPHA + LWALPHA
DIGIT = "0123456789"
MIXALNUM = MIXALPHA + DIGIT
def __init__(self, charset=MIXALNUM, min=1, max=25, prefix="", suffix="", encoding=None):
self.charset = charset
self.min = min
self.max = max
self.prefix = prefix
self.suffix = suffix
self.encoding = encoding
def expand(self, context):
count = random.randint(self.min, self.max)
s = []
while count > 0:
s.append(random.choice(self.charset))
count -= 1
s = self.prefix + ''.join(s) + self.suffix
if self.encoding == "base64":
s = base64.b64encode(s)
return s
class RandomInteger(RandomValue):
"Represents a randomly generated integer"
def __init__(self, min=0, max=1024):
self.min = min
self.max = max
def expand(self, context):
# TODO: Handle longs properly?
return random.randint(self.min, self.max)
class Variable(Expression):
"Refers to something in the context; expressions accepted too"
def __init__(self, id):
self.id = id
def expand(self, context):
return getattr(context, self.id)
class Choice(Expression):
"Expands to one element at random form the list; uniform distribution"
def __init__(self, choices):
self.choices = choices
def expand(self, context):
return random.choice(self.choices)
class Optional(Expression):
"Expands to either empty list or the single element"
def __init__(self, element, p=0.5):
self.element = element
self.p = p
def expand(self, context):
if random.random() >= self.p:
return []
return self.element
class Multiple(Expression):
"Expands to multiple instances of the element"
def __init__(self, element, min, max):
self.element = element
self.min = min
self.max = max
def expand(self, context):
return [ self.element for x in xrange(0, random.randint(self.min, self.max)) ]
class LeftRecursion(Expression):
"Performs a left-recursive expansion with probability p"
def __init__(self, recursion, termination, p=0.25):
self.recursion = recursion
self.termination = termination
self.p = p
def expand(self, context):
if random.random() >= self.p:
return self.termination
x = [ self ]
x.extend(self.recursion)
return x
#
# Expansion rules
#
class Context(object):
"Keeps track of different variable values"
def __init__(self, **kwargs):
self.__dict__.update(kwargs)
def expand(expr_list, context):
"Performs iterative expansion"
expanded = True
while expanded:
#print expr_list
#print
new_list = []
expanded = False
for expr in expr_list:
if isinstance(expr, Expression):
expanded = True
expr = expr.expand(context)
if isinstance(expr, (list, tuple)):
new_list.extend(expr)
else:
new_list.append(expr)
expr_list = new_list
return expr_list
# EOF
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment