Locking down the command line with the Anjuna SGX Runtime

One avenue that an attacker may use to collect sensitive data from an application is by hijacking control of command-line arguments. If an attacker can choose the arguments to give to a command, then it can ask the command to perform unauthorized operations or return sensitive data. The Anjuna SGX Runtime can protect against this type of attack by imposing requirements on the command-line arguments that a program can accept.

An attacker with access to the secured host might run an application in the terminal, passing arguments that enable it to read input files, process them, and generate output that leaks secrets. By restricting the command-line arguments that the application can receive, the secure enclave can prevent this type of attack.

This section shows how to configure the Anjuna SGX Runtime to lock down an application command line in order to protect it against this class of attacks. You will see how to configure a secure enclave that runs OpenSSL to decrypt input payloads, while preventing an attacker from exposing private keys.

This section assumes that you are using Ubuntu 18.04, and that OpenSSL and the Anjuna SGX Runtime are installed and configured.

To ensure that OpenSSL is installed, execute the following command:

$ sudo apt install openssl

For information about installing the Anjuna SGX Runtime, see Getting the Anjuna SGX Runtime.

Create a key pair

Begin by creating a working directory to hold the files you will be working with:

$ mkdir lockdown

$ cd lockdown

Next, create a public/private key pair to use for encrypting and decrypting data:

$ openssl genpkey -algorithm RSA -out private_key.pem -pkeyopt rsa_keygen_bits:2048

$ openssl rsa -in private_key.pem -pubout > public_key.pem

OpenSSL creates the files private_key.pem and public_key.pem.

Now use anjuna-sgxrun to generate a manifest template file. You will edit the template to configure the Anjuna SGX Runtime to run OpenSSL.

Generate the manifest template with the following command:

$ anjuna-sgxrun --setup openssl

anjuna-sgxrun creates the manifest template file, openssl.manifest.template.yaml. Edit this file and add the following entries:

keys:
- id: input_key
  source: enclave_generated

encrypted_files:
- path: private_key.pem.sealed
  key: input_key

Now use anjuna-sgxrun to generate a key pair for the secure enclave:

$ anjuna-sgxrun --provision openssl

You can now use anjuna-encrypt to encrypt the private key so that no cleartext copy of it exists, and it can be read only by OpenSSL running inside the secure enclave.

Encrypt the key:

$ anjuna-encrypt  --public-key provision/openssl.pubkey private_key.pem

anjuna-encrypt creates the file private_key.pem.sealed, a copy of the private key, which is encrypted so that it can be read only from within the secure enclave.

In normal use, you could now delete the private_key.pem file to make it completely inaccessible to any attacker, but for this example you should not delete it. You will use it again to make further changes to the secure enclave’s configuration.

In a normal case, after you delete the private_key.pem, there is no longer a cleartext copy of the private key anywhere, which means that the only process that can possibly read it is OpenSSL, and then only when it runs inside the secure enclave.

Encrypt an example file

Use the public key that you created to encrypt an example file.

First, create a file containing some example data:

$ echo Secret message > message.txt

This command creates a file named message.txt that contains the text Secret message.

Now use the public key to encrypt it:

$ openssl rsautl -encrypt -inkey public_key.pem -pubin -in message.txt > message.txt.encrypted

OpenSSL creates a file named message.txt.encrypted that contains an encrypted copy of message.txt.

You can now run OpenSSL in its secure enclave to decrypt the encrypted message:

$ anjuna-sgxrun openssl rsautl -decrypt -inkey private_key.pem.sealed -in message.txt.encrypted

anjuna-sgxrun runs OpenSSL inside its secure enclave, which enables it to automatically decrypt the data in the file private_key.pem.sealed. That decrypted key enables OpenSSL to decrypt message.txt.encrypted, so that it can then display the cleartext message: Secret message.

Without the private key, it would not be possible to decrypt message.txt.encrypted, and if you delete private_key.pem, the only way to get the private key is through OpenSSL running inside the proper secure enclave.

Command-line attacks

There is a weakness in the protection. If an attacker can gain access to the command line and run OpenSSL in its secure enclave, it becomes possible to retrieve the cleartext of the private key by passing the right parameters to OpenSSL:

$ anjuna-sgxrun openssl rsa -in private_key.pem.sealed -check

Even if you delete the cleartext private_key.pem, an attacker with the right access and permissions can use this method to recover the private key, and your sensitive data are no longer secure. How can you protect against this class of attacks?

The Anjuna SGX Runtime protects against this type of attack by enabling you to specify strict requirements on the command lines that a command may accept when run inside the secure enclave. To lock down the command line, you must configure the secure enclave using its manifest file.

Configure the allowed command line

Edit the openssl.manifest.template.yaml file and add the following entries:

command_arguments:
- openssl
- rsautl
- -decrypt
- -inkey
- private_key.pem.sealed
- -in
- message.txt.encrypted

These entries specify a literal command line that becomes the only command line that the secure enclave allows. If you try to run OpenSSL in the secure enclave with any other arguments, the secure enclave will prevent it from running.

To test the new configuration, run these commands:

$ anjuna-sgxrun --provision openssl
$ anjuna-encrypt --public-key provision/openssl.pubkey private_key.pem
$ anjuna-sgxrun openssl

OpenSSL can still decrypt the encrypted message, but any attempt to pass command-line arguments to OpenSSL results in an error. You can no longer use the OpenSSL command line to exfiltrate the cleartext of the private key.

You can test that protection by trying to run OpenSSL in the secure enclave with the command-line arguments needed to retrieve the private key:

$ anjuna-sgxrun openssl rsa -in private_key.pem.sealed -check

The secure enclave no longer allows you to run OpenSSL with command-line arguments.