SQL防注入
SQL注入实例
1.select语句
通常我们在用户登陆的时候,SQL语句如此写法:
$sql=select * from users where userName='{$_POST['unm']} '
主要是用来检查这个用户是否存在,
如果说我在用户名一栏填上: 1=1 or 1='1'
那么sql语句就变成了:
select * from users where userName=1=1 or 1='1';
你填上去试试看?可以轻松绕过验证,同样密码在输入的时候也可以如此做法
还可以如此填法:%1,或者*1,,只要以通配符开头都可以绕过验证
2.通配符
<form method=“POST” action=“<? echo $PHP_SELF; ?>“>
<input type=“text” name=“search”><br>
<input type=“submit” value=“Search”>
</form>
<?php
………
SELECT * FROM users WHERE username LIKE ‘%$search%’ ORDER BY username
…….
?>
’%’就是通配符,其它的通配符还有’*’和’_’,其中" * "用来匹配字段名,而" % "用来匹配字段值,注意的是%必须与like一起适用,还有一个通配符,就是下划线" _ ",它代表的意思和上面不同,是用来匹配任何单个的字符的。在上面的代码中我们用到了’*’表示返回的所有字段名,%$search%表示所有包含$search字符的内容。
在表单里提交
Aabb%’ or 1=1 order by id#
注:#在mysql中表示注释的意思,即让后面的sql语句不执行,后面将讲到。
或许有人会问为什么要用or 1=1呢,看下面,
把提交的内容带入到sql语句中成为
SELECT * FROM users WHERE username LIKE ‘%aabb%’ or 1=1 order by id# ORDER BY username
假如没有含有aabb的用户名,那么or 1=1使返回值仍为真,使能返回所有值
我们还可以这样
在表单里提交
%’ order by id#
或者
’ order by id#
带入sql语句中成了
SELECT * FROM users WHERE username LIKE ‘% %’ order by id# ORDER BY username
和
SELECT * FROM users WHERE username LIKE ‘%%’ order by id# ORDER BY username
当然了,内容全部返回。
列出所有用户了哟,没准连密码都出来哩。
3.update
我们先给出表的结构,这样大家看的明白
CREATE TABLE users (
id int(10) NOT NULL auto_increment,
login varchar(25),
password varchar(25),
email varchar(30),
userlevel tinyint,
PRIMARY KEY (id)
)
其中userlevel表示等级,1为管理员,2为普通用户
<?php
//change.php
……
$sql = "UPDATE users SET password='$pass', email='$email' WHERE id='$id'"
……
?>
Ok,我们开始注入了哦,在添email的地方我们添入
netsh@163.com’,userlevel=’1
sql语句执行的就是
UPDATE users SET password='youpass',
email='netsh@163.com’,userlevel=’1’ WHERE id='youid’
看看我们的userlevel就是1了,变成管理员了哟
哈哈,如此之爽,简直是居家旅行必备啊。
这里我们简单提一下单引号闭合的问题,如果只用了一个单引号而没有单引号与之组成一对,系统会返回错误。列类型主要分为数字类型,日期和时间类型,字符串类型,然而引号一般用在字符串类型里,而在数字类型里一般人都不会用到引号(然而却是可以用的,而且威力很大),日期和时间类型就很少用于注入了(因为很少有提交时间变量的)
4.insert
看看表的结构先
CREATE TABLE membres (
id varchar(15) NOT NULL default '',
login varchar(25),
password varchar(25),
email varchar(30),
userlevel tinyint,
PRIMARY KEY (id)
)
我们仍然假设userlevel表示用户等级,1为管理者,2为普通用户哈。
代码如下
<?php
//reg.php
……
$query = "INSERT INTO members VALUES('$id','$login','$pass','$email',’2')" ;
……
?>
默认插入用户等级是2
现在我们构建注入语句了哦
还是在要我们输入email的地方输入:
netsh@163.com’,’1’)#
sql语句执行时变成了:
INSERT INTO membres VALUES ('youid','youname','youpass',' netsh@163.com’,’1’)#',?')
看我们一注册就是管理员了。
#号表示什么来着,不是忘了吧,晕了,这么快?
忘就忘了吧,下面再详细给你说说
5.mysql中的注释
这个是很重要的,大家可不能再睡觉啦,要是再睡觉到期末考试的时候就挂了你们。
我们继续
相信大家在上面的几个例子中已经看到注释的强大作用了吧,这里我们将再详细介绍一下。
Mysql有3种注释句法
# 注射掉注释符后面的本行内容
-- 注射效果同#
/* ... */ 注释掉符号中间的部分
对于#号将是我们最常用的注释方法。
-- 号记得后面还得有一个空格才能起注释作用。
/*…*/ 我们一般只用前面的/*就够了,因为后面的我们想加也不行,是吧?
注意:在浏览器地址栏输入#时应把它写成%23,这样经urlencode转换后才能成为#,从而起到注释的作用。#号在浏览器的地址框中输入的话可什么也不是哦。
为了大家深刻理解
这里我给大家来个例题
有如下的管理员信息表
CREATE TABLE alphaauthor (
Id tinyint(4) NOT NULL auto_increment,
UserName varchar(50) NOT NULL default '',
PASSWORD varchar(50) default NULL,
Name varchar(50) default NULL,
PRIMARY KEY (Id),
UNIQUE KEY Id (Id),
KEY Id_2 (Id)
)
<?php
//Login.php
……
$query="select * from alphaauthor where UserName='$username' and Password='$passwd'";
$result=mysql_query($query);
$data=mysql_fetch_array($result);
if ($data)
{
Echo “重要信息”;
}
Else
Echo “登陆失败”;
……
?>
我们在浏览器地址框直接输入
http://***/login.php?username=a’or id=1 %23
%23转换成#了
放到sql语句中
select * from alphaauthor where UserName='a’or id=1 #' and Password='$passwd'
#号后面的都拜输入了,看看
这句话等价于
select * from alphaauthor where UserName='a’or id=1
再仔细看看表的结构,只要有id=1的账户,返回的$data就应该为真
我们就直接登陆了,当然你也可以写
hppt://***/login.php?username=a’or 1=1 %23
一样的啦
简单投票系统[防刷程序刷新]
<?php
include_once("../inc/connect.php");
$value =$_SERVER['HTTP_HOST'];
if(empty($_COOKIE["cook"])){
if(sizeof($_POST)<9){ exit("<script>alert('对不起,你还有选项未选!');history.back();</script>");}
for($i=1;$i<=8;$i++){
$c =$_POST['r'.$i];
switch( intval($c) ){
case 0:
$word ='vote_r1';
break;
case 1:
$word ='vote_r2';
break;
case 2:
$word ='vote_r3';
break;
default:
exit('error');
}
$sql ="update gx_votes set $word=$word+1,vote_times=vote_times+1 where id=$i";
mysql_query($sql) or die(mysql_error());
}
if( !empty($_POST['r9']) || !empty($_POST['r10']) ){ sava_voteinfo();}
echo "<script>alert('感谢你的参与,你的报表己提交!');history.back();</script>";
setcookie("cook", $value, time()+7200, "/");
}else{
print "对不起,你己经投票了,<a href=# onclick=\"history.back();\">点击返回</a>";
}
function sava_voteinfo(){
$vote_modi =addslashes(php_sava(isset($_POST['r9'])?$_POST['r9']:''));
$vote_info =addslashes(php_sava(isset($_POST['r10'])?$_POST['r10']:''));
$vote_ip =isset($_SERVER['REMOTE_ADDR'])?$_SERVER['REMOTE_ADDR']:'未获取到IP';
$vote_time =date("Y-m-d H:i:s");
$vote_sql ="Insert into ss(vote_ip,vote_modi,vote_info,vote_time) value('$vote_ip','$vote_modi','$vote_info','$vote_time')";
mysql_query($vote_sql) or die('error');
}
function php_sava($str)
{
$farr = array(
"/\s+/",
"/<(\/?)(script|i?frame|style|html|body|title|link|meta|\?|\%)([^>]*?)>/isU",
"/(<[^>]*)on[a-zA-Z]+\s*=([^>]*>)/isU",
);
$tarr = array(
" ",
"<\\1\\2\\3>", //如果要直接清除不安全的标签,这里可以留空
"\\1\\2",
);
$str = preg_replace( $farr,$tarr,$str);
return $str;
}
?>
最新说一下,这种用cookie形式的程序可以清除cookie再刷,有一种办法是我以前做过了,先是客户端防刷然后再把用户的IP保存到数据库,这样用户刷时就会用php程序来检查是否在我们规定的时间内操作喽这样就可以实现真正的防刷喽.
非法字符过滤本文章主要是讲 php 过滤非法字符没讲asp过滤非法字符 的函数但是思想都一样的.
) 过滤影响MySQL正常运行的字符。
当需要把用户输入的内容(有可能包含单引号、双引号 、反斜线、空字元 NUL )代入到mysql的语句 中执行时,应该把APACHE中的magic_quotes_gpc项设成On。
如果APACHE中的此项设成Off时,也可用php的函数addslashes()达到相同的目的,但这两种手段不能同时使用,否则会出现重复替换,出现错误。
样例:
PHP代码
<?php
if (get_magic_quotes_gpc()) {
$content=$_POST["content"];
} else {
$content=addslashes($_POST["content"]);
}
?>
当然,如果APACHE中的magic_quotes_gpc项为On,但有时又不想转义某项的特殊字符,可以使用stripslashes()去掉其中的 \
2) 过滤影响MSSQL正常运行的字符。
当需要把用户输入的内容(有可能包含单引号)代入到mssql的语句中执行时,应该把APACHE中的magic_quotes_sybase项设成On,此时magic_quotes_gpc项不再生效。
如果APACHE中的此项设成Off时,php中并没有合适的函数达到相同的目的,只能使用字符串替换函数来达到此目的。
样例:
PHP代码
<?php
$content=str_replace("'","''"$_POST["content"]);
?>
现在10.218.17.53上的PHP既要访问mysql又要访问mssql,APACHE中的设置不能兼顾两种数据库,所以只对mysql做了相应设置。
2. 应对用户输入包含SQL语句的一个措施。
以下两种SQL写法都比较普遍,但安全程度是不同的,当用户提交的$id='1 and 1=2 union select ...'时第一种就会显示出不该显示的数据,而第二种就相对安全些。
SQL代码
Select * FROM article Where articleid=$id
Select * FROM article Where articleid='$id'
3. 防止用户输入的内容因包含html标签或javascript而影响页面的正常显示。
可以用htmlspecialchars()过滤其中的 & " < >
PHP代码
$content = htmlspecialchars($content);
4. 当页面要显示的内容包含回车换行时,可以使用nl2br()来达到页面上换行的效果。
方法一.
<?
function chkstr($paravalue,$paratype) //过滤非法字符
{
if($paratype==1)
{
$inputstr=str_replace("'","''",$paravalue);
}
elseif($paratype==2)
{
$inputstr=str_replace("'","",$paravalue);
}
return $inputstr;
}
$user1=chkstr($_GET["user"],1);
$user2=chkstr($_GET["user"],2);
//$user=$_GET["user"];
print "方式1-----------------<br>";
print "$user1 <br>";
print "方式2-----------------<br>";
print "$user2 <br>";
?>
方法二.
<?php
//用法:qstr($str, get_magic_quotes_gpc())
function qstr($string, $magic_quotes=false, $tag=false)
{
$tag_str = '';
if ($tag) $tag_str = "'";
if (!$magic_quotes) {
if (strnatcmp(PHP_VERSION, '4.3.0') >= 0) {
return $tag_str.mysql_real_escape_string($string).$tag_str;
}
$string = str_replace("'", "[url=file://\\]\\'[/url]" , str_replace('\\', '\\\\', str_replace("\0", "[url=]\\\0[/url]", $string)));
return $tag_str.$string.$tag_str;
}
return $tag_str.str_replace('\\"', '"', $string).$tag_str;
}
?>
Public Function DecodeFilter(html, filter)
html=LCase(html)
filter=split(filter,",")
For Each i In filter
Select Case i
Case "SCRIPT" ' 去除所有客户端脚本javascipt,vbscript,jscript,js,vbs,event,...
html = exeRE("(javascript|jscript|vbscript|vbs):", "#", html)
html = exeRE("</?script[^>]*>", "", html)
html = exeRE("on(mouse|exit|error|click|key)", "", html)
Case "TABLE": ' 去除表格<table><tr><td><th>
html = exeRE("</?table[^>]*>", "", html)
html = exeRE("</?tr[^>]*>", "", html)
html = exeRE("</?th[^>]*>", "", html)
html = exeRE("</?td[^>]*>", "", html)
html = exeRE("</?tbody[^>]*>", "", html)
Case "CLASS" ' 去除样式类class=""
html = exeRE("(<[^>]+) class=[^ |^>]*([^>]*>)", "$1 $2", html)
Case "STYLE" ' 去除样式style=""
html = exeRE("(<[^>]+) style=""[^""]*""([^>]*>)", "$1 $2", html)
html = exeRE("(<[^>]+) style='[^']*'([^>]*>)", "$1 $2", html)
Case "IMG" ' 去除样式style=""
html = exeRE("</?img[^>]*>", "", html)
Case "XML" ' 去除XML<?xml>
html = exeRE("<\?xml[^>]*>", "", html)
Case "NAMESPACE" ' 去除命名空间<o></o>
html = exeRE("</?[a-z]+:[^>]*>", "", html)
Case "FONT" ' 去除字体<font></font>
html = exeRE("</?font[^>]*>", "", html)
html = exeRE("</?a[^>]*>", "", html)
html = exeRE("</?span[^>]*>", "", html)
html = exeRE("</?br[^>]*>", "", html)
Case "MARQUEE" ' 去除字幕<marquee></marquee>
html = exeRE("</?marquee[^>]*>", "", html)
Case "OBJECT" ' 去除对象<object><param><embed></object>
html = exeRE("</?object[^>]*>", "", html)
html = exeRE("</?param[^>]*>", "", html)
'html = exeRE("</?embed[^>]*>", "", html)
Case "EMBED"
html = exeRE("</?embed[^>]*>", "", html)
Case "DIV" ' 去除对象<object><param><embed></object>
html = exeRE("</?div([^>])*>", "$1", html)
html = exeRE("</?p([^>])*>", "$1", html)
Case "ONLOAD" ' 去除样式style=""
html = exeRE("(<[^>]+) onload=""[^""]*""([^>]*>)", "$1 $2", html)
html = exeRE("(<[^>]+) onload='[^']*'([^>]*>)", "$1 $2", html)
Case "ONCLICK" ' 去除样式style=""
html = exeRE("(<[^>]+) onclick=""[^""]*""([^>]*>)", "$1 $2", html)
html = exeRE("(<[^>]+) onclick='[^']*'([^>]*>)", "$1 $2", html)
Case "ONDBCLICK" ' 去除样式style=""
html = exeRE("(<[^>]+) ondbclick=""[^""]*""([^>]*>)", "$1 $2", html)
html = exeRE("(<[^>]+) ondbclick='[^']*'([^>]*>)", "$1 $2", html)
End Select
Next
'html = Replace(html,"<table","<")
'html = Replace(html,"<tr","<")
'html = Replace(html,"<td","<")
DecodeFilter = html
End Function
php过滤不安全字符函数
function uh($str)
{
$farr = array(
"/\s+/",//过滤多余的空白
"/<(\/?)(script|i?frame|style|html|body|title|link|meta|\?|\%)([^>]*?)>/isU",//过滤 <script 等可能引入恶意内容或恶意改变显示布局的代码,如果不需要插入flash等,还可以加入<object的过滤
"/(<[^>]*)on[a-zA-Z]+\s*=([^>]*>)/isU",//过滤JavaScript的on事件
);
$tarr = array(
" ",
"<\\1\\2\\3>", //如果要直接清除不安全的标签,这里可以留空
"\\1\\2",
);
$str = preg_replace($farr,$tarr,$str);
return $str;
相关文章
- PHPEMS(PHP Exam Management System)在线模拟考试系统基于PHP+Mysql开发,主要用于搭建模拟考试平台,支持多种题型和展现方式,是国内首款支持题冒题和自动评分与教师评分相...2016-11-25
- SQL注入攻击指的是通过构建特殊的输入作为参数传入Web应用程序,而这些输入大都是SQL语法里的一些组合,通过执行SQL语句进而执行攻击者所要的操作 标准注入语句1.判...2016-11-25
- 本文给大家分享C#连接SQL数据库和查询数据功能的操作技巧,本文通过图文并茂的形式给大家介绍的非常详细,需要的朋友参考下吧...2021-05-17
- 这篇文章主要介绍了MySQL性能监控软件Nagios的安装及配置教程,这里以CentOS操作系统为环境进行演示,需要的朋友可以参考下...2015-12-14
- 防止SQL注入是我们程序开发人员必须要做的事情了,今天我们就来看一篇关于PHP防止SQL注入的例子了,具体的实现防过滤语句可以参考下面来看看吧。 使用prepared以及参...2016-11-25
- 这篇文章主要介绍了PostgreSQL判断字符串是否包含目标字符串的多种方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-02-23
- 这篇文章主要介绍了PostgreSQL TIMESTAMP类型 时间戳操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-12-26
- 新版 Mysql 中加入了对 JSON Document 的支持,可以创建 JSON 类型的字段,并有一套函数支持对JSON的查询、修改等操作,下面就实际体验一下...2016-08-23
- 这篇文章主要介绍了postgresql 实现多表关联删除操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-01-02
- 这篇文章主要介绍了Postgresl 如何选择正确的关闭模式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-01-18
深入研究mysql中的varchar和limit(容易被忽略的知识)
为什么标题要起这个名字呢?commen sence指的是那些大家都应该知道的事情,但往往大家又会会略这些东西,或者对这些东西一知半解,今天我总结下自己在mysql中遇到的一些commen sense类型的问题。 ...2015-03-15- 这篇文章主要介绍了postgresql数据添加两个字段联合唯一的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-02-04
- 这篇文章主要介绍了MySQL 字符串拆分操作(含分隔符的字符串截取),具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-02-22
- 一、先说一下为什么要分表:当一张的数据达到几百万时,你查询一次所花的时间会变多,如果有联合查询的话,有可能会死在那儿了。分表的目的就在于此,减小数据库的负担,缩短查询时间。根据个人经验,mysql执行一个sql的过程如下:1...2014-05-31
- 这篇文章主要介绍了Vscode上使用SQL的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-01-26
- 我们自己鼓捣mysql时,总免不了会遇到这个问题:插入中文字符出现乱码,虽然这是运维先给配好的环境,但是在自己机子上玩的时候咧,总得知道个一二吧,不然以后如何优雅的吹牛B。...2015-03-15
- 这篇文章主要介绍了PostgreSQL 字符串处理与日期处理操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-02-01
- 这几天在centos下装mysql,这里记录一下安装的过程,方便以后查阅Mysql5.5.37安装需要cmake,5.6版本开始都需要cmake来编译,5.5以后的版本应该也要装这个。安装cmake复制代码 代码如下: [root@local ~]# wget http://www.cm...2015-03-15
- 这篇文章主要介绍了postgresql重置序列起始值,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-01-04
- 宿主机使用网线的时候,客户机在Bridged Adapter模式下,使用Atheros AR8131 PCI-E Gigabit Ethernet Controller上网没问题。 宿主机使用无线的时候,客户机在Bridged Adapter模式下,使用可选项里唯一一个WIFI选项,Microsoft Virtual Wifi Miniport Adapter也无法上网,故弃之。...2013-09-19