ur|编码是一种浏览器用来打包表单输入的格式。 ur|编码就是一个字符ascii码的十六进制。不过稍微有些变动,需要在前面加上“%" 。比如"\”, 它的ascii码是92 , 92的十六进制是5c ,所以"" 的ur|编码就是%5c。
转义函数
addslashes()
mysql real escape. string()
mysqL escape. string() php5.3以及之后就废除了。 。
addslashes()函数对单引号(’)、双引号(")、反斜线()与\x00 ( NULL字符)进
行处理
mysql_real_escape_string() 不会转义%和_
但是会转义: \x00, \n, \r,,’,", \x1a
解码函数
urldecode()
rawurldecode()
< ?php
echo urldecode($_ GET[‘id’]);
?>
注意:默认的GET和POST请求, php会先解码一次
日<?php
//连接数据库部分,注意使用了gbk编码
Sconn = mysql connect (' localhost', ' root', 'xoot') or die('bad!') ;
//mysq1_ query("SET NAMES "gbk'") ;
mysqL_ select db('dvwa". $conn) OR emMeg("连接数据库失败,未找到您填写的数据库");
//执行sq1语句
//$id = isset($_ GET["id']);
$id = addslashes($_ GET["id']) ;
$id = urldecode ($id) ;
//$id = addslashes($_ GET["id'l);
$sql = "SELECT * FROM guestbook WHERE comment_ id='{$id}' ";
echo ($sql) ;
Sresult = mysql_ query($sql,$conn) or die (mysql_ error());
?>
< DOCTYPE html s
日<html>
白<head>
<meta charaet="gbk" />
<title>guestbook</title>
</head>
白<body>
白<2php
$row = mysql_ fetch array ($result, MYSQL. ASSOC) ;
echo "<h2> {Srow['comment"1}</h2><p>{$row['name']}<p>\n";
mysq1_ free_ result (Sresult) ;
?>
</body>
< /html>
通过阅读源码,我们发现我们传入的ID值会先进行一次get解码,在get解码之后进行字符转义,转义之后的字符传给${id},urldecode再次进行解码后传给sql语句,在数据库进行执行。
此处,将我们需要进行sql注入构造的内容1’进行编码变成1%27,1%27为传入urldecode的内容,1%23在遇到转义函数时,由于不包含转义内容,会被直接放过,get或是post也会对传入内容进行一次解码,此处将%进行编码,变成1%2527.
解码内容如下:
i
d
=
a
d
d
s
l
a
s
h
e
s
(
id = addslashes(
id=addslashes(_ GET["id’]) ;
1%2527-get>1%27
不在转移函数的字符之内,不会进行转义。
i
d
=
u
r
l
d
e
c
o
d
e
(
id = urldecode (
id=urldecode(id) ;
1%27-urldecode>1’
构造注释符号#
“#”在url中是注释,不会传入,此处对#号进行url编码变成%23,在#号之前构造SQL语句。
产生这种问题的原因其实是逻辑的问题,如果将解码函数和转义函数进行位置更换就可以解决这个问题:
i
d
=
u
r
l
d
e
c
o
d
e
(
id = urldecode (
id=urldecode(_ GET["id’]) ;
解码过程:1%2527-get>1%27-urldecoe>1’
i
d
=
a
d
d
s
l
a
s
h
e
s
(
id = addslashes(
id=addslashes(id) ;
转义过程:1’-addslashes>1’
在进入数据库之前如果存在’等符号就会进行对应转义,转义过后传入数据库。