Zelda Adventures - nullcon HackIM
by devploit
0x01 Challenge:
Level: Easy
Description:
0x02 Write-up:
For this challenge and the next ones I’m going to explain they provide us with a game in Unity. For the whole process of modifying it I will make use of dnSpy.
First of all, for this challenge we need to kill any NPC, so let’s open the file Assembly-CSharp.dll from the folder Data > Managed in our dnSpy.
Within the available methods, we are going to modify Enemy > TakeDamage so that it receives the damage * 1000000 to be able to kill them in a single blow as we see in the image.
If we save the changes, log in to the game and try to attack any zombie…
Flag: REVOLUTIONSTARTSWITHME
1x01 Challenge:
Level: Easy
Description:
1x02 Write-up:
In this challenge we need to get to FlagTown to locate the string that validates us as a flag. To make this move easier we modify the movement speed of our character * 20.
We walk in search of the pond and that’s it.
Flag: BENDTHERULES42PIRATE
2x01 Challenge:
Level: Easy
Description:
2x02 Write-up:
The third challenge (the last one with this game file) sends us looking for other survivors. If we advance on the map to the end (northwest direction) we will reach the flag.
Flag: EXPLORERFORLIFE
3x01 Challenge:
Level: Medium
Description:
3x02 Write-up:
For this last challenge we are provided with a new game “Zelda in Space”. If we check the methods in dnSpy as in the previous challenges, we see that it has an “AntiHack” that kicks out cheating players.
But what interests us in this challenge is to find the 6 buttons and THE ORDER TO PUSH. We see how inside RoomMove > OnTriggerEnter2D these 6 buttons are referred to, which are named by ingredient names.
On the other hand we see the classes contained in the PlayerAttrs method. In OnGUI we have the execution of the Decrypt class if we reach the checkpoint called “final”.
We also reviewed the Decrypt class to see how they carry out this process.
Finally, it is important to note that our character starts with the checkpoint “0” hardcoded.
With all this data (and in consideration of that being 6 factorial there is a 720 possible results) we generated a small program that helps us to decrypt the flag returning us the order in which we have to add the ingredients.
using System;
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
public class Program
{
public List<string> cpoints;
public string encrypted;
public string f;
public Random rng = new Random();
public void Main()
{
cpoints = new List<string>();
cpoints.Add("pepper");
cpoints.Add("salt");
cpoints.Add("chilly");
cpoints.Add("pickles");
cpoints.Add("oregano");
cpoints.Add("masala");
encrypted = string.Empty;
f="0";
string text = "";
while(f == "0" && cpoints.Count >5 )
{
text = "";
StringBuilder stringBuilder = new StringBuilder();
cpoints.Shuffle();
foreach (string checkpoint in cpoints)
{
stringBuilder.Append(checkpoint);
}
text = stringBuilder.ToString();
text = "0"+text+"final";
try
{
encrypted = Decrypt("pI0gDg911A3Qcf++L3rvfkwIEkXsg4jq6pwOHMgG1VlpPuE9t4eljr4fQvXUa9bMJN4TL+DzQoj8aHTe1sNt+y5FND+gqn04OOltMhv/sms=", text);
f="1";
}
catch (CryptographicException)
{
encrypted = "wrong key";
f="0";
}
}
if (!string.Equals(text, string.Empty))
{
Console.WriteLine(text);
}
if (!string.Equals(encrypted, string.Empty))
{
Console.WriteLine(encrypted);
}
}
private string Decrypt(string cipherText, string key)
{
byte[] array = Convert.FromBase64String(cipherText);
using (Aes aes = Aes.Create())
{
Rfc2898DeriveBytes rfc2898DeriveBytes = new Rfc2898DeriveBytes(key, new byte[13]
{
73,
118,
97,
110,
32,
77,
101,
100,
118,
101,
100,
101,
118
});
aes.Key = rfc2898DeriveBytes.GetBytes(32);
aes.IV = rfc2898DeriveBytes.GetBytes(16);
using (MemoryStream memoryStream = new MemoryStream())
{
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, aes.CreateDecryptor(), CryptoStreamMode.Write))
{
cryptoStream.Write(array, 0, array.Length);
cryptoStream.Close();
}
cipherText = Encoding.Unicode.GetString(memoryStream.ToArray());
return cipherText;
}
}
}
}
static class MyExtensions
{
public static void Shuffle<T>(this IList<T> list)
{
int n = list.Count;
while (n > 1)
{
n--;
int k = ThreadSafeRandom.ThisThreadsRandom.Next(n + 1);
T value = list[k];
list[k] = list[n];
list[n] = value;
}
}
}
public static class ThreadSafeRandom
{
[ThreadStatic] private static Random Local;
public static Random ThisThreadsRandom
{
get { return Local ?? (Local = new Random(unchecked(Environment.TickCount * 31 + Thread.CurrentThread.ManagedThreadId))); }
}
}
By executing it, it gives us back…
If we wanted to check directly on the game, we’d add all the ingredients and go to the final platform of the game to have the “final” string added and check that everything is correct.
Flag: hackim20{z3lda_s0lved_the_sp4ce_puzzl3}