MYSQL基于SQL-LABS Less24二次注入详解

原理

二次注入是指攻击者构造的恶意数据存储在数据库后,恶意数据被读取并进入到SQL查询语句所导致的注入。防御者可能在用户输入恶意数据时对其中的特殊字符进行了转义处理,但在恶意数据插入到数据库时被处理的数据又被还原并存储在数据库中,当Web程序调用存储在数据库中的恶意数据并执行SQL查询时,就发生了SQL二次注入

二次注入思路

  • 通过构造数据的形式,在浏览器或者其他软件中提价HTTP数据报文请求到服务端进行处理,提交的数据报文请求中可能包含构造的恶意SQL语句或命令
  • 服务端将提交的请求信息进行存储,通常是保存在数据库中
  • 向服务端发送第二个与第一次不相同的请求数据信息
  • 服务端在接收到请求的信息后,为了处理该请求,调用存储的包含了构造的恶意信息的数据,从而触发SQL注入漏洞

注入分析(SQLLABS/LESS24)

观察页面,是一个登陆框,考虑是否存在POST型注入,参考MYSQL POST 型注入
MYSQL基于SQL-LABS Less24二次注入详解_第1张图片

经测试之后,账号密码处都不存在注入点;忘记密码点击之后没有响应,点击新建用户之后,可以看到新建用户,并会存在数据库中,此过程会触发post请求,执行SQL Insert请求,添加一个正确的用户尝试登陆

MYSQL基于SQL-LABS Less24二次注入详解_第2张图片

登陆之后的界面,发现需要修改密码,则这里会有一个update修改操作

MYSQL基于SQL-LABS Less24二次注入详解_第3张图片
结合所有的操作来看,那么如果构造存在危害的字段插入到数据库,那么在修改密码处可能触发二次注入

关键代码

创建用户的时候,mysql_escape_string()'#之类的转义了,所以导致没有办法注入;

创建用户执行Insert操作

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

echo "";
$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>;
    
        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_escape_string()函数将用户名和密码做了处理,所以在最开始是测试是否存在POST注入,是没有办法闭合单引号;当数据库存在该用户,则登录进入logged-in.php

登录执行Select操作

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

可以发现,$username= $_SESSION["username"];此代码是关键,username是从session中取,并且,在登录的时候可以发现,登录成功之后,$_SESSION["username"] = $login; $_session["username"]是直接存,直接取的

修改密码执行SQL Update操作


session_start();
if (!isset($_COOKIE["Auth"]))
{
	if (!isset($_SESSION["username"])) 
	{
   		header('Location: index.php');
	}
	header('Location: index.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' ";
	}
}
?>

注入流程

通过分析,以及查看关键代码,想想是否可以二次注入?二次注入主要是将有危害的语句写入数据库,那么能写入的页面则是执行创建用户,insert数据库,执行恶意SQL语句的页面则是在更新密码的时候

SQL 语句分析

// Insert
$username=  mysql_escape_string($_POST['username']) ;
$pass= mysql_escape_string($_POST['password']);
$sql = "insert into users ( username, password) values(\"$username\", \"$pass\")";
// Update
$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']);
$sql = "UPDATE users SET PASSWORD='$pass' where username='$username' and password='$curr_pass' ";

观察除了Update中username处没有使用mysql_escape_string()函数处理过,那么可以在此处做文章

  • 修改管理员密码(在update处注释掉后面and password= '$curr_pass'(正确密码))

猜测该表里有admin用户,且admin为管理员

那么由于在insert的时候,通过mysql_escape_string()函数转义了特殊字符并没有删除特殊字符,update更新表的时候,直接从session里取用户名,那么可以构造用户名为admin'#,那么带入SQL更新则是

UPDATE users SET PASSWORD='$pass' where username='admin'# and password='$curr_pass' ";

无论正确密码是多少,都可以更改admin用户的密码

MYSQL基于SQL-LABS Less24二次注入详解_第4张图片

MYSQL基于SQL-LABS Less24二次注入详解_第5张图片

MYSQL基于SQL-LABS Less24二次注入详解_第6张图片

MYSQL基于SQL-LABS Less24二次注入详解_第7张图片

  • 基于报错注入

在insert中插入报错语句updatexml或者extractValue

MYSQL基于SQL-LABS Less24二次注入详解_第8张图片
MYSQL基于SQL-LABS Less24二次注入详解_第9张图片

可以看到表中,username字段是有长度限制的,所以报错注入行不通,就更别说盲注了

你可能感兴趣的:(学习)