
CVE-2022-27499
Esta é a demonstração original do Unanticipated Snapshot Attack encontrado por nós. Agradecemos à Intel pelo Security Advisory.
Antes de tudo, qualquer pessoa que queira executar a demonstração deve instalar o Intel SGX SDK e o Occlum (você pode optar por usar nosso SGX SDK modificado). Fornecemos um Dockerfile para instalação rápida do Occlum/SDK. O SGX SDK modificado serve para ajudar o atacante a decidir o momento certo.
Você também pode instalar o Occlum na máquina host. (Consulte https://github.com/occlum/occlum para mais detalhes de instalação.) De qualquer forma, você precisará instalar o Intel SGX driver no seu host primeiro, ou usar um driver SGX no kernel.
(sudo) docker build -t $Your_Image_Name .
Após a imagem ser construída, execute
(sudo) docker run -it --privileged -p $Redis_Server_Port:6379 -v $Host_SGX_Driver_Path:/dev/sgx --name "snapshot-demo" $Your_Image_Name
Aqui $Redis_Server_Port é o número da porta do host que você deseja expor para o servidor Redis dentro do contêiner, enquanto $Host_SGX_Driver_Path é o caminho do dispositivo mencionado do seu driver SGX instalado.
O programa alvo está na pasta bash_redis.
O programa vítima executa um script bash (occlum_bash.sh). Ele primeiro obtém uma senha provisionada para gerar um arquivo de configuração Redis personalizado, com a entrada "requirepass" preenchida. Em seguida, invoca um servidor Redis, de acordo com o arquivo de configuração personalizado.
Para construir o programa de geração de configuração, execute make. Para construir o servidor Redis, execute os seguintes comandos.
cd bash_redis
./download_and_build_redis_glibc.sh
Abra um terminal para a vítima. Execute run_redis.sh, verificando se o servidor Redis funciona bem.
Use o comando redis-cli -h $Redis_Server_IP -p $Redis_Server_Port -a admin123456 para verificar se a senha (admin123456) foi definida no arquivo de configuração.
Pressione ctrl + C para encerrar o servidor Redis.
Prepare 2 terminais, um para a vítima e outro para o atacante. Você pode abrir apenas mais um terminal (para o atacante) se um terminal já tiver sido aberto para a vítima.
Execute run_redis.sh novamente no terminal da vítima. Este script iniciará o programa alvo.
O atacante precisa tirar um snapshot (usando ./take_snapshot_step-1.sh) quando ele/ela puder determinar que o snapshot está sendo descarregado (flushing). Na demonstração, o atacante pode obter um aviso claro do terminal da vítima da seguinte forma.
...
Run ./take_snapshot_step-1.sh AGORA!
linha 4522: # passwords, then flags, or key patterns. However note that the additive
linha 4523: # and subtractive rules will CHANGE MEANING depending on the ordering.
linha 4524: # For instance see the following example:
...
Execute o script ./take_snapshot_step-1.sh no terminal do atacante.
Se você construir o Occlum com nosso SGX SDK modificado, verá mais mensagens de dica. Isso ocorre porque modificamos a parte não confiável do Intel SGX SDK, imprimindo mensagens auxiliares para facilitar a decisão do momento certo pelo atacante. Para conveniência do atacante, reservamos slots de tempo para permitir que o atacante execute ./take_snapshot_step-1.sh. Na verdade, o atacante que tem privilégio root no host poderia interceptar a execução do enclave e capturar quaisquer snapshots modificando a parte não confiável do SGX SDK.
Assim que o servidor Redis estiver em execução, execute ./take_snapshot_step-2.sh para completar a coleta do snapshot.
O atacante executa replay_redis.sh para reproduzir (replay) o enclave usando nosso snapshot coletado. Qualquer cliente pode fazer login no servidor Redis sem autenticação.
Exemplo de comando para cliente Redis:
redis-cli -h $Redis_Server_IP -p $Redis_Server_Port
keys *
Se uma mensagem (error) NOAUTH Authentication required. for exibida, significa que você precisará de uma senha para acessar o servidor Redis. Digite auth $Your_Password para passar pela autenticação. Use auth admin123456 nesta demonstração.
Se uma mensagem (empty array) for exibida, significa que você não precisa de senha para acessar o servidor Redis.
Às vezes a demonstração falha devido à verificação de integridade do Occlum. Provavelmente você verá a seguinte mensagem.
Replaying ...
~/snapshot-demo/bash_redis_replay/occlum_instance ~/snapshot-demo/bash_redis_replay
In: writing meta-data in write_all_changes_to_disk
In: writing meta-data in write_all_changes_to_disk
Error: Os { code: 22, kind: InvalidInput, message: "Invalid argument" }
[ERROR] occlum-pal: The init process exit with code: 1 (line 59, file src/pal_api.c)
[ERROR] occlum-pal: Failed to run the init process: EINVAL (line 129, file src/pal_api.c)
Simplesmente execute a demonstração novamente (a partir da fase de gravação) e o erro desaparecerá de vez.
Boa sorte e divirta-se!