RSS

Leetmore CTF 2012 : Reverse 100 (Open Source)

0 Comments | This entry was posted on Oct 18 2012

We were given the following C source code:

#include
#include

int main(int argc, char *argv[]) {
if (argc != 4) {
printf("what?\n");
exit(1);
}

unsigned int first = atoi(argv[1]);
if (first != 0xcafe) {
printf("you are wrong, sorry.\n");
exit(2);
}

unsigned int second = atoi(argv[2]);
if (second % 5 == 3 || second % 17 != 8) {
printf("ha, you won't get it!\n");
exit(3);
}

if (strcmp("h4cky0u", argv[3])) {
printf("so close, dude!\n");
exit(4);
}

printf("Brr wrrr grr\n");

unsigned int hash = first * 31337 + (second % 17) * 11 + strlen(argv[3]) - 1615810207;

printf("Get your key: ");
printf("%x\n", hash);
return 0;
}`

So lets compile it:

$ gcc -o rev100 code.c
code.c: In function ‘main’:
code.c:7:6: warning: incompatible implicit declaration of built-in
function ‘exit’ [enabled by default]
code.c:13:6: warning: incompatible implicit declaration of built-in
function ‘exit’ [enabled by default]
code.c:19:6: warning: incompatible implicit declaration of built-in
function ‘exit’ [enabled by default]
code.c:24:6: warning: incompatible implicit declaration of built-in
function ‘exit’ [enabled by default]

Below is the commented source code:

#include
#include

int main(int argc, char *argv[]) {
// We need to have 4 arguments passed to the program.
// In C, the program name is a parameter too (so 3 real parameters are needed).
if (argc != 4) {
printf("what?\n");
exit(1);
}

// Convert argument 1 from a string to an integer.
unsigned int first = atoi(argv[1]);
// This integer must match the value of 0xcafe (= 51966 in decimal),
// to fail the next check.
if (first != 0xcafe) {
printf("you are wrong, sorry.\n");
exit(2);
}

// Convert argument 1 from a string to an integer.
unsigned int second = atoi(argv[2]);
// The following check fails when the integer:
// - doesn't have a modulus of 3 when dividing by 5
// and when it:
// - has a modulus of 8 when dividing by 17
if (second % 5 == 3 || second % 17 != 8) {
printf("ha, you won't get it!\n");
exit(3);
}

// This check fails if the third argument is h4cky0u.
// strcmp returns 0 (false), when there is an exact match.
if (strcmp("h4cky0u", argv[3])) {
printf("so close, dude!\n");
exit(4);
}

printf("Brr wrrr grr\n");

// Calculate the key based on the input.
unsigned int hash = first * 31337 + (second % 17) * 11 + strlen(argv[3]) - 1615810207;

printf("Get your key: ");
printf("%x\n", hash);
return 0;
}

We can use bash to convert hex values automatically and to do some
basic calculations with the $(()) construct.
(Programmers are lazy, right?)

$ ./rev100 $((0xcafe)) $((17*1+8)) h4cky0u
Brr wrrr grr
Get your key: c0ffee

$ ./rev100 $((0xcafe)) $((17*2+8)) h4cky0u
Brr wrrr grr
Get your key: c0ffee

$ ./rev100 $((0xcafe)) $((17*3+8)) h4cky0u
Brr wrrr grr
Get your key: c0ffee

Solution: c0ffee

CSAW CTF 2012: Reversing 1

0 Comments | This entry was posted on Oct 02 2012

For this problem, we had to patch an executable named csaw2012reversing.exe for 100 points.

After loaded in OllyDbg, we solved this problem by NOP-ing calls at virtual address 0x00D21106

Solution: welcome_to_csaw!

CSAW CTF 2012: Reversing 3

0 Comments | This entry was posted on Oct 02 2012

Here the challenge was to get the key out of a binary called CSAWQualification.exe for 300 points.

We used the same ILSpy decompiler that we used to solve one previous challenge. Following was the output from the decompiler:

// CSAWQualification.Program
private static void Main(string[] args)
{
Console.WriteLine("Do you really just run random binaries given to
you in challenges?");
Console.ReadLine();
Environment.Exit(0);
MD5CryptoServiceProvider mD5CryptoServiceProvider = new
MD5CryptoServiceProvider();
AesCryptoServiceProvider aesCryptoServiceProvider = new
AesCryptoServiceProvider();
foreach (string current in Directory.EnumerateDirectories(Program.target))
{
byte[] first =
mD5CryptoServiceProvider.ComputeHash(Encoding.UTF8.GetBytes(current.Replace(Program.target,
"")));
if (first.SequenceEqual(Program.marker))
{
byte[] rgbKey =
mD5CryptoServiceProvider.ComputeHash(Encoding.UTF8.GetBytes("sneakyprefix"
+ current.Replace(Program.target, "")));
ICryptoTransform cryptoTransform =
aesCryptoServiceProvider.CreateDecryptor(rgbKey, new byte[]
{
0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15
});
byte[] bytes = cryptoTransform.TransformFinalBlock(Program.data, 0,
Program.data.Length);
Console.Write(Encoding.UTF7.GetString(bytes));
}
}
Console.ReadLine();
}

// CSAWQualification.Program
static Program()
{
// Note: this type is marked as 'beforefieldinit'.
Program.data = new byte[]
{
15,
83,
222,
204,
130,
169,
253,
55,
165,
229,
219,
240,
206,
78,
102,
131,
243,
100,
115,
102,
231,
76,
235,
175,
2,
193,
249,
172,
174,
172,
227,
120,
67,
118,
87,
221,
124,
97,
202,
124,
191,
209,
164,
8,
61,
224,
193,
83,
13,
137,
114,
140,
42,
65,
247,
237,
202,
71,
66,
38,
58,
205,
158,
199,
246,
205,
178,
248,
21,
55,
82,
239,
36,
107,
104,
230,
193,
63,
157,
178,
224,
48,
198,
4,
66,
221,
12,
211,
215,
103,
209,
14,
117,
139,
111,
162
};
Program.marker = new byte[]
{
255,
151,
169,
253,
237,
224,
158,
175,
110,
28,
142,
201,
246,
166,
29,
213
};
Program.target = "C:\\Program Files\\";
}

We noticed that because of lines like Environment.Exit(0), program was exiting prematurely.  We were somehow forced to install Visual Studio this time.  :-P Then we commented out the “culprit” lines of code, recompiled it to get the output.

CSAW CTF 2012: Reversing 2

0 Comments | This entry was posted on Oct 02 2012

Here the challenge was to get the key out of a binary named CSAWQualificationEasy.exe for 200 Points.

The binary is a .NET compiled program, so we used ILSpy to decompile it.

Below is the disassembled code for the main program segment

// CSAWQualificationEasy.Program
private static void Main(string[] args)
{
Console.WriteLine("Okay, going to compute the key. Have to remember
to write it out at the end! I keep forgetting!");
string arg = "";
byte[] array = Program.encrypted;
for (int i = 0; i < array.Length; i++)
{
byte b = array[i];
arg += Convert.ToChar((int)(b ^ 255));
}
Console.ReadLine();
}

If we would have Visual Studio installed on the system, it could be as easy as changing the Console.ReadLine() to Console.WriteLine(arg) and recompile it. As we did not have the M$ compiler installed and were too lazy to get such a bulky package installed, we rewrote it in Python.

The "encrypted" array contains this:

// CSAWQualificationEasy.Program
private static byte[] encrypted = new byte[]
{
171,
151,
154,
223,
148,
154,
134,
223,
150,
140,
223,
198,
156,
207,
198,
153,
199,
203,
206,
201,
158,
205,
205,
207,
201,
205,
205,
206,
154,
202,
207,
157,
198,
199,
154,
204,
203,
201,
207,
203,
200,
157,
200
};

Accordingly, the Python script was 

# Encrypted bytes array of the .NET program:
encrypted_list = [ 171, 151, 154, 223, 148, 154, 134, 223, 150, 140,
223, 198, 156, 207, 198, 153, 199, 203, 206, 201, 158, 205, 205, 207,
201, 205, 205, 206, 154, 202, 207, 157, 198, 199, 154, 204, 203, 201,
207, 203, 200, 157, 200 ]

# This will contain the output string:
decrypted = ""

# Reimplement the for loop to decrypt the string:
for encrypted_chr in encrypted_str:
decrypted = decrypted + chr(encrypted_chr ^ 255)

# Print decrypted string
print decrypted

The output from the script was the solution itself.

Solution: 9c09f8416a2206221e50b98e346047b7