Web安全 学习日记3 - DVWA 普通手工SQL注入

普通注入

1、Low级别

1.1、代码分析

查看前端代码:发现是一个form表单,有id和submit两个参数,并且以GET方式提交。
在这里插入图片描述
查看后端PHP代码:

  • isset( $_REQUEST[ ‘Submit’ ] ) // 判断Submit变量是否存在
  • $id = R E Q U E S T [ ′ i d ′ ] / / 获取 i d 变量的值并赋值给变量 _REQUEST[ 'id' ] // 获取id变量的值并赋值给变量 REQUEST[id]//获取id变量的值并赋值给变量id
  • q u e r y = " S E L E C T f i r s t n a m e , l a s t n a m e F R O M u s e r s W H E R E u s e r i d = ′ query = "SELECT first_name, last_name FROM users WHERE user_id = ' query="SELECTfirstname,lastnameFROMusersWHEREuserid=id’;" //将查询语句字符串赋值给变量$query
  • r e s u l t = m y s q l i q u e r y ( result = mysqli_query( result=mysqliquery(GLOBALS[“___mysqli_ston”], q u e r y ) o r d i e ( ′ < p r e > ′ . ( ( i s o b j e c t ( query ) or die( '<pre>' . ((is_object( query)ordie(<pre>.((isobject(GLOBALS[“___mysqli_ston”]))…
    //执行查询语句,若出错则会输出错误信息。返回的结果集赋值给变量$result
    在这里插入图片描述

将结果集中first_name和last_name字段的值分别赋值给变量 f i r s t 和变量 first和变量 first和变量last,并打印输出。
在这里插入图片描述

1.2、Poc

输入单引号查询,页面报错,判断存在SQL注入。
在这里插入图片描述

如何判断是字符型还是数值型的方法,参考此链接:sql注入_字符型、数字型判断
在这里插入图片描述

输入1查询出的用户为admin,输入1+2查询出的用户还是admin,判断是字符型SQL注入。
或者
输入1 and 1=2 页面回显正常,判断是字符型SQL注入。

1.3、注入流程

1.3.1、猜字段数
1’ order by 1# 和 1’ order by 2# 回显正常,1’ order by 3# 报错,由此得到字段数目为2。使用#是注释掉后面那个单引号。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1.3.2、判断可显示字段
通过联合查询判断哪些字段可以显示出来:’ union select 1,2#
可以看到字段1和字段2都可以被显示出来
在这里插入图片描述

1.3.3、利用MySQL内置函数查询用户名和数据库名
输入:’ union select user(),database()#
得到当前用户名为root@localhost,数据库名为dvwa。
在这里插入图片描述

1.3.4、利用information_schema查询数据库名、表名、字段名

information_schema的三个表 SCHEMA,TABLES,COLUMNS 分别记录有系统上的数据库名,各个数据库的表名,各个表里面的字段名

这里需要先改一下dvwa数据库的排序规则,要和information_schema数据库的一致才行,即由 utf8_unicode_ci 改为 utf8_general_ci
具体操作为:phpMyAdmin - dvwa - 操作 - 排序规则 - 改为utf8_general_ci

获取全部数据库名称信息:’ union select 1,SHCEMA_NAME from information_schema.SCHEMA #
补充,这里我出现报错信息:Illegal mix of collations for operation ‘UNION’,解决办法参考此链接:sql注入时union出错(Illegal mix of collations for operation UNION)
在这里插入图片描述
可以看到有4个数据库,分别为information_schema,dvwa,mysql,performance_schema,sys,我们接着对名为dvwa的数据库进行SQL注入。

获取表名:’ union select 1,TABLE_NAME from information_schema.TABLES where TABLE_SCHEMA=‘dvwa’ #
在这里插入图片描述
可以看到dvwa数据库有两个表,分别为guestbook,users,很明显用户名和密码是在users表里面,我们继续对users表SQL注入。

获取字段名:'union select 1,COLUMN_NAME from information_schema.COLUMNS where TABLE_NAME = ‘users’ #
在这里插入图片描述
可以看到有许多字段,其中user和password正是我们需要的。

这里可以用group_concat()函数,使返回的结果更加醒目:‘union select 1,group_concat(COLUMN_NAME) from information_schema.COLUMNS where TABLE_NAME = ‘users’ #
或者使用limit限制输出个数:’ union select 1,COLUMN_NAME from information_schema.COLUMNS where TABLE_NAME = ‘users’ limit 0,1 #
在这里插入图片描述
在这里插入图片描述
最后爆出用户名和密码:’ union select user,password from users#
在这里插入图片描述

2、Medium级别

2.1、代码分析

通过分析前后端代码发现,Medium等级和Low等级的区别在于:

  • Medium等级的表单通过POST方式提交,所以我们需要使用BurpSuite进行抓包。
  • 在Medium级别的PHP代码里面,出现了mysqli_real_escape_string()函数,该函数的作用是转义 SQL 语句字符串中的特殊字符,如单引号【'】,双引号【"】,反斜杠【\】,百分号【%】、空字符【null】等等,转义的方式是在这些特殊字符前加上一个反斜杠【\】。
  • SQL语句中的变量$id是数值型,采取数值型的注入。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1.2、Poc
  • 输入单引号查询,页面报错,判断存在SQL注入。

  • 输入1 and 1=2,页面回显错误,判断存在数值型SQL注入。

1.3、注入流程

1.3.1、猜字段数和判断回显点和Low级别基本无差异,且不用考虑闭合单引号的问题,不做多的解释

1.3.2、利用MySQL内置函数查询用户名和数据库名,且不用考虑闭合单引号的问题,不做多的解释

1.3.3、利用information_schema爆出表名、字段名

爆表名:
union select 1,TABLE_NAME from information_schema.TABLES where TABLE_SCHEMA=0x64767761
因为 mysqli_real_escape_string() 函数会转义单引号,所以使用 16进制 进行绕过,dvwa 的16进制表示为 0x64767761
在这里插入图片描述
在这里插入图片描述

爆字段名:
union select 1,group_concat(COLUMN_NAME) from information_schema.COLUMNS where TABLE_NAME=0x7573657273
同样,因为 mysqli_real_escape_string() 函数会转义单引号,所以使用 16进制 进行绕过,users 的16进制表示为 0x7573657273

在这里插入图片描述
在这里插入图片描述

1.3.4、爆用户名、密码

union select user,password from users
在这里插入图片描述

3、High级别

High级别是在新的页面输入内容,查看源码发现只是比Low级别多了个 limit 1 来限制只输出一条,其他和Low级别一样。
在这里插入图片描述
而且查询提交页面与查询结果显示页面不是同一个,也没有执行302跳转,这样做的目的是为了防止一般的sqlmap注入(自动化注入),因为sqlmap在注入过程中,无法在查询提交页面上获取查询的结果,没有了反馈,也就没办法进一步注入。

4、Impossible级别

我们可以看到代码采用了PDO技术,划清了代码与数据的界限,有效防御SQL注入。

Check Anti-CSRF token部分:
防止CSRF攻击,Token 是在服务端产生的。如果前端使用用户名/密码向服务端请求认证,服务端认证成功,那么在服务端会返回 Token 给前端。前端可以在每次请求的时候带上 Token 证明自己的合法地位

Was a number entered?部分:
is_numeric() 函数用于检测变量是否为数字或数字字符串。
$data = $db->prepare预编译sql语句,能防止sql注入。

Make sure only 1 result is returned部分:
$data->rowCount() == 1限制了只返回一条语句。
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值