quinta-feira, 3 de março de 2016

Diga NÃO às drogas! falando sobre C novamente... 4dummies

Como você se sente num ambiente onde pessoas se reúnem para discutir (de forma dummies) um assunto que você já tem uma noção? - Pois é, dependendo do ensino da faculdade têm horas que dá sono! Principalmente quando estão falando de C para Windows. :(



NENHUM BOM PROFESSOR IRÁ OFERECER O USO DE DROGAS EM LUGAR ALGUM!
[Diga NÃO às drogas!] Saca seu notebook da mochila, mostre para o professor que àquele momento é uma perfeita ocasião para seus discípulos utilizarem alguma distribuição LINUX que se sinta melhor. Pode até usar Ubuntu! É melhor iniciar um ensino usando Ubuntu utilizando fgetc(); do quê, usar Windows fazendo com que os alunos se comportem feito "idiota" acomodando-se com SYSTEM("PAUSE"); e ainda pra piorar... usando DevC++! mesmo pra quem não conhece o software, é questão de uma simples pesquisa para reconhecer que este é um dos piores IDEs ultra desatualizado (ainda) existente para Windows. Ah! E outra coisa, não sei porque raios a maioria dos instrutores de instituições de ensino têm mania de apresentar uma header que não existe! Sim, estou falando da conio.h, a mesma que não faz parte dos compiladores modernos, quer vê-la funcionando? use MS Compiler 6.0 e dentre outros compiladores mais antigos. ;-)


Se você sabe que tal coisa é uma merda, não precisa ensiná-lo à se acostumar pra depois tentar fazer com que se acostume com outras. Por exemplo, acho totalmente errado o professor que realmente manja do assunto, ensinar para seu pupilo ficar usando gets(), strcpy(), scanf(), sprintf(), system() e outros... Pesquisem, leiam mais[1].


Sério, PARE de usar system("PAUSE");
[...] A não ser lógico, que quer levar uma Injeção de Comandos[2].



Podemos observar no código acima que temos um limite de 9 caracteres para executar qualquer comando que quisermos, mas isso não nos restringe de nada. Já que estamos numa interactive shell, podemos muito bem fazer o que mesmo?

clique na imagem para ampliar

Isso mesmo, criar outra sessão! :)


A função padrão system() , apesar de ser extremamente lenta... quando chamada, sabemos que é executado um específico comando. Assim como em Terminal (Unix-like systems) ou Command Prompt (Windows), a mesma têm críticas falhas a ponto de ser explorado por técnicas conhecidas como execução de código arbitrário ou aquele nome mais simples e famoso: "injeção de comandos" (do inglês, command injection).


Mostrando outra forma de explorar

Adotaremos o seguinte código abaixo (todo comentado)...



No momento que você faz o output do comando inserido, pode muito bem realizar um ataque usando o método clássico de "injeção".

'; uname -a;'

Assim, o terminal irá interpretar que estaríamos passando 2 comandos: "USER" e o "uname -a". Ou seja, da mesma forma que fizéssemos...


e agora, manjou?
Agora, vamos entender o script por completo para melhor exploração...
No início temos a inclusão do cabeçalho stdlib.h, vai servir na compilação quando o compilador ler a função getenv(), na sequencia o define que é um pré-processador, aquele que irá criar uma macro para associar o identificador com um token, que é inserido numa cadeia de caracteres. Logo, na hora da compilação, não dará erro por fato do compilador entender que o identificador MAXSIZE e u pode ser associado com qualquer cadeia de caracteres que contenha 512 (int) e "USER" (char).

stdio.h, clássico.

Uma função principal com void declarado como tipo da função e como argumento, significando que não faz retorno e não recebe argumentos. Logo mais, um ponteiro (aquele asterisco, serve para identificá-lo)! do tipo char nomeado como __env e temos abaixo um buffer nomeado como cmd, considere uma sala com um limite de 512 lugares. Posteriormente, entramos numa condição que diz... o que tiver na função getenv, iremos imprimir na tela do usuário. Até aí normal, porque ela vai chamar por: echo $USER, mas não têm nenhum interpretador de comandos para nos dar um output v3n0m, como mostrado na imagem acima. Não feliz com isso, na parte da qual entraremos com a mensagem... jogamos o diretório do interpretador "/bin/bash" (isso não irá interferir em nada, só vai imprimir o diretório), o %s que é o formato de dados para char e a variável ponteiro __env (pra onde ele está apontando?) - Certamente, apontando para o endereço que está os dados getenv(u). E assim temos como saída: "v3n0m". Ainda não satisfeito com toda esta brecha, abaixo, temos como saída (stdout == output) o valor contido no buffer que serão valores com tamanho de 512 bytes, ou seja, o nosso comando tem que ter no máximo 512 bytes. Poxa, que pouco.. não? (ironizando)

Contudo, numa mente inocente, o script faria uma impressão na tela mostrando o nome do usuário. Numa mente um pouco mais "ousada", poderíamos injetar um comando pra ter acesso ao terminal (normalmente) dentro do privilégio do usuário. Veremos...
** obs: a parte do %%execve... um "%" é o escape, seria para o compilador ler o caracter "%" ao invés de imaginar que estaríamos colocando algum formato de impressão. Ex: %s. - Ao visualizar a imagem abaixo vai esclarecer melhor.



Ok, primeira linha é o que falamos da impressão com "%%execve" e o debaixo é o resultado da função system(). Agora já entendemos né? Vamos explorar?

Raciocinando...
Já que temos um output de algo que está na variável do ambiente USER, podemos então, criar uma variável temporária chamada USER e passar alguns comandos diferentes, assim... manipulando o resultado esperado no output, será que funciona? Vamos ver...

clique na imagem para ampliar

E não é que funcionou? :D

Mesmo que você queira usar algo pra dar um "PAUSE", poxa.. utiliza o getchar().



Quer usar para ter interação com a shell do sistema? Poxa, existem 7 tipos de "exec" (execução), pode obter as informações essenciais no exec(3)[3].
Pra quê mesmo que você precisa do SYSTEM() ? Se for pra ser 0wn4d0, pode continuar que está no caminho certo. :)


Por fim, àquela tradição...



Refer:

[1] GNU Glibc : List of security vulnerabilities
https://www.cvedetails.com/vulnerability-list/vendor_id-72/product_id-767/GNU-Glibc.html
[2] Command Injection - OWASP
https://www.owasp.org/index.php/Command_Injection
[3] exec(3) - Linux manual page
http://man7.org/linux/man-pages/man3/exec.3.html