def SNMPRequest(result, OID, value='', TimeOut=defaults.timeOut): s = socket(AF_INET, SOCK_DGRAM) s.settimeout(TimeOut) response = '' r = result version = SNMPVersion.iversion(r.version) if value: p = SNMP( version=version, PDU=SNMPset( varbindlist=[SNMPvarbind(oid=ASN1_OID(OID), value=value)])) else: p = SNMP(version=version, PDU=SNMPget(varbindlist=[SNMPvarbind(oid=ASN1_OID(OID))])) SNMPsend(s, p, r.addr[0], r.addr[1], r.community) for x in range(0, 5): try: response, addr = SNMPrecv(s) break except timeout: # if request times out retry sleep(0.5) continue s.close if not response: raise timeout return response
def _snmp_set(self, oid, value): community, sock = self._snmp_connect() pdu = SNMPset(varbindlist=[SNMPvarbind(oid=str(oid), value=value)]) p = SNMP(community=community, PDU=pdu) sock.sendall(p.build()) r = SNMP(sock.recv(4096)) return r
def _snmp_set(self, oid, value): community, sock = self._snmp_connect() pdu = SNMPset(varbindlist=[SNMPvarbind(oid=str(oid), value=value)]) p = SNMP(version=0, community=community, PDU=pdu) #{0:"v1", 1:"v2c", 2:"v2", 3:"v3"}) sock.sendall(p.build()) r = SNMP(sock.recv(4096)) return r
def _snmp_get(self, oid): community, sock = self._snmp_connect() pdu = SNMPget(varbindlist=[SNMPvarbind(oid=str(oid))]) p = SNMP(community=community, PDU=pdu) sock.sendall(p.build()) r = SNMP(sock.recv(4096)) return r.PDU.varbindlist[0].value.val
def password_brutefore(options, communities, ips): s = socket(AF_INET, SOCK_DGRAM) s.settimeout(options.timeOut) results=[] #Start the listener T = threading.Thread(name='listener', target=listener, args=(s,results,)) T.start() # Craft SNMP's for both versions p1 = SNMP( version=SNMPVersion.iversion('v1'), PDU=SNMPget(varbindlist=[SNMPvarbind(oid=ASN1_OID('1.3.6.1.2.1.1.1.0'))]) ) p2c = SNMP( version=SNMPVersion.iversion('v2c'), PDU=SNMPget(varbindlist=[SNMPvarbind(oid=ASN1_OID('1.3.6.1.2.1.1.1.0'))]) ) packets = [p1, p2c] #We try each community string for i,community in enumerate(communities): #sys.stdout.write('\r{0}'.format('.' * i)) #sys.stdout.flush() for ip in ips: SNMPsend(s, packets, ip, options.port, community.rstrip(), options.rate) #We read from STDIN if necessary if options.stdin: while True: try: try: community=input().strip('\n') for ip in ips: SNMPsend(s, packets, ip, options.port, community, options.rate) except EOFError: break except KeyboardInterrupt: break try: print("Waiting for late packets (CTRL+C to stop)") sleep(options.timeOut+options.delay) #Waiting in case of late response except KeyboardInterrupt: pass T._Thread__stop() s.close #We remove any duplicates. This relies on the __equal__ newlist = [] for i in results: if i not in newlist: newlist.append(i) return newlist
def post_exploit(self, response): ''' ''' snmp = SNMP(response) if self.params.verbose: snmp.show() if self.params.verbose > 1: hexdump(response) print "[+] response received" return True
def _sr(self, p): retry = 0 while retry < self.retry: i = randint(0, 2147483647) p.PDU.id = i self.s.sendto(str(p), self.addr) r = None try: while True: r = SNMP(self.s.recvfrom(65535)[0]) if r.PDU.id.val == i: break except timeout: retry += 1 continue error = r.PDU.error.val if not error: return r elif error == 1: raise SNMPError('Response message too large to transport.') elif error == 2: raise SNMPError( 'The name of the requested object was not found.') elif error == 3: raise SNMPError( 'A data type in the request did not match the data type in the SNMP agent.' ) elif error == 4: raise SNMPError( 'The SNMP manager attempted to set a read-only parameter') raise SNMPError('An unknown error has occurred') raise SNMPError('Unable to connect to host %s.' % repr(self.addr))
def cmd_snmp_crack(ip, port, stop, verbose): FILEDIR = os.path.dirname(os.path.abspath(__file__)) DATADIR = os.path.abspath(os.path.join(FILEDIR, '../data')) COMMFILE = Path(os.path.abspath(os.path.join(DATADIR, 'dict_snmp.txt'))) with COMMFILE.open() as cf: communities = cf.read().split('\n') conf.verb = False pkt = IP(dst=ip)/UDP(sport=port, dport=port)/SNMP(community="public", PDU=SNMPget(varbindlist=[SNMPvarbind(oid=ASN1_OID("1.3.6.1"))])) for community in communities: if verbose: print('.', end='') sys.stdout.flush() pkt[SNMP].community=community ans = sr1(pkt, timeout=0.5, verbose=0) if ans: print('\nCommunity found:', community) if stop: break return True
def SNMPrecv(sock): try: recv, addr = sock.recvfrom(65535) response = SNMP(recv) return response, addr except: raise
def perform_healthcheck(self, exsock): ''' ''' healthy = False if self.params.healthcheckport: healthy = exsock.establish_tcp_connection(self.params.healthcheckport) else: oid = '1.3.6.1.2.1.1.3.0' pkt = SNMP(community=self.params.community,PDU=SNMPget(varbindlist=[SNMPvarbind(oid=ASN1_OID(oid))])) exsock.send(pkt[SNMP]) try: response = exsock.receive(2048) healthy = True except KeyboardInterrupt,e: print "[-] keyboard interrupt before response received" if self.terminateFlingOnException: raise KeyboardInterrupt,e except socket.timeout,e: okay = False print "[-] no response from health check - target may have crashed" if not okay and self.terminateFlingOnException: raise socket.timeout,e
def set(self, oid, value): p = SNMP( community=self.community, version=self.version, PDU=SNMPset( varbindlist=[SNMPvarbind(oid=ASN1_OID(oid), value=value)])) self._sr(p)
def trap_listen(): sock = socket(AF_INET, SOCK_DGRAM) sock.bind(('0.0.0.0', 162)) while True: data, address = sock.recvfrom(4096) trap = SNMP(data) for var in trap.PDU.varbindlist: if var.oid.val == '1.3.6.1.4.1.9.9.215.1.1.8.1.2.1': var.value.val = var.value.val[:11] operation, vlan, mac, port = unpack('>cH6sH', var.value.val) result = { 'operation': ord(operation), 'vlan': vlan, 'mac': ':'.join([('%x' % ord(x)).rjust(2, '0') for x in mac]).lower(), 'port': port, 'switch': address[0], } yield result
def handle_connect(self): snmp = SNMP(community=self.comm, PDU=SNMPget(varbindlist=[SNMPvarbind(oid=self.oid)])) buf = str(snmp) while buf: bytes = self.send(buf) buf = buf[bytes:]
def _snmp_walk(self, oid_prefix): community, sock = self._snmp_connect() nextoid = oid_prefix while True: p = SNMP(community=community, PDU=SNMPnext(varbindlist=[SNMPvarbind(oid=nextoid)])) sock.sendall(p.build()) r = SNMP(sock.recv(4096)) oid = r.PDU.varbindlist[0].oid.val if oid.startswith(oid_prefix): yield (oid, r.PDU.varbindlist[0].value.val) else: break nextoid = oid sock.close()
def guess(self, communities): p = SNMP(version=self.version, PDU=SNMPget(varbindlist=[SNMPvarbind(oid=ASN1_OID("1.3.6.1.2.1.1.1.0"))])) r = [] for c in communities: i = randint(0, 2147483647) p.PDU.id = i p.community = c self.s.sendto(str(p), self.addr) sleep(1 / self.rate) while True: try: p = SNMP(self.s.recvfrom(65535)[0]) except timeout: break r.append(p.community.val) return r
def cmd_crack_snmp(ip, community, port, stop, verbose): """Launches snmp-get queries against an IP, and tells you when finds a valid community string (is a simple SNMP cracker). The dictionary used is the distributed with the onesixtyone tool https://github.com/trailofbits/onesixtyone Example: \b # habu.crack.snmp 179.125.234.210 Community found: private Community found: public Note: You can also receive messages like \<UNIVERSAL\> \<class 'scapy.asn1.asn1.ASN1\_Class\_metaclass'\>, I don't know how to supress them for now. """ FILEDIR = os.path.dirname(os.path.abspath(__file__)) DATADIR = os.path.abspath(os.path.join(FILEDIR, '../data')) COMMFILE = Path(os.path.abspath(os.path.join(DATADIR, 'dict_snmp.txt'))) if community: communities = [community] else: with COMMFILE.open() as cf: communities = cf.read().split('\n') conf.verb = False for pkt in IP(dst=ip) / UDP(sport=port, dport=port) / SNMP( community="public", PDU=SNMPget(varbindlist=[SNMPvarbind(oid=ASN1_OID("1.3.6.1"))])): if verbose: print(pkt[IP].dst) for community in communities: if verbose: print('.', end='') sys.stdout.flush() pkt[SNMP].community = community ans = sr1(pkt, timeout=0.5, verbose=0) if ans and UDP in ans: print('\n{} - Community found: {}'.format( pkt[IP].dst, community)) if stop: break return True
def guess(self, communities): p = SNMP( version=self.version, PDU=SNMPget( varbindlist=[SNMPvarbind(oid=ASN1_OID('1.3.6.1.2.1.1.1.0'))])) r = [] for c in communities: i = randint(0, 2147483647) p.PDU.id = i p.community = c self.s.sendto(str(p), self.addr) sleep(1 / self.rate) while True: try: p = SNMP(self.s.recvfrom(65535)[0]) except timeout: break r.append(p.community.val) return r
def handle_read(self): response = SNMP(self.recv(4096)) if self.debug: logging.debug(response.show()) logging.debug(hexdump(response)) print self.dst, '[', self.comm, ']', if self.translate: # print response[SNMPvarbind].oid.val.replace(self.oid, self.oid_key), print response[SNMPvarbind].oid.__oidname__(), else: print response[SNMPvarbind].oid.val, if 'sysObjectID' not in self.oid_key: print '-', response[SNMPvarbind].value.val else: print '-', response[SNMPvarbind].value.__oidname__() self.handle_close()
def datagramReceived(self, data, host_and_port): try: snmp = SNMP(data) community = snmp.community.val requests = [x.oid.val for x in snmp.PDU.varbindlist] logdata = {'REQUESTS': requests, 'COMMUNITY_STRING': community} self.transport.getPeer = lambda: IPv4Address( 'UDP', host_and_port[0], host_and_port[1]) self.factory.log(logdata=logdata, transport=self.transport) except Exception as e: print(e) pass
def bulk(self, oid, num=10): tree = [] p = SNMP(community=self.community, version=self.version, PDU=SNMPbulk(max_repetitions=num, varbindlist=[SNMPvarbind(oid=ASN1_OID(oid))])) r = self._sr(p).PDU.varbindlist for v in r: tree.append({ 'oid': v.oid.val, 'type': type(v.value), 'value': v.value.val }) return tree
def main(self, *args): """ Main function """ if not self.ip: try: self.ip = gethostbyname(self.host) except Exception: raise InvalidTarget('Host not found.') packet = IP(dst=self.ip, src=SANDBOX_IP) / UDP( dport=self.SNMP_PORT, sport=self.SNMP_PORT) / SNMP( community='public', PDU=SNMPget(varbindlist=[ SNMPvarbind(oid=ASN1_OID(self.OID_SYSTEM_DESCRIPTION)) ])) self._write_result( 'Trying to read the system description through SNMP...') try: data = sr1(packet, timeout=self.SNMP_TIMEOUT) if not data or ICMP in data: self._write_result('No response received.') return value = data[SNMPvarbind].value.val if not value: value = 'no such object' self._write_result('Received response: %s' % str(value)) except Exception as e: self._write_result(str(e))
def send_touch(self, packet = None, exsock = None, attempts = 1): ''' ''' print '[+] probing target via snmp' if not packet: packet = self.generate_touch() try: if not exsock: print "[+] Connecting to %s:%s" % (self.params.dst['ip'], self.params.dst['port']) exsock = self.create_socket() while attempts: attempts -= 1 self.log.packet('sending touch packet', str(packet)) exsock.send(packet) self.log('sent touch packet') try: while 1: print '*'*40 self.log('receiving touch response') response = exsock.receive(2048) self.log.packet('received touch response', response) if self.params.verbose > 1: print '[+] Data returned' hexdump(response) SNMP(response).show() print '[+] End of Data returned\n' if self.post_touch(response): return True else: print response print '*'*40 print 'listening for responses - Ctrl-C to exit' except KeyboardInterrupt: return False except socket.timeout: if not attempts: return False print 'Retrying...' except Exception,message: print '\nExiting ...' print 'Debug info ','='*40 traceback.print_exc() print 'Debug info ','='*40 raise RuntimeError,message
def snmpwalk(self): start_oid = self.oid #print start_oid print try: t = table(self.oid_key) while 1: #print oid s = socket(AF_INET, SOCK_DGRAM) s.connect((self.dst, 161)) snmp = SNMP( community=self.comm, PDU=SNMPnext(varbindlist=[SNMPvarbind(oid=self.oid)])) buf = str(snmp) while buf: bytes = s.send(buf) buf = buf[bytes:] response = SNMP(s.recv(4096)) if self.debug: logging.debug(response.show()) logging.debug(hexdump(response)) self.oid = response[SNMPvarbind].oid.val if start_oid not in self.oid: break print self.dst, '[', self.comm, ']', if self.translate: # print response[SNMPvarbind].oid.val.replace(start_oid, self.oid_key), print response[SNMPvarbind].oid.__oidname__(), else: print response[SNMPvarbind].oid.val, print '-', # print type(response[SNMPvarbind].value.val), field = response[SNMPvarbind].oid.__oidname__() #31.223.255.13 [ NordEx7 ] ospfAreaStatus.0.0.0.0 - 1 # ^^^^^^^^^^^^^^ ^^^^^^^ ^ # v k res v = t.add_fields_name(field) k = t.add_keys_name(field) res = normalize_snmp_result(v, response[SNMPvarbind].value.val) t.add_values(k, v, res) print res if ICMP in response: print repr(response) break if response is None: print "No answers" break #print "%-40s: %r" % (r[SNMPvarbind].oid.val,r[SNMPvarbind].value.val) #print oid #print '===============' except KeyboardInterrupt: pass # print t.show_fields_list() # ['ospfSpfRuns', 'ospfAsBdrRtrCount', 'ospfAreaId', 'ospfAreaLsaCount', 'ospfAuthType', 'ospfAreaStatus', 'ospfAreaLsaCksumSum', 'ospfImportAsExtern', 'ospfAreaSummary', 'ospfAreaBdrRtrCount'] # print t.show_keys_list() # ['0.0.0.0'] print t.show_values_json() # { # "0.0.0.0": { # "ospfAreaBdrRtrCount": 2, # "ospfAreaId": "0.0.0.0", # "ospfAreaLsaCksumSum": 13869839, # "ospfAreaLsaCount": 437, # "ospfAreaStatus": 1, # "ospfAreaSummary": 2, # "ospfAsBdrRtrCount": 1, # "ospfAuthType": 0, # "ospfImportAsExtern": 1, # "ospfSpfRuns": 30842 # } # } t.populate_sql_table() # INFO:root:loading row to sql...DONE # t.print_sql_table('list') # [ ('ospfSpfRuns', 'ospfAsBdrRtrCount', 'ospfAreaId', 'ospfAreaLsaCount', '-', 'ospfAuthType', 'ospfAreaStatus', 'ospfAreaLsaCksumSum', 'ospfImportAsExtern', 'ospfAreaSummary', 'ospfAreaBdrRtrCount'), # (u'30842', u'1', u'0.0.0.0', u'437', u'0.0.0.0', u'0', u'1', u'13869839', u'1', u'2', u'2') ] t.print_sql_table('texttable') # +------------+------------+------------+------------+------------+------------+------------+------------+------------+------------+------------+ # | ospfSpfRun | ospfAsBdrR | ospfAreaId | ospfAreaLs | - | ospfAuthTy | ospfAreaSt | ospfAreaLs | ospfImport | ospfAreaSu | ospfAreaBd | # | s | trCount | | aCount | | pe | atus | aCksumSum | AsExtern | mmary | rRtrCount | # +============+============+============+============+============+============+============+============+============+============+============+ # | 30842 | 1 | 0.0.0.0 | 437 | 0.0.0.0 | 0 | 1 | 13869839 | 1 | 2 | 2 | # +------------+------------+------------+------------+------------+------------+------------+------------+------------+------------+------------+ # t.print_sql_table('json') # [ # { # "0.0.0.0": { # "ospfAreaBdrRtrCount": "2", # "ospfAreaId": "0.0.0.0", # "ospfAreaLsaCksumSum": "13869839", # "ospfAreaLsaCount": "437", # "ospfAreaStatus": "1", # "ospfAreaSummary": "2", # "ospfAsBdrRtrCount": "1", # "ospfAuthType": "0", # "ospfImportAsExtern": "1", # "ospfSpfRuns": "30842" # } # } # ] print '==============='
def get(self, oid): p = SNMP(community=self.community, version=self.version, PDU=SNMPget(varbindlist=[SNMPvarbind(oid=ASN1_OID(oid))])) r = self._sr(p).PDU.varbindlist[0] return {'oid': r.oid.val, 'type': type(r.value), 'value': r.value.val}