This was one of the Natas levels that I was stuck on for quite some time. Here's a clear and understandable explanation to help you get through it.
Understanding the Problem
We are faced with a webpage where you can input and set the background color based on hexadecimal colors.

We are also provided with a hint that "Cookies are protected with XOR encryption". In Google Chrome, we can find the value of the cookies by right-clicking and selecting the Inspect option. A panel should open on the right hand side with the HTML code. At the top, select the Application tab. On the left part of the panel, expand Cookies and select the only cookie in the choices underneath. You should see a cookie named data and its corresponding value. Click on the data cookie and look to the bottom. Check the box that says Show URL-decoded and you will get the value of the cookie at the bottom.

Playing around with the webpage, you'll notice that if you change the background color input, the value of the cookie also changes, although there are similarities for cookies with similar inputs. With the default input of #ffffff, the corresponding cookie is:
HmYkBwozJw4WNyAAFyB1VUcqOE1JZjUIBis7ABdmbU1GIjEJAyIxTRg=There is also a link to the source code. Looking at the source code, we see PHP code with three functions: xor_encrypt, loadData, and saveData.

Exploring xor_encrypt, it takes an input ($in) and a key ($key) and XORs them together to produce an output ($outText). However, the key is unknown. The main takeaway here is that XOR encryption is easy to break. Even if we don't know the key, because of the properties of XOR, if we know the input and output and XOR them together, we can get the key.
Next, loadData takes an input called $def, sets $mydata equal to it, and goes through a bunch of conditional if logic. Reading through the logic, the function first decodes and decrypts the cookie and stores it in $tempdata. If $tempdata is an array, has keys called showpassword and bgcolor, and bgcolor is in the right format, then it sets $mydata to the values in $tempdata.
The function saveData sets the cookie by first encoding the input ($d) as a json string, then using the xor_encrypt function, and finally encoding to a base64 value.
Now, looking through the code that is run, it boils down to this:
$defaultdata = array( "showpassword"=>"no", "bgcolor"=>"#ffffff");
$data = loadData($defaultdata);
if(array_key_exists("bgcolor",$_REQUEST)) {
if (preg_match('/^#(?:[a-f\d]{6})$/i', $_REQUEST['bgcolor'])) {
$data['bgcolor'] = $_REQUEST['bgcolor'];
}
}
saveData($data);There is a $defaultdata variable that has showpassword set to "no" and bgcolor set to "#ffffff". Using loadData with $defaultdata as the argument, a $data variable is created. If a properly formatted cookie exists, then $data would have its values set to the values in the cookie. If a properly formatted cookies doesn't exist, $data would just be $defaultdata.
The if blocks checks if bgcolor in $_REQUEST exists and is in the right format, and if it is, assigns its bgcolor in $data. $_REQUEST must be what is inputted by the user in the webpage.
Putting this together, when the webpage is first opened, $defaultdata has a bgcolor value of "#ffffff" corresponding to white and showpassword equal to "no". The value isn't changed by loadData because there is no cookie yet, so $data would equal $defaultdata. The saveData function encrypts $data as a json string, then uses xor_encrypt on it, encodes it to base64, and sets it as the cookie.
Finally, there is a snippet of code that shows how to get the password for natas12. We need to change showpassword in $data to "yes".
if($data["showpassword"] == "yes") {
print "The password for natas12 is <censored><br>";
}Solution
Now that we understand the code, we can think through how we can get the password to natas12. The user input doesn't affect showpassword, so we can't use it to manipulate the PHP variables. Instead, we'll need to manipulate the cookie to change $data. However, the cookie is encrypted with the xor_encrypt function which we don't know the key for, so we'll need to find the key first.
We know that for the input
$defaultdata = array("showpassword"=>"no", "bgcolor"=>"#ffffff")the corresponding cookie is
HmYkBwozJw4WNyAAFyB1VUcqOE1JZjUIBis7ABdmbU1GIjEJAyIxTRg=From our analysis of the code, we also know that the cookie was encoded to base64 after XOR encryption and $defaultdata has been encoded to json before XOR encryption. So we will need to encode $defaultdata to json and perform the opposite on the cookie — decode it from base64. Then we can XOR the values to find the key.
We can write a simple function to do just that. You actually don't have to use the default input of #ffffff, you can choose any input as long as the corresponding cookies is also used. If you don't have a PHP editor or compiler on your computer like me, you can use OneCompiler.
$defaultdata = array("showpassword"=>"no", "bgcolor"=>"#ffffff");
$cookie = "HmYkBwozJw4WNyAAFyB1VUcqOE1JZjUIBis7ABdmbU1GIjEJAyIxTRg=";
function xor_find_key($input, $output) {
$processed_output = base64_decode($output);
$processed_input = json_encode($input);
$calculated_key = $processed_input ^ $processed_output;
return $calculated_key;
}
$key = xor_find_key($defaultdata, $cookie);
echo $key;From this function, we find that the key is
eDWoeDWoeDWoeDWoeDWoeDWoeDWoeDWoeDWoeDWoeSo the key is "edWo" repeated multiple times. If we look back at the xor_encrypt function, the loop actually works so that the key is repeated if the input length is longer than the key. So we can simplify the key to "edWo".
Now that we know the key, we can creating a variable with showpassword equal to "yes" and put it through the xor_encrypt function with the key to generate a cookie that will show us the natas12 password.
$newdata = array("showpassword"=>"yes", "bgcolor"=>"#ffffff");
function xor_encrypt($in) {
$key = "eDWo";
$text = $in;
$outText = '';
// Iterate through each character
for($i=0;$i<strlen($text);$i++) {
$outText .= $text[$i] ^ $key[$i % strlen($key)];
}
return $outText;
}
$newcookie = base64_encode(xor_encrypt(json_encode($newdata)));
echo $newcookie;This gives us the new cookie we'll need to show the password.
HmYkBwozJw4WNyAAFyB1VUc9MhxHaHUNAic4Awo2dVVHZzEJAyIxCUc5The final part is going into Google Chrome, changing the cookie value, and refreshing the webpage. Using the same Application tab, right-click on the cookie value and select Edit "Value". Paste in your new cookie value and press Enter. Then refresh the webpage. The natas12 password will now be displayed on the page.

Congratulations! The password for the next level is yZdkjAYZRd3R7tq7T5kXMjMJlOIkzDeB.