IOS IPS


In this article i will try and setup a very simple example using Cisco IOS IPS (Intrusion Prevention System).

As before, a simple topology consisting of 3 routers will suffice.

They are configured as follows:

Topology for IPS example.

R1 will act as our source host. From this machine i will simulate an attacker trying to gain access to R3 through R2. This means R2 will be the device where we will be configuring the IPS functionality.

I have reachability using RIPv2:

R1:
R1#sh ip route rip
R    192.168.23.0/24 [120/1] via 192.168.12.2, 00:00:12, FastEthernet0/0

R3:

R3#sh ip route rip
R    192.168.12.0/24 [120/1] via 192.168.23.2, 00:00:25, FastEthernet0/0

R3 has the built-in webserver enabled:

R3#sh ip http server status
HTTP server status: Enabled
HTTP server port: 80
.....

Before we begin, lets verify reachability:

R1:

R1#ping 192.168.23.3
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 192.168.23.3, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 1/2/4 ms
R1#telnet 192.168.23.3 80
Trying 192.168.23.3, 80 ... Open
get /
HTTP/1.1 400 Bad Request
Date: Wed, 25 May 2011 16:52:14 GMT
Server: cisco-IOS
Connection: close
Accept-Ranges: none
400 Bad Request

So we have verified that we can access the webserver on R3.

Now lets get to the gritty details surround the IPS.

To understand the IPS feature, one has to understand that signature categories contain categories of things to “scan” and how to do it, while signature definitions contain information on what to do.

First off, you need Ciscos definition files which you can obtain from Cisco.

R2#sh flash:
-#- --length-- -----date/time------ path
1     40558800 Mar 01 2011 19:12:54 c1841-adventerprisek9-mz.124-24.T4.bin
2     12757876 May 22 2011 11:21:26 IOS-S556-CLI.pkg

Right now, the IOS-S556-CLI.pkg is the newest one available.

Also, in order to verify the signature file, you will need Ciscos public key. If you dont have this, the router will not accept the signature file at all.

In order to do that, use the following code snippet (available through Cisco documentation):

crypto key pubkey-chain rsa
named-key realm-cisco.pub signature
key-string
30820122 300D0609 2A864886 F70D0101 01050003 82010F00 3082010A 02820101
00C19E93 A8AF124A D6CC7A24 5097A975 206BE3A2 06FBA13F 6F12CB5B 4E441F16
17E630D5 C02AC252 912BE27F 37FDD9C8 11FC7AF7 DCDD81D9 43CDABC3 6007D128
B199ABCB D34ED0F9 085FADC1 359C189E F30AF10A C0EFB624 7E0764BF 3E53053E
5B2146A9 D7A5EDE3 0298AF03 DED7A5B8 9479039D 20F30663 9AC64B93 C0112A35
FE3F0C87 89BCB7BB 994AE74C FA9E481D F65875D6 85EAF974 6D9CC8E3 F0B08B85
50437722 FFBE85B9 5E4189FF CC189CB9 69C46F9C A84DFBA5 7A0AF99E AD768C36
006CF498 079F88F8 A3B3FB1F 9FB7B3CB 5539E1D1 9693CCBB 551F78D2 892356AE
2F56D826 8918EF3C 80CA4F4D 87BFCA3B BFF668E9 689782A5 CF31CB6E B4B094D3
F3020301 0001
quit

Next up, lets define an IPS rule:

R2(config)#ip ips name MYIPS

Lets create a directory for the IPS information on flash:

R2#mkdir flash:/IPS
Create directory filename [IPS]?
Created dir flash:/IPS

Now we need to tell IPS to use this directory for configuration information:

R2(config)#ip ips config location flash:/IPS/

I also want to receive IPS events as syslog messages:

R2(config)#ip ips notify log

Now lets enable/disable some of the signature categories:

R2(config)#
R2(config)#ip ips signature-category
R2(config-ips-category)#category all
R2(config-ips-category-action)#retired true
R2(config-ips-category-action)#exit
R2(config-ips-category)#ca
R2(config-ips-category)#category ios_ips
R2(config-ips-category-action)#retired false
R2(config-ips-category-action)#exit
R2(config-ips-category)#exit
Do you want to accept these changes? [confirm]

Here i only enable the basic ios_ips signatures. I “retire” everything else

Lets apply this to an interface, before we can proceed:

R2(config)#int f0/1
R2(config-if)#ip ips MYIPS out

Next up i want to copy my signature file into memory, and i do this using the following command:

R2#copy flash:/IOS-S556-CLI.pkg idconf
*May 26 09:08:13.535: %IPS-6-ENGINE_BUILDS_STARTED:  09:08:13 UTC May 26 2011
*May 26 09:08:13.543: %IPS-6-ENGINE_BUILDING: multi-string - 199 signatures - 1 of 13 engines
*May 26 09:08:14.299: %IPS-6-ENGINE_READY: multi-string - build time 756 ms - packets for this engine will be scanned
*May 26 09:08:14.327: %IPS-6-ENGINE_BUILDING: service-http - 887 signatures - 2 of 13 engines
*May 26 09:08:36.931: %IPS-6-ENGINE_READY: service-http - build time 22604 ms - packets for this engine will be scanned
*May 26 09:08:37.007: %IPS-6-ENGINE_BUILDING: string-tcp - 2372 signatures - 3 of 13 engines....

Now, this is what takes quite a while, so grab a coffee while you wait for your router to finish.

In the meantime we can verify the IPS using (using telnet from R1 for example):

R2#sh ip ips config
Signature files are currently being loaded and SMEs are being built.
...

As we can see, the signature files are still not done loading.

Eventually it will finish, and our verification should show something like this:

R2#sh ip ips config
IPS Signature File Configuration Status
 Configured Config Locations: flash:/IPS/
 Last signature default load time: 09:10:30 UTC May 26 2011
 Last signature delta load time: -none-
 Last event action (SEAP) load time: -none-
 General SEAP Config:
 Global Deny Timeout: 3600 seconds
 Global Overrides Status: Enabled
 Global Filters Status: Enabled
IPS Auto Update is not currently configured
IPS Syslog and SDEE Notification Status
 Event notification through syslog is enabled
 Event notification through SDEE is disabled
IPS Signature Status
 Total Active Signatures: 583
 Total Inactive Signatures: 3632
IPS Packet Scanning and Interface Status
 IPS Rule Configuration
 IPS name MYIPS
 IPS fail closed is disabled
 IPS deny-action ips-interface is false
 Interface Configuration
 Interface FastEthernet0/1
 Inbound IPS rule is not set
 Outgoing IPS rule is MYIPS
IPS Category CLI Configuration:
 Category all:
 Retire: True
 Category ios_ips:
 Retire: False
 

Again, lets try our verification from R1 to R3:

R1#telnet 192.168.23.3 80
Trying 192.168.23.3, 80 ... Open
get /
HTTP/1.1 400 Bad Request
Date: Thu, 26 May 2011 09:35:47 GMT
Server: cisco-IOS
Connection: close
Accept-Ranges: none
400 Bad Request
[Connection to 192.168.23.3 closed by foreign host]

We are still going through. But now lets attempt to invoke the IPS on R2:

R1#telnet 192.168.23.3 80
Trying 192.168.23.3, 80 ... Open
get /system32/cmd.exe
HTTP/1.1 400 Bad Request
Date: Thu, 26 May 2011 09:36:19 GMT
Server: cisco-IOS
Connection: close
Accept-Ranges: none
400 Bad Request
[Connection to 192.168.23.3 closed by foreign host]

On R2, we now get the following log message:

R2(config)#
*May 26 09:25:47.663: %IPS-4-SIGNATURE: Sig:5081 Subsig:0 Sev:100 WWW WinNT cmd.exe Access [192.168.12.1:18650 -> 192.168.23.3:80] VRF:NONE RiskRating:100

This means that our IPS is working.

To tweak the behavior of the IPS, we can go into the signature with an ID of 5081 and modify it:

R2(config)#ip ips signature-definition
R2(config-sigdef)#signature 5081
R2(config-sigdef-sig)#engine
R2(config-sigdef-sig-engine)#event-action ?
 deny-attacker-inline    Deny Attacker
 deny-connection-inline  Deny Connection
 deny-packet-inline      Deny Packet
 produce-alert           Produce Alert
 reset-tcp-connection    Reset TCP Connection
 <cr>

We can now tell it to reset the entire TCP connection:

R2(config-sigdef-sig-engine)#event-action reset-tcp-connection produce-alert
R2(config-sigdef-sig-engine)#exit
R2(config-sigdef-sig)#exit
R2(config-sigdef)#exit
Do you want to accept these changes? [confirm]

After this, the compilation of the signature begins once again:

*May 26 09:28:55.831: %IPS-6-ENGINE_BUILDS_STARTED:  09:28:55 UTC May 26 2011
*May 26 09:28:56.327: %IPS-6-ENGINE_BUILDING: service-http - 887 signatures - 1 of 13 engines
*May 26 09:28:56.943: %IPS-6-ENGINE_READY: service-http - build time 616 ms - packets for this engine will be scanned
*May 26 09:28:57.511: %IPS-6-ALL_ENGINE_BUILDS_COMPLETE: elapsed time 1680 ms

Fortunally, it is only the changes that will be recompiled:

R2(config)#do sh ip ips confi
IPS Signature File Configuration Status
 Configured Config Locations: flash:/IPS/
 Last signature default load time: 09:10:30 UTC May 26 2011
 Last signature delta load time: 09:28:57 UTC May 26 2011
 Last event action (SEAP) load time: -none-
 General SEAP Config:
 Global Deny Timeout: 3600 seconds
 Global Overrides Status: Enabled
 Global Filters Status: Enabled
IPS Auto Update is not currently configured
IPS Syslog and SDEE Notification Status
 Event notification through syslog is enabled
 Event notification through SDEE is disabled
IPS Signature Status
 Total Active Signatures: 583
 Total Inactive Signatures: 3632
IPS Packet Scanning and Interface Status
 IPS Rule Configuration
 IPS name MYIPS
 IPS fail closed is disabled
 IPS deny-action ips-interface is false
 Interface Configuration
 Interface FastEthernet0/1
 Inbound IPS rule is not set
 Outgoing IPS rule is MYIPS
IPS Category CLI Configuration:
 Category all:
 Retire: True
 Category ios_ips:
 Retire: False
 

Even though that in our testing resetting the TCP connection doesnt do much since we are immediately terminated anyways, this behavior will shut down the entire TCP connection and all state information regarding the “attack”, which would be very helpful.

R1#telnet 192.168.23.3 80
Trying 192.168.23.3, 80 ... Open
get /system32/cmd.exe
[Connection to 192.168.23.3 closed by foreign host]

We can observe that we are immediately disconnected from the http server, and since we also used the “produce-alert” keyword, we also get a log message on R2, just as we did before the change:

*May 26 09:32:46.927: %IPS-4-SIGNATURE: Sig:5081 Subsig:0 Sev:100 WWW WinNT cmd.exe Access [192.168.12.1:63490 -> 192.168.23.3:80] VRF:NONE RiskRating:100

Now all of this is just a very very small portion of what can be done with the IPS feature, and I am in no way a security guy, but I do believe this is an under-utilized feature, which is a shame since it is “real” security in my eyes.

I hope it has been useful. Any comments will be appreciated.