0xfat part one release and restructure

master
_N0x 1 year ago
parent 032e6c22e6
commit 73ea17ce9c

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Before

Width:  |  Height:  |  Size: 9.3 KiB

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Before

Width:  |  Height:  |  Size: 9.5 KiB

After

Width:  |  Height:  |  Size: 9.5 KiB

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Before

Width:  |  Height:  |  Size: 8.0 KiB

After

Width:  |  Height:  |  Size: 8.0 KiB

@ -1,17 +1,17 @@
+++
draft = true
date = 2023-03-07T23:54:16+01:00
title = "Solving 0xf.at!"
draft = false
date = 2023-03-14T23:54:16+01:00
title = "Solving 0xf.at - Part 1"
description = "A little collection of the approaches and stuff I used to solve 0xf.at challenges"
slug = ""
authors = ["_N0x"]
tags = []
tags = ["hackit", "challenges", "riddles", "0xf.at"]
categories = []
externalLink = ""
series = []
+++
# Solving 0xf.at funny little challenges
# Solving 0xf.at's funny little challenges - Part 1 Level 1 to 10
**WARNING!**
**THE FOLLOWING PAGE CONTAINS SPOILERS FOR THE PASSWORD-RIDDLE SITE 0XF.AT!**
@ -25,13 +25,18 @@ _Only continue reading if you are okay with seeing spoilers or need some help wi
\___//_/\_\_|(_)__,_|\__|
```
I guess it's time for my (almost) yearly blog entry so I remember how to use hugo... So why not do something fun and solve some hacking challenges!!
I guess it's time for my (almost) yearly blog entry so I remember how to use hugo...
So why not do something fun and solve some hacking challenges!!
[0xf.at](https://0xf.at) is a small website that offers a few password related riddles or "Hackits"
where the user is tasked to either recover passwords, bypass them or manipulate things in other ways to gain access.
There are a total of 30 levels ranging from very easy with nearly 20k solves to some super hard complex challenges that have less than five solves in comparison. Next to a little name they also have a type that hints at how the riddle can be solved, be it something JavaScript relates, some logic and programming or maybe reversing some PHP code to gain access.
There are a total of 38 levels ranging from very easy with nearly 20k solves to some super hard complex challenges that have less than five solves in comparison.
Next to a little name they also have a type that hints at how the riddle can be solved, be it something JavaScript relates, some logic and programming or maybe reversing some PHP code to gain access.
All in all some very fun things to tinker with and every now and then I stumble about this website and thought it might be a good idea to write down my though process and see how far I can make it. So let's take a peek!
All in all some very fun things to tinker with and every now and then I stumble about this website and thought it might be a good idea to write down my though process and see how far I can make it.
So let's take a peek!
Oh and just as a side note - most of these puzzles generate a random solution so just copy and pasting the solutions from here won't always be an option :)
## Level 1 - Easy beginnings
@ -56,13 +61,15 @@ But what could the password be? Since JavaScript is client site we take a peek a
</script>
```
Clicking the password calls the `checkPW()` function. And in there we can see that the value entered will be checked against the phrase "_tooeasy_".
Clicking the password calls the `checkPW()` function.
And in there we can see that the value entered will be checked against the phrase "_tooeasy_".
{{< figure src="images/lvl1_2.png" alt="Level 1 cleared" >}}
## Level 2 - JavaScript: Do you speak it?
Another JavaScript challenge. The screen looks just like with the first level so straight for the code it is.
Another JavaScript challenge.
The screen looks just like with the first level so straight for the code it is.
```html
<h1>Level 2</h1>
@ -115,7 +122,8 @@ Did I fool you?
</script>
```
The value of the password this time seems to be the result of the command `unescape("r%20i%20g%20h%20t%20")+""+"p"+"w"+""+"6304b3377"`. Pasting that into the development console of the browser reveals the passphrase for this level: "_r i g h t pw6304b3377_"
The value of the password this time seems to be the result of the command `unescape("r%20i%20g%20h%20t%20")+""+"p"+"w"+""+"6304b3377"`.
Pasting that into the development console of the browser reveals the passphrase for this level: "_r i g h t pw6304b3377_"
## Level 4 - Length matters
@ -137,13 +145,19 @@ Straight to the source code!
</script>
```
This is just as easy as the previous ones and the name of the level already gives pretty much everything away. We just need to take a look at how long the value of `pwinfo` is. We can do that with the console again. JavaScript is a silly language so it allows us to run something like `"2ab135a4dd3ffa04fd5b53ee5ed1cbf 3122c05 ecc31321321b 353a51a12e".length` in the console. Which reveals the length of 66. Just entering "_66_" as the password solves the level - I don't know what's worse, having the password in cleartext or using the length as a value which would probably be cracked even faster ;)
This is just as easy as the previous ones and the name of the level already gives pretty much everything away.
We just need to take a look at how long the value of `pwinfo` is.
We can do that with the console again.
JavaScript is a silly language so it allows us to run something like `"2ab135a4dd3ffa04fd5b53ee5ed1cbf 3122c05 ecc31321321b 353a51a12e".length` in the console.
Which reveals the length of 66.
Just entering "_66_" as the password solves the level - I don't know what's worse, having the password in cleartext or using the length as a value which would probably be cracked even faster ;)
Be aware that the value of `pwinfo` seems to be regenerated with each site reload so the actual value of the result might change!
## Level 5 - ASCII fun
ASCII is indeed fun and the author of the side also seems to be a fan of using something like `figlet` - [for example this website](https://www.askapache.com/online-tools/figlet-ascii/) - to generate silly ASCII images from text. But back to the challenge.
ASCII is indeed fun and the author of the side also seems to be a fan of using something like `figlet` - [for example this website](https://www.askapache.com/online-tools/figlet-ascii/) - to generate silly ASCII images from text.
But back to the challenge.
```html
<h1>Level 5</h1>
@ -164,11 +178,16 @@ ASCII is indeed fun and the author of the side also seems to be a fan of using s
</script>
```
`atoi()` is a usually function used in C and similar languages to convert a string or single character to it's corresponding ASCII value. But it just seems to be a wrapper for the JavaScript function `charCodeAt()`. Once more the debugging console comes to the rescue and we see that `"o".charCodeAt()` equals 111. Now we only add 66 and we have our password of "_177_". Nice!
`atoi()` is a usually function used in C and similar languages to convert a string or single character to it's corresponding ASCII value.
But it just seems to be a wrapper for the JavaScript function `charCodeAt()`.
Once more the debugging console comes to the rescue and we see that `"o".charCodeAt()` equals 111.
Now we only add 66 and we have our password of "_177_".
Nice!
## Level 6 - Color codes
Level 6 is yet again a JavaScript challenge. It looks a little different than the previous once tho.
Level 6 is yet again a JavaScript challenge.
It looks a little different than the previous once tho.
{{< figure src="images/lvl6_1.png" alt="Level 6 pretty colors" >}}
@ -199,13 +218,19 @@ Level 6 is yet again a JavaScript challenge. It looks a little different than th
</script>
```
Looking at the `if` statement is seems the color value of the element with the id `thought`. Checking that with the console reveals the value `rgb(153, 255, 51)` which gets passed into the `rgb2hex()` function. This only seems to turn the input format into the typical HTML color code. In this case the method returns "_#99ff33_" which once again solves the puzzle!
Looking at the `if` statement is seems the color value of the element with the id `thought`.
Checking that with the console reveals the value `rgb(153, 255, 51)` which gets passed into the `rgb2hex()` function.
This only seems to turn the input format into the typical HTML color code.
In this case the method returns "_#99ff33_" which once again solves the puzzle!
An even quicker way than to look at the `rgb2hex` function would be to look at the value of the `thought` element in the second line of code which reveals the value directly. Solved again!
An even quicker way than to look at the `rgb2hex` function would be to look at the value of the `thought` element in the second line of code which reveals the value directly.
Solved again!
## Level 7 - Jerry's screw-up
First level that isn't of type JavaScript. Apparently a Jerry is to blame for this mess. Starting the level greets us with the message "Jerry f\*cked up, he forgot the password for this level but he mumbled something about a robots.txt file and something about a hint.."
First level that isn't of type JavaScript.
Apparently a Jerry is to blame for this mess.
Starting the level greets us with the message "Jerry f\*cked up, he forgot the password for this level but he mumbled something about a robots.txt file and something about a hint.."
Oh well that can't be too hard then! Let's just look at the `robots.txt` file which is usually stored in the webroot of a website and is used for webcrawlers (for example how google indexes the web) to tell them where too look for specific information and how to scan the site or which areas are not to be scanned.
@ -227,7 +252,8 @@ But I guess "_jerryIsDaBossc0_"
## Level 8 - The password field
This one is a neat one that could actually prove useful in some case. It focuses more on HTML than JavaScript and there are multiple approaches to it
This one is a neat one that could actually prove useful in some case.
It focuses more on HTML than JavaScript and there are multiple approaches to it
{{< figure src="images/lvl8_1.png" alt="Typo in password!" >}}
@ -237,13 +263,15 @@ Now the easiest solution would be to just send the password as is and look a the
Just change the "0" to a "o" and send it again, level solved.
But there is a funnier version that seems to be more in line with what the author might have wanted us to do. Let's look at the HTML code.
But there is a funnier version that seems to be more in line with what the author might have wanted us to do.
Let's look at the HTML code.
```html
<h1>Level 8</h1>
<p>
Nice, someone already entered the password but they made a small mistake.<br />The
FIRST occurring 0 (zero) should actually be a small "o". Can you fix it?
FIRST occurring 0 (zero) should actually be a small "o".
Can you fix it?
</p>
<input id="pw" type="password" />
<br /><input type="button" value="OK" onclick="checkPW()" />
@ -257,7 +285,8 @@ But there is a funnier version that seems to be more in line with what the autho
[some more irrelevant code]
```
The password filed is an input field and has the id `pw` with the type `password`. We can just change the type to `text` and the text appears in our browser and we can edit the wrong password! So turning "z6sjdxnix9kfcu6qdnq809jtdp9k1edt" into "_z6sjdxnix9kfcu6qdnq8o9jtdp9k1edt_" gives us the same solution as the previous idea.
The password filed is an input field and has the id `pw` with the type `password`.
We can just change the type to `text` and the text appears in our browser and we can edit the wrong password! So turning "z6sjdxnix9kfcu6qdnq809jtdp9k1edt" into "_z6sjdxnix9kfcu6qdnq8o9jtdp9k1edt_" gives us the same solution as the previous idea.
## Level 9 - Calculations
@ -281,7 +310,12 @@ This one is just math and making sure you use the right variable in the right or
</script>
```
So `foo` is 47. This modulo 8 gives us 7 (for `bar`) which we add 1 to to get the solution of 8 for `moo`. `rar` is not even relevant as `moo` is the variable used in the condition for the password. The tricky bit is that in here not the password itself is compared with `moo` but the length of the password. So what we enter is irrelevant as long as the length is 8! So lets try the super secret passphrase of "_asdf1234_". Very nice!
So `foo` is 47.
This modulo 8 gives us 7 (for `bar`) which we add 1 to to get the solution of 8 for `moo`.
`rar` is not even relevant as `moo` is the variable used in the condition for the password.
The tricky bit is that in here not the password itself is compared with `moo` but the length of the password.
So what we enter is irrelevant as long as the length is 8! So lets try the super secret passphrase of "_asdf1234_".
Very nice!
## Level 10 - Variables
@ -304,4 +338,15 @@ With this level it's back to the JavaScript challenges so first let's get the co
}
</script>
```
Many fancy lines of code. But looking closely nothing really is happening with the initial value for `CodeCode`. Just some concatenation that has no effect and some very strange comparisons that also have nothing to do with the initial value. So it's all about reading the code a little. Very simple to see the solution here can only be "*moo0bc*"
Many fancy lines of code.
But looking closely nothing really is happening with the initial value for `CodeCode`.
Just some concatenation that has no effect and some very strange comparisons that also have nothing to do with the initial value.
So it's all about reading the code a little.
Very simple to see the solution here can only be "*moo0bc*"
## Final words for the first levels
All in all some easy but still fun challenges that makes you think a little more how things work in a browser, be it how JavaScript works or what the `robot.txt` file is and where to find it on a website!
To keep things a little more organized I've cut the Levels down into ten Level segments so it's not just one giant blog post but is a little more easy to navigate.
You can find the writeup for the next ten levels [here]({{< ref "/posts" >}}) once they are up!

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

@ -0,0 +1,110 @@
+++
draft = true
date = 2023-03-14T23:55:16+01:00
title = "Solving 0xf.at - Part 2"
description = "A little collection of the approaches and stuff I used to solve 0xf.at challenges"
slug = ""
authors = ["_N0x"]
tags = ["hackit", "challenges", "riddles", "0xf.at"]
categories = []
externalLink = ""
series = []
+++
# Solving 0xf.at's funny little challenges - Part 2 Level 11 to 20
## WARNING!
**THE FOLLOWING PAGE CONTAINS SPOILERS FOR THE PASSWORD-RIDDLE SITE 0XF.AT!**
_Only continue reading if you are okay with seeing spoilers or need some help with the riddles ;)_
```
___ __ _
/ _ \__ __/ _| __ _| |_
| | | \ \/ / |_ / _` | __|
| |_| |> <| _| (_| | |_
\___//_/\_\_|(_)__,_|\__|
```
To keep things a little more organized I've split up the solutions and approaches into ten challenge segments so not everything is crammed into a single post. In here we will look at levels 11 to 20. For Level 1 to 10 take a look at [the first post]({{< ref "0xfat_1" >}}).
## Level 11 - Understand the algorithm
The next challenges are more focused on PHP, programming and logic.
Level 11 shows us the PHP function with which the password is calculates:
```php
function pwCheck($password)
{
if($password==date("d.m.Y")) //GMT +1
return true;
else return false;
}
```
Even without much PHP knowledge we can assume that the `date` function might give us the current date in the specified format of `d.m.Y`.
PHP has a [very good documentation](https://www.php.net/docs.php) so we can just take a look a the [`date` function](https://www.php.net/manual/en/function.date) there.
It shows that it is used to format a UNIX timestamp into the specified format.
The meaning of the [format](https://www.php.net/manual/en/datetime.format.php) string is also easily found in the documentation and shows us that `d.m.Y` stands for
- d = Day of month (with leading zero!) e.g. `15`
- m = Month (with leading zero as well) e.g. `03`
- Y = Full year e.g. `2023`
Since no further parameter is specified for `date` it just defaults to the current timestamp so the solution will be the current date written as for example "*15.03.2023*"
## Level 12 - Sums
This level requires us to enter the sum of all (integer) numbers from 1 to (in my case) 465.
We could either write a little program that loops through all those number and sums them up but it's way easier to use the Gaussian summation formula of `( n ( n+1 ) ) / 2` so in this case `( 465 ( 465+1 )) / 2 = 108345`.
So "*108345*" is our solution for this level!
## Level 13 - Understand the algorithm II
Another PHP challenge!
```php
function pwCheck($username,$password)
{
if(!$username || !$password) return false;
if(strlen($username)==$password)
return true;
else return false;
}
```
}
```
This time we have two fields to fill - `Username` and `Password`.
First we see that Username and Password can't be the same so we have to type something different for each of them.
it seems the only condition we need to meet to pass this is that the password as a numeric value has to be the length of the username!
Not that hard either and we can freely choose what to try so let's for for something like `tooeasy` for the username and `7` for the password.
## Level 14 - Understand the algorithm IV
Strangely enough the fourth algorithm comes before the third (Level 16) but oh well.
This time we need to enter a GUID - so a sort of long, standardized identifier - as well as a password and the code displayed is:
```php
function pwCheck($guid,$password)
{
if(!$guid || !$password) return false;
$users = implode(file('/data/login_info.json'));
$json = json_decode($users,true);
foreach($json['result'] as $data)
if($data['guid']==$guid && $data['password'] == $password && $data['account_status']=='active')
return true;
return false;
}
```
For this challenge a little more PHP knowledge is required.
The first check makes sure both the `guid` field and the `password` field are actually filled with a value.
Next a JSON file `/data/login_info.json` is loaded as an array using the `file` method as well as `implode` to turn a string into an array.
`json_decode` is used on that array to turn the content of the file into a JSON object to further process.
Next each `result` object in the JSON file is checked if the `guid` and `password` match and if the account is still active.
Now we know what the method is checking for so we just need to take a look a the file which is located at https[]()://0xf.at/data/login_info.json.
Only one account is marked as active so we grab the guid "*bc3c1364-4b24-4f60-8fe4-7628e72391ed*" and the password "*Vencom*" aaaand success!
## Level 15 - The 0xf.at Enigma
{{< figure src="images/lvl15_1.png" alt="0xf.at Enigma" >}}

@ -0,0 +1,26 @@
+++
draft = true
date = 2023-03-14T23:56:16+01:00
title = "Solving 0xf.at - Part 3"
description = "A little collection of the approaches and stuff I used to solve 0xf.at challenges"
slug = ""
authors = ["_N0x"]
tags = ["hackit", "challenges", "riddles", "0xf.at"]
categories = []
externalLink = ""
series = []
+++
# Solving 0xf.at's funny little challenges - Part 3 Level 21 to 30
## WARNING!
**THE FOLLOWING PAGE CONTAINS SPOILERS FOR THE PASSWORD-RIDDLE SITE 0XF.AT!**
_Only continue reading if you are okay with seeing spoilers or need some help with the riddles ;)_
```
___ __ _
/ _ \__ __/ _| __ _| |_
| | | \ \/ / |_ / _` | __|
| |_| |> <| _| (_| | |_
\___//_/\_\_|(_)__,_|\__|
```
Loading…
Cancel
Save