Já fiz uma pergunta sobre um tópico semelhante ( caminho do arquivo vDSO no kernel do Android x86 ), mas encontrei outro problema.
Estou trabalhando em uma pesquisa escolar sobre a vulnerabilidade do Dirty CoW. Descobri que algumas das soluções existentes exploram o vDSO causando uma condição de corrida que injeta um shellcode no objeto compartilhado.
Eu tentei replicar o ataque ao Android 4.4-r4 (x86), eu injetou com sucesso meu shellcode em vDSO (eu escrevo o conteúdo de vDSO em um arquivo após o ataque), mas o sistema parece nem ter notado . O ataque original estava injetando dois shellcodes - o primeiro foi escrito por trás do código vDSO e do código contido, que estava chamando SYS_EXECVE executando /system/bin/touch /sdcard/FILE123.txt
. O outro shellcode foi gravado no prólogo de __vdso_clock_gettime
e continha instrução chamando o primeiro shellcode.
O prólogo antes da exploração:
000006ac <__vdso_clock_gettime@@LINUX_2.6>:
6ac: 55 push %ebp
6ad: 89 e5 mov %esp,%ebp
6af: 57 push %edi
6b0: 56 push %esi
6b1: 53 push %ebx
6b2: 83 ec 10 sub $0x10,%esp
O prlogue após a exploração:
000006ac <__vdso_clock_gettime@@LINUX_2.6>:
6ac: e8 6f 07 00 00 call e20 <__kernel_vsyscall@@LINUX_2.5+0x38c>
6b1: 90 nop
6b2: 83 ec 10 sub $0x10,%esp
O outro shellcode é gravado em um espaço vazio no offset 0xe20
.
Isso não funcionou, então fiz outro shellcode, que só grava 0x90 (nop)
a partir do começo de __vdso_clock_gettime
até o final da página de memória. Isso também teve sucesso, mas não tem efeito algum. Eu até escrevi um programa C que chama clock_gettime()
:
#include <time.h>
#include <errno.h>
...
struct timespec tp;
tp.tv_sec = 0;
tp.tv_nsec = 0;
int r = clock_gettime(CLOCK_REALTIME, &tp);
if(r != 0){
printf("Gettime error (%d) - errno: %d\n", r, errno);
} else {
printf("Gettime success (%d) - time is: %d s %ld ns\n", r, tp.tv_sec, tp.tv_nsec);
}
...
Depois de compilar este programa usando o toolchain autônomo Android NDK e executá-lo (via ADB), ele sempre terá sucesso e a saída será assim:
Gettime success (0) - time is: 1517237312 s 649357893 ns
Como isso é possível? Eu destruí a função que estou chamando, então não deve funcionar, certo? Ou as chamadas para as funções do vDSO estão armazenadas em algum outro lugar? Como persuadir o sistema a chamar essa função específica?
Tags kernel android clock linux-kernel