如何判断是Python语言开发?

当拿到一个网站,首先要搞清楚是否是由python语言开发的,才能知道是否有python的特性漏洞,首先看中间件,看是不是用Werkzeug中间件进行搭建的,如果是,那就是python语言开发的

c37c14cc6136311a65a0b00e9f8832de

什么是PYC文件

PYC文件就是python文件编译后生成的字节码文件。类似于JAVA的.class文件,pyc文件经过python解释器后最终会生成机器码运行,所以pyc文件是可以跨平台部署的,一般py文件改变后,对应的pyc文件也会改变,在实战中,如果我们拿到pyc文件,可以试着拿去反编译得到python文件

image-20240708212143062

接下来介绍几个反编译平台

python反编译 - 在线工具 (tool.lu)

image-20240708212254954

在线pyc,pyo,python,py文件反编译,目前支持python1.5到3.6版本的反编译-在线工具 (bugscaner.com)

image-20240708221521753

但是一般这种都在CTF中出现,在现实情况下很难遇到,因为很难拿到别人python跑出来的PYC文件

SSTI入门

什么是SSTI?

当前使用的一些框架,比如python的flask框架,PHP的tp框架,JAVA的Spring框架等一般都采用成熟的MVC模式,用户的输入先进入Controller控制器,然后根据请求类型和请求的指令发送给对应的Model业务模型进行业务逻辑判断,数据库存取,最后把结果返回给View视图层,经过模板渲染给用户

漏洞的成因就是服务器接受了用户的恶意输入后,未经过任何处理就将其作为Web应用模板内容的一部分,模板引擎在进行目标编译渲染的过程中,执行了用户插入的可以破坏模板的语句,因而可能导致敏感信息泄露、代码执行、GetShell等问题,其影响范围主要取决于模板引擎的复杂性

凡是使用模板的地方都可能出现SSTI问题,SSTI不仅仅出现于python中,但是在CTF中,SSTI主要出现在python中进行考查,正确的来讲,SSTI不属于任何一种语言,适用于所有的模板引擎

img

如何判断是否存在SSTI?

我们可以通过输入{{7*7}}观察输出的表达式是否被执行,如果被执行了,就说明存在SSTI模板注入,如下图所示

img

CTF例题

CISCN2019华东南赛区Web11

首先我们打开页面,可以看到如图的页面

image-20240708230543423

我们往下看,可以很清楚的看见Build With Smarty !的字样,我们可以知道这道题主要考的就是SSTI中的Smarty模板

3860da4d309281adc6c424147bd7ac8f

我们抓个包看看参数在哪传递进去

image-20240708232153190

我们可以看到几乎所有的参数都没有传递进去,但是有一个很可以的地方,就是它整个页面都在强调XFF,所以我们不妨大胆猜测是XFF这引起的模板注入,可以先验证一下

f440646097293883c99f0dce2546f9ba

很好,就是这里引起的模板注入,我们可以插入我们的执行代码,测试一下有没有过滤

image-20240708232527466

什么都没有过滤,我们直接读flag了

14d3e1ffe11f7164e784366203502509

成功解出这道题

Shrine

一进入页面,就看见了python源代码,可以知道是白盒测试了,直接开始一波代码审计

image-20240708233240474

看到flask就知道肯定有模板注入,关键代码@app.route('/shrine/<path:shrine>'),告诉我们路径是在shrine下的,我们进行简单的测试

image-20240708233612526

很显然是存在的,我们去网上寻找一些SSTI的POC,但是要注意,本题是限制了()的,并且存在黑名单config,self,我们要想办法绕过这两个限制

通过资料的查阅,我们可以使用以下两个python内置函数

url_for() 方法:
url_for() 会返回视图函数对应的URL。如果定义的视图函数是带有参数的,则可以将这些参数作为命名参数传入。
get_flashed_messages() 方法:
返回之前在Flask中通过 flash() 传入的闪现信息列表。把字符串对象表示的消息加入到一个消息队列中,然后通过调用 get_flashed_messages() 方法取出(闪现信息只能取出一次,取出后闪现信息会被清空)。

我们先用url_for.__globals__查看全局变量

image-20240708234212325

我们查current_app下的config

http://dd977e47-983a-46c1-aa1b-a739d74a2742.node5.buuoj.cn:81/shrine/%7B%7Burl_for.__globals__['current_app'].config%7D%7D

image-20240708234424810

我们成功拿到flag值