Cisco has provided a method of determining if your router has the SYNful Knock router implant.
=========================================================
http://blogs.cisco.com/security/offline-analysis-of-ios-image-integrity
Offline Analysis of IOS Image Integrity
Forensic analysis of IOS images can be a tricky science, due in part to the diversity in IOS image versions and branches. Between IOS 11 and IOS 12.4, over five thousand different images were built, a quarter of which belong to the 12.2 train. Some IOS trains are in more widespread use than others, just as some hardware platforms are more popular than others, but even when narrowing down by feature-set or hardware, there is a large diversity of images. There are however, some steps that can be taken, both while the IOS device is running, as well as offline, that can help determine the integrity of an IOS image.
The first method that can be used to verify the integrity of an IOS image is to use the verify command, which is built into IOS; the second way is by conducting off-line analysis of an IOS core dump. The first method is covered in detail in the Cisco IOS Image Verification whitepaper. It is included below for completeness.
router#verify /ios disk1:s72033-ipservicesk9_wan-mz.122-18.SXF15.bin %Filesystem does not support verify operations Verifying file integrity of disk1:s72033-ipservicesk9_wan-mz.122-18.SXF15.bin... .................................................................. .................................................................. ..........Done! Embedded Hash MD5 : 91AEA61961CB042A776860D5F190DF12 Computed Hash MD5 : 91AEA61961CB042A776860D5F190DF12 CCO Hash MD5 : 709685E496E1B27091DE984DD7D78751Signature Verified router# |
A description of each of these hashes is available in the Cisco IOS Image Verification whitepaper.
•Embedded Hash: MD5 hash stored by Cisco in a section of the Cisco IOS image file during the image build process; used to verify section integrity for the Cisco IOS software image file. This MD5 hash value is calculated for certain sections of the Cisco IOS image file.
•Computed Hash: MD5 hash that the “Image Verification” feature calculates for certain sections of the Cisco IOS software image file when the verify command is executed. This value should be the same as the Embedded Hash to verify section integrity of the Cisco IOS image file. If this value is not equal to the Embedded Hash, the Cisco IOS image file may be corrupted or intentionally altered.
•CCO Hash: MD5 hash for the entire Cisco IOS image file. This hash is computed by the verify command and is not stored in the Cisco IOS software image.
The Embedded and Computed hash values must match. The CCO hash must match the MD5 hash value provided for this image on CCO. It is also possible to verify the has provided for the image on CCO against the image stored on disk, by providing the MD5 hash as argument.
router#verify /md5 disk1:s72033-ipservicesk9_wan-mz.122-18.SXF15.bin 709685e496e1b27091de984dd7d78751 ................................................................... ................................................................... ................................................................... .........Done! Verified (disk1:s72033-ipservicesk9_wan-mz.122-18.SXF15.bin) = 709685e496e1b27091de984dd7d78751 |
router(config)#exception core-file ROUTERNAME timestamp compress router(config)#exception dump 10.0.0.1 router(config)#exception protocol ftp router(config)#ip ftp username ftpuser router(config)#ip ftp password ftppass router(config)#exception region-size 65536 router(config)#do wr me |
An organization’s specific policy may require that the memory contents should not be compressed prior to being sent across the wire. If this is the case, simply remove the compress keyword from the first command listed above. However, making use of the compress greatly speeds-up the transfer.
Please note that generating a core file will have an impact on a production network; it should only be done in a controlled environment.
router#write core Remote host [10.0.0.1]? Base name of core files to write [RTR]? Writing RTRiomem_20081006-195646.Z !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ..output omitted.. |
Once the output is finished writing to the destination (FTP server in this case), there will be three files, which include the hostname (RTR in this case) and the datestamp:
-rw-r--r-- 28002867 Oct 7 11:00 RTRiomem_20081006-195646.Z -rw-r--r-- 45724430 Oct 7 11:02 RTR_20081006-195646.Z -rw-r--r-- 1862436 Oct 7 11:03 RTRmore |
All three files are compressed with Unix compress, including the last file which doesn’t have a .Z appended:
$ file RTRmore RTRmore: compress'd data 12 bits $ file *Z RTR_20081006-195646.Z: compress'd data 12 bits RTRiomem_20081006-195646.Z: compress'd data 12 bits |
In order to verify the integrity of the image running on the router, we can extract the text segment from the memory dump, run a cryptographic hash on it, and compare this hash value to that of a hash of the text segment of an image taken in a controlled environment. This implies trust in the memory-dumping process, which may itself be compromised; it is however an initial step.The text segment should be marked RO (read-only) as it contains the instructions to be executed, and these should not be overwritten.
To determine which file corresponds to each portion of the memory output in the show region command, we may look at the core files generated by the write core command, and also compare the file sizes and names with the output of show region:
router# sh region Region Manager: Start End Size(b) Class Media Name 0x08000000 0x0BFFFFFF 67108864 Iomem R/W iomem 0x40000000 0x4BFFFFFF 201326592 Local R/W main 0x40101040 0x42DCFFFF 46985152 IText R/O main:text 0x42DDA370 0x430F534F 3256288 IData R/W main:data 0x430F5350 0x44B156EF 27394976 IBss R/W main:bss 0x44B156F0 0x4BFFFFFF 122595600 Local R/W main:heap 0x50000000 0x5FFF7FFF 268402688 Local R/W more heap 0x80000000 0x8BFFFFFF 201326592 Local R/W main:(main_k0) 0xA0000000 0xABFFFFFF 201326592 Local R/W main:(main_k1) router# |
In this example, the file RTR_20081006-195646 corresponds to main memory.
From this output, we know the text segment resides between address 0x40101040 and 0x42DDA370, and is 46985152 bytes in size. Since show region outputs the virtual memory addresses, we need to look at the translation lookaside buffer (TLB) and map to the address in physical memory. The TLB contains the virtual memory to physical memory mappings.
To obtain the TLB, we may issue the show platform tlb command:
router#sh platform tlb Mistral revision 5 TLB entries : 45 Virt Address range Phy Address range Attributes 0x10000000:0x1001FFFF 0x010000000:0x01001FFFF CacheMode=2, RW, Valid 0x10020000:0x1003FFFF 0x010020000:0x01003FFFF CacheMode=2, RW, Valid 0x10040000:0x1005FFFF 0x010040000:0x01005FFFF CacheMode=2, RW, Valid 0x10060000:0x1007FFFF 0x010060000:0x01007FFFF CacheMode=2, RW, Valid 0x10080000:0x10087FFF 0x010080000:0x010087FFF CacheMode=2, RW, Valid 0x10088000:0x1008FFFF 0x010088000:0x01008FFFF CacheMode=2, RW, Valid 0x18000000:0x1801FFFF 0x010000000:0x01001FFFF CacheMode=0, RW, Valid 0x19000000:0x1901FFFF 0x010000000:0x01001FFFF CacheMode=7, RW, Valid 0x1E000000:0x1E1FFFFF 0x01E000000:0x01E1FFFFF CacheMode=2, RW, Valid 0x1E880000:0x1E899FFF 0x01E880000:0x01E899FFF CacheMode=2, RW, Valid 0x1FC00000:0x1FC7FFFF 0x01FC00000:0x01FC7FFFF CacheMode=2, RO, Valid 0x30000000:0x3001FFFF 0x070000000:0x07001FFFF CacheMode=2, RW, Valid 0x40000000:0x41FFFFFF 0x000000000:0x001FFFFFF CacheMode=3, RO, Valid 0x42000000:0x427FFFFF 0x002000000:0x0027FFFFF CacheMode=3, RO, Valid 0x42800000:0x429FFFFF 0x002800000:0x0029FFFFF CacheMode=3, RO, Valid 0x42A00000:0x42BFFFFF 0x002A00000:0x002BFFFFF CacheMode=3, RO, Valid 0x42C00000:0x42C7FFFF 0x002C00000:0x002C7FFFF CacheMode=3, RO, Valid 0x42C80000:0x42CFFFFF 0x002C80000:0x002CFFFFF CacheMode=3, RO, Valid 0x42D00000:0x42D7FFFF 0x002D00000:0x002D7FFFF CacheMode=3, RO, Valid 0x42D80000:0x42D9FFFF 0x002D80000:0x002D9FFFF CacheMode=3, RO, Valid 0x42DA0000:0x42DBFFFF 0x002DA0000:0x002DBFFFF CacheMode=3, RO, Valid 0x42DC0000:0x42DC7FFF 0x002DC0000:0x002DC7FFF CacheMode=3, RO, Valid 0x42DC8000:0x42DCFFFF 0x002DC8000:0x002DCFFFF CacheMode=3, RO, Valid 0x42DD0000:0x42DD7FFF 0x002DD0000:0x002DD7FFF CacheMode=3, RW, Valid 0x42DD8000:0x42DDFFFF 0x002DD8000:0x002DDFFFF CacheMode=3, RW, Valid 0x42DE0000:0x42DFFFFF 0x002DE0000:0x002DFFFFF CacheMode=3, RW, Valid 0x42E00000:0x42FFFFFF 0x002E00000:0x002FFFFFF CacheMode=3, RW, Valid 0x43000000:0x437FFFFF 0x003000000:0x0037FFFFF CacheMode=3, RW, Valid 0x43800000:0x43FFFFFF 0x003800000:0x003FFFFFF CacheMode=3, RW, Valid 0x44000000:0x45FFFFFF 0x004000000:0x005FFFFFF CacheMode=3, RW, Valid 0x46000000:0x47FFFFFF 0x006000000:0x007FFFFFF CacheMode=3, RW, Valid 0x48000000:0x49FFFFFF 0x008000000:0x009FFFFFF CacheMode=3, RW, Valid 0x4A000000:0x4BFFFFFF 0x00A000000:0x00BFFFFFF CacheMode=3, RW, Valid 0x4C000000:0x4DFFFFFF 0x00C000000:0x00DFFFFFF CacheMode=3, RW, Valid 0x4E000000:0x4FFFFFFF 0x00E000000:0x00FFFFFFF CacheMode=3, RW, Valid 0x08000000:0x09FFFFFF 0x00C000000:0x00DFFFFFF CacheMode=2, RW, Valid 0x0A000000:0x0BFFFFFF 0x00E000000:0x00FFFFFFF CacheMode=2, RW, Valid 0x50000000:0x51FFFFFF 0x080000000:0x081FFFFFF CacheMode=3, RW, Valid 0x52000000:0x53FFFFFF 0x082000000:0x083FFFFFF CacheMode=3, RW, Valid 0x54000000:0x55FFFFFF 0x084000000:0x085FFFFFF CacheMode=3, RW, Valid 0x56000000:0x57FFFFFF 0x086000000:0x087FFFFFF CacheMode=3, RW, Valid 0x58000000:0x59FFFFFF 0x088000000:0x089FFFFFF CacheMode=3, RW, Valid 0x5A000000:0x5BFFFFFF 0x08A000000:0x08BFFFFFF CacheMode=3, RW, Valid 0x5C000000:0x5DFFFFFF 0x08C000000:0x08DFFFFFF CacheMode=3, RW, Valid 0x5E000000:0x5FFFFFFF 0x08E000000:0x08FFFFFFF CacheMode=3, RW, Valid router# |
From the TLB we can see that the translation simply requires changing the 0x4 by 0x0 in calculations. Different tools can be used to extract the text segment from the memory dump, dd is used in this example.
In order to eliminate block errors, we can specify a block size of 1, skip to the beginning of the text segment and provide the value listed under Size(b) in the output to show region as count:
dd if=RTR_20081006-195646 bs=1 skip=1052736 count=46985152 of=RTR_text_segment |
We can compare the content present at the beginning and end of the RTR_text_segment with that at the beginning and end of the text segment:
$ xxd RTR_20081006-195646 | grep -i 0101040\: 0101040: 27bd ffe0 afb0 0010 0080 8021 afb1 0014 '..........!.... $ xxd RTR_main_text | head -1 0000000: 27bd ffe0 afb0 0010 0080 8021 afb1 0014 '..........!.... $ xxd RTR_20081006-195646 | grep -i 2dcfff0\: 2dcfff0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ $ xxd RTR_main_text | tail -1 2ccefb0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ $ |
A cryptographic hash can now be computed on the text segment, to compare with the text segment of a known-good IOS copy.
$ md5sum RTR_main_text 441ec282be815e24c74ac917f3a42fec RTR_main_text $ |
Perimeter Defense
When designing a layered defense no component exists in a vacuum: verifying the integrity of an IOS image is only one component, configuring AAA and logging on IOS devices, and enabling perimeter defense to record connections destined to router interface IPs, are other essential components that facilitate subsequent forensic investigations and post-mortem analyses.
Tags: Cisco IOS software, IOS, security