当前位置:   article > 正文

DVWA靶场-SQL InjectionSQL注入

DVWA靶场-SQL InjectionSQL注入

 SQL Injection(SQL注入)概念

就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。具体来说,它是利用现有应用程序,将(恶意)的SQL命令注入到后台数据库引擎执行的能力,它可以通过在Web表单中输入(恶意)SQL语句得到一个存在安全漏洞的网站上的数据库,而不是按照设计者意图去执行SQL语句。

手工注入常规思路 

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

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

3.确定回显位置

4.获取当前数据库

5.获取数据库中的表

6.获取表中的字段名

7.得到数据

low等级
  1. <?php
  2. if( isset( $_REQUEST[ 'Submit' ] ) ) {
  3. // Get input
  4. $id = $_REQUEST[ 'id' ];
  5. switch ($_DVWA['SQLI_DB']) {
  6. case MYSQL:
  7. // Check database
  8. $query = "SELECT first_name, last_name FROM users WHERE user_id = '$id';";
  9. $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>' );
  10. // Get results
  11. while( $row = mysqli_fetch_assoc( $result ) ) {
  12. // Get values
  13. $first = $row["first_name"];
  14. $last = $row["last_name"];
  15. // Feedback for end user
  16. $html .= "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";
  17. }
  18. mysqli_close($GLOBALS["___mysqli_ston"]);
  19. break;
  20. case SQLITE:
  21. global $sqlite_db_connection;
  22. #$sqlite_db_connection = new SQLite3($_DVWA['SQLITE_DB']);
  23. #$sqlite_db_connection->enableExceptions(true);
  24. $query = "SELECT first_name, last_name FROM users WHERE user_id = '$id';";
  25. #print $query;
  26. try {
  27. $results = $sqlite_db_connection->query($query);
  28. } catch (Exception $e) {
  29. echo 'Caught exception: ' . $e->getMessage();
  30. exit();
  31. }
  32. if ($results) {
  33. while ($row = $results->fetchArray()) {
  34. // Get values
  35. $first = $row["first_name"];
  36. $last = $row["last_name"];
  37. // Feedback for end user
  38. $html .= "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";
  39. }
  40. } else {
  41. echo "Error in fetch ".$sqlite_db->lastErrorMsg();
  42. }
  43. break;
  44. }
  45. }
  46. ?>

 没有对用户输入进行任何过滤或转义,直接注入即可

medium等级
  1. <?php
  2. if( isset( $_POST[ 'Submit' ] ) ) {
  3. // Get input
  4. $id = $_POST[ 'id' ];
  5. $id = mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $id);
  6. switch ($_DVWA['SQLI_DB']) {
  7. case MYSQL:
  8. $query = "SELECT first_name, last_name FROM users WHERE user_id = $id;";
  9. $result = mysqli_query($GLOBALS["___mysqli_ston"], $query) or die( '<pre>' . mysqli_error($GLOBALS["___mysqli_ston"]) . '</pre>' );
  10. // Get results
  11. while( $row = mysqli_fetch_assoc( $result ) ) {
  12. // Display values
  13. $first = $row["first_name"];
  14. $last = $row["last_name"];
  15. // Feedback for end user
  16. $html .= "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";
  17. }
  18. break;
  19. case SQLITE:
  20. global $sqlite_db_connection;
  21. $query = "SELECT first_name, last_name FROM users WHERE user_id = $id;";
  22. #print $query;
  23. try {
  24. $results = $sqlite_db_connection->query($query);
  25. } catch (Exception $e) {
  26. echo 'Caught exception: ' . $e->getMessage();
  27. exit();
  28. }
  29. if ($results) {
  30. while ($row = $results->fetchArray()) {
  31. // Get values
  32. $first = $row["first_name"];
  33. $last = $row["last_name"];
  34. // Feedback for end user
  35. $html .= "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";
  36. }
  37. } else {
  38. echo "Error in fetch ".$sqlite_db->lastErrorMsg();
  39. }
  40. break;
  41. }
  42. }
  43. // This is used later on in the index.php page
  44. // Setting it here so we can close the database connection in here like in the rest of the source scripts
  45. $query = "SELECT COUNT(*) FROM users;";
  46. $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>' );
  47. $number_of_rows = mysqli_fetch_row( $result )[0];
  48. mysqli_close($GLOBALS["___mysqli_ston"]);
  49. ?>

 mysqli_real_escape_string()

mysqli_real_escape_string()函数用于对用户输入的id进行转义,以防止恶意SQL代码被插入到SQL查询语句中。通过使用这个函数,特殊字符(如单引号)将被转义,从而使输入的数据变得安全,并且不会破坏SQL查询语句的结构。

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

high等级
  1. <?php
  2. if( isset( $_SESSION [ 'id' ] ) ) {
  3. // Get input
  4. $id = $_SESSION[ 'id' ];
  5. switch ($_DVWA['SQLI_DB']) {
  6. case MYSQL:
  7. // Check database
  8. $query = "SELECT first_name, last_name FROM users WHERE user_id = '$id' LIMIT 1;";
  9. $result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( '<pre>Something went wrong.</pre>' );
  10. // Get results
  11. while( $row = mysqli_fetch_assoc( $result ) ) {
  12. // Get values
  13. $first = $row["first_name"];
  14. $last = $row["last_name"];
  15. // Feedback for end user
  16. $html .= "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";
  17. }
  18. ((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
  19. break;
  20. case SQLITE:
  21. global $sqlite_db_connection;
  22. $query = "SELECT first_name, last_name FROM users WHERE user_id = '$id' LIMIT 1;";
  23. #print $query;
  24. try {
  25. $results = $sqlite_db_connection->query($query);
  26. } catch (Exception $e) {
  27. echo 'Caught exception: ' . $e->getMessage();
  28. exit();
  29. }
  30. if ($results) {
  31. while ($row = $results->fetchArray()) {
  32. // Get values
  33. $first = $row["first_name"];
  34. $last = $row["last_name"];
  35. // Feedback for end user
  36. $html .= "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";
  37. }
  38. } else {
  39. echo "Error in fetch ".$sqlite_db->lastErrorMsg();
  40. }
  41. break;
  42. }
  43. }
  44. ?>

在上面的代码中,虽然没有直接调用mysqli_real_escape_string()函数对$_SESSION['id']进行转义处理,但是通过将$_SESSION['id']直接插入到SQL查询语句中,可以利用PHP会自动转义会话变量的特性来防止SQL注入。

SELECT first_name, last_name FROM users WHERE user_id = '$id' LIMIT 1;

这个LIMIT 1;会在sql注入中被注释符号注释掉,相当于没用

impossible等级
  1. <?php
  2. if( isset( $_GET[ 'Submit' ] ) ) {
  3. // Check Anti-CSRF token
  4. checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );
  5. // Get input
  6. $id = $_GET[ 'id' ];
  7. // Was a number entered?
  8. if(is_numeric( $id )) {
  9. $id = intval ($id);
  10. switch ($_DVWA['SQLI_DB']) {
  11. case MYSQL:
  12. // Check the database
  13. $data = $db->prepare( 'SELECT first_name, last_name FROM users WHERE user_id = (:id) LIMIT 1;' );
  14. $data->bindParam( ':id', $id, PDO::PARAM_INT );
  15. $data->execute();
  16. $row = $data->fetch();
  17. // Make sure only 1 result is returned
  18. if( $data->rowCount() == 1 ) {
  19. // Get values
  20. $first = $row[ 'first_name' ];
  21. $last = $row[ 'last_name' ];
  22. // Feedback for end user
  23. $html .= "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";
  24. }
  25. break;
  26. case SQLITE:
  27. global $sqlite_db_connection;
  28. $stmt = $sqlite_db_connection->prepare('SELECT first_name, last_name FROM users WHERE user_id = :id LIMIT 1;' );
  29. $stmt->bindValue(':id',$id,SQLITE3_INTEGER);
  30. $result = $stmt->execute();
  31. $result->finalize();
  32. if ($result !== false) {
  33. // There is no way to get the number of rows returned
  34. // This checks the number of columns (not rows) just
  35. // as a precaution, but it won't stop someone dumping
  36. // multiple rows and viewing them one at a time.
  37. $num_columns = $result->numColumns();
  38. if ($num_columns == 2) {
  39. $row = $result->fetchArray();
  40. // Get values
  41. $first = $row[ 'first_name' ];
  42. $last = $row[ 'last_name' ];
  43. // Feedback for end user
  44. $html .= "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";
  45. }
  46. }
  47. break;
  48. }
  49. }
  50. }
  51. // Generate Anti-CSRF token
  52. generateSessionToken();
  53. ?>

加了token检查

代码使用is_numeric()函数来检查id是否为数字类型。

使用intval()函数将id转换为整数类型,以确保输入的id是一个有效的整数值。

代码使用了PDO(PHP Data Objects)扩展来执行预处理语句,通过绑定参数和执行查询来防止SQL注入。

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/267477
推荐阅读
相关标签
  

闽ICP备14008679号