WEBVTT

0:00:03.720000 --> 0:00:06.900000
 The non-algorithm vulnerabilities.

0:00:06.900000 --> 0:00:13.380000
 So in this video, we're going to be
 exploring one type of JSON web token

0:00:13.380000 --> 0:00:18.640000
 vulnerability, and that is going to
 be the non-algorithm vulnerability.

0:00:18.640000 --> 0:00:23.040000
 So as I mentioned at the tail end of
 the previous video, when I introduced

0:00:23.040000 --> 0:00:27.880000
 you to JSON web tokens, the objective
 was to cover or highlight some of

0:00:27.880000 --> 0:00:34.400000
 these vulnerabilities in JWTs, more
 specifically the implementations of

0:00:34.400000 --> 0:00:41.020000
 JWTs individually as opposed to just
 telling you all the vulnerabilities.

0:00:41.020000 --> 0:00:43.200000
 I think that makes much more sense.

0:00:43.200000 --> 0:00:47.360000
 But with that being said, again, we'll
 have a practical section at the

0:00:47.360000 --> 0:00:53.100000
 end of this video, but we need to
 cover some theoretical stuff.

0:00:53.100000 --> 0:00:57.140000
 So what is the non-algorithm
 vulnerability?

0:00:57.140000 --> 0:01:02.180000
 So the non-algorithm vulnerability occurs
 when a JSON web token is signed

0:01:02.180000 --> 0:01:04.820000
 with the non-algorithm.

0:01:04.820000 --> 0:01:09.000000
 So if you remember in the previous video,
 we were talking about the header

0:01:09.000000 --> 0:01:12.340000
 payload and signature.

0:01:12.340000 --> 0:01:26.020000
 When an algorithm is not specified,
 there's many reasons for this, but

0:01:26.020000 --> 0:01:34.600000
 when an algorithm is not specified either
 when a token is issued or whether

0:01:34.600000 --> 0:01:39.580000
 the server or let's say the API endpoint
 doesn't check for or doesn't

0:01:39.580000 --> 0:01:45.760000
 verify the algorithm, that can bring
 up or that typically raises a few

0:01:45.760000 --> 0:01:50.160000
 issues. So again, I want to keep it
 simple at least for this light delay

0:01:50.160000 --> 0:01:53.640000
 dive into the meat and bones here,
 but this vulnerability essentially

0:01:53.640000 --> 0:01:58.560000
 allows attackers to manipulate the token
 and bypass verification mechanisms

0:01:58.560000 --> 0:02:02.160000
 because the signature is either
 missing or is ignored.

0:02:02.160000 --> 0:02:07.280000
 So you may be thinking to yourself, well,
 that's quite strange given that

0:02:07.280000 --> 0:02:10.200000
 you mentioned just how important
 the signature is.

0:02:10.200000 --> 0:02:11.980000
 And you're right.

0:02:11.980000 --> 0:02:18.440000
 However, if the server does not really
 process or doesn't really pretty

0:02:18.440000 --> 0:02:25.720000
 much ignores the signature, then we
 can still use or create or forge a

0:02:25.720000 --> 0:02:28.900000
 JSON web token with just the
 header and the payload.

0:02:28.900000 --> 0:02:35.520000
 Again, permitting that the server or the
 API endpoint ignores the signature.

0:02:35.520000 --> 0:02:37.580000
 So that's really the vulnerability here.

0:02:37.580000 --> 0:02:43.380000
 So you'll understand a little bit better
 when I explain what causes it.

0:02:43.380000 --> 0:02:46.640000
 So what causes the non-algorithm
 vulnerability?

0:02:46.640000 --> 0:02:52.120000
 So firstly, misconfiguration in the
 implementation of JWT libraries.

0:02:52.120000 --> 0:02:56.540000
 So many JWT libraries support the non
-algorithm for testing purposes,

0:02:56.540000 --> 0:02:59.980000
 where a token does not
 require a signature.

0:02:59.980000 --> 0:03:04.820000
 So if improperly configured, a library
 may accept tokens with the non

0:03:04.820000 --> 0:03:09.440000
-algorithm as valid without verifying
 the token's integrity as a whole,

0:03:09.440000 --> 0:03:11.560000
 which is what it's there for.

0:03:11.560000 --> 0:03:16.320000
 Secondly, also quite common is the failure
 to validate signature requirements.

0:03:16.320000 --> 0:03:20.860000
 So applications fail to enforce the need
 for a valid cryptographic signature,

0:03:20.860000 --> 0:03:23.900000
 allowing unsigned tokens to be accepted.

0:03:23.900000 --> 0:03:29.560000
 And then obviously improper trust in
 the JWT header, whereby the algorithm

0:03:29.560000 --> 0:03:33.240000
 field in the JWT header specifies
 the signing algorithm.

0:03:33.240000 --> 0:03:38.800000
 As we saw in the previous video, these
 examples of these are HS256, RS256

0:03:38.800000 --> 0:03:45.160000
 or none. If an application blindly trusts
 this value without verification,

0:03:45.160000 --> 0:03:54.620000
 and this is sort of what modifies it to
 none, if it doesn't remember without

0:03:54.620000 --> 0:03:59.300000
 verification, then you can pretty much
 modify it to none, and then bypass

0:03:59.300000 --> 0:04:01.960000
 signature validation altogether.

0:04:01.960000 --> 0:04:06.400000
 And this brings us to the whole idea
 of creating your own tokens.

0:04:06.400000 --> 0:04:13.260000
 If you understand, again, if you're
 able to test and analyze a JSON web

0:04:13.260000 --> 0:04:18.180000
 token generated by a web application,
 the first thing I would do is to

0:04:18.180000 --> 0:04:22.820000
 perform this test where, you know,
 the web application may be creating

0:04:22.820000 --> 0:04:24.840000
 tokens with the algorithm specified.

0:04:24.840000 --> 0:04:30.540000
 However, that doesn't mean that the
 web server will not accept a token

0:04:30.540000 --> 0:04:33.440000
 without it. So I hope you're
 getting the idea.

0:04:33.440000 --> 0:04:34.940000
 And again, you'll see this practically.

0:04:34.940000 --> 0:04:36.600000
 So how does this all work?

0:04:36.600000 --> 0:04:40.180000
 Well, you know, we start off with
 the JWT header exploitation.

0:04:40.180000 --> 0:04:45.200000
 So attackers craft a JWT with the
 algorithm field set to none.

0:04:45.200000 --> 0:04:48.840000
 And what this tells the server to
 do is not validate the signature.

0:04:48.840000 --> 0:04:51.280000
 So that's something that
 should not happen.

0:04:51.280000 --> 0:04:56.960000
 But if, again, if a JWT library or implementation
 is misconfigured, then

0:04:56.960000 --> 0:04:59.340000
 this can work. And you'll see it.

0:04:59.340000 --> 0:05:02.040000
 You'll see how this works shortly.

0:05:02.040000 --> 0:05:05.560000
 And then second step is the
 JWT signature removal.

0:05:05.560000 --> 0:05:09.100000
 So, you know, if you remember in the
 previous video, I said that, you

0:05:09.100000 --> 0:05:14.060000
 know, a JWT should contain three parts,
 the third part of the final being

0:05:14.060000 --> 0:05:19.580000
 the signature, and that ideally, you
 know, a server or API endpoint should

0:05:19.580000 --> 0:05:24.300000
 not process a JSON web token
 without all three parts.

0:05:24.300000 --> 0:05:29.000000
 However, if there's no verification,
 the attacker modifies the token and

0:05:29.000000 --> 0:05:30.820000
 removes the signature all together.

0:05:30.820000 --> 0:05:35.400000
 And with this example, you can see
 that the signature portion or after

0:05:35.400000 --> 0:05:38.920000
 the or the third part is
 missing or is empty.

0:05:38.920000 --> 0:05:42.760000
 Now, when using this, it's very important
 to state that if you're removing

0:05:42.760000 --> 0:05:46.980000
 the signature, for example, that you
 still maintain the dot or the full

0:05:46.980000 --> 0:05:52.820000
 stop after the payload part of the JWT
 token and then step three finally

0:05:52.820000 --> 0:05:54.280000
 authentication bypass.

0:05:54.280000 --> 0:05:58.920000
 So the server interprets the token
 as valid because it does not verify

0:05:58.920000 --> 0:06:02.700000
 the signature when the algorithm
 is set to none.

0:06:02.700000 --> 0:06:06.980000
 So attackers can basically modify the
 payload to impersonate any user

0:06:06.980000 --> 0:06:08.460000
 or escalate privileges.

0:06:08.460000 --> 0:06:14.260000
 And this is arguably one of the most
 common misconfigurations that you

0:06:14.260000 --> 0:06:16.220000
 see, especially with APIs.

0:06:16.220000 --> 0:06:20.620000
 It's starting to get better or, you know,
 I've at least noticed that this

0:06:20.620000 --> 0:06:24.000000
 issue is not that prevalent anymore,
 but it's still present.

0:06:24.000000 --> 0:06:28.040000
 And I think it's important you understand
 or we start off with this vulnerability.

0:06:28.040000 --> 0:06:34.480000
 So how is it X, how is this vulnerability
 exploited, which I've gone over,

0:06:34.480000 --> 0:06:38.520000
 but, you know, generally speaking,
 what does it allow you to do?

0:06:38.520000 --> 0:06:44.460000
 So privilege escalation where you modify
 the payload or the claims within

0:06:44.460000 --> 0:06:46.020000
 a payload to elevate your privileges.

0:06:46.020000 --> 0:06:51.140000
 So, you know, for example, changing
 a public, a public claim like user

0:06:51.140000 --> 0:06:56.400000
 to roll admin or, you know, changing
 the role from just your user use

0:06:56.400000 --> 0:06:57.880000
 ID to that of admin.

0:06:57.880000 --> 0:07:01.240000
 And as you know, admin typically
 has the idea of one.

0:07:01.240000 --> 0:07:02.360000
 That's not always the case.

0:07:02.360000 --> 0:07:05.340000
 But generally speaking,
 secondly, impersonation.

0:07:05.340000 --> 0:07:08.980000
 So you forge tokens to impersonate
 other users by altering the fields

0:07:08.980000 --> 0:07:10.820000
 like username or email.

0:07:10.820000 --> 0:07:14.280000
 And then obviously session hijacking
 where you gain unauthorized access

0:07:14.280000 --> 0:07:19.420000
 to a session by forging a token
 with a valid user's payload.

0:07:19.420000 --> 0:07:22.680000
 With that being said, I think it's
 time to actually show you how this

0:07:22.680000 --> 0:07:26.320000
 works. So this video has
 a lab associated with it.

0:07:26.320000 --> 0:07:28.860000
 It's going to be the lab
 just below this video.

0:07:28.860000 --> 0:07:33.300000
 The lab will provide you with access
 to a calilinic system and we'll take

0:07:33.300000 --> 0:07:37.000000
 it from there. So I'm going to fire
 up my lab environment and I'll see

0:07:37.000000 --> 0:07:39.120000
 you there in a couple of seconds.

0:07:39.120000 --> 0:07:43.740000
 All right. So I'm currently within
 the lab environment and you'll have

0:07:43.740000 --> 0:07:47.900000
 to forgive me because again, this particular
 calilinic system does not

0:07:47.900000 --> 0:07:50.700000
 scale to the entirety of my resolution.

0:07:50.700000 --> 0:07:56.300000
 However, I'll be zooming in or increasing
 my font size so that you can

0:07:56.300000 --> 0:07:57.540000
 see what's going on.

0:07:57.540000 --> 0:08:03.100000
 So this calilinic system again is
 fully configured ready to go.

0:08:03.100000 --> 0:08:07.380000
 And you may be asking what's the IP
 address of the target in this case

0:08:07.380000 --> 0:08:12.680000
 API. And in the case of this lab, you
 can find that down by typing in

0:08:12.680000 --> 0:08:19.160000
 the iFconfig command or identifying
 your calilinics IP, which in most

0:08:19.160000 --> 0:08:20.740000
 cases is going to be different.

0:08:20.740000 --> 0:08:25.580000
 So you want to look for the interface
 Ethernet 1 and your calilinics IP

0:08:25.580000 --> 0:08:28.740000
 will be the second IP within the subnet.

0:08:28.740000 --> 0:08:31.920000
 So in your case, this will be different,
 but you will be on the second

0:08:31.920000 --> 0:08:35.100000
 IP within the subnet or network.

0:08:35.100000 --> 0:08:38.400000
 The target API is on the third IP.

0:08:38.400000 --> 0:08:42.320000
 So you just need to copy this value
 and change the two at the end to a

0:08:42.320000 --> 0:08:43.720000
 three and your golden.

0:08:43.720000 --> 0:08:46.180000
 So again, I'll copy mine here.

0:08:46.180000 --> 0:08:51.840000
 Make sure you use the value or the
 IP or the subnet that's within your

0:08:51.840000 --> 0:08:54.340000
 lab environment or instance.

0:08:54.340000 --> 0:08:59.840000
 And in this particular case, the lab
 documentation outlines the port or

0:08:59.840000 --> 0:09:07.600000
 the port as well as the API
 endpoints for the API.

0:09:07.600000 --> 0:09:12.260000
 In this case, it's a Rust API that's
 running on port 1337 on the target

0:09:12.260000 --> 0:09:17.720000
 IP. So we can just do a quick curl and
 say, you know, in this case, I'll

0:09:17.720000 --> 0:09:23.540000
 paste in that and change the two at
 the end to a three and say 1337.

0:09:23.540000 --> 0:09:25.580000
 And let's see what we get here.

0:09:25.580000 --> 0:09:31.680000
 All right. So as we can see, it looks
 like it's running string API or

0:09:31.680000 --> 0:09:35.740000
 SDR, Strapi, SDR API, depending
 on how you pronounce it.

0:09:35.740000 --> 0:09:41.280000
 So we can also open this up in our browser
 just to see Strapi or SDR API

0:09:41.280000 --> 0:09:46.400000
 in action. So I think it should
 have a web interface.

0:09:46.400000 --> 0:09:49.340000
 Yeah. So there we go.

0:09:49.340000 --> 0:09:53.580000
 Anyway, the bottom line is
 that I'll close that here.

0:09:53.580000 --> 0:10:01.000000
 We can access the API and you've also
 been provided with credentials that

0:10:01.000000 --> 0:10:03.660000
 you can use to authenticate with the API.


0:10:03.660000 --> 0:10:08.040000
 In this case, you've been given two
 as per what's in the lab docs, one

0:10:08.040000 --> 0:10:11.420000
 of whom is Eliot Alderson.

0:10:11.420000 --> 0:10:17.120000
 I'll not delve into the reference
 there, but we can just say curl.

0:10:17.120000 --> 0:10:20.720000
 And for the headers, we want it obviously
 because we're dealing with an

0:10:20.720000 --> 0:10:28.840000
 API. The content type is going
 to be that of application JSON.

0:10:28.840000 --> 0:10:30.580000
 That's quite important.

0:10:30.580000 --> 0:10:33.280000
 And we're then going to say post.

0:10:33.280000 --> 0:10:35.420000
 It's sending a post here.

0:10:35.420000 --> 0:10:41.140000
 And then the data, the body of the post
 request, we're going to specify

0:10:41.140000 --> 0:10:50.680000
 the following. So in this case,
 identifier is going to be Eliot.

0:10:50.680000 --> 0:10:53.260000
 That's the username you've been provided.


0:10:53.260000 --> 0:10:57.560000
 And what we're trying to do is
 to get the JWT token for Eliot.

0:10:57.560000 --> 0:11:00.940000
 So we need to off pretty much.

0:11:00.940000 --> 0:11:03.800000
 So we'll say, yeah, that's Eliot.

0:11:03.800000 --> 0:11:08.340000
 And then the password is going to be
 just password, at least for this

0:11:08.340000 --> 0:11:09.420000
 particular user.

0:11:09.420000 --> 0:11:16.200000
 So password. And then we are going to
 say, Eliot Alderson being the full

0:11:16.200000 --> 0:11:18.580000
 name right over here.

0:11:18.580000 --> 0:11:26.760000
 Eliot Alderson. And then we're just
 going to close that up there.

0:11:26.760000 --> 0:11:33.400000
 Nice and clean. And then HTTP,
 the target IP and port 1337.

0:11:33.400000 --> 0:11:37.600000
 The API endpoint for authentication
 is off local.

0:11:37.600000 --> 0:11:43.500000
 So off local. And then I'm just going to
 pipe and pass this to JQ to actually

0:11:43.500000 --> 0:11:48.380000
 display the JSON response correctly.

0:11:48.380000 --> 0:11:51.300000
 So JQ hit enter.

0:11:51.300000 --> 0:11:59.740000
 Let's see. Making mistake here.

0:11:59.740000 --> 0:12:09.580000
 Eliot password. In this particular case,
 Infi- Eliot password is, yeah,

0:12:09.580000 --> 0:12:11.340000
 that looks right.

0:12:11.340000 --> 0:12:17.860000
 Identify here. I think I found
 my mistake right over here.

0:12:17.860000 --> 0:12:20.660000
 I forgot to pass that in correctly.

0:12:20.660000 --> 0:12:27.280000
 There we go. And as you can see,
 right over here in the response.

0:12:27.280000 --> 0:12:28.420000
 Just want to show you there.

0:12:28.420000 --> 0:12:29.320000
 Yeah, there we go.

0:12:29.320000 --> 0:12:33.280000
 So we can see the JWT given here.

0:12:33.280000 --> 0:12:35.420000
 And we can see all three parts.

0:12:35.420000 --> 0:12:40.520000
 And now what we want to test for again
 is to see whether the server accepts,

0:12:40.520000 --> 0:12:44.520000
 you know, the algorithm to be
 set to none, for example.

0:12:44.520000 --> 0:12:46.800000
 That's just one example here.

0:12:46.800000 --> 0:12:51.040000
 Now, you know, before we do that, as
 I mentioned in the previous video,

0:12:51.040000 --> 0:12:55.840000
 when we were discussing JSON web tokens,
 we can decode the head end payloads,

0:12:55.840000 --> 0:12:59.460000
 because generally speaking, they're
 going to be encoded in base 64.

0:12:59.460000 --> 0:13:05.680000
 So I'm just going to copy this
 JWT for Eliot really quickly.

0:13:05.680000 --> 0:13:08.700000
 And do I have a text editor
 somewhere here?

0:13:08.700000 --> 0:13:13.060000
 Let's see. All about accessories
 maybe in here.

0:13:13.060000 --> 0:13:14.900000
 Probably just use, there we are.

0:13:14.900000 --> 0:13:16.260000
 We have mousepad.

0:13:16.260000 --> 0:13:19.520000
 Just so I have it at hand.

0:13:19.520000 --> 0:13:28.340000
 So I'll just give that a
 few seconds to pop up.

0:13:28.340000 --> 0:13:31.880000
 All right. So I've just used it then
 because I don't think mousepad wants

0:13:31.880000 --> 0:13:35.720000
 to open up. So I'm just keeping
 these nice and safe.

0:13:35.720000 --> 0:13:40.620000
 But to show you what I'm talking about
 here, if I, I'm just going to copy

0:13:40.620000 --> 0:13:44.020000
 the header here, the first
 part without the dot.

0:13:44.020000 --> 0:13:49.720000
 If we wanted to decode it, what we
 can do, because it is base 64 is we

0:13:49.720000 --> 0:13:57.380000
 can just say echo base that in there
 and then just pipe it to base 64,

0:13:57.380000 --> 0:14:00.520000
 the base 64 utility and then say decode.

0:14:00.520000 --> 0:14:04.080000
 All right. So we hit enter and you can
 see you might be a little bit confused

0:14:04.080000 --> 0:14:08.580000
 that in this case, the token that's
 generated by the API endpoint says

0:14:08.580000 --> 0:14:12.640000
 the, you know, we have the type so
 JWT, but it also has the algorithm

0:14:12.640000 --> 0:14:14.860000
 and it's set to HS256.

0:14:14.860000 --> 0:14:18.500000
 Now this might be something
 that confuses you.

0:14:18.500000 --> 0:14:22.000000
 Remember, this is the server
 generating the token.

0:14:22.000000 --> 0:14:26.440000
 It doesn't mean that the server or API
 endpoint will not accept a token

0:14:26.440000 --> 0:14:32.860000
 that doesn't have the algorithm specified
 or whose algorithm, you know,

0:14:32.860000 --> 0:14:35.380000
 just has the value of none.

0:14:35.380000 --> 0:14:37.460000
 And that's really what
 we're testing here.

0:14:37.460000 --> 0:14:44.240000
 So we can also do this for the payload,
 which is going to be this right

0:14:44.240000 --> 0:14:49.680000
 over here. Just trying
 to see there we go.

0:14:49.680000 --> 0:14:52.780000
 Right there and just copy that there.

0:14:52.780000 --> 0:14:58.860000
 Nice and easy. And we're going to
 just say echo base that in there.

0:14:58.860000 --> 0:15:03.840000
 And then we're going to say pipe this
 to base 64 and please decode that

0:15:03.840000 --> 0:15:05.620000
 for us while you're at it.

0:15:05.620000 --> 0:15:09.560000
 Okay, so there we are.

0:15:09.560000 --> 0:15:16.240000
 We can see that we get some some error
 here regarding invalid input.

0:15:16.240000 --> 0:15:20.220000
 Now the reason why we may get this is
 because sometimes decoding the head

0:15:20.220000 --> 0:15:25.000000
 of payload using base 64 or the Linux
 utility will give you an error.

0:15:25.000000 --> 0:15:32.000000
 And that happens because the JWT token
 is using the base 64 URL encode

0:15:32.000000 --> 0:15:36.200000
 algorithm. And as a result, what that
 does if you're familiar with base

0:15:36.200000 --> 0:15:40.980000
 64, it strips all the equal signs, you
 know, which essentially are used

0:15:40.980000 --> 0:15:48.260000
 in base 64 for padding in, you
 know, base 64 encoded data.

0:15:48.260000 --> 0:15:52.220000
 So that really is not something
 we need to worry about.

0:15:52.220000 --> 0:15:55.180000
 But what if we try and
 create our own token?

0:15:55.180000 --> 0:16:00.160000
 So we can see in this case our use ID
 for Elliot all the sudden is two.

0:16:00.160000 --> 0:16:03.040000
 And you can see we have it here.

0:16:03.040000 --> 0:16:08.500000
 So if you remember that what that particular
 claim means, that is the

0:16:08.500000 --> 0:16:11.400000
 issued at claim right over here.

0:16:11.400000 --> 0:16:15.800000
 And this is the Unix that the time,
 you know, in Unix timestamp format.

0:16:15.800000 --> 0:16:22.000000
 So what if we try and tamper with this
 token and we again don't sign it,

0:16:22.000000 --> 0:16:25.420000
 obviously, because the, you know, in
 order to sign it, we would need the

0:16:25.420000 --> 0:16:30.540000
 key. But if the server or API endpoint,
 you know, is not verifying the

0:16:30.540000 --> 0:16:34.560000
 algorithm then, or it's, you know,
 that doesn't really verify them, we

0:16:34.560000 --> 0:16:38.880000
 can just set the algorithm in the header
 to none and just have or use

0:16:38.880000 --> 0:16:45.560000
 a JWT token that does not include the
 third part, which is the signature.

0:16:45.560000 --> 0:16:48.640000
 So what we can do is let's
 do it right now.

0:16:48.640000 --> 0:16:50.520000
 So we can actually do it within Linux.

0:16:50.520000 --> 0:16:57.640000
 So echo and I'm going to say within curly
 braces using the same formatting,

0:16:57.640000 --> 0:17:01.240000
 we're going to say the type
 is going to be JWT.

0:17:01.240000 --> 0:17:02.680000
 So we don't want to change that.

0:17:02.680000 --> 0:17:09.280000
 So JWT. And then what we want to do
 is just follow the same format here.

0:17:09.280000 --> 0:17:12.760000
 So algorithm, instead of HS 256.

0:17:12.760000 --> 0:17:17.500000
 Now, we're going to see whether the
 API endpoint or server accepts the

0:17:17.500000 --> 0:17:20.240000
 non algorithm option.

0:17:20.240000 --> 0:17:23.660000
 All right. And we're then going to close
 the curly braces, single quote,

0:17:23.660000 --> 0:17:25.760000
 and then encode this in base 64.

0:17:25.760000 --> 0:17:28.400000
 So we'll just pipe it to base 64.

0:17:28.400000 --> 0:17:31.000000
 And it enter. Okay.

0:17:31.000000 --> 0:17:34.480000
 Now one important thing is, if you remember
 what I said earlier, a few,

0:17:34.480000 --> 0:17:38.280000
 a few, I think a minute ago, you want
 to get rid of the equal sign because

0:17:38.280000 --> 0:17:39.260000
 they're used for padding.

0:17:39.260000 --> 0:17:42.680000
 So you just want to copy
 this right over here.

0:17:42.680000 --> 0:17:44.760000
 So that's the first part there.

0:17:44.760000 --> 0:17:50.880000
 And I'll go ahead into Vim here, where
 I had, you know, I sort of added

0:17:50.880000 --> 0:17:59.660000
 that there. We have the original and
 just say, sorry, say, header is equal

0:17:59.660000 --> 0:18:02.780000
 to paste that in there.

0:18:02.780000 --> 0:18:08.060000
 Okay. And then we have the payload,
 which is the second part and nothing

0:18:08.060000 --> 0:18:10.380000
 else. We don't want the signature.

0:18:10.380000 --> 0:18:18.020000
 So there we go. And then what we want
 to do now is modify the payload,

0:18:18.020000 --> 0:18:21.420000
 which in this case said
 that our ID is too.

0:18:21.420000 --> 0:18:25.640000
 So in this case, we can try for privilege
 escalation because string API,

0:18:25.640000 --> 0:18:29.780000
 and this is highlighted in the lab
 documentation string API identifies

0:18:29.780000 --> 0:18:33.360000
 the admin user using the ID one.

0:18:33.360000 --> 0:18:41.360000
 So what we can do is, in this particular
 case, we can just say echo, you

0:18:41.360000 --> 0:18:45.160000
 know, pretty much just modify this here.

0:18:45.160000 --> 0:18:48.880000
 So we're going to just say echo n.

0:18:48.880000 --> 0:18:53.500000
 And what we want is open
 up single quotes there.

0:18:53.500000 --> 0:18:57.020000
 We want to change this ID to one.

0:18:57.020000 --> 0:19:05.660000
 Okay. And we also, we don't need
 to modify anything else there.

0:19:05.660000 --> 0:19:11.420000
 So we are just going to say close that
 and then send it, you know, base

0:19:11.420000 --> 0:19:15.160000
 64 pipette to base 64 to
 do the encoding for us.

0:19:15.160000 --> 0:19:17.720000
 We don't want any trailing
 characters or any padding.

0:19:17.720000 --> 0:19:20.180000
 So just get this right over here.

0:19:20.180000 --> 0:19:26.980000
 And now we have our JWT token that
 we have forged in order to test and

0:19:26.980000 --> 0:19:34.000000
 see whether the servo API endpoint checks
 or verifies the signature, you

0:19:34.000000 --> 0:19:38.540000
 know, the actual algorithm in the header.


0:19:38.540000 --> 0:19:45.720000
 So with that being said now, what we
 can do is we can actually create

0:19:45.720000 --> 0:19:47.560000
 our forged token.

0:19:47.560000 --> 0:19:53.860000
 And this is where you could use a tool
 like JWT.io to essentially verify

0:19:53.860000 --> 0:19:55.780000
 that your forged it correctly.

0:19:55.780000 --> 0:20:00.940000
 So what I'm going to do in separate
 browser tab is open up JWT.io and

0:20:00.940000 --> 0:20:05.100000
 just copy the header and append it to
 the payload that we just created.

0:20:05.100000 --> 0:20:07.120000
 And I just want to show
 you that it works.

0:20:07.120000 --> 0:20:08.660000
 So just give me a second.

0:20:08.660000 --> 0:20:13.820000
 All right. So I'm currently on the JWT
.io website that gives you a very

0:20:13.820000 --> 0:20:17.920000
 cool, you know, I wanted to show you
 using the tool as opposed to mention

0:20:17.920000 --> 0:20:19.000000
 it in the slides.

0:20:19.000000 --> 0:20:23.420000
 But, you know, what is JWT.io
 or this particular debugger?

0:20:23.420000 --> 0:20:27.860000
 Well, JWT.io as it says, he allows
 you to decode, verify and generate

0:20:27.860000 --> 0:20:32.000000
 JWT. So in this case, what I've done
 is I've pasted in right over here

0:20:32.000000 --> 0:20:36.700000
 the encoded base 64 encoded
 token that we generated.

0:20:36.700000 --> 0:20:40.180000
 So the header followed by the payload.

0:20:40.180000 --> 0:20:44.600000
 And in this case, it's going to
 say invalid, which is fine.

0:20:44.600000 --> 0:20:47.660000
 And you can see our data is highlighted
 in there correctly, which means,

0:20:47.660000 --> 0:20:50.060000
 you know, we've encoded it correctly.

0:20:50.060000 --> 0:20:52.580000
 We have the header, the payload,
 and then the signature.

0:20:52.580000 --> 0:20:56.240000
 But one important thing is that regardless
 of whether you're including

0:20:56.240000 --> 0:21:01.360000
 the signature, the third part of the
 JWT or not, you still need to include

0:21:01.360000 --> 0:21:04.600000
 the dot right over there.

0:21:04.600000 --> 0:21:09.580000
 So the you don't need to worry about
 invalid signature cause, again, this

0:21:09.580000 --> 0:21:14.020000
 is doing this actually correct
 from a security perspective.

0:21:14.020000 --> 0:21:18.200000
 All we want to do is just verify that
 the when decoded that it gives us

0:21:18.200000 --> 0:21:24.080000
 the values that we wanted, especially
 the algorithms specified as none.

0:21:24.080000 --> 0:21:30.160000
 And then the payload, the payload part,
 you know, we have the ID, which

0:21:30.160000 --> 0:21:35.900000
 is a public claim set to one to sort
 of try and impersonate the admin

0:21:35.900000 --> 0:21:40.280000
 user or to, you know, perform
 administrative actions.

0:21:40.280000 --> 0:21:44.440000
 So now that we've sort of verified this,
 I'm just going to copy it here.

0:21:44.440000 --> 0:21:48.460000
 Again, there's no real need to use
 JWT dot I was just a great tool if

0:21:48.460000 --> 0:21:50.160000
 you ever doing this on the fly.

0:21:50.160000 --> 0:21:53.780000
 So I'm going to switch back over into
 the lab and we can try and see whether

0:21:53.780000 --> 0:21:58.420000
 this works. All right, so I'm
 back on the Kali Linux system.

0:21:58.420000 --> 0:22:03.380000
 And what we want to do is let's try
 and see whether we have, you know,

0:22:03.380000 --> 0:22:07.960000
 we can successfully impersonate the,
 you know, the administrator or at

0:22:07.960000 --> 0:22:09.900000
 least their privileges.

0:22:09.900000 --> 0:22:16.920000
 And let's see if we can create a new user
 account, a new admin user account,

0:22:16.920000 --> 0:22:18.820000
 because that would require
 admin privileges.

0:22:18.820000 --> 0:22:21.760000
 Right. So what we will
 do is we'll use curl.

0:22:21.760000 --> 0:22:23.960000
 We want to make a post.

0:22:23.960000 --> 0:22:32.240000
 And then the headers are going to be
 obviously content, content type is

0:22:32.240000 --> 0:22:36.240000
 going to be, you know, application, JSON.


0:22:36.240000 --> 0:22:41.980000
 And from this point on, we are going
 to say an additional header.

0:22:41.980000 --> 0:22:47.940000
 And this API uses, you remember the
 video on token placement, where we

0:22:47.940000 --> 0:22:51.200000
 were introduced to token
 based authentication.

0:22:51.200000 --> 0:23:00.360000
 This API uses or essentially utilizes
 authentication in the form of the

0:23:00.360000 --> 0:23:01.880000
 the bearer token.

0:23:01.880000 --> 0:23:04.100000
 So we use the authorization header.

0:23:04.100000 --> 0:23:07.060000
 So authorization.

0:23:07.060000 --> 0:23:11.260000
 And we then specify that as bearer.

0:23:11.260000 --> 0:23:17.200000
 And then we specify the JWT
 token that we created.

0:23:17.200000 --> 0:23:20.760000
 So I'll paste it in there.

0:23:20.760000 --> 0:23:25.620000
 My apologies. Doesn't look like I, I
 copied the one that we had on JWT,

0:23:25.620000 --> 0:23:26.540000
 but no, no matter.

0:23:26.540000 --> 0:23:31.000000
 So we have it right over here, we
 have the header that we created.

0:23:31.000000 --> 0:23:33.840000
 So I'll just paste that in there.

0:23:33.840000 --> 0:23:37.960000
 We'll use a full stop or a
 dot, and then the payload.

0:23:37.960000 --> 0:23:40.940000
 Again, remember to exclude the equals.

0:23:40.940000 --> 0:23:42.380000
 That's just padding.

0:23:42.380000 --> 0:23:46.740000
 And we then use another dot, because
 that's always required.

0:23:46.740000 --> 0:23:51.160000
 And then let's close our quotes
 here for the headers.

0:23:51.160000 --> 0:23:56.980000
 At this point, we're making the request
 to what's the address, what's

0:23:56.980000 --> 0:24:00.680000
 our IP address or the target IP,
 because I've forgotten it.

0:24:00.680000 --> 0:24:02.800000
 It is this right over here.

0:24:02.800000 --> 0:24:05.180000
 So actually, I'll just copy that there.

0:24:05.180000 --> 0:24:11.560000
 Actually, we're not off local, because
 we're registering, we want to utilize.

0:24:11.560000 --> 0:24:14.580000
 And again, this is highlighted
 in the lab documentation.

0:24:14.580000 --> 0:24:21.340000
 The end point for creating a user is
 going to be, I believe it is users.

0:24:21.340000 --> 0:24:22.680000
 Let's test it out.

0:24:22.680000 --> 0:24:28.200000
 So HTTP, and this is
 just port 1337 users.

0:24:28.200000 --> 0:24:34.240000
 And then the data right over here is
 going to be, we'll put it in the

0:24:34.240000 --> 0:24:41.920000
 JSON format. So this is also outlined
 in the lab documentation, the fields

0:24:41.920000 --> 0:24:44.280000
 required for creating user accounts.

0:24:44.280000 --> 0:24:47.960000
 So we'll just create one called
 test, use name test.

0:24:47.960000 --> 0:24:52.720000
 And then the email is going to be
 also something very, very simple.

0:24:52.720000 --> 0:24:56.260000
 So we'll go for test at test.com.

0:24:56.260000 --> 0:25:01.860000
 And we'll then say the password,
 because that's quite important.

0:25:01.860000 --> 0:25:07.460000
 The password is going to be, let me not
 forget to do what I did last time.

0:25:07.460000 --> 0:25:10.280000
 The password will just go for password.

0:25:10.280000 --> 0:25:13.460000
 Just keep it nice and simple, like so.

0:25:13.460000 --> 0:25:17.940000
 And then the role, we want to set to
 one, to try and see whether, you

0:25:17.940000 --> 0:25:22.140000
 know, the token that we forged actually
 gives us admin privileges, enough,

0:25:22.140000 --> 0:25:26.300000
 you know, privileges that should allow
 us to create another admin user.

0:25:26.300000 --> 0:25:34.360000
 So we'll then close this up and
 close the single quote there.

0:25:34.360000 --> 0:25:39.720000
 And I'll also pipe this to JQ, so that
 the JSON data is displayed correctly

0:25:39.720000 --> 0:25:42.880000
 on the screen, or at least formatted.

0:25:42.880000 --> 0:25:44.740000
 And there we are.

0:25:44.740000 --> 0:25:51.660000
 Let's see, right over here, looks
 like it was successful.

0:25:51.660000 --> 0:25:56.700000
 And we don't get an error, which means
 the JWT token that we forged actually

0:25:56.700000 --> 0:26:03.960000
 worked. And that means that the server
 or the, the API endpoint does not

0:26:03.960000 --> 0:26:05.720000
 verify the algorithm.

0:26:05.720000 --> 0:26:10.680000
 So pretty much, you know, we
 were able to authenticate.

0:26:10.680000 --> 0:26:14.580000
 And, you know, we pretty much impersonated
 the admin, because we fought

0:26:14.580000 --> 0:26:20.280000
 down JWT token bypassed, not bypassed,
 we didn't have to bypass it.

0:26:20.280000 --> 0:26:25.460000
 There was no, you know, algorithm verification
 or signature verification,

0:26:25.460000 --> 0:26:30.280000
 if you will. What this essentially
 means is that this API pretty much

0:26:30.280000 --> 0:26:33.880000
 supports JWT tokens signed
 using the non algorithm.

0:26:33.880000 --> 0:26:40.060000
 So we can now go into, let us open up
 Firefox here and see whether that

0:26:40.060000 --> 0:26:44.260000
 user was created successfully,
 just paste and go.

0:26:44.260000 --> 0:26:50.580000
 And we're going to see admin to try
 and log into Strapi or string API.

0:26:50.580000 --> 0:26:52.800000
 There we are. And with
 the user we created.

0:26:52.800000 --> 0:26:56.740000
 So the username was just user,
 password was password.

0:26:56.740000 --> 0:26:58.920000
 And we just hit login.

0:26:58.920000 --> 0:27:02.140000
 Let's see, we do that correctly.

0:27:02.140000 --> 0:27:04.940000
 Oh, it was not user, it was test my bad.

0:27:04.940000 --> 0:27:08.800000
 I almost gave, gave you guys a heart
 attack, as well as I did myself.

0:27:08.800000 --> 0:27:12.760000
 There we go. And we should
 have admin privileges.

0:27:12.760000 --> 0:27:22.300000
 I'm not sure how to verify this, but
 let's see, we also have, if we go,

0:27:22.300000 --> 0:27:27.020000
 yeah, I should be admin, but yeah, so
 secret flags, right over here, this

0:27:27.020000 --> 0:27:31.500000
 is the flag. So pretty much, and you
 can also verify this now, if we tried

0:27:31.500000 --> 0:27:35.280000
 to log in or to authenticate with the
 API with curl, you would have seen

0:27:35.280000 --> 0:27:39.280000
 the token. And it would, in this case,
 because the token would be generated

0:27:39.280000 --> 0:27:44.060000
 by, and in this, what I'm referring
 to is for the test user, if we try

0:27:44.060000 --> 0:27:47.500000
 and authenticate with the test user,
 we created the token that the server

0:27:47.500000 --> 0:27:52.160000
 or the API will send back will have
 the algorithm set in the header to

0:27:52.160000 --> 0:27:59.760000
 HS 256, which means it's creating the
 JWTs correctly or securely, but

0:27:59.760000 --> 0:28:06.600000
 in terms of authenticating with the
 API, the server or API endpoint, the

0:28:06.600000 --> 0:28:11.940000
 API doesn't seem to verify or validate
 the algorithm and pretty much allows

0:28:11.940000 --> 0:28:16.660000
 us to tokens with the algorithm set
 to none, which is a huge issue.

0:28:16.660000 --> 0:28:19.800000
 And I just wanted to show you
 what that would look like.

0:28:19.800000 --> 0:28:23.840000
 And from this point, I'm pretty sure
 you're seeing that JWTs are not that

0:28:23.840000 --> 0:28:27.920000
 complicated. After all, you just need to
 understand what the header contains,

0:28:27.920000 --> 0:28:34.200000
 the payload, and what the signature is
 used for, and then how to properly

0:28:34.200000 --> 0:28:38.740000
 test an API or a web application for
 that matter, because this is not

0:28:38.740000 --> 0:28:42.560000
 really limited to APIs alone.

0:28:42.560000 --> 0:28:46.560000
 APIs are not the only services
 that utilize JWTs.

0:28:46.560000 --> 0:28:49.800000
 Anyway, that brings us to the end of
 the practical demonstration section

0:28:49.800000 --> 0:28:55.580000
 of this video. All right, so that was
 the non algorithm vulnerability.

0:28:55.580000 --> 0:28:59.660000
 I hope you found that useful,
 insightful into JWTs.

0:28:59.660000 --> 0:29:04.120000
 If this is your first time interacting
 with them, at least via an API.

0:29:04.120000 --> 0:29:06.860000
 But with that being said, that's
 going to be it for this video.

0:29:06.860000 --> 0:29:09.280000
 And I will be seeing you
 in the next video.

