Almost all vendors have released patches to defend devices- both clients and access points- against KRACK attacks (https://www.krackattacks.com). Can anybody help me understand how these patches fix device vulnerability to KRACK? I can find a lot of articles recommending workarounds, or recommending to patch your devices, but none that actually give any information about how those patches might work.
(Context: I'm trying to determine devices vulnerability to KRACK attacks from a wireless sniffer to let people know if they need to worry).
The general attack vector for KRACK attack is replaying the M3 message in the 4 way handshake using the same key. Each time a vulnerable client receives this message it will reset its key replay counter and NONCE. This allows replay attacks - i.e. the same ciphertext encrypted using the same key but different NONCEs allows an attacker to eventually deduce the key that is being used.
So a patch to a vulnerable client would probably involve checking the key received in M3 messages, and if it's the same as was previously received, do not install it just silently ignore the message.
Related
Background: I'm working on a mobile application (online chat) that use persistent TCP connections to a backend server. In the previous version, we used a well-known encryption scheme to protect the payload and sign using a shared secret key. This provided sufficient protection against data tampering and reverse engineering. But the traffic was still susceptible to replay attacks: someone can capture the network traffic and replay it and server would accept the requests since it had no idea whether it was real or replayed. To counter this, we introduced timestamps and nonces which provided protection against replay attacks.
All well and good. A decision was later made to use TLS (Transport Layer Security) to protect all communication between clients and servers. TLS was implemented and to provide an extra layer of protection against Man-in-the-Middle attacks, we pinned the public certificate of the server on clients.
Which brings me to the question: is it still necessary to use custom encryption and guard against replay attacks since TLS already provides protection against these? In my research, I found that TLS provides protection during transmission i.e. prevents man in the middle but what if the originator itself wants to cheat the system and modify payload or replay traffic? Does TLS protect against an intentional cheater trying to somehow intercept the traffic in the network layer of their OS? My understanding was that TLS provides end-to-end encryption but I have a suspicion that TLS traffic could, in fact, be replayed if the originator wishes to.
I'm also aware of memory-based attacks where the attacker would modify the memory on the device this modifying payload (may be even record and replay.) But even our custom encryption + replay guard won't protect against these.
From: https://www.owasp.org/index.php/Transport_Layer_Protection_Cheat_Sheet#Benefits
"TLS also provides two additional benefits that are commonly overlooked; integrity guarantees and replay prevention. A TLS stream of communication contains built-in controls to prevent tampering with any portion of the encrypted data. In addition, controls are also built-in to prevent a captured stream of TLS data from being replayed at a later time.
It should be noted that TLS provides the above guarantees to data during transmission. TLS does not offer any of these security benefits to data that is at rest. Therefore appropriate security controls must be added to protect data while at rest within the application or within data stores."
TLS only protects the transport and thus it provides protection against modifying or replaying of the encrypted data only. It does not protect against any kind of modifications or replaying of the data before the encryption or after decryption. Sending the same data again over a TLS connection is actually perfectly valid.
But, the nonce and timestamp you use to detect replay do not protect against modification or replaying too. The sender can still use the same data but "protect" these with the new nonce and the new timestamp. It is simply not possible to protect against this kind of client based attacks as long as the attacker is able to modify the client code which is usually the case if the client runs on a system owned by the attacker like in case of a smartphone game where the owner of the smartphone likes to cheat.
I'm trying to figure out the most data-use efficient way to secure our CoAP API. DTLS seems to be the right way to do it, but looking at how much data the handshake requires (and making some uninformed assumptions about how often that needs to happen) it seems that DTLS with X.509 certificates dwarfs the actual data use of CoAP itself.
The most obvious solution would be to just use symmetric keys that are programmed in at the factory, but I don't think I like the security risks that imposes. As far as I understand there is no way to recover from a server-side intrusion other than manually installing new keys on all the devices.
The solution that I'm thinking of proposing is basically a hybrid of the two, distribute the devices with a secured CA that lets the devices do a standard handshake and establish a "temporary" symmetric key. Then to save bandwidth to the device I'd store that key (session?) in a database for the device to continue for months or years at a time, but still have the ability to expire the keys if we discover any have gotten out.
I know I could just use the standard session resumption handshake to resume a session, but I'm not sure that is required since DTLS is connection-less and I can pretend the "connection" is always open. And if I can avoid having to repeat the handshake that would lower data consumption and probably lower server load somewhat too.
The things that I don't know are: Does DTLS define a limit on how long a session can remain open? Or is there a timeout where a session must be removed after some period of inactivity? If not, do the implementations of DTLS define one themselves?
Is there any thing else that I may be overlooking as to why this wouldn't work? Or is there something more straightforward that I'm not thinking of?
Timeouts are application specific, and you can set them as high as you need, or just keep the connections around as long as you can (eg. with a fixed number of usable connections, timing out the least recently used when a new one is opened).
Session resumption data can be held for as long as both parties agree the resumption data is still good (eg. no underlying certificates have expired). Session resumption should be at least as cheap as manually installed symmetric keys.
So a sensible approach seems to be to just try continuing the session if the sending party still has it open, fall back to session resumption on error, and if that doesn't work go through the full handshake again. There don't necessarily need to be agreed-on times for any of that.
(and making some uninformed assumptions about how often that needs to happen)
My feeling is, an ip-address change after a quiet periode is assumed. If that is assumed, the "DTLS session timeout" is the timeout of "NAT(like)s" on your ip-route. And that NAT timeout is still (too frequently) 30s.
If there are no "NAT(like)" on your ip-route, and so the peers are able to exchange ip-messages by their static (not changing) ip-address and port, then there is no such DTLS timeout. Except, as already answered, your application requires that. There are also some discussions in the IETF when the exchange the connection keys for some security reasons. But the number are rather high (except you want to use AES128_CCM8).
since DTLS is connection-less
DTLS requires a context with a master-key and the "association keys" (TLS "connection keys"). That master-key is assigned to the DTLS session id, and the "association keys" are usually assigned to the ip-address and port. The DTLS session resumption is then used in scenarios, where the addresses may change (e.g. because of "NAT(like)s", or, because the peers are entering a sleeping mode and gets a new ip-address on wake-up). With such ip-address changes, the DTLS session resumption is used to refresh the assignment of the "association keys" with the new address. A DTLS resumption is more, it uses also new "association keys", but it's mainly done to overcome the address change.
The most obvious solution would be to just use symmetric keys
Between PSK and x509, there is also RPK, which offers similiar security as x509 with less data used. Also PSK_ECDHE cipher suites may be a choice.
And hopefully DTLS CID will make CoAP/DTLS more efficient. At least for my tests, experiments and usage over the last 2 years, that was the technique, which brought back CoAP into "must be considered"!
Is there any brief explanation for IP security? And Why do we use it?
If you mean IPsec It encrypts network traffic at the IP packet level. You use it to prevent other people -- in general -- from extracting the data travelling through your network -- especially sensitive data that is meant to be encrypted, however the application in question doesn't support encryption.
Encryption is just one aspect of security. Sometimes, you don't really care if the data can be read by anyone --- you just want to ensure that no one has tampered with it. In this case, the sender can use IP security (IPSec) to just integrity protect the data. The data is now tamper-evident: that is, any attempt to tamper with the data will be discovered by the receiver as integrity verification will fail. In this case NULL algo for encryption (i.e. no encryption) and SHA1 algo for integrity will be used.
Also, note that encryption without integrity protection is not very useful as an attacker can tamper with the data and the receiver won't be able to discover it. You may have to use application level checks to discover tampering and this is not foolproof.
IPSec also gives you protection against replay attacks: an attacker will not be able to capture the packets and replay them back later in an attempt to impersonate the sender.
So, use integrity protection alone (if the data is not sensitive) or integrity plus encryption.
Assuming I've securely exchanged keys with another computer (using Diffie-Hellman perhaps), here's my tentative solution:
packet number + encrypted data + message authentication code (MAC)
The packet number is an incrementally-increased number starting at 0. After that is the encrypted data itself, followed by a MAC of them both. If someone attempts a MITM attack, the MAC should fail to compute. If they attempt a replay attack, the recipient will notice it has already received that packet number.
Is there any flaw in my reasoning here?
Assuming I've securely exchanged keys with another computer (using Diffie-Hellman perhaps)
This is where you face the biggest danger - if the man-in-the-middle manages to control the key exchange (for example, by establishing one key with the client and itself, and establishing another key with server and itself), then the MITM can decrypt (and re-encrypt) everything. Once you've established the secure key exchange, you should be invulnerable to the MITM attack. But the hard part is ensuring that the key exchange is truly secure.
Consult Practical Cryptography (or at Amazon) by Ferguson and Schneier for information about this.
You're not describing a man in the middle attack, but a replay attack.
With a MITM attack the key exchange is intercepted and you say that you already have exchanged keys securely - so it is not the problem.
Replay attacks are easy enough to mitigate against, you include a unique message ID and then check it for uniqueness on the receiving side. Generally each message has an expiry date and time so you don't need to keep an ever growing list of message IDs to validate.
Your approach for protecting against replay attacks seems reasonable to me. You are essentially describing a method called timestamping. Your packet number is a "virtual time" that is used by the recipient to verify that the message was not sent before.
Once the keys have been exchanged then the data cannot be intercepted or spoofed by a third party. (Except when your packet # counter loops. Hypothetically packets from the old window could be replayed as being from the new window.) The solution to this problem is timestamping (as others have mentioned.) Again, though, this can be sabotaged if the attacker is able to compromise in some way the system time. (If they are a man in the middle, they could hypothetically imitate an NTP server and in that way modify a client's system time.)
What an eavesdropper COULD do however is to insert himself between the two parties and disrupt the channel. This would likely cause a new key exchange to occur which could be observed. In order to make key exchange truly secure, you must use 3rd party validation or a pre shared key which only the two communicators know.
I'm using RSA to encrypt communication between a server and a client.
Lets say we have 2 Asymetric keys, key 1 and key2.
The server has key1 (Private) from the start and the client has the key1(public)
So here is the scenario:
the client generates key2
client connects to the server
sending key2(public) encrypted with key1(public)
from now on the server will send all data encrypted with the key2(public)
the client sends some random data to the server
the server sends back the same data hashed
the client verifies that the data is right
As far as I can see this should prevent a man-in-the-middle attack, or am I missing something?
At point 7 the client should know if someone is trying to give the server the wrong key to encrypt with, as no one else but the server can decrypt key2(public).
If there is anything that can be done to improve the security please tell me.
The best thing you can do to improve the security is to use an existing design and not try to reinvent the wheel. I'm not saying that what you've done is necessarily wrong, but just that many people much smarter than you and me have spent a lot of time thinking about this problem. Use TLS instead.
As long as key1 (private) has not been intercepted somehow by a third-party, your scenario looks secure.
I think I saw this somewhere in a paper actually. In it, Alice gave Bob an unlocked box (key 1 public), then Bob put a bunch of his own boxes (key 2 public) in it, locks it and sends it back to Alice. Alice then opens the box(key 1 private), and now she can securely seal the boxes that Bob just gave her.
Despite the box analogy, that's essentially what you're doing, so I'd say its secure.
I agree, just use TLS.
Also, what value do steps 5 through 7 provide? A MITM wanting to do an attack that would work after steps 1-4 (e.g. DoS of some sort by passing n transactions through and then stopping, forcing a retry from the start) could do so just as well after 5-7. What do they add?
-- MarkusQ
No, this protocol is not safe.
A man-in-the-middle can intercept the data sent by the client and send whatever it wants to the server, since you haven't specified any mechanism for the server to authenticate the client or verify the integrity of messages it receives.
Sure, you could doctor up your protocol to fix these glaring problems, but there would be others. If you ever fix them all, you'd have something that maps to TLS or SSH, so why not just start there?
#Petojāthe problem I was focusing on was that of the server trusting the messages it receives; your proposal doesn't provide any security there. However, if you are worried about confidentiality, you still have a problem, because the MITM could pass messages back and forth unaltered until he sees what wants to find because you don't have any privacy on the client messages.
Your proposal seems to be aimed at ensuring the integrity of messages from the client. You've developed the protocol to the point where the client can't distinguish between an attack and a network failure. Rather than trying to help the client determine whether the server acted on a tampered message, allow the server to verify the integrity of the message before acting on it.
I will agree with Greg that you are reinventing the wheel. What you are essentially describing is some basic form of key exchange. Incidentally, in order to ensure that it is secure against man-in-the-middle attacks you must also be certain of the server's identity, i.e. ensure that the client can know with certainty that what it believes to be public(key1) really is the server's and not the man-in-the-middle's (e.g. using a CA or having the server's public(key1) in secure storage on the client side.)
Moreover, there are additional considerations you must be aware from a systems standpoint, such as:
asymmetric key encryption is slower than symmetric key encryption, which is one of the reasons why existing solutions such as TLS will use asymmetric key encryption only to negotiate a temporary symmetric key, which is then used for channel encryption.
if traffic analysis by a third-party succeeds in cracking a temporary symmetric key, you have not compromised you asymmetric key pair. You are encouraged to re-negotiate the temporary key relatively often for this reason. Arguably, generating a new key2 in your scenario would mitigate this aspect.