WEBVTT

0:00:13.640000 --> 0:00:15.780000
 MongoDB NoSQL injection.

0:00:15.780000 --> 0:00:19.740000
 In this video, we're going to be getting
 an introduction as to what NoSQL

0:00:19.740000 --> 0:00:25.120000
 injection is, after which we'll get a
 theoretical example as to what goes

0:00:25.120000 --> 0:00:31.120000
 on with regards to a web application and
 its relationship or how it communicates

0:00:31.120000 --> 0:00:33.660000
 with a NoSQL database.

0:00:33.660000 --> 0:00:37.580000
 And that'll sort of give us enough information
 to go ahead and identify

0:00:37.580000 --> 0:00:42.820000
 and exploit a NoSQL injection vulnerability,
 specifically in MongoDB.

0:00:42.820000 --> 0:00:47.960000
 So this video will have a lab environment
 attached to it that will essentially

0:00:47.960000 --> 0:00:52.920000
 provide you with a target web application
 that is utilizing MongoDB.

0:00:52.920000 --> 0:00:56.380000
 However, before we get to the lab, there's
 a couple of things I need to

0:00:56.380000 --> 0:01:01.040000
 clarify, right? So firstly, this is
 really our first foray into NoSQL

0:01:01.040000 --> 0:01:05.760000
 injection, but the process in comparison
 to SQL injection remains the

0:01:05.760000 --> 0:01:10.920000
 same. The only thing that changes is
 really the queries or the payloads

0:01:10.920000 --> 0:01:14.040000
 that you specify or that you inject.

0:01:14.040000 --> 0:01:16.500000
 So what is NoSQL injection?

0:01:16.500000 --> 0:01:21.000000
 NoSQL injection is a security vulnerability
 that occurs in applications

0:01:21.000000 --> 0:01:24.640000
 and web applications that
 utilize NoSQL databases.

0:01:24.640000 --> 0:01:29.860000
 And it is a type of attack that involves
 an attacker manipulating a NoSQL

0:01:29.860000 --> 0:01:35.180000
 database query by injecting malicious
 input leading to unauthorized access,

0:01:35.180000 --> 0:01:38.200000
 data leakage, or unintended operations.

0:01:38.200000 --> 0:01:41.860000
 In traditional SQL injection attacks,
 attackers exploit vulnerabilities

0:01:41.860000 --> 0:01:46.760000
 by inserting malicious SQL code or
 queries into application inputs or

0:01:46.760000 --> 0:01:56.060000
 input fields that are concatenated
 with the application's handling of

0:01:56.060000 --> 0:02:00.360000
 user supplied input to manipulate
 the NoSQL database query.

0:02:00.360000 --> 0:02:04.080000
 So it pretty much remains the same
 with regards to the methodology of

0:02:04.080000 --> 0:02:06.320000
 identification and exploitation.

0:02:06.320000 --> 0:02:10.280000
 So if you compare it to SQL injection,
 you're still going to be required

0:02:10.280000 --> 0:02:14.240000
 to find an application input, preferably
 one that does not have any input

0:02:14.240000 --> 0:02:18.780000
 validation. And secondly, that application
 input needs to be interacting

0:02:18.780000 --> 0:02:20.160000
 with a database.

0:02:20.160000 --> 0:02:24.860000
 In this case, the NoSQL database based
 on the nature of data that is being

0:02:24.860000 --> 0:02:28.840000
 submitted. So the identification
 process remains the same.

0:02:28.840000 --> 0:02:32.180000
 As I said, it just comes down to
 the payloads that you utilize.

0:02:32.180000 --> 0:02:36.060000
 Now the best way to demonstrate how
 this works is to use an example.

0:02:36.060000 --> 0:02:40.340000
 So let's assume we have a web application
 that utilizes MongoDB as the

0:02:40.340000 --> 0:02:42.460000
 NoSQL database backend.

0:02:42.460000 --> 0:02:46.320000
 The application has a login functionality
 where users provide their username

0:02:46.320000 --> 0:02:50.420000
 and password. And the application performs
 a query to check if the provided

0:02:50.420000 --> 0:02:51.860000
 credentials are valid.

0:02:51.860000 --> 0:02:54.400000
 So this is how it handles the input.

0:02:54.400000 --> 0:02:58.060000
 So we have a variable username that's
 equal to get request parameter,

0:02:58.060000 --> 0:02:59.380000
 which is username.

0:02:59.380000 --> 0:03:00.660000
 And this is string based.

0:03:00.660000 --> 0:03:04.260000
 And this is all user supplied input,
 the same for the password.

0:03:04.260000 --> 0:03:08.720000
 And then what happens is the MongoDB
 query will look like the following.

0:03:08.720000 --> 0:03:14.480000
 So we have the variable query that stores
 the values of username and password

0:03:14.480000 --> 0:03:16.660000
 provided by the user.

0:03:16.660000 --> 0:03:20.020000
 And then the query here will perform
 a check to see if the credentials

0:03:20.020000 --> 0:03:24.240000
 are valid. So we're really targeting
 the weakness of the actual query.

0:03:24.240000 --> 0:03:29.380000
 In this case, the actual Mongo
 query language or MQL.

0:03:29.380000 --> 0:03:31.920000
 So variable result equals two.

0:03:31.920000 --> 0:03:35.720000
 And remember, we ran this in the previous
 video DB dot users that could

0:03:35.720000 --> 0:03:37.640000
 be a database or collection.

0:03:37.640000 --> 0:03:40.380000
 In this case, the function
 being used is find one.

0:03:40.380000 --> 0:03:43.140000
 So instead of matching two,
 they're finding one.

0:03:43.140000 --> 0:03:55.680000
 So either username or the database, as
 it were, then the login is successful.

0:03:55.680000 --> 0:03:59.980000
 If there's no result, that
 means that login is failed.

0:03:59.980000 --> 0:04:04.160000
 And then the web application responds
 based on what result it gets from

0:04:04.160000 --> 0:04:07.720000
 the actual backend DB,
 in this case, MongoDB.

0:04:07.720000 --> 0:04:12.320000
 So in this example, the application constructs
 a MongoDB query using user

0:04:12.320000 --> 0:04:15.520000
 supplied values for the username
 and password files.

0:04:15.520000 --> 0:04:19.760000
 If an attacker intentionally provides
 a specially crafted value, they

0:04:19.760000 --> 0:04:23.340000
 could potentially exploit a no
 SQL injection vulnerability.

0:04:23.340000 --> 0:04:26.760000
 For instance, an attacker might enter
 the following value or they might

0:04:26.760000 --> 0:04:29.620000
 inject the following value
 as the username parameter.

0:04:29.620000 --> 0:04:34.020000
 So they might inject greater
 than and then leave it blank.

0:04:34.020000 --> 0:04:36.420000
 And that will return a result.

0:04:36.420000 --> 0:04:40.960000
 If not sanitized or if the query, the
 actual MongoDB query is not set

0:04:40.960000 --> 0:04:45.920000
 up correctly. This would evaluate to
 pretty much displaying all other

0:04:45.920000 --> 0:04:51.000000
 values or all other documents within
 that particular collection.

0:04:51.000000 --> 0:04:54.740000
 So in a normal scenario, the query would
 search for a user with the exact

0:04:54.740000 --> 0:04:55.580000
 username provided.

0:04:55.580000 --> 0:04:59.680000
 However, in this case, the attacker is
 utilizing the greater than operator

0:04:59.680000 --> 0:05:02.540000
 with an empty string as the value.

0:05:02.540000 --> 0:05:06.280000
 This can manipulate the query's logic
 causing it to retrieve a user record

0:05:06.280000 --> 0:05:11.180000
 that the attacker should not have access
 to the attacker could then potentially

0:05:11.180000 --> 0:05:14.440000
 bypass the login mechanism and
 gain unauthorized access.

0:05:14.440000 --> 0:05:15.580000
 And that's true.

0:05:15.580000 --> 0:05:19.200000
 You might be asking yourself, are authentication
 bypasses possible with

0:05:19.200000 --> 0:05:20.860000
 no SQL databases?

0:05:20.860000 --> 0:05:26.100000
 Yes, they are. And that brings me to
 the final slide here where I've sort

0:05:26.100000 --> 0:05:31.200000
 of listed out some examples of no SQL
 injection payloads for primarily

0:05:31.200000 --> 0:05:35.320000
 for login forms here, where you can see
 we have the username and the password

0:05:35.320000 --> 0:05:40.300000
 as parameters. And what you can do is
 set the, you can utilize the following

0:05:40.300000 --> 0:05:45.680000
 operation. So our logical operator
 like not equals to, and then equals

0:05:45.680000 --> 0:05:46.680000
 to the username.

0:05:46.680000 --> 0:05:50.380000
 And this is typically what's used for
 authentication bypasses, depending

0:05:50.380000 --> 0:05:53.660000
 on the query. You can also check
 for regular expression.

0:05:53.660000 --> 0:05:57.000000
 Again, the same thing is used
 for authentication bypasses.

0:05:57.000000 --> 0:06:01.560000
 This one right over year is used to perform
 or checks the rejects to find

0:06:01.560000 --> 0:06:02.500000
 the length of a value.

0:06:02.500000 --> 0:06:07.440000
 So typically for brute force against
 username, the values of the username

0:06:07.440000 --> 0:06:12.760000
 parameter. And then this one is the equals
 to, which also works for authentication

0:06:12.760000 --> 0:06:16.280000
 bypasses in certain cases,
 depending on the query.

0:06:16.280000 --> 0:06:18.140000
 And then the greater
 than right over here.

0:06:18.140000 --> 0:06:21.860000
 Now, if you want to learn more about
 no SQL injection, and if you want

0:06:21.860000 --> 0:06:26.440000
 to find some additional no SQL injection
 payloads, I highly recommend

0:06:26.440000 --> 0:06:30.760000
 you take a look at the payload, all the
 things GitHub repost specifically

0:06:30.760000 --> 0:06:34.860000
 the no SQL injection section, because
 it sort of outlines the different

0:06:34.860000 --> 0:06:39.760000
 payloads to use in different
 circumstances or scenarios.

0:06:39.760000 --> 0:06:44.180000
 And that brings us to the live lab or
 the practical section of this course.

0:06:44.180000 --> 0:06:48.060000
 So as I said, this video has
 a lab associated with it.

0:06:48.060000 --> 0:06:50.960000
 This lab will not provide you with
 your own calilinic system.

0:06:50.960000 --> 0:06:51.700000
 It's not required.

0:06:51.700000 --> 0:06:54.780000
 It's just going to open up a web application
 that is vulnerable to no

0:06:54.780000 --> 0:06:59.260000
 SQL injection. And we can pretty much
 perform the injection directly via

0:06:59.260000 --> 0:07:01.460000
 the URL. So it's going to be very simple.


0:07:01.460000 --> 0:07:05.760000
 It'll sort of give you a feel as to
 what no SQL injection is all about.

0:07:05.760000 --> 0:07:11.400000
 So I'm going to start up the
 lab and I'll see you there.

0:07:11.400000 --> 0:07:14.720000
 All right. So I am back
 in my calilinics VM.

0:07:14.720000 --> 0:07:16.620000
 And this is the target web application.

0:07:16.620000 --> 0:07:19.240000
 It's a very simple search
 web application.

0:07:19.240000 --> 0:07:22.820000
 And you can see that it allows
 us to search for users.

0:07:22.820000 --> 0:07:27.140000
 And in the back end, we have a MongoDB
 database server running.

0:07:27.140000 --> 0:07:30.760000
 And you can see the output will tell us
 the name of the user, the password,

0:07:30.760000 --> 0:07:32.500000
 and whether the user is admin.

0:07:32.500000 --> 0:07:41.980000
 Now, if we try and search for a user
 in or rather whatever we put in or

0:07:41.980000 --> 0:07:45.680000
 input it is passed in as the value
 of a parameter called name.

0:07:45.680000 --> 0:07:49.600000
 All right. And you know,
 this user doesn't exist.

0:07:49.600000 --> 0:07:50.300000
 So there's no output.

0:07:50.300000 --> 0:07:55.420000
 Now you could typically try your common
 SQL injection error based hunting

0:07:55.420000 --> 0:07:58.480000
 here where we put a single code, but
 that will not give us anything.

0:07:58.480000 --> 0:08:03.400000
 So what we need, what we can do is
 if we say, for example, admin, just

0:08:03.400000 --> 0:08:06.300000
 to see if that user exists,
 we can say admin.

0:08:06.300000 --> 0:08:08.000000
 And yes, admin exists.

0:08:08.000000 --> 0:08:11.100000
 And you can see name is admin
 password is also admin.

0:08:11.100000 --> 0:08:13.140000
 And this user is an admin.

0:08:13.140000 --> 0:08:15.080000
 So this is confirmed.

0:08:15.080000 --> 0:08:23.340000
 This is essentially how the web application
 works from a behavior perspective.

0:08:23.340000 --> 0:08:30.780000
 Now, how can we get this login or this
 particular form input form here?

0:08:30.780000 --> 0:08:41.240000
 How can we perform no SQL
 database and collection?

0:08:41.240000 --> 0:08:42.960000
 We don't know anything about the query.

0:08:42.960000 --> 0:08:48.300000
 If we view the page source here, we
 can see that, yeah, we don't have

0:08:48.300000 --> 0:08:52.140000
 any for regarding the actual query
 that's been documented on the page

0:08:52.140000 --> 0:08:56.900000
 itself. So the way what we can typically
 do, and this is a very quick

0:08:56.900000 --> 0:09:03.700000
 no SQL injection bypass is we can pass
 in a logical operation here before

0:09:03.700000 --> 0:09:05.520000
 the actual value of the parameter.

0:09:05.520000 --> 0:09:09.740000
 So we can say in here in square brackets,
 we can utilize the logical operator,

0:09:09.740000 --> 0:09:11.980000
 not equal to admin.

0:09:11.980000 --> 0:09:16.200000
 So what this is going to do is it's going
 to run the query and it's going

0:09:16.200000 --> 0:09:22.040000
 to set the name parameter to not equal
 or not be equal to anything.

0:09:22.040000 --> 0:09:26.880000
 So in that case, this should display
 all of the other users within the,

0:09:26.880000 --> 0:09:32.320000
 within the actual collection, or in
 this particular case, so we'll hit

0:09:32.320000 --> 0:09:34.280000
 enter and there we are.

0:09:34.280000 --> 0:09:37.920000
 So that is in essence, no SQL injection.

0:09:37.920000 --> 0:09:41.820000
 I know it's a very, very simple demo, but
 it sort of explains or demonstrates

0:09:41.820000 --> 0:09:44.760000
 how this works with regards
 to logical operations.

0:09:44.760000 --> 0:09:48.960000
 So based on the construction of this
 query, it was just looking for a

0:09:48.960000 --> 0:09:51.900000
 match, right, for admin or
 whatever we input here.

0:09:51.900000 --> 0:09:56.020000
 Now, when we say it's not equal to
 it'll still return a result, right?

0:09:56.020000 --> 0:09:59.320000
 In this case, the result of this will
 be pretty much to display all other

0:09:59.320000 --> 0:10:02.600000
 documents within the collection, right?

0:10:02.600000 --> 0:10:06.360000
 And you can see the various fields, we
 have the name password and whether

0:10:06.360000 --> 0:10:08.060000
 the user is admin.

0:10:08.060000 --> 0:10:09.800000
 So hopefully this makes sense.

0:10:09.800000 --> 0:10:14.540000
 Now we can also say, you know, greater
 than if we hit enter, we'll pretty

0:10:14.540000 --> 0:10:15.640000
 much get the same thing.

0:10:15.640000 --> 0:10:20.780000
 Now, what happens if we say name equals
 to a user that doesn't exist,

0:10:20.780000 --> 0:10:22.200000
 do we have a user called test?

0:10:22.200000 --> 0:10:28.060000
 No, we don't. So if we say, name is
 and we'll put in the square brackets

0:10:28.060000 --> 0:10:33.400000
 and we say not equals two, and it
 enter, you can see that works.

0:10:33.400000 --> 0:10:37.020000
 And if we don't put anything in
 here, that will still work.

0:10:37.020000 --> 0:10:43.440000
 All right, so this is just a poorly
 designed MongoDB query or, you know,

0:10:43.440000 --> 0:10:47.260000
 Mongo query language query
 or MQL query as it were.

0:10:47.260000 --> 0:10:53.640000
 And this is sort of an example as to,
 this is an example as to what or

0:10:53.640000 --> 0:10:57.020000
 how no SQL injection works.

0:10:57.020000 --> 0:11:00.620000
 And it all comes down to whether you're
 dealing with SQL injection or

0:11:00.620000 --> 0:11:03.880000
 SQL injection, it all comes down to
 the actual construction of the query

0:11:03.880000 --> 0:11:06.220000
 and input validation.

0:11:06.220000 --> 0:11:11.840000
 Now we can also utilize another one
 called none of the array or none in

0:11:11.840000 --> 0:11:15.260000
 the array. So we can say
 n i n and then hit enter.

0:11:15.260000 --> 0:11:16.840000
 And in this case is not going to match.

0:11:16.840000 --> 0:11:22.080000
 So if we say test now, this in certain
 cases usually works where we can

0:11:22.080000 --> 0:11:28.100000
 specify maybe, you know, if we wanted
 to match none of the values of the

0:11:28.100000 --> 0:11:34.580000
 array, and then specify users or values
 we don't want to match, that can

0:11:34.580000 --> 0:11:39.640000
 also be useful. We can also utilize the
 equals to operator here, but just

0:11:39.640000 --> 0:11:46.240000
 by saying we can say equals test
 and that will return nothing.

0:11:46.240000 --> 0:11:49.080000
 But we can say EQ equals test.

0:11:49.080000 --> 0:11:53.640000
 And then, you know, for example, we could
 say, or pass in, you know, additional

0:11:53.640000 --> 0:11:57.280000
 parameters or additional operators here.

0:11:57.280000 --> 0:12:00.700000
 But this is typically what you're
 going to be dealing with.

0:12:00.700000 --> 0:12:02.860000
 And again, this is not a login form.

0:12:02.860000 --> 0:12:08.580000
 But in certain cases, you may, when
 dealing with Mongo, Mongo DB, you

0:12:08.580000 --> 0:12:15.820000
 may need to put in the absolute
 values for logical operators.

0:12:15.820000 --> 0:12:21.720000
 So for example, that would typically
 be, let's see if I can show you this

0:12:21.720000 --> 0:12:26.940000
 here. So if we say, for example, I
 will terminate and then we can say,

0:12:26.940000 --> 0:12:31.080000
 or one equals one.

0:12:31.080000 --> 0:12:34.040000
 And we use the comment there.

0:12:34.040000 --> 0:12:37.980000
 So we'll see that's input incorrectly.

0:12:37.980000 --> 0:12:41.940000
 So we have to put it, this is, in this
 particular case, we have to utilize

0:12:41.940000 --> 0:12:45.160000
 the logical operators before
 the actual value.

0:12:45.160000 --> 0:12:49.120000
 So in this case, you know,
 we can just say test.

0:12:49.120000 --> 0:12:56.900000
 And then we can say, in
 here, or one equals one.

0:12:56.900000 --> 0:13:02.880000
 So these are the absolute alternatives
 to the actual text based logical

0:13:02.880000 --> 0:13:06.240000
 operators. We hit enter.

0:13:06.240000 --> 0:13:10.760000
 There we are. So you can see in this
 particular case, we can say, for

0:13:10.760000 --> 0:13:15.120000
 example, greater than.

0:13:15.120000 --> 0:13:20.060000
 And in this case, that's not passed
 in correctly, but you get the idea.

0:13:20.060000 --> 0:13:27.400000
 So we could say, you know, test, and
 that name greater than equals test.

0:13:27.400000 --> 0:13:31.220000
 We say, for a user that exists,
 then it should display it.

0:13:31.220000 --> 0:13:34.940000
 But if we put it for a user that doesn't,
 greater than does not work.

0:13:34.940000 --> 0:13:38.360000
 So when we say greater than is just
 going to show other records greater

0:13:38.360000 --> 0:13:42.740000
 than admin. However, if the record doesn't
 exist, in this case, it still

0:13:42.740000 --> 0:13:44.780000
 works. That's very interesting.

0:13:44.780000 --> 0:13:50.340000
 We say test. Okay, that doesn't
 work, greater than test.

0:13:50.340000 --> 0:13:53.920000
 So if we say anything greater
 than a, it'll display it.

0:13:53.920000 --> 0:13:57.000000
 So you can also use characters here,
 we can say anything greater than

0:13:57.000000 --> 0:14:00.620000
 z, nothing there, anything
 greater than f.

0:14:00.620000 --> 0:14:03.580000
 We only have hidden flag,
 because it starts with h.

0:14:03.580000 --> 0:14:07.360000
 All right, in this case, what's being searched
 for is the name field specifically.

0:14:07.360000 --> 0:14:09.780000
 So hopefully all of this makes sense.

0:14:09.780000 --> 0:14:13.860000
 I just wanted to give you the this
 sort of introductory foray into no

0:14:13.860000 --> 0:14:14.500000
 sequel injection.

0:14:14.500000 --> 0:14:18.760000
 As I said, it's something we'll be exploring
 in even more advanced environments

0:14:18.760000 --> 0:14:23.520000
 as we proceed in this learning path,
 as well as more advanced learning

0:14:23.520000 --> 0:14:27.780000
 paths. But it's becoming increasingly
 prevalent, and hopefully by the

0:14:27.780000 --> 0:14:31.180000
 end of this section now, you should
 have a good feel and understanding

0:14:31.180000 --> 0:14:34.180000
 as to what no sequel injection
 is all about.

0:14:34.180000 --> 0:14:38.160000
 With that being said, that's going to
 bring us to the close of the practical

0:14:38.160000 --> 0:14:40.180000
 section of this video.

0:14:40.180000 --> 0:14:44.980000
 All right, so that brings us to the end
 of the no sequel injection section

0:14:44.980000 --> 0:14:48.880000
 of this course and the end
 of the course as a whole.

0:14:48.880000 --> 0:14:53.100000
 So hopefully, you've learned a lot within
 this section and the other sections

0:14:53.100000 --> 0:14:57.380000
 within this course, and you now should
 have a firm grip of SQL injection

0:14:57.380000 --> 0:15:03.000000
 attacks, as well as no sequel injection
 attacks or vulnerabilities, more

0:15:03.000000 --> 0:15:06.860000
 so the former, as opposed to the latter,
 as I said, the no sequel injection

0:15:06.860000 --> 0:15:11.700000
 section was something that I added as
 a bonus to essentially get you curious

0:15:11.700000 --> 0:15:15.820000
 and, you know, to the point where you
 can go out there and obviously legally

0:15:15.820000 --> 0:15:19.620000
 and ethically try and play around with
 no sequel injection vulnerabilities.

0:15:19.620000 --> 0:15:23.980000
 With that being said, we're now going
 to go on to the final video of the

0:15:23.980000 --> 0:15:25.460000
 course, which is the course conclusion.

0:15:25.460000 --> 0:15:30.220000
 It's a very important video because it's
 essentially a report card check.

0:15:30.220000 --> 0:15:34.280000
 And will allow us to see how far we've
 come and whether we hit all of

0:15:34.280000 --> 0:15:37.180000
 our learning objectives or
 outcomes for this course.

0:15:37.180000 --> 0:15:40.960000
 With that being said, I'll be seeing
 you in the course conclusion video.

