clock_gettime chamada não usando vDSO?

0

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?

    
por Topper Harley 17.02.2018 / 13:12

0 respostas