Skip to main content

Attacking OSPF - route injection

LOKI and author's Black Hat presentation can be downloaded here: 

Falsifying routing information can have disastrous consequences to network stability. For example an attacker could reroute traffic through a monitoring station and capture traffic for later analysis. An attacker could also reroute traffic to a black hole or reroute a 10 Gig transit link traffic towards a 1 GB link causing a Denial of Service (DoS) condition. 

Both network topology and scenario presented in this post are extremely simplistic but should be sufficient to present potential implications.

Our topology:

R1's routing table looks as follows:

R1#show ip route
C is directly connected, FastEthernet1/0 is subnetted, 1 subnets
C is directly connected, FastEthernet0/0
O [110/2] via, 00:00:01, FastEthernet0/0 is subnetted, 1 subnets
C is directly connected, Loopback0
O [110/3] via, 00:00:01, FastEthernet0/0

Its OSPF neighbor table:

R1#show ip ospf neighbor

Neighbor ID     Pri   State                  Dead Time   Address         Interface       1    FULL/BDR        00:00:35      FastEthernet0/0

To launch LOKI in its default directory -  #python /usr/bin/ 

Once we click run, LOKI will by default capture all control plane protocols it supports. In the screenshot below we can see that LOKI captured an OSPF Hello packet from its adjacent router. From the captured packet we can see the following:
  • IP address the hello was sent from is
  • router ID is (by default highest loopback interface address)
  • OSPF Area is 1
  • OSPF authentication is not enabled

From here we can craft our own OSPF packets. 

Firstly we'll send an empty Hello packet and see what happens. To do so we set "area" to "1" and Authentication type to "AUTH_NONE". We start sending packets by clicking "Hello".

In R1's console we confirm that adjacency was set up:

*Mar  1 04:42:46.654: %OSPF-5-ADJCHG: Process 1, Nbr on FastEthernet1/0 from LOADING to FULL, Loading Done

R1#show ip ospf neighbor

Neighbor ID     Pri   State                 Dead Time   Address         Interface              1   FULL/BDR        00:00:38          FastEthernet1/0       1   FULL/BDR        00:00:35      FastEthernet0/0

To get even more details we enable debugging. 

R1#debug ip ospf events

*Mar  1 00:58:49.691: OSPF: Rcv hello from area 1 from FastEthernet1/0
*Mar  1 00:58:49.691: OSPF: 2 Way Communication to on FastEthernet1/0, state 2WAY
*Mar  1 00:58:49.695: OSPF: Neighbor change Event on interface FastEthernet1/0
*Mar  1 00:58:49.695: OSPF: DR/BDR election on FastEthernet1/0
*Mar  1 00:58:49.695: OSPF: Elect BDR
*Mar  1 00:58:49.695: OSPF: Elect DR
*Mar  1 00:58:49.695:        DR: (Id)   BDR: (Id)
*Mar  1 00:58:49.699: OSPF: Send DBD to on FastEthernet1/0 seq 0x24F2 opt 0x52 flag 0x7 len 32
*Mar  1 00:58:49.699: OSPF: Neighbor change Event on interface FastEthernet1/0
*Mar  1 00:58:49.699: OSPF: DR/BDR election on FastEthernet1/0
*Mar  1 00:58:49.699: OSPF: Elect BDR
*Mar  1 00:58:49.703: OSPF: Elect DR
*Mar  1 00:58:49.703:        DR: (Id)   BDR: (Id)
*Mar  1 00:58:49.703: OSPF: Send immediate hello to nbr, src address, on FastEthernet1/0
*Mar  1 00:58:49.703: OSPF: Send hello to area 1 on FastEthernet1/0 from
*Mar  1 00:58:49.707: OSPF: End of hello processing 

At this point we've set ourselves up as an OSPF neighbor and successfully created an adjacency.

Now we'll inject a false route to network

Now R1 believes that it can get to network via F0/0 (real route) and F1/0 (bogus route). Both paths have the same cost.

R1#show ip route

C is directly connected, FastEthernet1/0 is subnetted, 1 subnets
C is directly connected, FastEthernet0/0
O [110/2] via, 00:00:00, FastEthernet0/0
                    [110/2] via, 00:00:00, FastEthernet1/0 is subnetted, 1 subnets
C is directly connected, Loopback0192.
O [110/3] via, 00:00:00, FastEthernet0/0

We didn't do any actual damage in this example, but this type of attack in an enterprise network could cause serious disruptions. 

This attack can be easily defeated in a number of ways. We can use OSPF authentication, passive interfaces, access control lists or route filtering. Actually all of the above should be used together. More on defenses some other time.  

LOKI supports both clear text (though I couldn't get it to work) and MD5 authentication for OSPF. Clear text is not much of security as the key is sent in clear text so it can be sniffed.  In 

LOKI detects type of authentication used and let's us attempt to crack it. We can feed it a word list or use brute force. LOKI cracked my key of "test" (not much of a key) on a slow VM in a couple of seconds. 


Popular posts from this blog

x.509 Certificates - Critical vs non-critical extensions

Extensions are used to associate additional information with the user or the key.  Each certificate extension has three attributes - extnID, critical, extnValue extnID - Extension ID - an OID that specifies the format and definitions of the extension critical - Critical flag - Boolean value extnValue - Extension value  Criticality flag specifies whether the information in an extension is important. If an application doesn't recognize the extension marked as critical, the certificate cannot be accepted. If an extension is not marked as critical (critical value False) it can be ignored by an application. In Windows, critical extensions are marked with a yellow exclamation mark,  View certificate extensions using OpenSSL: # openssl x509 -inform pem -in cert.pem -text -noout (output abbreviated)         X509v3 extensions:             X509v3 Key Usage: critical                 Digital Signature, Key Encipherment             X509v3 Subject Key Identifier

Count number of lines - 'findstr'

How do I count number of lines in a command output? findstr /r/n "^" | find /c ":" Above commands will display number of lines output by whatever command (well, nearly whatever) you specify in the front.  For example:  C:\>ping localhost | findstr /r/n "^" | find /c ":" FINDSTR: // ignored 12 This comes handy if you want to find out how many OUs you have in Active Directory: dsquery ou  -limit 0 | findstr /r/n "^" | find /c ":" How many user accounts there are: dsquery user -limit 0 | findstr /r/n "^" | find /c ":" Computers: dsquery computer -limit | findstr /r/n "^" | find /c ":"

Cisco ASA Certificate Revocation Checking

ASA supports status verification using CRLs and OCSP. CRL can be retrieved using HTTP, LDAP or SCEP. Revocation checking using CRL: Over HTTP: ciscoasa(config)# crypto ca trustpoint ASDM_TrustPoint2 ciscoasa(config-ca-trustpoint)# revocation-check crl ciscoasa(config-ca-crl)# protocol http By default ASA will use address listed in CDP extension of the certificate that is being validated.  To override default behaviour we need to add the following in the CRL configuration context. ciscoasa(config-ca-crl)# policy static ciscoasa(config-ca-crl)# url 1 Over LDAP: Certificate I'm using for this lab, doesn't have LDAP address in its CDP extension. Therefore I'm using "policy static"  to specify LDAP URL where CRL can be retrieved.  ciscoasa(config)# crypto ca trustpoint ASDM_TrustPoint2 ciscoasa(config-ca-trustpoint)# revocation-check crl ciscoasa(config-ca-trustpoint)# crl configure ciscoasa