Introdução
João Pedro Pereira
@joaoppereira
#codebits2010
Novembro 2010
function verify($str) {
$badwords = array('javascript','expression','vbscript','script',
'applet','alert','document','write','cookie','window','<?php','<?',
'onblur','onchange','onclick','onfocus','onload','onmouseover',
'onmouseup','onmousedown','onselect','onsubmit','onunload','onkeydown',
'onkeyup','onresize','xmlns','basefont','base','behavior','blink',
'body','embed','form','frameset','frame','head','html','iframe','input',
'layer','link','meta','object','style','textarea','xml','cmd',
'passthru','eval','exec','escapeshellarg','escapeshellcmd','proc_open',
'proc_nice','shell_exec','system','fopen','fsockopen','file',
'file_get_contents','readfile','unlink','\\''\/','<','<','img',
'ALTER DATABASE','ALTER TABLE','CREATE DATABASE','CREATE TABLE',
'DROP DATABASE','DROP TABLE','RENAME TABLE','DELETE','REPLACE',
'SELECT','TRUNCATE','CREATE PROCEDURE','ALTER PROCEDURE',[.....]]);
for($x = 0; $x < count($badwords); $x++) {
preg_match("/".$badwords[$x]."/", $str, $matches);
if(count($matches) > 0) return false;
else return true;
} }
| Not Good | | | Nice |
| ---------------------- | --- | ----------------------------- |
| Plain Text | | | encoded attacks! |
| alert('xss') | | | prompt('xss') |
| <script> | | | <ScRIPT src=//0x.lv? |
| ' OR 1=1 -- | | | ' OR 2=2 -- |
| UNION SELECT | | | UNION ALL SELECT |
| /etc/passwd | | | /lol/../etc/lol/../passwd |
/^([-a-z0-9_-])+$/i /* alfanumérico + travessões */ /^[0-9]+$/ /* numeros naturais */ /^(((?:\.)(?!\.))|\w)+$/ /* nomes de ficheiros válidos */
if( $idade > 0 and $idade < 120 ) { /* code */
$query = "... AND `idade` = '$idade'";
} else die('buh');
Cuidado ! 19 UNION ALL SELECT ... Result: TRUE!
$idade < '120' //$idade < 120
Melhor ainda seria com REGEX !
Pode dar problemas com:
Procedimento Correcto:
SELECT * FROM users WHERE `login`='$_POST["user"]' AND `password`='$_POST["password"]'Request: url/?user=' or 1=1 --&password=codebits
SELECT * FROM users WHERE `login`='' OR 1=1 --Ups... Ver Código
O que é? Como explorar?
$dbh = new PDO('mysql:host=127.0.0.1;dbname=codebits_talk',
$dbUser, $dbPass);
$stmt = $dbh->prepare("SELECT * FROM `teste`
WHERE `login` = '?' AND `password` = '?'");
if ($stmt->execute(array($_GET['login'], $_GET['password']))) {
while ($row = $stmt->fetch()) {
print_r($row);
}
}
Para mais desenvolvimentos deste tema "Advanced SQL Injection: attacks" Nuno Loureiro, Tiago Mendo @ Codebits 2010
<object><param name="src" value="javascript:alert(0)"></param></object>
<object data="javascript:alert(0)">
Creditos: Alex. K (kuza55)
<isindex type=image onerror=alert(1) src=>
<isindex action=javascript:alert(1) type=image>
Creditos: Gareth Heyes
<x:script xmlns:x="http://www.w3.org/1999/xhtml">alert('xss');</x:script>
Conteúdo mostrado como text/xml | text/xml-xhtml executa JavaScript usando namespaces de HTML e xHTML.
Canonicalize / Normalize
- reduzir uma string, possívelmente codificada, e convertê-la até a sua forma mais simples;
(Algumas) Formas de Escrever "<"
%3C
0x3C
0xC0 0xBC
0xE0 0x80 0xBC
0xF0 0x80 0x80 0xBC
O que se faz no Codebits enquanto espera pelo SecurityContest part2 ?
Karaoke, Guitar Hero,... e que tal desenvolver um filtro para CSRF ?
if (top != self) {
top.location = self.location;
}
Header always append X-Frame-Options SAMEORIGIN
OWASP, Acunetix, Wikipedia, inquis, stamparm, teckV, Terry Chay, Paul Kinlan, kuza55, Gareth Heyes, Eric Kerr
Imagens:
Arraial de Engenharia 2010, XKCD.com, Chris Shiflett,