Cryptography question (cross-posted from Twitter):
You want to make a ransomware worm that goes onto machines, encrypts the contents, and demands a ransom in return for the decryption key. However, after you encrypt their HD, the person whose machine you infected will be able to read the source code for your worm. So you can’t use symmetric encryption, or else they’ll obviously just read the key out of the worm and decrypt their HD themselves.
You could solve this problem by using public key encryption—give the worm the public key but not the private key, encrypt using the public key, and sell the victim the private key.
Okay, but here’s an additional challenge: you want your worm to be able to infect many machines, but you don’t want there to be a single private key that can be used to decrypt all of them, you want your victims to all have to pay you individually. Luckily, everyone’s machine has some unique ID that you can read when you’re on the machine (e.g. the MAC address). However, the worm cannot communicate with other attacker-controlled machines after going onto a victim’s machine.
Is there some way to use the ID to make it so that the victim has to pay for a separate private key for each infected machine?
Basically, what I want is `f(seed, private_key) → private_key` and `g(seed, public_key) → public_key` such that `decrypt(encrypt(message, g(seed, public_key)), f(seed, private_key)) = message`, but such that knowing `seed`, `public_key`, and `f(seed2, private_key)` doesn’t help you decrypt a message encrypted with `f(seed, private_key)`.
One lame strategy would be to just have lots of public keys in your worm, and choose between them based on seed. But this would require that your worm be exponentially large.
Another strategy would be to have some monoidal operation on public keys, such that compose_public(public_key1, public_key2) gives you a public key which encrypts compose_private(private_key1, private_key2), but such that these keys were otherwise unrelated. If you had this, your worm could store two public keys and combine them based on the seed.
Symmetric encryption is fine, as long as the malware either fetches it from C&C locations, or generates it randomly and discards it after sending it somewhere safe from the victim. Which is, in fact, how public-key encryption usually works—use PKI to agree on a large symmetric key, then use that for the actual communication.
offline-capable encrypting worm would be similar. The viral payload has the public key of the attacker, and uses that to encrypt a large randomly-generated symmetric key. The public-key-encrypted key is stored along with the data, which has been encrypted by that key. It can only be recovered by giving the attacker the blob of the encrypted-key, so they can decrypt it using their private key, and then provide the unencrypted symmetric key.
This requires communication, but never reveals the private key, and each installation has a unique symmetric key so it can’t be reused for multiple sites. I mean, there must be SOME communication with the attacker, in order to make payment. So, decrypting the key seems like it doesn’t add any real complexity.
This isn’t practically important because in real life, “the worm cannot communicate with other attacker-controlled machines after going onto a victim’s machine” is an unrealistic assumption
I don’t know if it’s relevant to what you were looking into, but it’s a very realistic assumption. In air-gapped environments it’s common for infiltration to be easier than exfiltration, and it’s common for highly sensitive environments to be air-gapped.
Cryptography question (cross-posted from Twitter):
You want to make a ransomware worm that goes onto machines, encrypts the contents, and demands a ransom in return for the decryption key. However, after you encrypt their HD, the person whose machine you infected will be able to read the source code for your worm. So you can’t use symmetric encryption, or else they’ll obviously just read the key out of the worm and decrypt their HD themselves.
You could solve this problem by using public key encryption—give the worm the public key but not the private key, encrypt using the public key, and sell the victim the private key.
Okay, but here’s an additional challenge: you want your worm to be able to infect many machines, but you don’t want there to be a single private key that can be used to decrypt all of them, you want your victims to all have to pay you individually. Luckily, everyone’s machine has some unique ID that you can read when you’re on the machine (e.g. the MAC address). However, the worm cannot communicate with other attacker-controlled machines after going onto a victim’s machine.
Is there some way to use the ID to make it so that the victim has to pay for a separate private key for each infected machine?
Basically, what I want is `f(seed, private_key) → private_key` and `g(seed, public_key) → public_key` such that `decrypt(encrypt(message, g(seed, public_key)), f(seed, private_key)) = message`, but such that knowing `seed`, `public_key`, and `f(seed2, private_key)` doesn’t help you decrypt a message encrypted with `f(seed, private_key)`.
One lame strategy would be to just have lots of public keys in your worm, and choose between them based on seed. But this would require that your worm be exponentially large.
Another strategy would be to have some monoidal operation on public keys, such that compose_public(public_key1, public_key2) gives you a public key which encrypts compose_private(private_key1, private_key2), but such that these keys were otherwise unrelated. If you had this, your worm could store two public keys and combine them based on the seed.
Symmetric encryption is fine, as long as the malware either fetches it from C&C locations, or generates it randomly and discards it after sending it somewhere safe from the victim. Which is, in fact, how public-key encryption usually works—use PKI to agree on a large symmetric key, then use that for the actual communication.
offline-capable encrypting worm would be similar. The viral payload has the public key of the attacker, and uses that to encrypt a large randomly-generated symmetric key. The public-key-encrypted key is stored along with the data, which has been encrypted by that key. It can only be recovered by giving the attacker the blob of the encrypted-key, so they can decrypt it using their private key, and then provide the unencrypted symmetric key.
This requires communication, but never reveals the private key, and each installation has a unique symmetric key so it can’t be reused for multiple sites. I mean, there must be SOME communication with the attacker, in order to make payment. So, decrypting the key seems like it doesn’t add any real complexity.
Apparently this is supported by ECDSA, thanks Peter Schmidt-Nielsen
This isn’t practically important because in real life, “the worm cannot communicate with other attacker-controlled machines after going onto a victim’s machine” is an unrealistic assumption
I don’t know if it’s relevant to what you were looking into, but it’s a very realistic assumption. In air-gapped environments it’s common for infiltration to be easier than exfiltration, and it’s common for highly sensitive environments to be air-gapped.