WEBVTT

0:00:03.360000 --> 0:00:06.700000
 Hello everyone and welcome.

0:00:06.700000 --> 0:00:12.460000
 In this video we're going to get a formal
 introduction to insecure deserialization.

0:00:12.460000 --> 0:00:20.460000
 Now before we dive into exploiting insecure
 deserialization in web applications,

0:00:20.460000 --> 0:00:25.900000
 we need to understand, I would say, quite
 well exactly what serialization

0:00:25.900000 --> 0:00:32.200000
 is. Deserialization will become apparent
 the moment you understand what

0:00:32.200000 --> 0:00:38.840000
 serialization is as a process, specifically
 in the context of web applications,

0:00:38.840000 --> 0:00:43.680000
 but broadly speaking in the
 context of programming.

0:00:43.680000 --> 0:00:48.840000
 This is one of those vulnerabilities
 that a lot of people, especially

0:00:48.840000 --> 0:00:54.760000
 beginners in web app testing or pen
 testing in general, is always quite

0:00:54.760000 --> 0:00:59.880000
 cautious about in terms of the fact that
 they may have presumptions about

0:00:59.880000 --> 0:01:02.660000
 its difficulty or the complexity.

0:01:02.660000 --> 0:01:08.400000
 The word looks a little bit, the word
 serialization or deserialization

0:01:08.400000 --> 0:01:14.500000
 specifically looks a bit ambiguous.

0:01:14.500000 --> 0:01:18.920000
 It's really very difficult to decipher
 exactly what it means, but as I've

0:01:18.920000 --> 0:01:26.120000
 stated many, many times the name itself
 reveals a lot about exactly what's

0:01:26.120000 --> 0:01:29.740000
 going on and more importantly,
 what will be targeting.

0:01:29.740000 --> 0:01:32.380000
 But let me not take too
 much of your time.

0:01:32.380000 --> 0:01:37.380000
 Let's just get started firstly by understanding
 what serialization is

0:01:37.380000 --> 0:01:40.460000
 and then what deserialization is.

0:01:40.460000 --> 0:01:52.740000
 First things are the parameters of converting
 an object or data structure.

0:01:52.740000 --> 0:01:56.620000
 We'll talk about what object
 means and object means.

0:01:56.620000 --> 0:02:02.560000
 An example of this would be a Python
 object, a Java object or a C sharp

0:02:02.560000 --> 0:02:07.220000
 object, right? And you're converting
 this object or data structure into

0:02:07.220000 --> 0:02:12.360000
 a format that can easily
 be stored or transmitted.

0:02:12.360000 --> 0:02:16.340000
 Very important that you understand
 stored or transmitted.

0:02:16.340000 --> 0:02:21.100000
 But more importantly, sort of following
 along here and then reconstructed

0:02:21.100000 --> 0:02:23.860000
 or deserialized later.

0:02:23.860000 --> 0:02:31.140000
 Now this is arguably one of my best definitions
 of serialization and I'll

0:02:31.140000 --> 0:02:35.680000
 explain why. The reason why I like this
 explanation is because it covers

0:02:35.680000 --> 0:02:41.980000
 quite a bit of what you'd consider
 to be the key elements or processes

0:02:41.980000 --> 0:02:46.780000
 involved in serialization itself.

0:02:46.780000 --> 0:02:49.980000
 So first things first, converting.

0:02:49.980000 --> 0:02:52.960000
 So you're converting something.

0:02:52.960000 --> 0:02:54.360000
 What are you converting?

0:02:54.360000 --> 0:02:57.100000
 Typically, it's an object
 or data structure.

0:02:57.100000 --> 0:02:59.200000
 All right, what's an object
 or data structure?

0:02:59.200000 --> 0:03:00.500000
 If you're new to that, don't worry.

0:03:00.500000 --> 0:03:02.420000
 We'll get into that shortly.

0:03:02.420000 --> 0:03:04.940000
 Just think of it as just data.

0:03:04.940000 --> 0:03:09.320000
 It could be a Python object, Java,
 it doesn't really matter.

0:03:09.320000 --> 0:03:12.900000
 The reason that's sort of relevant here
 is because each of these languages

0:03:12.900000 --> 0:03:17.940000
 or frameworks has their own
 serialization format.

0:03:17.940000 --> 0:03:21.900000
 And that's why, you know, this sort
 of esoteric or why we need to factor

0:03:21.900000 --> 0:03:24.680000
 in what type of object
 we're talking about.

0:03:24.680000 --> 0:03:26.740000
 But let's just keep it simple.

0:03:26.740000 --> 0:03:28.820000
 You're converting an object.

0:03:28.820000 --> 0:03:31.940000
 Okay. And what are you
 converting it into?

0:03:31.940000 --> 0:03:34.700000
 Well, you're converting it into a format.


0:03:34.700000 --> 0:03:38.440000
 Okay. So you may be asking, well,
 what is this format used for?

0:03:38.440000 --> 0:03:42.220000
 Well, typically you're going to be converting
 it into a format that can

0:03:42.220000 --> 0:03:44.220000
 easily be stored.

0:03:44.220000 --> 0:03:46.840000
 All right. So you just I want
 you to think about it.

0:03:46.840000 --> 0:03:48.760000
 You're converting an object.

0:03:48.760000 --> 0:03:54.340000
 All right. Just think of, you know,
 a function variable could be Python,

0:03:54.340000 --> 0:03:57.040000
 you know, Java, etc.

0:03:57.040000 --> 0:04:02.760000
 You're converting it into a, you know,
 you're converting it into a format

0:04:02.760000 --> 0:04:05.580000
 that can be stored even in a database.

0:04:05.580000 --> 0:04:12.040000
 Okay. Or you're converting an object
 into a format that can easily or

0:04:12.040000 --> 0:04:14.620000
 efficiently be transmitted.

0:04:14.620000 --> 0:04:19.120000
 Now, the most important thing about serialization
 as a process, you know,

0:04:19.120000 --> 0:04:24.960000
 sort of what makes it or distinguishes
 it from, you know, just standard

0:04:24.960000 --> 0:04:34.340000
 conversion is the fact that you can
 reconstruct this or deserialize this

0:04:34.340000 --> 0:04:41.740000
 serialized object back into its original
 form without losing anything.

0:04:41.740000 --> 0:04:47.840000
 So you essentially, you know, can take
 an object that was serialized and

0:04:47.840000 --> 0:04:52.360000
 you can then deserialize it without losing
 anything again, just back into

0:04:52.360000 --> 0:04:53.740000
 its original format.

0:04:53.740000 --> 0:04:58.500000
 So if you store an object in a database,
 you know, serialized, obviously,

0:04:58.500000 --> 0:05:04.540000
 you should be able to deserialize it and
 then use it, you know, for whatever,

0:05:04.540000 --> 0:05:06.700000
 you know, purpose it was intended.

0:05:06.700000 --> 0:05:11.080000
 Now, this serialized format, what is it?

0:05:11.080000 --> 0:05:15.200000
 Well, the serialized format
 is often a byte stream.

0:05:15.200000 --> 0:05:17.160000
 This is typically the case.

0:05:17.160000 --> 0:05:19.840000
 It can also be text based.

0:05:19.840000 --> 0:05:22.740000
 A very good example of that is JSON.

0:05:22.740000 --> 0:05:28.640000
 JSON was actually created for serialization,
 or I should say the serialization

0:05:28.640000 --> 0:05:31.960000
 of data, but we also have XML.

0:05:31.960000 --> 0:05:36.120000
 Or it could be, and this is also quite
 common, a binary representation

0:05:36.120000 --> 0:05:39.320000
 of the object. Okay.

0:05:39.320000 --> 0:05:45.840000
 And there's many different reasons for,
 you know, there's many serialized

0:05:45.840000 --> 0:05:52.860000
 formats that you will, you will essentially
 come by or come across, you

0:05:52.860000 --> 0:05:57.520000
 know, in terms of, you know, what you'll
 find when performing a pentas,

0:05:57.520000 --> 0:06:01.300000
 but the key thing to understand,
 and this is as simple as it gets.

0:06:01.300000 --> 0:06:06.280000
 This is really how simple it is, is you're
 just converting an object into

0:06:06.280000 --> 0:06:10.920000
 a format that can be stored or transmitted,
 but then later reconstructed

0:06:10.920000 --> 0:06:14.760000
 or deserialized when required.

0:06:14.760000 --> 0:06:16.720000
 So that's what it is.

0:06:16.720000 --> 0:06:19.960000
 Now, we'll get into what objects are.

0:06:19.960000 --> 0:06:23.160000
 Again, if you're familiar, if you're
 experienced in programming, you know

0:06:23.160000 --> 0:06:27.980000
 what an object is or what I'm referring
 to, but objects are typically

0:06:27.980000 --> 0:06:32.640000
 serialized to convert them into a format,
 as I've mentioned, that can

0:06:32.640000 --> 0:06:38.360000
 be easily stored, transmitted and reconstructed
 later, enabling data persistence

0:06:38.360000 --> 0:06:43.600000
 and communication across different
 systems or components.

0:06:43.600000 --> 0:06:47.960000
 So there's a reason why I did that,
 that particular paragraph, because

0:06:47.960000 --> 0:06:53.700000
 it sort of answers why this is performed,
 but not, you know, completely,

0:06:53.700000 --> 0:06:58.000000
 just gives you an idea as to why you'd
 want to have sort of this standardized

0:06:58.000000 --> 0:07:05.020000
 process that allows you to convert objects
 into a format that can be stored,

0:07:05.020000 --> 0:07:06.460000
 but reconstructed.

0:07:06.460000 --> 0:07:12.560000
 But more importantly, you know, transferred
 or transmitted, you know,

0:07:12.560000 --> 0:07:15.440000
 to different systems or components.

0:07:15.440000 --> 0:07:21.200000
 And, you know, doing all of this while
 ensuring that whatever serialized

0:07:21.200000 --> 0:07:27.160000
 data you send to another system or
 service or endpoint, ensuring that

0:07:27.160000 --> 0:07:31.180000
 that endpoint is able to
 deserialize it for use.

0:07:31.180000 --> 0:07:38.300000
 So a lot of people sort of compare serialization
 to encryption or encoding.

0:07:38.300000 --> 0:07:45.320000
 And I would say that that's sort of
 the wrong approach, because it is

0:07:45.320000 --> 0:07:50.000000
 quite different in terms of how it works
 and, you know, what its objectives

0:07:50.000000 --> 0:07:56.200000
 are. It's really not focused on obscuring
 anything, or, you know, encrypting

0:07:56.200000 --> 0:07:57.720000
 or encoding anything.

0:07:57.720000 --> 0:08:03.720000
 It's really focused on, you know, converting
 an object into a format that

0:08:03.720000 --> 0:08:08.820000
 can easily be stored or transmitted
 storage transmission.

0:08:08.820000 --> 0:08:10.840000
 That's the key thing to understand.

0:08:10.840000 --> 0:08:14.180000
 And of course, as I've pointed out in
 this slide, the most important thing

0:08:14.180000 --> 0:08:23.860000
 to understand in terms of, you know,
 what is actually required when you

0:08:23.860000 --> 0:08:28.260000
 consider to be serialized is the fact
 that the recipient of the serialized

0:08:28.260000 --> 0:08:33.700000
 data should be able to reconstruct or
 deserialize the object back to its

0:08:33.700000 --> 0:08:36.260000
 unchanged original form.

0:08:36.260000 --> 0:08:42.100000
 The key point I'm making here is that,
 you know, regardless of what, you

0:08:42.100000 --> 0:08:47.160000
 know, whatever method or tool or system
 you use for serialization, when

0:08:47.160000 --> 0:08:52.420000
 you deserialize this serialized file back
 into the original object, nothing

0:08:52.420000 --> 0:08:53.880000
 should be lost at all.

0:08:53.880000 --> 0:08:58.760000
 It should, you know, go back exactly
 to the, you know, to its original

0:08:58.760000 --> 0:09:00.340000
 form as an object.

0:09:00.340000 --> 0:09:03.300000
 So, very, very important.

0:09:03.300000 --> 0:09:06.760000
 Now that begs the question, and I'm
 pretty sure you're already aware of

0:09:06.760000 --> 0:09:10.600000
 this now, given the long-winded
 explanation I gave you there.

0:09:10.600000 --> 0:09:13.360000
 But how does serialization work?

0:09:13.360000 --> 0:09:18.360000
 Well, it all starts firstly with the
 conversion of the object, right?

0:09:18.360000 --> 0:09:24.700000
 So, the in-memory representation of an
 object, which, you know, is comprised

0:09:24.700000 --> 0:09:29.780000
 of its properties, methods, and state,
 is transformed into a specific

0:09:29.780000 --> 0:09:34.420000
 format. Now some example formats
 include binary, right?

0:09:34.420000 --> 0:09:38.460000
 So, this is compact and fast
 for storage and transmission.

0:09:38.460000 --> 0:09:49.740000
 You then have YAML, all right?

0:09:49.740000 --> 0:09:52.500000
 Step two, storing or transmitting.

0:09:52.500000 --> 0:09:57.640000
 So, you know, you could be serializing
 data either for storage and or

0:09:57.640000 --> 0:10:02.520000
 transmission. But bottom line is that
 once serialized, the data can be

0:10:02.520000 --> 0:10:07.220000
 stored, for example, in a file or database
 or transmitted, for example,

0:10:07.220000 --> 0:10:10.180000
 over a network or through an API.

0:10:10.180000 --> 0:10:16.500000
 And then finally, you have a reconstruction
 of the object or deserialization,

0:10:16.500000 --> 0:10:21.780000
 where the serialized data is passed
 to recreate the original object or

0:10:21.780000 --> 0:10:23.940000
 data structure in memory.

0:10:23.940000 --> 0:10:24.860000
 That's pretty much it.

0:10:24.860000 --> 0:10:28.140000
 That's what serialization
 and deserialization is.

0:10:28.140000 --> 0:10:33.160000
 Now, you may be asking yourself, what
 exactly are objects, all right?

0:10:33.160000 --> 0:10:37.640000
 If this is your first time coming across
 this term, especially in this

0:10:37.640000 --> 0:10:45.620000
 context, a object or an object refers to
 a structured data entity in programming.

0:10:45.620000 --> 0:10:50.220000
 That's the keyword in programming that
 encapsulates properties, what are

0:10:50.220000 --> 0:10:52.700000
 properties or what am
 I referring to here?

0:10:52.700000 --> 0:10:57.560000
 Well, this is data or attributes and potentially
 behaviors, which comprises

0:10:57.560000 --> 0:11:03.380000
 of methods or functions, representing
 a specific instance of a class or

0:11:03.380000 --> 0:11:08.020000
 data type that can be converted into
 a storeable or transmittable format

0:11:08.020000 --> 0:11:10.460000
 for later construction.

0:11:10.460000 --> 0:11:13.680000
 So you're pretty much what you're doing
 the easiest way to think about

0:11:13.680000 --> 0:11:18.900000
 it is any aspect or any function within
 the web app, you know, all that's

0:11:18.900000 --> 0:11:24.120000
 part of the web app that you would like
 to essentially store, for example,

0:11:24.120000 --> 0:11:30.420000
 in a database, you know, and not let's
 say on the file system, would be

0:11:30.420000 --> 0:11:34.040000
 a potential candidate for serialization,
 where you can just say, hey,

0:11:34.040000 --> 0:11:38.040000
 serialize this function
 called delete user.

0:11:38.040000 --> 0:11:43.860000
 And when I need it, I will through
 another through another function or

0:11:43.860000 --> 0:11:50.080000
 script, if you will, call upon or,
 you know, reach into the database,

0:11:50.080000 --> 0:11:52.300000
 uncerialize it, and then execute it.

0:11:52.300000 --> 0:11:57.700000
 That's, you know, pretty much the best
 way to understand what serialization

0:11:57.700000 --> 0:12:02.440000
 is and, you know, what deserialization
 is because deserialization is just

0:12:02.440000 --> 0:12:04.360000
 the reverse of serialization.

0:12:04.360000 --> 0:12:08.820000
 But the bottom line is, when speaking
 about objects, again, you know,

0:12:08.820000 --> 0:12:14.620000
 object just refers to a structured data
 entity in programming that encapsulates

0:12:14.620000 --> 0:12:18.420000
 properties and potentially behaviors,
 which are comprised, as I said,

0:12:18.420000 --> 0:12:25.500000
 of methods or functions, of which,
 you know, essentially representing

0:12:25.500000 --> 0:12:29.860000
 a specific instance of a class or data
 type that can be converted into

0:12:29.860000 --> 0:12:33.720000
 a storeable or transmittable format
 for later construction.

0:12:33.720000 --> 0:12:36.140000
 So what is deserialization?

0:12:36.140000 --> 0:12:42.000000
 If it, you know, if it isn't obvious
 already, well, deserialization is

0:12:42.000000 --> 0:12:46.120000
 the process of converting serialized
 data, for example, a byte stream

0:12:46.120000 --> 0:12:52.420000
 or JSON, JSON string or binary format
 back into its original in-memory

0:12:52.420000 --> 0:12:57.500000
 representation, such as an object or
 data structure, so that it can be

0:12:57.500000 --> 0:13:01.000000
 used again in the application
 or web application.

0:13:01.000000 --> 0:13:07.120000
 This process reconstructs the data structure
 and state enabling operations

0:13:07.120000 --> 0:13:11.440000
 or interactions, as if the data
 had never been serialized.

0:13:11.440000 --> 0:13:12.960000
 And that's very important.

0:13:12.960000 --> 0:13:18.860000
 If anything within the object is changed
 after it has been deserialized,

0:13:18.860000 --> 0:13:24.220000
 in comparison to, you know, what the
 object was before it was serialized,

0:13:24.220000 --> 0:13:26.100000
 that's not deserialization.

0:13:26.100000 --> 0:13:27.700000
 Something's gone wrong.

0:13:27.700000 --> 0:13:33.100000
 And hopefully it's starting to understand
 what exactly is targeted when

0:13:33.100000 --> 0:13:37.040000
 you talk about insecure deserialization.

0:13:37.040000 --> 0:13:41.880000
 So another thing that I want to point
 out is, you know, the most popular

0:13:41.880000 --> 0:13:45.900000
 and widely used data format used
 for data serialization is JSON.

0:13:45.900000 --> 0:13:48.140000
 Prior to that, it was XML.

0:13:48.140000 --> 0:13:55.020000
 Now, another important point, something
 that I probably alluded to earlier,

0:13:55.020000 --> 0:14:00.620000
 is that many programming languages provide
 built in capabilities or libraries

0:14:00.620000 --> 0:14:06.300000
 for object serialization, often offering
 more features than formats like

0:14:06.300000 --> 0:14:12.540000
 JSON or XML, including greater flexibility
 and customization of the serialization

0:14:12.540000 --> 0:14:14.280000
 process, which is true.

0:14:14.280000 --> 0:14:18.960000
 And this is one of the aspects that confuses
 a lot of people because when

0:14:18.960000 --> 0:14:23.160000
 you're dealing with a Python web application,
 most likely you're dealing,

0:14:23.160000 --> 0:14:27.540000
 you know, if you're dealing with a Python
 based web application that is

0:14:27.540000 --> 0:14:33.800000
 performing serialization and deserialization,
 it's most likely using pickle.

0:14:33.800000 --> 0:14:37.720000
 And then when you're dealing with PHP,
 something else, when you're dealing

0:14:37.720000 --> 0:14:42.280000
 with Java, you know, it has its
 own serialization capabilities.

0:14:42.280000 --> 0:14:47.040000
 That's what confuses a lot of, you know,
 junior pen testers or individuals

0:14:47.040000 --> 0:14:51.480000
 getting into web app and testing, just
 getting into it, is that there's

0:14:51.480000 --> 0:14:55.440000
 all these different types that all require
 sort of different exploitation

0:14:55.440000 --> 0:14:57.720000
 techniques or, you know, different tools.


0:14:57.720000 --> 0:15:02.520000
 But as you'll see in this section,
 it really isn't that complicated as

0:15:02.520000 --> 0:15:06.220000
 long as you understand what
 exactly is going on.

0:15:06.220000 --> 0:15:09.340000
 It may look different depending on,
 you know, the different programming

0:15:09.340000 --> 0:15:15.460000
 language, but at the core, you just need
 to understand what exactly serialization

0:15:15.460000 --> 0:15:17.860000
 is, what it does to the data.

0:15:17.860000 --> 0:15:21.960000
 And then, you know, in the context of
 the web application, just understand

0:15:21.960000 --> 0:15:25.200000
 why the data is being serialized.

0:15:25.200000 --> 0:15:29.960000
 And in terms of how it's being deserialized,
 what that means for you,

0:15:29.960000 --> 0:15:32.240000
 right? So very, very important.

0:15:32.240000 --> 0:15:38.760000
 So I've sort of summarized or illustrated
 the serialization and deserialization

0:15:38.760000 --> 0:15:41.420000
 process, which as you can
 see is very, very simple.

0:15:41.420000 --> 0:15:46.660000
 So this diagram illustrates the process
 of serialization and deserialization

0:15:46.660000 --> 0:15:49.520000
 using a structured flow
 of data transformation.

0:15:49.520000 --> 0:15:53.500000
 So you start off here, this is just
 an example of, you know, of a Python

0:15:53.500000 --> 0:15:57.540000
 object. So serialization, a Python object
 with attributes, in this case,

0:15:57.540000 --> 0:16:02.180000
 name and age. So you can see name is
 Alice, age is 30, right, is converted

0:16:02.180000 --> 0:16:04.320000
 into a serialized data format.

0:16:04.320000 --> 0:16:15.140000
 In this case, we're just storage or
 transmission, this specific step.

0:16:15.140000 --> 0:16:18.980000
 So now you have the serialized
 JSON, okay?

0:16:18.980000 --> 0:16:23.180000
 And it may look the same, but again,
 I couldn't represent it any better

0:16:23.180000 --> 0:16:26.320000
 way. You can actually see there's a
 few syntax differences between the

0:16:26.320000 --> 0:16:30.820000
 original Python object and how
 it looks like in in JSON.

0:16:30.820000 --> 0:16:34.480000
 But you then have the transmission
 or storage.

0:16:34.480000 --> 0:16:38.140000
 So the serialized data is either
 transmitted over a network.

0:16:38.140000 --> 0:16:44.140000
 So for example, via an API or saved to
 persistent storage, examples here,

0:16:44.140000 --> 0:16:46.140000
 a file or a database.

0:16:46.140000 --> 0:16:49.900000
 And then you have retrieval or loading.

0:16:49.900000 --> 0:16:54.740000
 So the serialized data is retrieved
 from storage or received from the

0:16:54.740000 --> 0:16:57.120000
 network maintaining its
 serialized format.

0:16:57.120000 --> 0:17:04.060000
 And then deserialization, the serialized
 data is transformed back into

0:17:04.060000 --> 0:17:07.040000
 a reconstructed object.

0:17:07.040000 --> 0:17:11.140000
 Restoring its original structure and
 attributes, in this case, name and

0:17:11.140000 --> 0:17:15.160000
 age. And you can see here, it's restored
 and it can be used for whatever

0:17:15.160000 --> 0:17:17.480000
 it was intended to be used for.

0:17:17.480000 --> 0:17:23.180000
 The bottom line is, or I should say
 the key thing is to understand what

0:17:23.180000 --> 0:17:30.120000
 the original object looks
 like or what it contained.

0:17:30.120000 --> 0:17:37.920000
 But more importantly, in the context
 of what is important for you as a

0:17:37.920000 --> 0:17:44.980000
 web app, for you as a web app, and just
 to understand is the format that

0:17:44.980000 --> 0:17:50.580000
 is being used or the object
 is serialized into.

0:17:50.580000 --> 0:17:56.880000
 And I think that's sort of the key
 distinguishing factor or one of the

0:17:56.880000 --> 0:17:59.200000
 things that makes this
 a little bit complex.

0:17:59.200000 --> 0:18:03.740000
 But the bottom line is to understand
 when you see serialized data, you

0:18:03.740000 --> 0:18:09.600000
 must be able to correctly identify and say
 that looks like pickle serialization.

0:18:09.600000 --> 0:18:14.280000
 As a result, you then know it's Python
 or the actual application is built

0:18:14.280000 --> 0:18:18.620000
 in Python. But that's what
 the process looks like.

0:18:18.620000 --> 0:18:23.280000
 Now there's some important considerations
 I must make very clear before

0:18:23.280000 --> 0:18:29.120000
 we proceed. So firstly, it is important
 to note that serialized data is

0:18:29.120000 --> 0:18:31.800000
 typically neither encrypted nor signed.

0:18:31.800000 --> 0:18:34.080000
 This is extremely important.

0:18:34.080000 --> 0:18:35.380000
 And this is by default.

0:18:35.380000 --> 0:18:39.320000
 I'm not saying it can't be done, but
 by default, you know, it's going

0:18:39.320000 --> 0:18:43.800000
 to be unencrypted and it's
 not going to be signed.

0:18:43.800000 --> 0:18:44.880000
 Now what does this mean?

0:18:44.880000 --> 0:18:49.860000
 It means that once in once intercepted,
 it can often be freely tampered

0:18:49.860000 --> 0:18:55.500000
 with potentially leading to unexpected
 or malicious behavior in the component

0:18:55.500000 --> 0:18:58.400000
 responsible for deserialization.

0:18:58.400000 --> 0:19:00.060000
 Okay, very, very important.

0:19:00.060000 --> 0:19:07.880000
 You can tamper with serialized data,
 then, you know, in terms of whether

0:19:07.880000 --> 0:19:14.760000
 there's any protection or validation
 in the de-serialization function,

0:19:14.760000 --> 0:19:18.300000
 you can get the application to
 do some interesting things.

0:19:18.300000 --> 0:19:22.680000
 Now, in some cases, transport protocols
 may incorporate serialization

0:19:22.680000 --> 0:19:28.220000
 alongside compression or encryption,
 which can conceal or secure the de

0:19:28.220000 --> 0:19:29.460000
-serialized data.

0:19:29.460000 --> 0:19:34.880000
 However, serialized data may be also encountered
 in an unprotected plaintext

0:19:34.880000 --> 0:19:41.040000
 format. The latter scenario or this
 plaintext the this plaintext format

0:19:41.040000 --> 0:19:45.700000
 scenario is particularly significant for
 penetration testers and attackers,

0:19:45.700000 --> 0:19:50.680000
 as it provides an opportunity to
 analyze and manipulate the data.

0:19:50.680000 --> 0:19:55.700000
 So that now begs the question, well,
 I now know what serialization and

0:19:55.700000 --> 0:19:57.060000
 deserialization is.

0:19:57.060000 --> 0:19:59.140000
 What is insecure deserialization?

0:19:59.140000 --> 0:20:01.920000
 What is this vulnerability
 you're yapping about?

0:20:01.920000 --> 0:20:03.640000
 Well, let's get into it.

0:20:03.640000 --> 0:20:09.960000
 So insecure deserialization is a vulnerability
 that occurs when untrusted

0:20:09.960000 --> 0:20:16.420000
 or user controlled data is deserialized
 by an application without proper

0:20:16.420000 --> 0:20:19.380000
 validation or security checks.

0:20:19.380000 --> 0:20:22.320000
 Okay, that's as simple as I can put it.

0:20:22.320000 --> 0:20:28.560000
 Now, this can obviously lead to severe
 consequences such as remote code

0:20:28.560000 --> 0:20:32.500000
 execution, privilege escalation
 or data manipulation.

0:20:32.500000 --> 0:20:38.260000
 So, serialization converts an object into
 a format for storage or transmission,

0:20:38.260000 --> 0:20:42.400000
 while deserialization reconstructs
 the object from that format.

0:20:42.400000 --> 0:20:50.180000
 If deserialization processes input that's
 been tampered with, it may execute

0:20:50.180000 --> 0:20:54.840000
 unintended actions or compromise
 the application itself.

0:20:54.840000 --> 0:20:56.560000
 That's pretty much it.

0:20:56.560000 --> 0:21:03.200000
 So again, just revisiting it untrusted or
 user controlled data is deserialized.

0:21:03.200000 --> 0:21:06.760000
 Now, this may seem a little bit confusing
 because you may be asking yourself,

0:21:06.760000 --> 0:21:14.520000
 well, do we are we attacking the file
 or data before it is serialized

0:21:14.520000 --> 0:21:19.260000
 or are we trying to attack
 the serialized data itself?

0:21:19.260000 --> 0:21:23.700000
 Or are we trying to attack the
 deserialization mechanism?

0:21:23.700000 --> 0:21:31.360000
 Well, all three can be targeted
 to varying extents.

0:21:31.360000 --> 0:21:34.980000
 And again, this is all going to depend
 on the target web application.

0:21:34.980000 --> 0:21:38.720000
 But for now, let's not focus on that
 because we'll be diving into this,

0:21:38.720000 --> 0:21:42.200000
 using practical examples in
 the next set of videos.

0:21:42.200000 --> 0:21:48.900000
 For now, I just want you to keep in
 mind exactly what you're trying to

0:21:48.900000 --> 0:21:54.920000
 achieve here. So, let's get an understanding
 of how this works procedurally.

0:21:54.920000 --> 0:21:59.900000
 So, firstly, serialization, the application
 serializes an object into

0:21:59.900000 --> 0:22:01.680000
 a format. This can be whatever.

0:22:01.680000 --> 0:22:04.560000
 It could be JSON, XML, binary, etc.

0:22:04.560000 --> 0:22:06.580000
 And stores or transmits it.

0:22:06.580000 --> 0:22:08.020000
 Deserialization.

0:22:08.020000 --> 0:22:12.120000
 Later, the application reconstructs the
 object by deserializing the stored

0:22:12.120000 --> 0:22:13.860000
 or transmitted data.

0:22:13.860000 --> 0:22:18.660000
 Exploitation. If an attacker intercepts
 or controls the serialized data,

0:22:18.660000 --> 0:22:24.000000
 they can modify it to inject malicious
 payloads or manipulate object behavior.

0:22:24.000000 --> 0:22:28.020000
 The vulnerable application deserializes
 the tampered data without validation

0:22:28.020000 --> 0:22:33.140000
 leading to unexpected or dangerous outcomes,
 just by virtue of what objects

0:22:33.140000 --> 0:22:38.060000
 are used for. If you can imagine you
 use, you know, you have an object

0:22:38.060000 --> 0:22:42.600000
 in your web application that let's
 say does something quite important

0:22:42.600000 --> 0:22:44.400000
 or doesn't really need to do anything.

0:22:44.400000 --> 0:22:48.520000
 But the bottom line is it's being
 executed, you know, by the system.

0:22:48.520000 --> 0:22:55.120000
 It's a script. You know, so you're actually,
 objects are very, very powerful

0:22:55.120000 --> 0:22:58.340000
 from that perspective.

0:22:58.340000 --> 0:23:02.740000
 And again, regardless of what the object
 does, if you can somehow manipulate

0:23:02.740000 --> 0:23:09.180000
 the serialized version of it and, you
 know, get it to do something, let's

0:23:09.180000 --> 0:23:13.860000
 say even more malicious or malicious,
 and then it is deserialized and

0:23:13.860000 --> 0:23:18.740000
 then used. And whatever you injected
 there is now executed as part of

0:23:18.740000 --> 0:23:26.160000
 the, you know, as part of what the original
 object was doing, then, you

0:23:26.160000 --> 0:23:32.840000
 know, you're able to get the web application
 to do stuff that it was not

0:23:32.840000 --> 0:23:35.100000
 designed or configured to do.

0:23:35.100000 --> 0:23:38.920000
 Hopefully this is giving an understanding
 as to where the issues arise.

0:23:38.920000 --> 0:23:44.980000
 If you remember, I kept on harping about
 the fact that if an object, if

0:23:44.980000 --> 0:23:49.700000
 a serialized object when deserialized
 is not what it was before it was

0:23:49.700000 --> 0:23:55.500000
 serialized, then the whole serialization
 deserialization process has failed

0:23:55.500000 --> 0:23:59.780000
 because again, it may be
 down to various reasons.

0:23:59.780000 --> 0:24:05.920000
 But from an attacker's perspective,
 you're trying to break the, you're

0:24:05.920000 --> 0:24:08.140000
 trying to tamper with the process here.

0:24:08.140000 --> 0:24:12.300000
 And hopefully this is giving you an understanding
 if you are a web application

0:24:12.300000 --> 0:24:15.600000
 developer of what is actually important.

0:24:15.600000 --> 0:24:23.040000
 And to me, the last stand is usually the function
 or, you know, the deserialization

0:24:23.040000 --> 0:24:29.660000
 process, because if it does not verify
 that, hey, does this match the

0:24:29.660000 --> 0:24:35.020000
 original object or, you know, perform
 a check like that, then it's, you

0:24:35.020000 --> 0:24:37.660000
 know, it's always going to lead to
 issues or that's where the attacks

0:24:37.660000 --> 0:24:40.020000
 or vulnerabilities stem from.

0:24:40.020000 --> 0:24:43.700000
 So what causes the vulnerability sort
 of diving a little bit deeper?

0:24:43.700000 --> 0:24:48.280000
 So obviously, number one, a
 lack of input validation.

0:24:48.280000 --> 0:24:52.600000
 So the application blindly accepts serialized
 data from untrusted sources

0:24:52.600000 --> 0:24:56.260000
 without validating its authenticity
 or integrity.

0:24:56.260000 --> 0:25:00.380000
 Secondly, overly permissive deserialization
 libraries, as I just mentioned.

0:25:00.380000 --> 0:25:05.440000
 So many deserialization frameworks
 automatically instantiate objects,

0:25:05.440000 --> 0:25:10.080000
 call methods or execute code as part of
 the deserialization process, therefore

0:25:10.080000 --> 0:25:12.880000
 increasing the potential attack factors.

0:25:12.880000 --> 0:25:15.100000
 You then have trusting user input.

0:25:15.100000 --> 0:25:20.940000
 So serialized data from users or external
 sources is inherently untrusted,

0:25:20.940000 --> 0:25:23.940000
 but is often treated as
 safe by applications.

0:25:23.940000 --> 0:25:29.400000
 So you're sort of exploiting that trust
 that we we were able to see in

0:25:29.400000 --> 0:25:32.180000
 the SSRF section of this course.

0:25:32.180000 --> 0:25:36.180000
 And then of course, you also have just
 by virtue of how complex web apps

0:25:36.180000 --> 0:25:40.480000
 web apps are today, you have
 complex object hierarchy.

0:25:40.480000 --> 0:25:44.900000
 So deserializing data into complex objects
 or hierarchies can introduce

0:25:44.900000 --> 0:25:49.080000
 unexpected behaviors, especially if
 deserialization invokes constructors

0:25:49.080000 --> 0:25:52.940000
 or methods. And then of course, you
 know, lack of security control.

0:25:52.940000 --> 0:25:56.800000
 So missing cryptographic signing or validation
 mechanisms allow attackers

0:25:56.800000 --> 0:26:00.420000
 to tamper with serialized
 data undetected.

0:26:00.420000 --> 0:26:03.380000
 So fairly simple to understand
 where it's coming from.

0:26:03.380000 --> 0:26:06.120000
 What are the impacts or the outcomes?

0:26:06.120000 --> 0:26:09.640000
 Well, you're obviously going to have RCE.


0:26:09.640000 --> 0:26:14.040000
 So attackers inject payloads that exploit
 insecure deserialization processes

0:26:14.040000 --> 0:26:16.020000
 to execute arbitrary code.

0:26:16.020000 --> 0:26:21.560000
 An example of this is replacing serialized
 objects with once containing

0:26:21.560000 --> 0:26:25.420000
 malicious code. You have
 privilege escalation.

0:26:25.420000 --> 0:26:28.700000
 So tampering with serialized data to
 escalate privileges or impersonate

0:26:28.700000 --> 0:26:33.560000
 users by modifying access tokens or
 session objects like cookies, data

0:26:33.560000 --> 0:26:42.760000
 tampering, so changing serialized passing
 restrictions, application logic

0:26:42.760000 --> 0:26:45.920000
 abuse and denial of service,
 which I'll not dive into.

0:26:45.920000 --> 0:26:50.240000
 But you get the idea, you can do a
 lot of dangerous stuff that really

0:26:50.240000 --> 0:26:54.000000
 could only be achieved or can only be
 achieved when you're targeting the

0:26:54.000000 --> 0:26:58.100000
 actual application server layer or,
 you know, the back end of the web

0:26:58.100000 --> 0:27:01.200000
 application. And that's why again, this
 is one of those vulnerabilities

0:27:01.200000 --> 0:27:05.980000
 that is quite, quite prevalent
 at that layer.

0:27:05.980000 --> 0:27:08.180000
 So that's the impact.

0:27:08.180000 --> 0:27:13.820000
 Now let's take a look at example of pickle
 deserialization or pickle serialization

0:27:13.820000 --> 0:27:15.180000
 and deserialization.

0:27:15.180000 --> 0:27:17.260000
 I'll explain what pickle is in a second.

0:27:17.260000 --> 0:27:19.060000
 So what is pickle?

0:27:19.060000 --> 0:27:23.160000
 Well, pickle is a Python module used
 for serializing and deserializing

0:27:23.160000 --> 0:27:25.720000
 Python objects. Okay.

0:27:25.720000 --> 0:27:29.680000
 Serialization in this context refers
 to the process of converting a Python

0:27:29.680000 --> 0:27:31.300000
 object into a byte stream.

0:27:31.300000 --> 0:27:39.480000
 So remember what is being converted
 and the, the serialized format of

0:27:39.480000 --> 0:27:41.400000
 what is being converted.

0:27:41.400000 --> 0:27:46.220000
 In this case, byte stream, not plaintext,
 not JSON, byte stream, which

0:27:46.220000 --> 0:27:50.980000
 can then be stored in a file database
 or transmitted over a network.

0:27:50.980000 --> 0:27:55.380000
 So deserialization is the reverse process
 reconstructing the original

0:27:55.380000 --> 0:27:59.100000
 Python object from the byte stream.

0:27:59.100000 --> 0:28:03.020000
 So how does pickle work?

0:28:03.020000 --> 0:28:06.240000
 So pickle is fairly simple
 to use in Python.

0:28:06.240000 --> 0:28:08.360000
 So you have pickle.dump.

0:28:08.360000 --> 0:28:16.200000
 So this would require an object and
 a file or pickle.dumps, you know,

0:28:16.200000 --> 0:28:21.780000
 where you'd have the object converts
 the Python object into a byte stream.

0:28:21.780000 --> 0:28:26.460000
 The resulting byte stream can be stored
 or transmitted, hence file, for

0:28:26.460000 --> 0:28:31.160000
 example, pickle.dumps object can then
 be equals to let's say a variable

0:28:31.160000 --> 0:28:35.820000
 that would essentially store the
 data that's being transmitted.

0:28:35.820000 --> 0:28:40.180000
 And then deserialization, you just
 use pickle.load the file or pickle

0:28:40.180000 --> 0:28:45.820000
.loads data. This would be for transmission
 or receiving data reads the

0:28:45.820000 --> 0:28:49.280000
 byte stream and recreates the original
 Python object in memory.

0:28:49.280000 --> 0:28:50.600000
 So very, very simple.

0:28:50.600000 --> 0:28:56.060000
 An example here, you can see we
 import the pickle library there.

0:28:56.060000 --> 0:29:00.320000
 We have an example object, which is
 just data is equal to, in this case,

0:29:00.320000 --> 0:29:01.340000
 an array of data.

0:29:01.340000 --> 0:29:05.240000
 So name, Alice, age 30,
 roles admin and user.

0:29:05.240000 --> 0:29:08.140000
 Okay, that would be something that you'd
 like to serialize to be stored,

0:29:08.140000 --> 0:29:12.920000
 right? To serialize it, we just say,
 serialize data is equal to pickle

0:29:12.920000 --> 0:29:14.980000
.dumps data, right?

0:29:14.980000 --> 0:29:16.000000
 And then you print it out.

0:29:16.000000 --> 0:29:19.880000
 So serialize data, just print out
 the value of serialize data.

0:29:19.880000 --> 0:29:22.060000
 And then deserialize the object.

0:29:22.060000 --> 0:29:25.860000
 That's equal to pickle
.loads, serialize data.

0:29:25.860000 --> 0:29:27.300000
 And it's very, very simple.

0:29:27.300000 --> 0:29:32.640000
 That's it. That's how simple
 it is to use the pickle.

0:29:32.640000 --> 0:29:36.440000
 Of course, it can be used in a much more
 complex context, which will also

0:29:36.440000 --> 0:29:42.180000
 be exploring. So I'm now going to give
 you a demo that is specific to

0:29:42.180000 --> 0:29:46.600000
 pickle, or that utilizes pickle for
 serialization and deserialization

0:29:46.600000 --> 0:29:48.140000
 in the form of a web app.

0:29:48.140000 --> 0:29:51.220000
 Actually, there'll be two demos we'll
 start off with the basics and then

0:29:51.220000 --> 0:29:53.840000
 go to a, you know, web app that I set up.


0:29:53.840000 --> 0:30:00.020000
 Don't worry. We'll be exploring or you'll
 be able to go through deserialization

0:30:00.020000 --> 0:30:05.940000
 or how to exploit insecure deserialization
 in Java, PHP and .NET in the

0:30:05.940000 --> 0:30:08.680000
 next set of videos through labs on INE.

0:30:08.680000 --> 0:30:12.280000
 But for this demonstration, because
 of how simple it is, I'll just be

0:30:12.280000 --> 0:30:15.580000
 using a web app in my own, you
 know, local environment.

0:30:15.580000 --> 0:30:16.860000
 And I'll be going through the code.

0:30:16.860000 --> 0:30:24.640000
 So if you might, can't be in the next
 system and I'll see you there in

0:30:24.640000 --> 0:30:25.500000
 a couple of seconds.

