Nmap Development mailing list archives

Re: Request for Comments: Nping Echo Protocol


From: Brandon Enright <bmenrigh () ucsd edu>
Date: Mon, 27 Jul 2009 19:35:27 +0000

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi Luis,

If you're anything like me you aren't going to be satisfied doing
something just because somebody told you so.  I'll try to explain why I
think some approaches are better than others.  It isn't my intention to
be patronizing and I hope this email doesn't come of as such.

First, let me define a few phrases that I think will help me explain
what I mean.

Confidentiality:  This is what encryption provides.  It means that if
all you have is the ciphertext, you can't get the plaintext.  If the
attacker already knows some or all of the plaintext then encryption
won't provide any additional confidentiality.

Integrity:  This is what a hash provides.  It makes sure that nothing
was accidentally/randomly changed.  Since anybody can make a new hash,
it doesn't protect against malicious changes.

Authenticity:  This is what a message authentication code (MAC)
provides.  Only somebody possessing the MAC key can create the
authentication field.  A MAC generally uses a hash in a special
construction to prevent others from being able to generate the same MAC
code.

Block Cipher: this is encryption.  Depending on the mode, it can be
easy or hard to change the plaintext in a useful way by changing the
ciphertext.  Block ciphers are only designed to provide
confidentiality.  Only very special constructions (modes of operation)
are designed to provide both confidentiality and integrity.


On Mon, 27 Jul 2009 11:55:28 +0200
"Luis M." <luis.mgarc () gmail com> wrote:

Hi Brandon,

Brandon Enright wrote:

        Unless Nping is compiled without OpenSSL support,
    

You haven't described what happens if you use a client compiled with
OpenSSL but a server without or vice versa.  I'd suggest that the
server and client both require a flag like "--unencrypted" to allow
fallback no encryption.  A server/client compiled without OpenSSL
should return a fatal warning if used without --unencrypted.  This
will prevent a MitM attack degrading the channel to no encryption.

  
Yes, that makes sense.


Okay, SHA-256.  It's overkill but you're right that there isn't a
good smaller alternative.  We could truncate SHA-256 to only 128
bits but since we aren't pressed for space, might as well use the
full 256. 
Yes, I think we should use the full 256 bits.

If we use SHA-256 to generate the nonce/IV for use with AES-256-MODE we
will have to truncate to 128 bits.  The nonce/IV needs to be the same
size as the block.


  
Encryption is good at hiding contents,
it is bad at resisting certain types of attacks.

Matasano *just* did a long and annoying blog post about this very
thing:

http://74.125.155.132/search?q=cache:693pTMNFilMJ:www.matasano.com/log/1749/typing-the-letters-a-e-s-into-your-code-youre-doing-it-wrong/+matsano+aes&cd=1&hl=en&ct=clnk&gl=us

In short, you want to use the encryption to protect the contents.
You want to use a MAC to authenticate the contents.

Put another way, the SHA-3 competition would not exist if one could
just use AES.
  

Maybe I didn't explain myself very well. When I talk about using the
checksum for authentication, what I mean is the following:

Given your explanation below, I think I understood exactly what you
meant.


Given message A, we compute its checksum  S=H(A). The message we want
to transmit is P=A+S. So what we do is to encrypt the whole thing to
obtain the ciphertext: C=Ek(A+S). 


As the hash is included into the
encrypted text, any change to the ciphertext (whatever mode we use),
corrupts the message.

Ah so this is where the mode *really* matters.  With CTR mode for
example, the block cipher has been turned into what is essentially a
stream cipher that gets XOR'd with the plaintext.

If you flip a bit in the ciphertext, that exact bit gets flipped in the
plaintext.  Yes, unless you flipped bits really smartly, the hash won't verify.

Let's say an attacker flips one single bit of
C, obtaining C' and forwards C' to the server. When the server gets
C', decrypts it P'=Dk(C'). P' should correspond to a message A' and a
checksum S' but the fact that the attacker flipped one bit in the
message means that now S' != H(A'), because even if the attacker
managed to change the message so P and P' differ only in a single
bit, there is no way the decrypted checksum validates.

Suppose for a moment that we are using CTR mode and we are sending the
message "secret".

This is what we'd get:

$ echo -n "secret" | sha256sum 
2bb80d537b1da3e38bd30361aa855686bde0eacd7162fef6a25fe97bf527a25b

So:

ciphertext = aes("secret" + 2bb80d537b1da3e38bd...)

But, if the attacker already knows the plaintext is "secret" and they
want to change it to "owndju" they would first:

XOR ciphertext with "secret" + 2bb80d537b1da3e38bd... to get the CTR
mode keystream.  They would then compute a new hash:

$ echo -n "owndju" | sha256sum 
d35a7d3e4a2cb75b4216917e2f092c2c540df673712a3f0e04816de3ff6d7916

And then do newciphertext = keystream XOR "owndju" + d35a7d3e4a2cb75...

The attacker has changed the message but newciphertext will still verify
by whomever is doing the decrypting.

So what did this attack take?

* CTR mode
* A hash for integrity, (not authentication)
* Knowledge of the plaintext

We want to fix/prevent this attack.  Lets talk about each of the three:

* CTR mode:

This mode is secure.  The same attack can be mounted against ECB and
CBC.  Different steps are required but the will still succeed under the
right circumstances because encryption does not offer authentication.

* A hash for integrity:

This is easy to fix.  Changed it to a MAC like HMAC.  Then even if the
attacker wanted to change to "owndju" they have no way of generating
the MAC to make the new message verify.

* Knowledge of the plaintext:

We can't prevent this.  For one, we have to transmit our probe packet
unencrypted.  Two, it is not a very big stretch of the imagination that
the attacker can guess the packet we are going to send.  They may
already know the source and destination IPs, etc.  There isn't much
randomness in most probe packets.  This is one of the reasons why
attacks on WEP work -- the attacker knows some of the bytes of the
plaintext.

In short, we can defeat the above attack with a MAC.


However, although I think using encrypted hashes is almost the same as
using MACs, we should probably go for MAC as Openssl has support for
them and it sounds right to use Message Authentication Codes to
actually do authentication.

Sounds good.

...snip...
  

Well, yes, I'm actually having problems to understand your proposal.
This is what I've understood. Here I present a simple list of steps
and in the attached document I include a modified version of the
protocol RFC.

 (Please check sections 2.4,

Looks good.

2.5,

Looks good.

2.6 and 2.7.

These seem redundant.  The HMAC-SHA256 in 2.4 and 2.5 should have
allowed the server to authenticate to the client and vice-versa.

The HELLO and HELLO_RESPONSE can also serve as challenges.

My primary reason for having both a client nonce and a server nonce is
that there should be two different keystreams, one from the server to
client and another from the client to the server.  The nonce/IV will be
used as input into the encryption routine.  All modes other than ECB
require a nonce/IV.

An also
flow diagrams in section 2.12). However, if I didn't get it right, it
would be really helpful

I'd actually suggest having the server be the first to send a message.
If the client gets to pick it's own nonce/IV it becomes more likely to
be able to replay sessions or spoof the client.

If you could sketch the basic flow diagram  or how the initial packets
headers would look like.

I'd change it to:

         +------+             +------+
         |CLIENT|             |SERVER|
         +------+             +------+
            |                    |
            |       HELLO        |  :: Hi. I'm an Nping Server.
            |<<------------------|     I support version 1.
            |                    |     Here is your nonce.
            |                    |     Here is a challenge
            |                    |
            |    HELLO RESPONSE  |
            |------------------>>|  :: Nice 2 meet u. Im a client..
            |                    |     I also support version 1.
            |                    |     Your MAC looked good
            |                    |     Here is my challenge reponse
            |                    |      
            [....................]


Here's what I've understood:

1. Client sends initial HELLO packet encrypted, but also provides the
nonce unencrypted, at the beginning of the packet.

2. Server sends HELLO RESPONSE also encrypted and also providing its
own nonce unencrypted, at the beginning of the packet.

3. Client computes the challenge: 
    HMAC-SHA256("dummy text" + <server_nonce>, <psk>)
and sends it to the server.

4. Server verifies the challege response. If correct, now it's
server's turn prove himself computing:
    HMAC-SHA256("dummy text" + <client_nonce>, <psk>)

5. The client verifies the challenge response received from the
server. If it is correct, proceeds with the SPECS packet and both
server and client live happily during their session.

I think I clarified your questions above.



NOTES:

The first packet (1) is AES-CTR encrypted using client_nonce as the
IV. Subsequent client packets are also encrypted that way, but nonce
is not included anymore as the server already knows it.

Sure, you probably don't need to include the nonce if you know how
you're going to be evolving the nonce over the session.  It's
important though that that the nonce (number used once) changes.  If it
is used more than once the security goes away.


The second packet (2) is encrypted using server_nonce as the IV.
Subsequent server-generated packets are also encrypted that way,
but the nonce is not included anymore as the client already knows it.

Again, as long as the server and client can stay in sync with the new
nonce for each message it doesn't need to be included.


The HMAC-SHA256 is sent unencrypted, this is, it is not feed into the
encryption function.  (Why do we do this?)

We need the HMAC for reasons described above.


The HMAC-SHA256 does NOT cover the plaintext, but authenticates
the ciphertext. This is, the data fed into the HMAC computation
function is the ciphertext, not the plaintext. (Why do we do this?)
 

Good question.  My logic was this:  Even if we decrypt first, we still
have to compute the HMAC to verify the message.  If we verify it first
we can save ourselves the time of decrypting if it doesn't check out.

I don't actually which of authenticating the plaintext or the
ciphertext is the generally accepted practice.  I tried to find a
discussion of each but wasn't able to find one.  I can't think of any
drawbacks to authenticating the ciphertext rather than the plaintext
but that's likely my lack of crypto knowledge.  If you feel more
comfortable authenticating the plaintext and then encrypting the MAC, go
ahead.


Again, thanks for your comments, Brandon,


Sure thing.  I suspect there is still more to discuss so let me know if
you have any more questions.

If anybody else wants to jump into this conversation with suggestions
please do.

Brandon

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.11 (GNU/Linux)

iEYEARECAAYFAkpuAYUACgkQqaGPzAsl94ImJACfXNRSayq8pvSzVfntqzYXbj0E
dmcAn10foFtrnKUtH873+q9JF4YvFiR/
=zJ3L
-----END PGP SIGNATURE-----

_______________________________________________
Sent through the nmap-dev mailing list
http://cgi.insecure.org/mailman/listinfo/nmap-dev
Archived at http://SecLists.Org


Current thread: