前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >二次注入简单介绍

二次注入简单介绍

作者头像
Al1ex
发布2024-04-28 10:05:11
950
发布2024-04-28 10:05:11
举报
文章被收录于专栏:网络安全攻防网络安全攻防
基本介绍

这里所谓的二次注入其实就是将可能导致SQL注入的字符先存入到数据库中,而当我们再次调用这个恶意构造的字符时就可以触发SQL注入,这一种注入在平时并不常见,但是确实是存在的一种注入,故此在这里将其单独拎出来说一下

注入原理

二次注入的原理是在第一次进行数据库插入数据的时候,仅仅只是使用了addslashes或者是借助get_magic_quotes_gpc对其中的特殊字符进行了转义,在写入数据库的时候还是保留了原来的数据,但是数据本身还是脏数据,在将数据存入到了数据库中之后开发者就认为数据是可信的,在下一次进行需要进行查询的时候直接从数据库中取出了脏数据,没有进行进一步的检验和处理,这样就会造成SQL的二次注入,比如在第一次插入数据的时候,数据中带有单引号,直接插入到了数据库中然后在下一次使用中在拼凑的过程中就形成了二次注入:

总结起来二次注入其实是分为两个步骤:

  • 插入恶意数据
  • 引用恶意数据
注入思路

二次排序注入思路:

1、黑客通过构造数据的形式在浏览器或者其他软件中提交HTTP数据报文请求到服务端进行处理,提交的数据报文请求中可能包含了黑客构造的SQL语句或者命令 2、服务端应用程序会将黑客提交的数据信息进行存储,通常是保存在数据库中,保存的数据信息的主要作用是为应用程序执行其他功能提供原始输入数据并对客户端请求做出响应 3、黑客向服务端发送第二个与第一次不相同的请求数据信息 4、服务端接收到黑客提交的第二个请求信息后为了处理该请求,服务端会查询数据库中已经存储的数据信息并处理,从而导致黑客在第一次请求中构造的SQL语句或者命令在服务端环境中执行 5、服务端返回执行的处理结果数据信息,黑客可以通过返回的结果数据信息判断二次注入漏洞利用是否成功

注入案例

这里以Sql-labs中的Less-24为例做演示:

程序源代码

login_create.php

代码语言:javascript
复制
<html>
<head>
</head>
<body bgcolor="#000000">
<?PHP
session_start();
?>
<div align="right">
<a style="font-size:.8em;color:#FFFF00" href='index.php'><img src="../images/Home.png" height='45'; width='45'></br>HOME</a>
</div>
<?php

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



if (isset($_POST['submit']))
{
  

# Validating the user input........

  //$username=  $_POST['username'] ;
  $username=  mysql_escape_string($_POST['username']) ;
  $pass= mysql_escape_string($_POST['password']);
  $re_pass= mysql_escape_string($_POST['re_password']);
  
  echo "<font size='3' color='#FFFF00'>";
  $sql = "select count(*) from users where username='$username'";
  $res = mysql_query($sql) or die('You tried to be smart, Try harder!!!! :( ');
    $row = mysql_fetch_row($res);
  
  //print_r($row);
  if (!$row[0]== 0) 
    {
    ?>
    <script>alert("The username Already exists, Please choose a different username ")</script>;
    <?php
    header('refresh:1, url=new_user.php');
       } 
    else 
    {
           if ($pass==$re_pass)
      {
        # Building up the query........
           
           $sql = "insert into users ( username, password) values(\"$username\", \"$pass\")";
           mysql_query($sql) or die('Error Creating your user account,  : '.mysql_error());
          echo "</br>";
          echo "<center><img src=../images/Less-24-user-created.jpg><font size='3' color='#FFFF00'>";           
          //echo "<h1>User Created Successfully</h1>";
          echo "</br>";
          echo "</br>";
          echo "</br>";          
          echo "</br>Redirecting you to login page in 5 sec................";
          echo "<font size='2'>";
          echo "</br>If it does not redirect, click the home button on top right</center>";
          header('refresh:5, url=index.php');
      }
      else
      {
      ?>
      <script>alert('Please make sure that password field and retype password match correctly')</script>
      <?php
      header('refresh:1, url=new_user.php');
      }
    }
}

?>

</body>
</html>

从以上代码来主要实现用户注册功能,且对用户的账号密码中的特殊字符进行了转义~

login.php

代码语言:javascript
复制
<html>
<head>
</head>
<body bgcolor="#000000">
<font size="3" color="#FFFF00">
<div align="right">
<a style="font-size:.8em;color:#FFFF00" href='index.php'><img src="../images/Home.png" height='45'; width='45'></br>HOME</a>
</div>
<?PHP

session_start();
//including the Mysql connect parameters.
include("../sql-connections/sql-connect.php");




function sqllogin(){

   $username = mysql_real_escape_string($_POST["login_user"]);
   $password = mysql_real_escape_string($_POST["login_password"]);
   $sql = "SELECT * FROM users WHERE username='$username' and password='$password'";
//$sql = "SELECT COUNT(*) FROM users WHERE username='$username' and password='$password'";
   $res = mysql_query($sql) or die('You tried to be real smart, Try harder!!!! :( ');
   $row = mysql_fetch_row($res);
  //print_r($row) ;
   if ($row[1]) {
      return $row[1];
   } else {
          return 0;
   }

}






$login = sqllogin();
if (!$login== 0) 
{
  $_SESSION["username"] = $login;
  setcookie("Auth", 1, time()+3600);  /* expire in 15 Minutes */
  header('Location: logged-in.php');
} 
else
{
?>
<tr><td colspan="2" style="text-align:center;"><br/><p style="color:#FF0000;">
<center>
<img src="../images/slap1.jpg">
</center>
</p></td></tr>
<?PHP
} 
?>






</body>
</html>

以上代码主要实现用户登录认证功能~

pass_change.php

代码语言:javascript
复制
<html>
<head>
</head>
<body bgcolor="#000000">
<?PHP
session_start();
if (!isset($_COOKIE["Auth"]))
{
  if (!isset($_SESSION["username"])) 
  {
       header('Location: index.php');
  }
  header('Location: index.php');
}
?>
<div align="right">
<a style="font-size:.8em;color:#FFFF00" href='index.php'><img src="../images/Home.png" height='45'; width='45'></br>HOME</a>
</div>
<?php

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



if (isset($_POST['submit']))
{
  
  
  # Validating the user input........
  $username= $_SESSION["username"];
  $curr_pass= mysql_real_escape_string($_POST['current_password']);
  $pass= mysql_real_escape_string($_POST['password']);
  $re_pass= mysql_real_escape_string($_POST['re_password']);
  
  if($pass==$re_pass)
  {  
    $sql = "UPDATE users SET PASSWORD='$pass' where username='$username' and password='$curr_pass' ";
    $res = mysql_query($sql) or die('You tried to be smart, Try harder!!!! :( ');
    $row = mysql_affected_rows();
    echo '<font size="3" color="#FFFF00">';
    echo '<center>';
    if($row==1)
    {
      echo "Password successfully updated";
  
    }
    else
    {
      header('Location: failed.php');
      //echo 'You tried to be smart, Try harder!!!! :( ';
    }
  }
  else
  {
    echo '<font size="5" color="#FFFF00"><center>';
    echo "Make sure New Password and Retype Password fields have same value";
    header('refresh:2, url=index.php');
  }
}
?>
<?php
if(isset($_POST['submit1']))
{
  session_destroy();
  setcookie('Auth', 1 , time()-3600);
  header ('Location: index.php');
}
?>
</center>  
</body>
</html>

以上代码为修改密码逻辑,在L38行会更新用户的账号密码,此处我们如果先通过注册方式注册一个带有注释符的账号,例如:admin'#,那么在更新密码时,更新的sql语句就会变成下面的这样:

代码语言:javascript
复制
$sql = "UPDATE users SET PASSWORD='$pass' where username=' admin'# ' and password='$curr_pass' ";

由此可见,可以直接将后门的语句全部给注释掉,最后实现对admin账号的改密码操作,下面具体来实现一下~

初始用户表
注册恶意账号

注册一个admin'#账号:

查询表内信息

再次查询用户表信息时发现出现了admin'#账户:

登陆恶意账号

随后登陆admin'#账号

修改账号密码

随后进入修改密码的页面设置新的密码,这里打算给admin账号设置一个新的密码:

提交表单之后成功修改账号密码

admin密码被改

再次查看用户表发现admin账号的密码发生了变化,改为了——al1ex,成功实现了二次排序注入

文末小结

当目标系统有对用户的输入进行转义但是没有进行替换操作时,可能存在二次排序注入的可能性,这时候可以找相关的利用点,例如:上面的用户注册到更新用户信息

本文参与?腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2024-04-27,如有侵权请联系?cloudcommunity@tencent.com 删除

本文分享自 七芒星实验室 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与?腾讯云自媒体分享计划? ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 基本介绍
  • 注入原理
  • 注入思路
  • 注入案例
    • 程序源代码
      • 初始用户表
        • 注册恶意账号
          • 查询表内信息
            • 登陆恶意账号
              • 修改账号密码
                • admin密码被改
                • 文末小结
                相关产品与服务
                数据库
                云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
                http://www.vxiaotou.com