SQL注入 Less24(二次注入)

本文详细讲解了存储型二次注入的原理,通过实例演示如何利用未转义的用户输入在PHP环境中触发漏洞,包括数据原封存储、数据库查询时不校验的环节。重点介绍了如何通过验证、转义策略的不足导致攻击成功,并给出了修复建议。
摘要由CSDN通过智能技术生成

二次注入原理

二次注入(存储型注入),这种手法所利用的原理是:在网站处理用户提交的数据的时候,只是将某些敏感字符进行了转义。因而使得用户第一次提交的时候不会被当做代码执行。但是这些数据存入数据库的时候却没有转义(比如用户输入的数据为admin'#,进行执行代码的时候会转义为admin\'#,存入数据库的数据仍为admin'#),而网站程序默认数据库中的数据都是安全的,当网站程序第二次调用刚才存储的脏数据的时候,则不会转义使用而是直接使用,因此就会达到注入的效果。

注意两点:
1、网站会将数据原封不动的存入数据库中。
2、网站会直接调用数据库中的数据而不会对其进行检测等操作。(信任数据库中的数据)

第一次进行数据库插入数据的时候,使用了 addslashes 、get_magic_quotes_gpc、mysql_escape_string、mysql_real_escape_string等函数对其中的特殊字符进行了转义,但是addslashes有一个特点就是虽然参数在过滤后会添加 “\” 进行转义,但是“\”并不会插入到数据库中,在写入数据库的时候还是保留了原来的数据。在将数据存入到了数据库中之后,开发者就认为数据是可信的。在下一次进行需要进行查询的时候,直接从数据库中取出了脏数据,没有进行进一步的检验和处理,这样就会造成SQL的二次注入。

  • 第一步:插入恶意数据
    进行数据库插入数据时,对其中的特殊字符进行了转义处理,在写入数据库的时候又保留了原来的数据。
  • 第二步:引用恶意数据
    开发者默认存入数据库的数据都是安全的,在进行查询时,直接从数据库中取出恶意数据,没有进行进一步的检验的处理。并不会进行转义操作,而是直接拼接到SQL语句中执行。

Less24黑盒

在这里插入图片描述
一个用户登录界面,可以注册新用户和登录。

我们登录一个Dumb:Dumb看一下
在这里插入图片描述
可以更改密码

我们看一下我们当前的users表
在这里插入图片描述
我们注册一个新用户admin'#,密码为123456
在这里插入图片描述
admin'#是直接原数据存入了数据库

我们登录admin'#用户,进行修改密码
在这里插入图片描述
将密码修改为nihao
在这里插入图片描述
但发现admin用户的密码变为了nihao

然后我们就获得了admin:nihao,可以登录这个账户了。这就是我们的目的

Less24白盒

注册用户

<?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');
			}
		}
}



?>

对用户输入的数据进行了转义

	$username=  mysql_escape_string($_POST['username']) ;
	$pass= mysql_escape_string($_POST['password']);
	$re_pass= mysql_escape_string($_POST['re_password']);

插入数据库

insert into users ( username, password) values(\"$username\", \"$pass\")

为什么插入的是原数据而不是转义后的数据,我觉得应该是数据库内部的操作,自动去除了转义符\
之所以转义,是为了预防用户进行SQL注入

修改密码

<?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');
	}
}
?>

同样对用户输入的数据进行了转义

	$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']);

但是注意,这里的username是直接拿过来的,没有进行转义操作!!!
如果对username进行转义了,就不会出现二次注入漏洞了

UPDATE users SET PASSWORD='$pass' where username='$username' and password='$curr_pass'

https://blog.csdn.net/hhhhhhhhh85/article/details/121328475
https://blog.csdn.net/weixin_43901998/article/details/107288123

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

开心星人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值