sqli-labs靶场详解less-24(二次注入)

news2024/12/28 20:29:22

less-24

对于一个像我一样的小白来说这关就像php代码审计 

一开始进行判断注入点的时候怎么都找不到一点思路都没有

只能搜教程 说是二次注入 从来没遇见的题型 于是从代码审计开始

先说一下什么叫二次注入

二次注入
二次注入是指通过SQL语句存储到数据库的用户输入被读取后再次被SQL语句执行导致的注入。

原理
在第一次进行数据库插入数据的时候,仅仅只是使用了个别函数对其中的特殊字符进行了转义,在后端代码中可能被转义,但在存入数据库时还是原来的数据,数据中一般带有单引号和#号,然后下次使用拼凑SQL语句中,所以就形成了二次注入。
 

代码分析

login.php

<?PHP
session_start();
//当调用 session_start() 函数时,PHP 会检查当前请求中是否存在会话标识符(通常是通过 cookie 或 URL 参数传递的),
//如果存在会话标识符,则会恢复之前的会话数据;如果不存在会话标识符,则会创建一个新的会话,并生成一个唯一的会话标识符。
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'"; //把转义后的用户和密码带入到数据库中进行查找 
   $res = mysql_query($sql) or die('You tried to be real smart, Try harder!!!! :( ');//执行 如果失败返回提示信息
   $row = mysql_fetch_row($res); //
   if ($row[1]) {      //$row[1]也就是username的位置 看看是否有值
			return $row[1];
   } else {
      		return 0;
   }
}
$login = sqllogin();//将函数返回值给login参数
if (!$login== 0)     //如果username位置有值
{
	$_SESSION["username"] = $login;//给会话赋值
	setcookie("Auth", 1, time()+3600);  /* expire in 15 Minutes */
	header('Location: logged-in.php');//转到另一个logged-in.php
} 
else
{
?>
<img src="../images/slap1.jpg">
<?PHP
} 
?>

Logged-in.php

<?PHP
session_start();
if (!isset($_COOKIE["Auth"]))//如果cookie的auth的值不存在进入语句块
{
	if (!isset($_SESSION["username"])) //回话的username不存在进入语句块
	{
   		header('Location: index.php');//跳转到首页 也就是登录界面
	}
	header('Location: index.php');//同理 我感觉这两个跳转 在这个位置放一个就行
}
?>
//如果会话存在往下走 也就是cookie
<img src="../images/Logged-in.jpg"></br><font size="4" color="#FFFF00"></br></br>
YOU ARE LOGGED IN AS </br> 
<?php
echo $_SESSION["username"];//输出session中的username的值
?>
You can Change your password here. //如果修改密码跳转页面到passs_change.php页面
<form name="mylogin" method="POST" action="pass_change.php">
<strong>Current Password:</strong></font>
<strong>New Password:</strong>
<strong>Retype Password:</strong>

pass_change.php

<?PHP
session_start();
if (!isset($_COOKIE["Auth"]))
{
	if (!isset($_SESSION["username"])) 
	{
   		header('Location: index.php');
	}
	header('Location: index.php');
}
//以上同理查看是否存在cookie和session
?>
<?php
include("../sql-connections/sql-connect.php");
if (isset($_POST['submit']))
{
	$username= $_SESSION["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();//获取sql操作了数据库的几行数据
		if($row==1)//如果一行 也就是正常的情况
		{
			echo "Password successfully updated";//输出更改成功
		}
		else//如果修改密码失败 跳转到failed.php页面
		{
			header('Location: failed.php');
		}
	}
	else//两次输出的修改密码不一样 跳转到首页面
	{
		echo "Make sure New Password and Retype Password fields have same value";
		header('refresh:2, url=index.php');
	}
}
?>
<?php
if(isset($_POST['submit1']))//删除cookie也就是退出登录
{
	session_destroy();//销毁当前会话的所有数据
	setcookie('Auth', 1 , time()-3600);//清除cookie的有效时限 也就是清除cookie
	header ('Location: index.php');//跳转到登录界面
}
?>

failed.php

<?PHP
session_start();
if (!isset($_COOKIE["Auth"]))
{
	if (!isset($_SESSION["username"])) 
	{
   		header('Location: index.php');
	}
	header('Location: index.php');
}
//以上同理查看是否存在cookie和会话
//下面特别有意思 这个页面是因为输入的原始密码不对 所以给你个提示 滚开你个愚蠢的黑客
?>
<html>
<head>
</head>
<body bgcolor="#000000">
<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>
</div>
<div style=" margin-top:150px;color:#FFF; font-size:24px; text-align:center">
<center>
<img src="../images/slap1.jpg">
</center>
</div> 
</body>
</html>

new_user.php

<?php
include '../sql-connections/sql-connect.php' ;
?>
//创建新用户的页面 把参数传给login_create.php
<a style="font-size:.8em;color:#FFFF00" href='index.php'><img src="../images/Home.png" height='45'; width='45'></br>HOME</a>
<form name="mylogin" method="POST" action="login_create.php">

<h2 style="text-align:center;background-image:url('../images/Less-24-new-user.jpg');background-repeat:no-repeat;background-position:center center">
<div style="padding-top:300px;text-align:center;color:#FFFF00;"><?php echo $form_title_ns; ?></div>
</h2>

</html>

login_create.php

<?PHP
session_start();//同理
?>
<?php
include("../sql-connections/sql-connect.php");
if (isset($_POST['submit']))//判断是否存在submit也就是提交的参数 如果有进入语句块
{
	$username=  mysql_escape_string($_POST['username']) ;//同理 对非法字符转义
	$pass= mysql_escape_string($_POST['password']);		 //同理
	$re_pass= mysql_escape_string($_POST['re_password']);//同理
	$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);//获取一行数据
	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)//两次密码输入的是否一致 一致执行代码块
			{
   				$sql = "insert into users ( username, password) values(\"$username\", \"$pass\")";//将数据插入数据库中
   				mysql_query($sql) or die('Error Creating your user account,  : '.mysql_error());//执行sql语句如果报错提醒你
					echo "<center><img src=../images/Less-24-user-created.jpg><font size='3' color='#FFFF00'>";   									
					echo "</br>Redirecting you to login page in 5 sec................";
					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');
			}
		}
}
?>

代码其实不难理解

第一步

盲猜里面有一个admin的用户

新建一个admin'#的用户  

走的login_create.php的文件

这个文件对所有的输入的非法字符转义(输入数据中的单引号注释符等)转成字符串

然后使用select count(*) from users where username='admin'#'  判断admin'#用户是否存在

不存在  使用 insert into users ( username, password) values(\"$username\", \"$pass\") 插入到数据库中(这个双引号加反斜杠就是确定双引号里面的是字符串 记住就行)

然后使用刚刚注册的进行登录

SELECT * FROM users WHERE username='$username' and password='$password'"; //把转义后的用户和密码带入到数据库中进行查找 查到后输出用户名 到这里都是没有问题的

先查看一下上帝视角users表里面的内容 原始admin账户密码是123456 刚刚我们注册时密码是 qwe

登录新建用户admin'#后我们进行更改密码为asd

服务器执行的代码是

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

这个时候就出现问题了 admin'#进入数据库的时候单引号和#号被当成了字符 但是从$username提取出来的admin'# 单引号和#号又被当成了特殊字符

于是语句就变成了

UPDATE users SET PASSWORD='asd' where username='admin'#' and password='$curr_pass'

标记红的是被注释掉了 这样就造成了无admin密码的情况下 就可以修改admin密码

这样就成功的无视原始用户密码的条件进行修改密码 前提你知道里面的用户是谁

其实这都不重要  重要的是我们发现了这个二次注入的注入点 和注入方式

有了这个我估计可以实施进一步注入 构造新的语句作为用户名

我看所有教程都是教更改密码的 没有进行下一步的注入 

有可能是太难了 没人愿意演示

也有可能是不存在下一步注入

下一步注入也是我估计的 我先不进行下一步注入 如果以后碰到类似的题 我再回来做

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1260752.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

创建SpringBoot Helloword 程序详细步骤

本文档实现SpringBoot hello word 程序&#xff0c;翻译于Spring | Quickstart 目录 一、项目创建步骤1.1 创建项目1.2 添加代码1.3 运行 参考教程 一、项目创建步骤 1.1 创建项目 在官网Spring Initializr上创建项目 1.2 添加代码 在IDE中打开项目并在src/main/java/com/zo…

【数据结构】二叉树之链式结构

&#x1f525;博客主页&#xff1a; 小羊失眠啦. &#x1f3a5;系列专栏&#xff1a;《C语言》 《数据结构》 《Linux》《Cpolar》 ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 文章目录 一、前置说明二、二叉树的遍历2.1 前序遍历2.2 中序遍历2.3 后序遍历2.4 层序遍历 三、…

mysql处理40w数据脚本执行慢问题

需求背景&#xff1a; 2张表 SS_ZYXX 1w数据&#xff0c;WD_GZPZ 50w数据 SS_ZYXX.id WD_GZPZ.zyxx_id 找到SS_ZYXX表有数据&#xff0c;关联表WD_GZPZ没有数据的SS_ZYXX表的id 处理方案 方案一&#xff1a; 联合查询&#xff1a; 下面sql&#xff0c;在mysql执行时间3…

netty(三) taskQueue自定义任务,http服务器快速入门,netty核心模块,Unpooled

如果执行某些业务比较复杂&#xff0c;比较耗时&#xff0c;可以使用异步来完成 当然可以有多个任务 上面的结果是&#xff0c;在第一个任务处理完&#xff0c;再等20秒执行&#xff0c;简单来说&#xff0c;就是第一个在10秒执行&#xff0c;第二个在第30秒的时候执行&#…

vue2使用ts vue-class-component

目前&#xff0c;对于Vue3来说&#xff0c;TypeScript的支持已经相当成熟&#xff0c;但公司的老项目一直处于迭代和维护无法从v2重构成v3&#xff0c;并且重构的成本也是很大的一个问题&#xff0c;所以记录一下vue2如何去搭配TypeScript。 目录 一、脚手架创建项目 二、vu…

二叉树的递归套路(2)

与其明天开始&#xff0c;不如现在行动&#xff01; 文章目录 最大二叉搜索树 &#x1f48e;总结 最大二叉搜索树 题目 给定一颗二叉树的头节点head&#xff0c;返回这颗二叉树中最大的二叉搜索子树的节点数量 搜索二叉树&#xff1a;整棵树上没有重复值&#xff0c;左树的值都…

解决ansible批量加入新IP涉及known_hosts报错的问题

我们把一批新的IP加入到ansible的hosts文件&#xff0c;比如/etc/ansible/hosts&#xff0c;往往会有这样的提示&#xff0c; 因为本机的~/.ssh/known_hosts文件中并有fingerprint key串&#xff0c;使用ssh连接目标主机时&#xff0c;一般会提示是否将key字符串加入到~/.ssh/…

【密码学引论】分组密码

第三章 分组密码 DES、IDEA、AES、SM4 1、分组密码定义&#xff08;按照五个组成部分答&#xff09; 密钥空间&#xff1a;属于对称加密算法kekd明密文空间&#xff1a;将明文划分为m比特的组&#xff0c;每一块依次进行加密加解密算法&#xff1a;由key决定一个明文到密文的…

Redis多机数据库

文章目录 Redis多机数据库一、主从复制1、旧版复制功能的实现a、同步b、命令传播 2、旧版复制功能的缺陷3、新版复制功能的实现a、部分同步功能b、复制实现步骤 4、心跳检测 二、哨兵1、Sentinel概念2、Sentinel初始化流程3、故障转移过程 三、集群1、几个概念2、集群创建流程a…

西南科技大学(数据结构A)期末自测练习一

一、填空题(每空0.5分,共5分) 1、数据结构是指( A )。 A、数据元素的组织形式 B、数据类型 C、数据存储结构 D、数据定义 2、数据结构被形式地定义为(D,R),其中D是( B )的有限集合,R是D上( D )的有限集合。 (1)A.算法B.数据元素C.数据操作D.逻辑结构 (2)A.操作B.…

springboot启动Table ‘xxx‘ already exists

jpa.generate-ddl和jpa.hibernate.ddl-auto都可以控制是否执行datasource.schema脚本&#xff0c;来初始化数据库结构&#xff0c;只要有一个为可执行状态就会执行&#xff0c;比如jpa.generate-ddl:true或jpa.generate-ddl:update&#xff0c;并没有相互制约上下级的关系。 要…

使用com组件编辑word

一个普通的窗体应用&#xff0c;6个button using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; u…

Kafka 如何保证消息消费的全局顺序性

哈喽大家好&#xff0c;我是咸鱼 今天我们继续来讲一讲 Kafka 当有消息被生产出来的时候&#xff0c;如果没有指定分区或者指定 key &#xff0c;那么消费会按照【轮询】的方式均匀地分配到所有可用分区中&#xff0c;但不一定按照分区顺序来分配 我们知道&#xff0c;在 Kaf…

【操作宝典】SQL Server Management

目录 ⛳️【SQL Server Management】 ⛳️1. 启动登录 ⛳️2. 忘记密码 ⛳️3. 操作数据库和表 3.1 新建数据库text 3.2 新建表 3.3 编辑表 3.4 编写脚本 ⛳️【SQL Server Management】 ⛳️1. 启动登录 需要开启服务 ⛳️2. 忘记密码 登录windows--> 安全性 -->…

优雅使用docker-compose部署Skywalking

Skywalking使用docker-compose部署 version: 3.1 services: // 部署elasetic search 用于存储获取的应用信息与日志elasticsearch:image: elasticsearch:7.13.3container_name: elasticsearchprivileged: trueenvironment:- "cluster.nameelasticsearch" #设置集群名…

Vue3使用kkFileView预览文件pdf

kkFileView - 在线文件预览kkFileView官网 - kkFileView使用Spring Boot搭建&#xff0c;易上手和部署&#xff0c;基本支持主流办公文档的在线预览&#xff0c;如doc,docx,Excel,pdf,txt,zip,rar,图片等等https://kkfileview.keking.cn/zh-cn/docs/usage.html业务场景&#xf…

powershell获取微软o365 21v日志

0x00 背景 o365 21v为o365的大陆版本&#xff0c;主要给国内用户使用。微软提供了powershell工具和接口获取云上日志。微软o365国内的代理目前是世纪互联。本文介绍如何用powershell和配置证书拉取云上日志。 0x01 实践 第一步&#xff0c;ip权限开通&#xff1a; 由世纪互联…

生命科学领域 - 新药从研发到上市全流程

新药是指新研制的、临床尚未应用的药物&#xff0c;其化学本质应为新的化合物或称新化学实体、 新 分子实体、新活性实体。新药研发的根本目的是治疗疑难危重疾病&#xff0c;研制出来的药物即使是全新的化学结构&#xff0c;但是疗效或安全性却不及现有的药物便失去新药价值&a…

JAVAEE 初阶 多线程基础(三)

启动,中断,等待基础 一.如何创建线程二.启动线程 start()1.1 调用两次start方法1.2 创建新对象解决多个start问题2.1 经典面试题 run和start的区别 三.中止线程3.1 引入标志位3.2 高级写法3.3高级写法的错误之处3.4问题的解决3.5 将标志位放在main的局部变量中是否可行 四.等待…

Android 单元测试初体验(二)-断言

[TOC](Android 单元测试初体验(二)-断言) 前言 当初在学校学安卓的时候&#xff0c;老师敢教学进度&#xff0c;翻到单元测试这一章节的时候提了两句&#xff0c;没有把单元测试当重点讲&#xff0c;只是说我们工作中几乎不会用到&#xff0c;果真在之前的几年工作当中我真的没…