Practical routing attacks (3/3): BGP

Introduction

This is the last article about practical routing attacks, after the one against RIPv2 and the one having OSPF as target. Today, we are going to see how an attacker could leverage the BGP protocol on his or her own advantage.

Based on the fact that this topic has been widely covered on great articles online, this one will be nothing more than an introduction; I will let some references in the last section.

Routing theory: precedence

Whenever a router needs to decide where a specific packet has to be forwarded, it has to evaluate its routing table, containing the association between subnets and the gateways that have to be used to reach them.

While in theory subnets never overlap, in practice this is not always the case.

Let’s imagine that we are a router with the following routing table:

  • current subnet is 192.168.254.0/24
  • subnet A is 192.168.0.0/24, reachable through GW-A 192.168.254.100
  • subnet B is 192.168.1.0/24, reachable through GW-B 192.168.254.101
  • subnet C is 192.168.2.0/24, reachable through GW-C 192.168.254.102

What happen if a new routing entry is added, defining subnet B1 as 192.168.1.128/25, with GW-B1 192.168.254.200? Basically, the more specific a subnet is, the higher its priority when a packet has to be routed.

Before inserting the entry B1, every host between 192.168.1.1 and 192.168.1.254 is reachable through GW-B; after inserting the more specific route, every host between 192.168.1.1 and 192.168.1.127 is still reachable through GW-B, while every host between 192.168.1.129 and 192.168.1.254 is now assumed to be reachable through GW-B1.

This is not a big deal, unless someone could inject arbitrary, more specific routes inside routers around the world. And yes, this is something that could happen when using BGP.

BGP: the theory

BGP stands for Border Gateway Protocol, that is the gateway protocol that actually runs the whole Internet (it is normally used as exterior gateway protocol, but can be also used as an interior gateway protocol, whenever it is used inside an AS). It is defined, in details, inside different RFCs:

  • RFC 4271 defines BGP version 4, that is the one in use today;
  • RFC 4760 describes how BGP have been extended in order to be able to deal with protocols different from IPv4, such as IPv6, IPX, etc… (for this reason, the title of the RFC is “Multiprotocol Extensions for BGP-4”).

While the protocol is quite complex, we are more or less only interested in how routers exchange information. Basically, it is only a matter of trust: routers accept new announcements from the peers defined in their configuration, without nearly any check against the content of the announcement.

A weak form of protection for those messages can be applied by using a shared secret between the peers, that is used for cryptographically sign the messages, using an MD5 hash; unluckily, as explained in the previous article, this hashing function is badly broken.

This is only one of the most straightforward BGP vulnerability to understand and exploit, but there are plenty of them. As a proof of this, there is also an RFC (RFC 4272) describing various vulnerabilities and various attack scenarios. Ehm.

BGP: attack analysis

Based on the fact that BGP runs more or less the whole Internet, an attacker could potentially generate huge damages with “little” effort; in the past, various / attacks / proved / that / this / is / absolutely / the / case.

An attacker could in fact diverge the traffic from a specific country, having a specific subnet (or a set of subnets) as destination, gaining the possibility to carry out different attacks, such passive sniffing or Man-In-The-Middle .

There are plenty of different ways to achieve this, but the most straightforward way is to compromise a router, if and only if you are not a malicious actor legally owning the access of one or more routers. Like, you know, a nation.

bgp-meme

BGP: exploit lab

Even in this case, the whole scenario will be simulated using GNS3, with Cisco based firmware emulated inside it. What follows is a screenshot of a possible scenario, using known ISP to identify different AS (the name are randomly selected, as the associated AS number); I just decided to use ISP names because ISPs are an example of entities managing an AS.

bgp-scenario

BGP: exploit impact

Being able to inject malicious routes is always bad, but it is even worst if this affects the traffic of a whole country or company. Unluckily, while such attacks could lead to huge security problems for the users having their traffic redirected, they are hard to stop, due to weaknesses in the protocol specification.

While there are different companies providing monitor of the BGP routes announced around the world, every user and every company can do their part, by using (or providing), secure protocols, such as the one protected by TLS (e.g.: HTTPS). Unluckily, as you can see in the articles linked below, sometimes this is not enough.

BGP: references

There are plenty of great articles online describing vulnerabilities, attacks and countermeasures online, such as:

UPDATE:

A good friend of mine reminded me also the hijack attributed in 2015 to Hacking Team:

Practical routing attacks (2/3): OSPF

Introduction

In the previous post I described the first exploit I was able to prepare, working against RIPv2. In this one, I am going to present another attack, this time having OSPF as target.

Routing theory: types of routing protocols

We have already seen what a routing protocol is and which is its purpose. It is now time to dive more deeply into them to understand the difference between each other.

routing-algorithms
Source: http://www.ciscopress.com/articles/article.asp?p=2180210&seqNum=7

The schema above introduces two concepts: the family of the protocol (interior or exterior) and the type (distance vectorlink state and path-vector). Once again, all the details can be found either in “Computer Networking: A Top-Down Approach” (ISBN-13: 978-0133594140) or in “Computer Networks” (ISBN-13: 978-0132126953), but let’s recap here the basic concepts.

First of all, we have to introduce what is an an autonomous system (abbreviated in AS): we can define it as a group of networks that are controlled by a single administrative entity. An administrative entity could be an Internet Service Provider, an international enterprise or something similar. To deal with the routing inside an AS, we can use interior gateway protocols; whenever we have to exchange information between different AS, we use exterior gateway protocols.

This is a simple concept, but then you could ask: why do we need multiple routing protocols types? Because they use a different approach to deal with the needs of a network administrator (e.g.: how the cost of a path is calculated, how fast they converge, etc… ).

Trying to be concise, we can define the three types in the schema as follows:

  • Distance vector routing protocols: with those protocols, every router advertise its routing table, defining each known network using the concept of distance (e.g.: hop count, delay, …) and a vector, that is the direction of the next hop;
  • Link state routing protocols: those protocols use a different approach, by sharing with all the other routers in the AS the state of the links they are connected with and by letting every other router to construct its own map of the whole AS;
  • Path-vector routing protocols: those protocols share the whole path used to reach a destination, specifying which AS the packets are going to traverse to travel from the origin to the destination.

OSPF: the theory

OSPF stands for Open Shortest Path First and it is probably one of the most used routing protocols for interior-gateway routing because it works fairy well, it is robust, it has built-in security features and it is widely supported by network devices. There are three version of the protocol:

  • OSPFv1: described in RFC 1131 (has never gone beyond the experimental phase, as far as I know);
  • OSPFv2: described in RFC 2328, it superseeds v1 and it is the version deployed worldwide for dealing with IPv4 networks;
  • OSPFv3: it supports IPv6 and is described in RFC 6340.

While OSPF protocol is quite complex, we can summarise the main concepts as follows:

  • neighbors: every router establish a trust relationship with the neighbors routers, that are those residing in the same subnet and sharing some characteristics (e.g.: areaID, area type, subnet, …);
  • hello, advertisements and updates: these are different messages sent by the routers to share their routing links information;
  • fight-back mechanism: whenever a router receives a fake advertisement / update containing its own information it sends, to the OSPF multicast address (224.0.0.5), a new advertisement / update, overwriting the fake one.

In practice, after configuring the routers, the information is exchanged automatically and after some minutes (at least, in the GNS3 scenario), the routing tables inside the AS converge, meaning that every router has a stable routing table it can use.

OSPF: attack analysis

There are various attacks known against OSPF (see on Google Scholar), but they are normally able to “only” generate a DoS condition.

In 2011, Alex Kirshon, Dima Gonikman, Dr. Gabi Nakibly demonstrated an attack, during the Black Hat USA, that was able to circumvent the fightback packets.

The idea behind the attack is quite simple.

Imagine two neighbours routers, A and B. The attacker generates two packets, one sent to the victim router A to trigger the fightback and another sent, at the very same time, to the router B inside which the malicious routes have to be injected. The fightback packet, sent by A is received by B after the malicious one and it is discarded because seen as identical, even tough the content of the two packets is different.

From the rest of the article, we are going to speak about trigger packet, referring to the first one, and disguised packet, referring to the second one.

This is possible because two OSPF LSA (Link State Advertisement) packets are considered identical if they have:

  • the same sequence number;
  • the same 16 bits checksum value;
  • approximately the same age (within a 15 minutes time difference).

The sequence number and the age are quite easy to spot and fake, while the checksum has to be calculated. Luckily, it can be predicted, because it is calculated on LSA fields that have values that can be inferred in advance.

I let you carefully read the paper linked above for all the detail, because in the next paragraphs I would like to concentrate on the practical side of the attack.

OSPF: exploit lab

Even in this case, the whole scenario will be simulated using GNS3, with Cisco based firmware emulated inside it. What follows is a screenshot of the result, where the attacking machine, the victim router and the target router are highlighted.

ospf-gns3-notes

OSPF: exploit development

If an attack is known and publicly described, the exploit should also be easy to find or, in the worst case, easy to write. Well, no.

Thanks to the fact that Google is my friend, I started looking for a public exploit but I soon realised that the only PoC available was contained in a paper provided by nes.fr, but it was not complete.

So the first thing I did was to import some OSPF packets in Scapy to get used to them, but I discovered that it was not able to dissect them correctly. Theory VS practice.

After spending some days trying to figure out what was wrong, I discovered a bug and I submitted a patch, so now Scapy is working as expected. I then used the partial code provided by nes.fr to prepare the first draft of the exploit, but the most difficult part, at least for me, was to understand how to made the checksum of the two packets to collide. The guys from nes.fr suggest to use NumPy to solve a system of linear equations. Unluckily, this is not so trivial to do and, moreover, this generates a packet that is malformed, because the values inside the various fields do not follow any rule. In another paper, from 2012, the original authors state that “The value [of the checksum] can be either directly calculated or found by an exhaustive search within a few seconds.“, that is interesting to say but led to the same, malformed packets.

I then went back to the nes.fr article and I discovered, by looking at the system of linear equation, that the last field of the link used, inside the LSA packet, to generate the collision, was 2 bytes long. Due to the fact that the checksum has the same length, all the possible values of the checksum can be generated by keeping constant all the fields in the link and by trying every possible value of the last field, from 0 to 32768.

ospf-hack-without-math

 

My exploit was then able to sniff for the first LSA packet generated by the victim router and to use it as a template for both the trigger and the malicious ones. By comparing them, the checksum, the sequence and the age were actually the same, but the malicious one was never accepted. Theory VS practice.

After literally spending days on troubleshooting the problem, I discovered that the Cisco firmware was discarding my disguised packet, because both the packets were sent to the multicast address and the second one was arriving to fast and was discarded – I think – as a security measure.

The final exploit is available on my GitHub profile has been extensively tested against Cisco firmwares, but feel free to test it in other scenarios and let me know if you encounter any problem.

OSPF: exploit impact

If defining the real impact for the RIPv2 attack was hard, defining it for OSPF is even harder, because it is used in very different scenarios. Probably, due to the fact that it can replace RIP (that is older and not so powerful), it is currently more used and, hence, the impact of this attack is bigger.

A good network engineer could argue that normally the OSPF packets use a dedicated VLAN, that is accessible by no one but the administrators. While this is the theory (and it is luckily also the practice in some networks), from my experience it is absolutely not always the case.

Another mitigation of the attack could be constituted by the MD5 signature added to the packets, right? In theory, yes. In practice, no. MD5 is badly broken, the same password  has to be shared on every router attached to the link and too often it can be simply guessed or broken through a dictionary attack. Last but not least, the original paper reports also this note, regarding MD5:

“OSPF computes the packet integrity tag as MD5(data||key||pad||length) where || denotes concatenation. While this integrity method is now known to be insecure, we do not use this fact in our attacks. OSPF does not use HMAC for historical reasons.”

So, from my point of view, if an attacker is able to interact with the routers through OSPF, probably his or her possibilities are only limited by his or her imagination.

OSPF: acknowledgments

I would thank both the researchers who discovered this attack and also the researchers of nes.fr for providing me the starting point for my own exploit!

Practical routing attacks (1/3): RIP

Introduction

Back in 2017, I started looking on some known vulnerabilities in the most commonly used routing protocols. One of my goal was to test each of them in my lab, but unfortunately I was not able to find any maintained / functioning / documented exploit. So I decided to write them on my own.

There will be 3 article: this one, focusing on the exploit I wrote for RIPv2, and 2 others, one for OSPF and one for BGP. While all the details are discussed here, the exploit code and the GNS3 configuration files can be found on my GitHub account.

Last but not least, I am going to cover only the details needed to understand how each attack works: if you are interested in a gentle introduction, I suggest you to carefully read the protocols description either in “Computer Networking: A Top-Down Approach” (ISBN-13: 978-0133594140) or in “Computer Networks” (ISBN-13: 978-0132126953).

Goal

This small series of articles has two goals:

  • to give the community some tools that could be useful both to understand how the described attacks work and for proving the associated risk;
  • to demonstrate the gap between the theory (where everything is simple) and the practice (fighting the “e che ce vò” approach).

The need of a routing protocol

Internet can be defined as a network of networks. While we use it everyday, nobody (more or less) cares about how those networks can interact each other.

The rules describing how every packet travels from its source (e.g.: your PC) to its destination (e.g.: your email server) and back, are called routes, being applied by devices called routers.

For routing packets in the right way, routers need to share information about the routes they know, the networks they serve and the cost (in terms of money, delay, etc…) associated to each route.

While in theory this can be achieved manually, by inserting each route in the configuration of the router, this is not feasible in practice, because routers can be everywhere around the world. Moreover, if something changes, (for example, a link from one router to another stops working), updating the configuration, by hand, of every router to adapt to the new situation may require days or weeks.

Routing protocols allow routers to dynamically exchange routes, avoiding any manual intervention (apart from the first configuration).

RIP: the theory

RIP stands for Routing Information Protocol and it is one of the oldest routing protocol being used today.

There are three versions of RIP:

  • RIPv1: the original version, defined in RFC1058 in 1988;
  • RIPv2: an improved version, defined in RFC2453, adds authentication support and other improvements;
  • RIPv3: sometimes called RIPng, described in RFC2080 and supporting IPv6.

This article will focus on RIPv2, but from now on we are going to refer to it simply as RIP.

For calculating the cost from one network to another, RIP uses the the concept of hop: we have an hop whenever a packet passes through a router while moving from a network to another. With RIP, routers keep track of networks which are at most 15 hops away: every other network is considered unreachable.

Another important aspect, as specified in the RFC, is the fact that every router using RIP exchanges routing information every 30 seconds.

RIP: attack analysis

RIP is simple and so is the attack. The basic idea is to keep issuing fake RIP Response messages, containing basically whatever we need (in terms of routes). The other routers will eventually insert our malicious entries in they tables and start routing the packets accordingly.

Normally, RIP Response messages are sent to the dedicated multicast address 224.0.0.9, but the same messages seem to be accepted even when their destination IP address is a specific router. This is great, from an attacker point of view, because it allows he or she to be surgical in the injection process.

RIP: exploit lab

For testing my exploit, I used GNS3, which is an awesome open source network simulation tool. It provides some great features, such as:

  • emulation of different routers / switches firmwares (e.g.: Cisco firmwares) through Dynamips, QEMU and so on;
  • interaction with external virtualization hypervisors (e.g.: VMware, Virtualbox, …);
  • sniffing of the traffic flowing between devices, using Wireshark;

For this lab, I used some Cisco 2960 firmwares to create the whole infrastructure. Then I configured the routers in such a way that they exchange their routes using RIPv2. Finally, I created a Kali VM that I attached to the scenario.

This configuration allowed me to:

  • test how the configuration is done on enterprise-grade devices;
  • have a VM which I can use both to develop and to launch the exploits (it is not mandatory to use Kali, but I like Kali Light because it is what I am used to);
  • check the content of the packets generated by my exploit;

While setting up everything is not always trivial, GNS3 has both great documentation and a great community. Moreover, spending time setting up everything allows you to understand how every device is interacting and how to exploit the powerfulness of the various tools.

What follows is the screenshot of the scenario I created on GNS3, with the 3 steps of the attack highlighted:

  1. generate the malicious packet(s);
  2. send the packet(s) to the victim router;
  3. let the victim router spam the injected routes.

rip-scenario

RIP: exploit development

I started the exploit development by looking at the network traffic, to understand how the messages were composed. I then checked the Scapy‘s source code and it confirmed that Scapy is capable to generate RIP messages.

scapy-01

I then analysed some PCAP files, grabbed from packetlife.net, to understand how the packets were composed. The structure is quite simple, so I tried to craft some packages with Scapy, only to discover that they were not accepted by the victim router. Theory VS practice. After spending hours reviewing the content of the packets I generated, I ended up discovering only one difference between the ones I was sending and the ones inside the PCAP files: the source UDP port.

I did not setup the source port, so it was pick up randomly by Scapy, while on the PCAP files every packet had the same source port, 520/UDP. To understand better what was going on, I read carefully the RFC, discovering what follows:

“RIP is a UDP-based protocol. Each router that uses RIP has a routing process that sends and receives datagrams on UDP port number 520, the RIP-1/RIP-2 port. All communications intended for another routers’s RIP process are sent to the RIP port. All routing update messages are sent from the RIP port. Unsolicited routing update messages have both the source and destination port equal to the RIP port. Update messages sent in response to a request are sent to the port from which the request came. Specific queries may be sent from ports other than the RIP port, but they must be directed to the RIP port on the target machine.”

What. The. Hell. Theory VS Practice.

I really don’t know why an RFC defines the source port but one person at the 34c3 (where I did a workshop explaining those attacks), suggested me that this could be an ancient form of “light authentication” when, 30 years ago, the security was an interesting add on, not something mandatory. Cool!

But let’s go ahead. After statically setting the source port, the packets started being accepted. While the whole exploit code is a little bit more complicated, due to the need of getting parameters from the command line, etc… , the three lines in charge of the actual exploitation are reported here:


# prepare the evil packet
pkt_evil = Ether()/
IP(dst=dst_ip)/
UDP(sport=520, dport=520)/
RIP(cmd=2, version=2)/
RIPEntry( AF="IP",
RouteTag=0,
addr=network,
mask="255.255.255.0",
nextHop="0.0.0.0",
metric=metric)

# spoof the source IP
pkt_evil[IP].src = spoof_ip

# keep sending the evil packet every second
sendp(pkt_evil, loop=1, inter=2, iface=iface)

RIP: exploit impact

The exploit impact is hard to define, because it depends on the network inside which it is carried out.

To estimate it, just think about an attacker who is capable to inject basically every route he or she wants. Then, try to imagine what that would mean in your network:

  • Are you able to identify someone sending fake routes?
  • Are you able to identify traffic routed anomaly outside your network?
  • Is the traffic router in your network encrypted end-to-end?

From my point of view, thinking at the worst case scenario and try to mitigate/resolve the issues is the best approach, even though it could become quite complex. And expensive.