DOS 攻击常以 Web 应用程序中脆弱的线路或 URL 作为 目标,并向其发送精心设计的数据包或 URL,这样会迫使服务器陷入无限循环或进行 CPU 密集型运算,从而使得它从数据库中大规模加载数据,最终迫使服务器 CPU 超负荷运载以阻止服务器执行其他请求。
DDOS 攻击是指 DOS 攻击以一种精心设计的方式执行 —— 利用多系统针对单域进行攻击。通常有数千个 IP 地址被使用,这些 IP 地址由发动 DDOS 攻击的僵尸网络控制。
下面看一个关于 DOS 攻击的最小示例:
from flask import Flask
from flask import request, render_template_string, render_template
app = Flask(__name__)
TEMPLATE = '''
Hello {{ person.name }}
Hello FOO
'''
@app.route('/login')
def hello_ssti():
person = {
'name': 'world',
'secret': '7d793037a0760186574b0282f2f435e7'
}
if request.args.get('name'):
person['name'] = request.args.get('name')
template = TEMPLATE.replace('FOO', person['name'])
return render_template_string(template, person=person)
if __name__ == "__main__":
app.run(debug=True)
上面的代码同样可以使用服务器端模板注入的方式进行攻击,任何传递的表达式都会被求值,当然也包括算术运算。
我们先进行一次正常的请求,访问 http://127.0.0.1:5000/login?name=Tom
:
然后我们尝试输入一个简单的算术表达式,访问 http://127.0.0.1:5000/login?name={{ 2*2 }}
:
可以看到我们输入的算术表达式被求值了,通过传入服务器无法处理的 CPU 密集型运算,就为简单的 DOS 攻击开辟了途径。我们只需要输入一个足够大的算术表达式,它就会占用系统的 CPU,进而导致服务器超负荷运载,从而无法处理其他请求。访问 http://127.0.0.1:5000/login?name={{100%20**%2010000000}}
:
你会发现请求一直无法完成,而且因为这次计算占用了大量的系统 CPU,服务器对其他正常的请求也无法做出响应。这时候访问 http://127.0.0.1:5000/login?name=Tom
:
你会发现请求同样无法完成。
XSS 是一种常见的 Web 攻击形式,攻击者可以将恶意脚本注入服务器的代码中,这些脚本是从其他网站加载,并控制服务器。
我们使用服务器端模板和脚本注入的 XSS 脚本进行一次简单的跨站脚本攻击,访问
http://127.0.0.1:5000/login?name=Tom
(因为上面的服务已经瘫痪,这里要重启一下服务):
这次请求是使用的 edge 浏览器,其他的请求使用的都是 chrome 浏览器,因为使用 chrome 浏览器发起这次请求时,被浏览器拦截了。
对上面的例子我们使用 Jinja2 的转义过滤器 “|e” 进行转义即可。
from flask import Flask
from flask import request, render_template_string, render_template
app = Flask(__name__)
TEMPLATE = '''
Hello {{ person.name | e}}
Hello {{ person.name | e}}
'''
@app.route('/login')
def hello_ssti():
person = {
'name': 'world',
'secret': '7d793037a0760186574b0282f2f435e7'
}
if request.args.get('name'):
person['name'] = request.args.get('name')
template = TEMPLATE.replace('FOO', person['name'])
return render_template_string(template, person=person)
if __name__ == "__main__":
app.run(debug=True)
然后我们再次访问 http://127.0.0.1:5000/login?name={{%202*2%20}}
,可以看到算术表达式没有被求值了。
同样,我们再次访问 http://127.0.0.1:5000/login?name=Tom
也没有问题。