Skip to content
Permalink
Browse files
Merge commit '54dd91e7765e3fe8757936e59a719abc4572fe47' as 'Deserial'
  • Loading branch information
aa9863 committed Oct 25, 2021
2 parents d4f8498 + 54dd91e commit 15527e0344a8ad12abd4358def934b53ab6b39fd
Show file tree
Hide file tree
Showing 23 changed files with 632 additions and 0 deletions.
@@ -0,0 +1,2 @@
*~
__pycache__
@@ -0,0 +1,9 @@
version: "3.7"
services:
node:
build:
context: webapp
ports:
- "5000:3000"
expose:
- 5000
@@ -0,0 +1,16 @@
FROM node:buster-slim

WORKDIR /opt/app

#Requirements
ADD package.json /opt/app
ADD server.js /opt/app

RUN npm install

EXPOSE 3000

RUN apt-get update && apt-get install -y ncat
ADD serverflag.txt /

CMD ["node", "server.js"]
@@ -0,0 +1,16 @@
{
"name": "Vulnerable_Deserialisation_App",
"version": "1.0.0",
"description": "Node.js on Docker",
"author": "First Last <first.last@example.com>",
"main": "server.js",
"scripts": {
"start": "node server.js"
},
"dependencies": {
"express": "^4.16.1",
"cookie-parser": "latest",
"escape-html": "latest",
"node-serialize": "latest"
}
}
@@ -0,0 +1,25 @@
var express = require('express');
var cookieParser = require('cookie-parser');
var escape = require('escape-html');
var serialize = require('node-serialize');
var app = express();
app.use(cookieParser())

app.get('/', function(req, res) {
if (req.cookies.profile) {
var str = new Buffer(req.cookies.profile, 'base64').toString();
var obj = serialize.unserialize(str);
if (obj.username) {
res.send("Hello " + escape(obj.username));
}
} else {
res.cookie('profile', "eyJ1c2VybmFtZSI6IkFkaXR5YSIsImNvdW50cnkiOiJpbmRpYSIsImNpdHkiOiJEZWxoaSJ9", {
maxAge: 900000,
httpOnly: true
});
}
res.send("Hello World");
});
app.listen(3000);
console.log("Listening on port 3000...");

@@ -0,0 +1 @@
245{NodeRCEExample}
@@ -0,0 +1,12 @@
version: "3.7"
services:
flask:
build:
context: webapp
ports:
- "5000:5000"
expose:
- 5000
environment:
- FLASK_ENV=development
- FLASK_APP=/opt/webapp/app.py
@@ -0,0 +1,21 @@
FROM cueh/flask

USER root
#Netcat for the Shell
RUN apt-get update && apt-get install -y ncat

WORKDIR /opt

#Copy Files
ADD REQUIREMENTS.txt /opt

#Install Requirements
RUN pip install -r REQUIREMENTS.txt

ADD serverflag.txt /

ADD app.py /opt/webapp/
ADD templates/* /opt/webapp/templates/

CMD ["flask", "run", "--host=0.0.0.0"]

@@ -0,0 +1,3 @@
pyyaml
flask

@@ -0,0 +1,91 @@
"""
Flask Based Rework of our app
So much easier with a web interface
"""
import flask
from flask import request
import pickle

class ShoppingItem:
def __init__(self, name, cost, number = 1):
self.name = name
self.cost = cost
self.number = number

class ShoppingList:
def __init__(self):
self.shoppingList = []

def addItem(self, item):
self.shoppingList.append(item)

def calcCost(self):
totalCost = 0
for item in self.shoppingList:
totalCost += item.cost * item.number

return totalCost


def createList():
"""Helper Function to create a list"""
theList = ShoppingList()

item = ShoppingItem("foo widget", 100)
theList.addItem(item)
item = ShoppingItem("bar widget", 10, 5)
theList.addItem(item)
return theList


# ------------ AND THE APP ITSELF -----------
app = flask.Flask(__name__)
app.theList = createList()

@app.route('/')
def main():
return flask.render_template('index.html', theList = app.theList)

@app.route("/save")
def save():
#We can save the basket to a file
with open("/opt/webapp/backup.pkl","wb") as fd:
out = pickle.dump(app.theList, fd)
#fd.write(out)

return flask.send_file('backup.pkl',
mimetype='application/octet-stream',
attachment_filename='backup.pkl',
as_attachment=True)


@app.route("/load", methods=["GET","POST"])
def load():
message = None
if request.method == "POST":
print (request.files)
if 'uploadFile' in request.files:

theFile = request.files['uploadFile']
try:
data = pickle.load(theFile)#, Loader=yaml.Loader)
app.theList = data
message = "Upload Successful"
except Exception as ex:
message = "Error Loading List {0}".format(ex)


else:
message = "You must select a file to upload"


return flask.render_template('load.html', message=message)

@app.route("/pay")
def pay():

totalCost = app.theList.calcCost()

return flask.render_template("pay.html", cost=totalCost)

@@ -0,0 +1 @@
CUEH{"R0tten_P1ckLes"}
@@ -0,0 +1,59 @@
<!doctype html>

<html lang="en">
<head>
<meta charset="utf-8">

<title>The Dodgy Shopper</title>
<meta name="author" content="aa9863@coventry.ac.uk">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
</head>

<body>
<div class="container">
<h1>Dodgy PICKLE Shopper v2</h1>

<p>Buy Widgets and Stuff</p>

<h2>Shopping Basket</h2>

<table class="table">
<thead>
<tr>
<th>Item</th>
<th>Cost</th>
<th>Quantity</th>
<th>Total Cost</th>
</te>
</thead>
<tbody>
{% for item in theList.shoppingList %}
<tr>
<td>{{item.name}}</td>
<td>£{{item.cost}}</td>
<td>{{item.number}}</td>
<td>£{{ item.cost * item.number}}</td>
</tr>
{% endfor %}

<tr>
<td><em>TOTAL</td>
<td></td>
<td></td>
<td><b>£{{theList.calcCost()}}</b></td>
</tbody>
</table>

<ul>
<li>
<a href="save">Save Basket</a>
</li>
<li>
<a href="load">Load Saved Basket</a>
</li>
</ul>

<a class="btn btn-primary" href="pay">Pay</a>
</div>
</body>
</html>
@@ -0,0 +1,38 @@
<!doctype html>

<html lang="en">
<head>
<meta charset="utf-8">

<title>The Dodgy Shopper</title>
<meta name="author" content="aa9863@coventry.ac.uk">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
</head>

<body>
<div class="container">
<a href="/">
<h1>Dodgy PICKLE Shopper</h1>
<p>Back to Home</p>
</a>
<p>Buy Widgets and Stuff</p>

<h2>Load Saved Basket</h2>

<form method="post" enctype="multipart/form-data">
<div class="form-group">
<label for="uploadFile">Example file input</label>
<input type="file" class="form-control-file" id="uploadFile" name="uploadFile">
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>

{% if message %}
<div class="alert alert-info">{{message}}</div>
{% endif %}
</div>
</body>
</html>



@@ -0,0 +1,44 @@
<!doctype html>

<html lang="en">
<head>
<meta charset="utf-8">

<title>The Dodgy Shopper</title>
<meta name="author" content="aa9863@coventry.ac.uk">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">

</head>

<body>
<div class="container">
<a href="/">
<h1>Dodgy PICKLE Shopper</h1>
<p>Back to Home</p>
</a>

<p>Buy Widgets and Stuff</p>

<h2>PAY FOR STUFF</h2>

{% if cost > 0 %}
<h3>You Owe £{{ cost }}</h3>
<form>
<div class="form-group">
<label for="exampleInputEmail1">Credit Card Number</label>
<input type="text" class="form-control" id="exampleInputEmail1" aria-describedby="emailHelp" placeholder="Enter email">
<small id="emailHelp" class="form-text text-muted"></small>
</div>
<button class="btn btn-primary">Pay Dan</button>
</form>

{% else %}
<div class="alert alert-success">You Win, Have a flag CUEH{M@nual_P1kl_Mods}</div>
{% endif %}

</div>
</body>
</html>



@@ -0,0 +1,26 @@
# Deserialisation Trainers

Various Training / Demos for Insecure Deserialisation

## YAML Demo

This service is vulnerable to insecure deserialisation through PyYaml
and will let you try out the example given in the course materials.

### Starting Stopping the service

Start

```
$ cd YamlDemo
$ docker-compose up
```

Stop

```
$ cd YamlDemo
$ docker-compose down
```


@@ -0,0 +1,12 @@
version: "3.7"
services:
flask:
build:
context: webapp
ports:
- "5000:5000"
expose:
- 5000
environment:
- FLASK_ENV=development
- FLASK_APP=/opt/webapp/app.py

0 comments on commit 15527e0

Please sign in to comment.