terça-feira, 2 de fevereiro de 2016

Injetar código em processo de execução com linux-inject

lkubuntu

Uma listagem de aleatórios de software, dicas, tweaks, hacks, e tutoriais que eu fiz para Ubuntu

Injetar código em processo de execução com linux-injete

Eu estava prestes a título de "código Injectar, por diversão e lucro", até que percebi que isso pode dar um sentido diferente do que eu originalmente destinados ...: P
Eu não vai cobrir as razões por trás fazendo tal, porque eu tenho certeza que se você aterrou sobre este artigo, você já teria um bom senso de por que você quer fazer isso .... para o divertimento, lucro, ou ambos;)
De qualquer forma, depois de tentar vários programas e lendo sobre como fazê-lo manualmente (não é fácil!), Me deparei com linux-injeção, um programa que injeta uma .so em um aplicativo em execução, semelhante à forma como LD_PRELOAD obras, exceto que ele pode ser feito enquanto um programa está sendo executado ... e ele também não realmente substituir todas as funções, quer (mas veja o PS no final deste post para uma maneira de fazer isso). Em outras palavras, talvez ignorar o LD_PRELOAD símile: P
A documentação dele (e alguns outros programas que eu tentei) foi belos falta embora. E por uma boa razão, os desenvolvedores provavelmente esperar que a maioria dos usuários que estaria usando esses tipos de programas não seria novatos neste campo, e gostaria de saber exatamente o que fazer. Infelizmente, porém, não sou parte desse público-alvo: P Levei um longo tempo para descobrir o que fazer, por isso na esperança de que ele pode ajudar alguém, eu estou escrevendo este post! : D
Vamos começar rapidamente a clonagem e construí-la:
git clone https://github.com/gaffe23/linux-inject.git
cd linux-injete
faço
Uma vez feito isso, vamos tentar o exemplo de exemplo fornecido com o programa. Abra um outro terminal (de modo que você tem duas versões livres), cd para o diretório que você clonado linux-injetar a (por exemplo, cd ~ / workspace / linux-injeção), e executar ./sample-target.
Voltar no primeiro terminal, executar sudo ./inject -n sample-library.so amostra-alvo
O que isto significa é que injetar s biblioteca sample-library.so a um processo pelo -n ame de amostra-alvo.Se em vez disso, você quer escolher sua vítima-alvo pelo seu PID, basta usar o -p opção em vez de -n.
Mas ... isso pode ou não funcionar. Desde que o Linux 3.4, há um módulo de segurança chamado Yama que pode desativar injeções de código baseado em ptrace (período ou injeções de código, duvido que exista qualquer outra forma). Para permitir que isso funcione, você terá que executar qualquer um destes comandos (eu prefiro o segundo, por razões de segurança):
echo 0 | sudo tee / proc / sys / kernel / yama / ptrace_scope # Permite que qualquer processo de injetar código em qualquer outro processo iniciado pelo mesmo usuário. Root pode acessar todos os processos
echo 2 | sudo tee / proc / sys / kernel / yama / ptrace_scope # Somente permite raiz para injetar código
Tente novamente, e espero que você vai ver "Acabei de ser carregado" "... dormir" mensagens em-entre o.
Antes de eu chegar à parte sobre como escrever seu próprio código para injetar, eu tenho que avisá-lo: Alguns aplicativos (como o VLC) vai segfault se você injetar código para eles (via linux-injeção, eu não sei sobre outros programas, este é o primeiro programa de injeção que eu consegui trabalhar, período: P). Certifique-se de que você está bem com a possibilidade de a queda do programa quando você injeta o código.
Com esse aviso (possivelmente ameaçador) para fora do caminho, vamos começar a escrever algum código!
#include <stdio.h>

__attribute __ ((constructor))
Olá anular () {
    puts ("Olá, mundo!");
}
Se você conhece C, a maior parte deste deve ser muito fácil de entender. A parte que me confundiu foi __ __attribute ((constructor)). Tudo isto é que se diz para executar esta função, assim que a biblioteca é carregada. Em outras palavras, esta é a função que será executado quando o código é injetado. Como você pode imaginar, o nome da função (neste caso, Olá) pode ser o que quiser.
Compilando é bastante simples, nada fora do comum requerido:
gcc -fPIC -shared -o libhello.so hello.c
Assumindo que-alvo amostra está funcionando, vamos tentar!
sudo ./inject -n libhello.so amostra-alvo
Entre a parede de "dormindo ...", você deverá ver "Olá, mundo!" Pop up!
Há um problema com isso, porém: o código interrompe o fluxo do programa. Se você tentar looping puts ("Olámundo!");, Ele irá imprimir continuamente "Olá, mundo!" (Como esperado), mas o programa principal não será retomada até que a biblioteca injetado terminar a execução. Em outras palavras, você não vai ver "dormindo ..." pop up.
A resposta é executá-lo em um segmento separado! Então, se você alterar o código para isso ...
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>

void * thread (void * a) {
    enquanto (1) {
        puts ("Olá, mundo!");
        usleep (1000000);
    }
    retornar NULL;
}

__attribute __ ((constructor))
Olá anular () {
    pthread_t t;
    pthread_create (& t, NULL, linha, NULL);
}
... Ele deve trabalhar, certo? Não se você injetá-lo para provar-alvo. amostra-alvo não está ligada a libpthread, e, portanto, qualquer função que usa funções pthread simplesmente não vai funcionar. Claro, se você ligá-lo a libpthread (adicionando -lpthread aos argumentos que ligam), ele vai funcionar bem.
No entanto, vamos mantê-lo como está, e em vez disso, use uma função que linux-injete depende:__libc_dlopen_mode (). Por que não dlopen ()? Dlopen () exige que o programa a ser ligada a libdl, enquanto __libc_dlopen_mode () está incluída na biblioteca padrão C! (versão de glibc dele, de qualquer maneira)
Aqui está o código:
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <dlfcn.h>

/ * Atacante declarar essas funções * /
void * __libc_dlopen_mode (const char *, int);
void * __libc_dlsym (void *, const char *);
int __libc_dlclose (void *);

void * thread (void * a) {
    enquanto (1) {
        puts ("Olá, mundo!");
        usleep (1000000);
    }
}

__attribute __ ((constructor))
Olá anular () {
    / * Nota libpthread.so.0. Por algum motivo,
       usando o link simbólico (libpthread.so) não funcionará * /
    void * pthread_lib = __libc_dlopen_mode ("libpthread.so.0", RTLD_LAZY);
    int (* pthread_lib_create) (void *, void *, void * (*) (void *), void *);
    pthread_t t;

    * (void **) (& pthread_lib_create) = __libc_dlsym (pthread_lib, "pthread_create");
    pthread_lib_create (& t, NULL, linha, NULL);

    __libc_dlclose (pthread_lib);
}
Se você não tiver usado as funções dl * de antes, este código provavelmente parece absolutamente louco.Gostaria de tentar explicá-lo, mas as páginas man são bastante legível, e fazer uma maneira melhor trabalho de explicar do que eu jamais poderia esperar para experimentar.
E nessa nota, você deve (espero) estar bem para injetar seu próprio código em outros processos!
Se alguma coisa não faz sentido, ou precisar de ajuda, ou apenas até para dar um agradecimento (eles são realmente apreciado !!), sentir-se mais do que livre para deixar um comentário ou envie-me um e-mail! : D E se você gosta de usar linux-injeção, certifique-se de agradecer ao autor do mesmo, bem !!
PS E se você quer mudar uma função dentro do processo de acolhimento? Este tutorial foi ficando um pouco longo, então ao invés, eu vou deixar você com isso: http://www.ars-informatica.com/Root/Code/2010_04_18/LinuxPTrace.aspx e especificamente http: //www.ars- informatica.com/Root/Code/2010_04_18/Examples/linkerex.c. Vou tentar fazer um tutorial sobre isso mais tarde, se alguém quiser :)

Nenhum comentário:

Postar um comentário