Opened 7 years ago

Last modified 3 years ago

#1336 assigned enhancement

SAM Datagram Handling Enables Replay Attack

Reported by: ExtraBattery Owned by: slumlord
Priority: minor Milestone:
Component: www/i2p Version: 0.9.13
Keywords: Cc:
Parent Tickets: Sensitive: no


At the moment the datagram protocol by itself does not guarantee that a repliable datagram is really directly coming from the address it appears to be from. It could just be replayed by anyone who ever received the datagram. This came as a surprise to me, as I thought I2P is very secure. I don't know if this problem is limited to SAM or affects I2P in general, as I don't know to which module the repliable datagram protocol belongs.

An attacker can listen to repliable datagrams, collect and store them and later re-send them as if the original sender had sent them, effectively achieving I2P address spoofing. There seems to be no way for the victim to notice that the datagram was just replayed. The attacker can arbitrarily choose the recipient and thus forward the collected datagrams to recipients not intended by the original sender, or simply send them at a different point in time or in an excessive quantity. This might be used to enable other attacks or disrupt distributed networks.

I have - using SAM v3.1 - confirmed that it's possible to do this, at least in the sense that SAM tells you that the datagram came from the original sender when in fact it was replayed by another sender.

An example: The attacker would first become part of the iMule Kademlia network. Thus the attacker would receive a lot of repliable datagrams from different peers, all signed by their original senders. The attacker can then re-send each datagrams at will to arbitrary destinations, fooling the recipients regarding the origin. A denial of service attack against a certain group of nodes could be performed this way.

Suggested solution: The attack is possible because the repliable datagram contains no info concerning the intended recipient (in the actual message). The solution would be to include the SHA-256 of the intended recipient's destination in repliable datagrams. This hash must of course be part of the signed text. A repliable datagram ought to be dropped if the included hash doesn't match that of the recipient's destination. This change might not be compatible, but one could allow repliable datagrams without the hash for another year and then start to drop them to fix the vulnerability.


Change History (11)

comment:1 Changed 7 years ago by nom

So in the datagram system, 'raw' datagrams are just blobs of data that you receive, and theres no signing or sender verification. and 'repliable' ones are really just blobs which include a signature and a sending destination (which is basically the public key that signed them).

If you want them to not be relayable to other peers then your idea of adding the receiving destination to the payload could work, but that wouldn't stop time delayed replaying to the original receiving peer. For that you would need timestamping, and only accept datagrams who had a timestamp that was within some limit. This could be done at the application level, or at the SAM level, or at the i2cp level, by adding another datagram type. IMO the best solution is for app makers who are going to use udp, to structure their messages for protection against replay attacks, if that is needed for their application.
I guess this is equivalent to the fact that on the clearnet you can do ip spoofing and relaying of other peoples packets, so the app needs to take that into account.

comment:2 Changed 7 years ago by zzz

Component: apps/SAMapi/general

Agreed w/ nom, this is an application-layer issue, unlikely to be solvable in a general-purpose way in the datagram API. The traditional system to prevent replays requires nonces + timestamps + bloom filters.

comment:3 Changed 7 years ago by nom

Well it could be done as part of the datagram api, by adding another datagram type which included timestamps, receiver dest or nonce + bloom. Bloom would probably add a lot of extra overhead to i2p tho, which would be bad, but a simple 'non replayable' datagram extension could be made, which included a receiver dest, timestamp and randomly generated nonce. Maybe do the receiver dest validation at i2cp level, but leave the timestamp checking and nonce checking to SAM / application layer?

Simplest solution is to leave it completely up to app layer, but that could create problems for people who want to port existing udp based programs onto i2p, and are assuming non replay is already built in.

comment:4 Changed 7 years ago by ExtraBattery

I really think the I2P router should provide this sort of basic protection - at least the hash check at i2cp level as proposed in comment 3. Further measures could be left to applications.

A destination hash is sufficient unless the attacker compromises one of the endpoints, in which case the private destination key was potentially exposed anyway. [Supplemental: When I wrote this I only thought about the scenario where the attacker is able to capture the decrypted message while it's not in transport, i.e. when it arrives at the receiving end. I'm unable to judge if it's possible to capture a message during transport and successfully (much) later replay it its encrypted form. I see why a timestamp is needed if that is possible. This would theoretically also be true for non-repliable datagrams (or maybe other kinds of messages).]

Adding a timestamp sounds meaningful to me. It only has the potential disadvantage that it will prevent routers with a wrong clock from successfully sending datagrams.

Talking about nonces, do you mean that the datagram receiver publishes a challenge when registering its destination in Kademlia, so that potential senders can see and use it? Or how would this work? [The sending peer gives each datagram a nonce and the receiving peer remembers nonces of ingoing datagrams for a while and drops messages with a recurring nonce.]

Last edited 7 years ago by ExtraBattery (previous) (diff)

comment:5 Changed 7 years ago by zzz

I fail to understand how any clearnet app not vulnerable to replay becomes vulnerable by porting to I2P, or why you consider this a bug in I2P.

comment:6 Changed 7 years ago by ExtraBattery

Where did I(?) say that "any clearnet app not vulnerable to replay becomes vulnerable by porting to I2P"? - It would be great if the opposite were true: Simply porting to I2P made you safe. Until yesterday I had blindly assumed this is true.

I would consider this a bug because there are certain expectations when you - as an application developer - use an anonymity network like Tor or I2P. It's great that you can route your traffic with some reasonable expectation of privacy, but it would also be nice to have other built-in security features, like prevention of address spoofing, etc. Regarding the cost/benefit relation, I think it's reasonable to add hash and timestamp to repliable datagrams for enhanced security. This would cause practically no overhead. It doesn't have to be a 100% replay prevention, just one small step to make the most severe attacks impossible.

comment:7 Changed 7 years ago by zzz

I2P promises transport security and anonymity. We don't promise to magically make insecure protocols secure. That should not be part of the "certain expectations" of an 'application developer". If your expectations were otherwise, that's a mistake.

If an application is concerned about replays, they have already incorporated protections into their protocol. If not, we aren't making it more vulnerable.

As you note, the change you propose is backwards-incompatible. Any change would have to be implemented and the migration or version tracking managed by the client. I suggest you discuss this with the developers of any I2P datagram app that you think may be vulnerable. Any potential changes - adding one or more of the 'to' hash, a timestamp, a nonce, a bloom filter, etc., depends on the threat model and tradeoffs that are very much protocol- and application-specific.

This is not a bug and not our problem.

comment:8 Changed 7 years ago by ExtraBattery

Type: defectenhancement

You are right - it's not your bug. I2P is not making applications vulnerable. It just has a huge opportunity to make them safer. This change would be a service to applications and make I2P a more attractive platform for application developers.

About that backward-incompatibility: I take it you refer to applications becoming incompatible. Applications that let SAM/BOB handle their repliable datagrams would normally not notice the change. Would it be possible to make the change so that it's off by default, allowing you to opt-in? Like specifying a parameter in the form "i2cp.sendEnhancedRepliableDatagrams=true". This would allow applications to control what kind of repliable datagram they send. If you have an old application that needs to interpret ingoing repliable datagrams on the (raw) binary level and thus relies on the "old" (427+ bytes) format, your application would continue to be able to interact with itself.

If you look at things from the position of an application developer, there are a lot of protocols in use that cannot easily be changed. [Wrong claim removed.]

Not that I2P is at fault. It's just in the optimal position to solve the problem. I believe you don't need a nonce and a bloom filter to have a satisfying result. 32 bytes of receiver destination hash + four bytes of timestamp (with say one second granularity starting at y2k) would already make a huge difference.

Last edited 7 years ago by ExtraBattery (previous) (diff)

comment:9 Changed 7 years ago by ExtraBattery

If you want to leave this issue to the application, I think you should close the ticket. The only thing I encourage you to do then is to document the problem (if you haven't already), so that application developers are aware of it.

comment:10 Changed 3 years ago by zzz

Component: api/generalwww/i2p
Priority: majorminor

Reclassifying as a doc issue

comment:11 Changed 3 years ago by zzz

Owner: changed from mkvore to slumlord
Status: newassigned

We do have replay detection and prevention at the I2NP layer with message IDs, expiration, and a Bloom filter.

Note: See TracTickets for help on using tickets.