Can you crack it by the Lazy Hacker

0
287

Like many ethical hackers,there is a small part of me that dreams of working as a professional computer hacker for the government, so when I saw the GCHQ challenge at  http://www.canyoucrackit.co.uk/ I couldn’t resist…

Challenge #1

So the first challenge was a mess for me. I broke out my PHP development tools and got to work. I typed out all the numbers in a sequence of arrays and started running cryptography tests on it. The frequency analysis was off the charts… panic time!  This wasn’t the simple challenges you find in a newspaper. From my years of experience, I thought “I needed to figure out what encryption algorithm they are using“.  I did some google searches trying to find an algorithm for calculating the randomness of the sequences and a list of randomnesses of known algorithms. That didn’t go well; I couldn’t find anything of value. The page does say enter the keyword, so I figured it must be a cypher based on a repeating keyword since there wasn’t enough data for this to be a real encryption challenge.

Modern encryption techniques like RSA or DES would need a much larger data set to have any possibility of cracking it. Assuming this was a password, then I needed to figure out how long the password was. I ran some more frequency analysis tests and came up empty. The keyword length was undetectable. I did notice that the HEX patterns looked a bit like it could be binary executable code, but I I don’t have any assembly language tools on my computer to test it, and I’m not going to just execute code posted on a web site  without seeing the source first so I didn’t want to risk it.

So whats left… Social engineering!

I went to work searching google for forums on the subject. Turned out that it was binary assembly language code, oh well, I probably could have cracked this first challenge but I was just too lazy.  So they posted the link to the next challenge so I went to work on it.

Challenge #2

Project two was a virtual machine which contained a pre-loaded application. The only thing that the machine was missing was a bytecode interpreter.  Ok, so this is something I can handle. I went to work. Here was my results…

[code]

<html>
<head></head>

<script src=”15b436de1f9107f3778aad525e5d0b20.js”></script>
<body>

<script>
function bin2String(array) {
var result = “”;
for (var i = 0; i < array.length; i++) {
result += String.fromCharCode(parseInt(array[i], 2));
}
return result;
}

function getMem() {
//var val = bin2String(VM.mem);

//document.getElementById(‘tgt’).value = val;

for(idx=448;idx<VM.mem.length;idx++) {
var n = document.createElement(‘p’);
n.appendChild(document.createTextNode(String.fromCharCode(VM.mem[idx])));
document.getElementById(‘tgt2’).appendChild(n);
}
}

</script>

<textarea cols=”80″ rows=”20″ id=”tgt”>
</textarea>
<a href=”#” onclick=”getMem()”>XXX</a>
<div id=”tgt2″></div>
</body>
</html>

Javascript:

//————————————————————————————————–
//
// stage 2 of 3
//
// challenge:
//   reveal the solution within VM.mem
//
// disclaimer:
//   tested in ie 9, firefox 6, chrome 14 and v8 shell (http://code.google.com/apis/v8/build.html),
//   other javascript implementations may or may not work.
//
//————————————————————————————————–

var VM = {

cpu: {
ip: 0x00,

r0: 0x00,
r1: 0x00,
r2: 0x00,
r3: 0x00,

cs: 0x00,
ds: 0x10,

fl: 0x00,

firmware: [0xd2ab1f05, 0xda13f110]
},

mem: [
/* 0000 */
0x31, 0x04, // 00110001 movr r1, 4
0x33, 0xaa, // 00110011 movr r3, 170
0x40, 0x02, // 01000000 movm r0, [ds:r2]
0x80, 0x03, // 10000000 xor r0, r3
0x52, 0x00, // 01010010 movm [ds:r2], r0
0x72, 0x01, // 01110010 add r2, 1
0x73, 0x01, // 01110010 add r3, 1
0xb2, 0x50, // 10110010 cmp r2 ,#80
/* 0010 */
0x30, 0x14, // 00110000 movr r0, 20
0xc0,  // 11000000 jmpe r0
0x01,  // 00000001 jmp r1
0x80, 0x00, // 10000000 xor r0, r0
0x10, 0x10, // 00010000 jmp 16:r0
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 0020 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 0030 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 0040 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 0050 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 0060 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 0070 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 0080 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 0090 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 00A0 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 00B0 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 00C0 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 00D0 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 00E0 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 00F0 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 0100 */  0x98, 0xab, // xor r1, 171
0xd9, // 11011001 JMPE r2:r1
0xa1,
0x9f, 0xa7, 0x83, 0x83, 0xf2, 0xb1, 0x34, 0xb6, 0xe4, 0xb7, 0xca, 0xb8,
0xc9, 0xb8, 0x0e, 0xbd, 0x7d, 0x0f, 0xc0, 0xf1, 0xd9, 0x03, 0xc5, 0x3a, 0xc6, 0xc7, 0xc8, 0xc9,
0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9,
0xda, 0xdb, 0xa9, 0xcd, 0xdf, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
0x26, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9,
0x7d, 0x1f, 0x15, 0x60, 0x4d, 0x4d, 0x52, 0x7d, 0x0e, 0x27, 0x6d, 0x10, 0x6d, 0x5a, 0x06, 0x56,
0x47, 0x14, 0x42, 0x0e, 0xb6, 0xb2, 0xb2, 0xe6, 0xeb, 0xb4, 0x83, 0x8e, 0xd7, 0xe5, 0xd4, 0xd9,
0xc3, 0xf0, 0x80, 0x95, 0xf1, 0x82, 0x82, 0x9a, 0xbd, 0x95, 0xa4, 0x8d, 0x9a, 0x2b, 0x30, 0x69,
0x4a, 0x69, 0x65, 0x55, 0x1c, 0x7b, 0x69, 0x1c, 0x6e, 0x04, 0x74, 0x35, 0x21, 0x26, 0x2f, 0x60,
0x03, 0x4e, 0x37, 0x1e, 0x33, 0x54, 0x39, 0xe6, 0xba, 0xb4, 0xa2, 0xad, 0xa4, 0xc5, 0x95, 0xc8,
0xc1, 0xe4, 0x8a, 0xec, 0xe7, 0x92, 0x8b, 0xe8, 0x81, 0xf0, 0xad, 0x98, 0xa4, 0xd0, 0xc0, 0x8d,
0xac, 0x22, 0x52, 0x65, 0x7e, 0x27, 0x2b, 0x5a, 0x12, 0x61, 0x0a, 0x01, 0x7a, 0x6b, 0x1d, 0x67,
0x75, 0x70, 0x6c, 0x1b, 0x11, 0x25, 0x25, 0x70, 0x7f, 0x7e, 0x67, 0x63, 0x30, 0x3c, 0x6d, 0x6a,
0x01, 0x51, 0x59, 0x5f, 0x56, 0x13, 0x10, 0x43, 0x19, 0x18, 0xe5, 0xe0, 0xbe, 0xbf, 0xbd, 0xe9,
0xf0, 0xf1, 0xf9, 0xfa, 0xab, 0x8f, 0xc1, 0xdf, 0xcf, 0x8d, 0xf8, 0xe7, 0xe2, 0xe9, 0x93, 0x8e,
0xec, 0xf5, 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x37, 0x7a, 0x07, 0x11, 0x1f, 0x1d, 0x68, 0x25, 0x32, 0x77, 0x1e, 0x62, 0x23, 0x5b, 0x47, 0x55,
0x53, 0x30, 0x11, 0x42, 0xf6, 0xf1, 0xb1, 0xe6, 0xc3, 0xcc, 0xf8, 0xc5, 0xe4, 0xcc, 0xc0, 0xd3,
0x85, 0xfd, 0x9a, 0xe3, 0xe6, 0x81, 0xb5, 0xbb, 0xd7, 0xcd, 0x87, 0xa3, 0xd3, 0x6b, 0x36, 0x6f,
0x6f, 0x66, 0x55, 0x30, 0x16, 0x45, 0x5e, 0x09, 0x74, 0x5c, 0x3f, 0x29, 0x2b, 0x66, 0x3d, 0x0d,
0x02, 0x30, 0x28, 0x35, 0x15, 0x09, 0x15, 0xdd, 0xec, 0xb8, 0xe2, 0xfb, 0xd8, 0xcb, 0xd8, 0xd1,
0x8b, 0xd5, 0x82, 0xd9, 0x9a, 0xf1, 0x92, 0xab, 0xe8, 0xa6, 0xd6, 0xd0, 0x8c, 0xaa, 0xd2, 0x94,
0xcf, 0x45, 0x46, 0x67, 0x20, 0x7d, 0x44, 0x14, 0x6b, 0x45, 0x6d, 0x54, 0x03, 0x17, 0x60, 0x62,
0x55, 0x5a, 0x4a, 0x66, 0x61, 0x11, 0x57, 0x68, 0x75, 0x05, 0x62, 0x36, 0x7d, 0x02, 0x10, 0x4b,
0x08, 0x22, 0x42, 0x32, 0xba, 0xe2, 0xb9, 0xe2, 0xd6, 0xb9, 0xff, 0xc3, 0xe9, 0x8a, 0x8f, 0xc1,
0x8f, 0xe1, 0xb8, 0xa4, 0x96, 0xf1, 0x8f, 0x81, 0xb1, 0x8d, 0x89, 0xcc, 0xd4, 0x78, 0x76, 0x61,
0x72, 0x3e, 0x37, 0x23, 0x56, 0x73, 0x71, 0x79, 0x63, 0x7c, 0x08, 0x11, 0x20, 0x69, 0x7a, 0x14,
0x68, 0x05, 0x21, 0x1e, 0x32, 0x27, 0x59, 0xb7, 0xcf, 0xab, 0xdd, 0xd5, 0xcc, 0x97, 0x93, 0xf2,
0xe7, 0xc0, 0xeb, 0xff, 0xe9, 0xa3, 0xbf, 0xa1, 0xab, 0x8b, 0xbb, 0x9e, 0x9e, 0x8c, 0xa0, 0xc1,
0x9b, 0x5a, 0x2f, 0x2f, 0x4e, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
],

exec: function()
{
// virtual machine architecture
// ++++++++++++++++++++++++++++
//
// segmented memory model with 16-byte segment size (notation seg:offset)
//
// 4 general-purpose registers (r0-r3)
// 2 segment registers (cs, ds equiv. to r4, r5)
// 1 flags register (fl)
//
// instruction encoding
// ++++++++++++++++++++
//
//           byte 1               byte 2 (optional)
// bits      [ 7 6 5 4 3 2 1 0 ]  [ 7 6 5 4 3 2 1 0 ]
// opcode      – – –
// mod               –
// operand1            – – – –
// operand2                         – – – – – – – –
//
// operand1 is always a register index
// operand2 is optional, depending upon the instruction set specified below
// the value of mod alters the meaning of any operand2
//   0: operand2 = reg ix
//   1: operand2 = fixed immediate value or target segment (depending on instruction)
//
// instruction set
// +++++++++++++++
//
// Notes:
//   * r1, r2 => operand 1 is register 1, operand 2 is register 2
//   * movr r1, r2 => move contents of register r2 into register r1
//
// opcode | instruction | operands (mod 0) | operands (mod 1)
// ——-+————-+——————+—————–
// 0x00   | jmp         | r1               | r2:r1
// 0x01   | movr        | r1, r2           | rx,   imm
// 0x02   | movm        | r1, [ds:r2]      | [ds:r1], r2
// 0x03   | add         | r1, r2           | r1,   imm
// 0x04   | xor         | r1, r2           | r1,   imm
// 0x05   | cmp         | r1, r2           | r1,   imm
// 0x06   | jmpe        | r1               | r2:r1
// 0x07   | hlt         | N/A              | N/A
//
// flags
// +++++
//
// cmp r1, r2 instruction results in:
//   r1 == r2 => fl = 0
//   r1 < r2  => fl = 0xff
//   r1 > r2  => fl = 1
//
// jmpe r1
//   => if (fl == 0) jmp r1
//      else nop

//throw “VM.exec not yet implemented”;

var halt = false;
var bsz = 1;
var debug = function(msg) {
var log = function(object, context, className, rep, noThrottle, sourceLink) {
try {
if (‘undefined’ != typeof Firebug && ‘undefined’ != typeof Firebug.Console) {
Firebug.Console.log(object, context, className, rep, noThrottle, sourceLink);
} else if (‘undefined’ != typeof console && ‘undefined’ != typeof console.log) {
console.log(object);
}
} catch (e) {
}
};
log(VM.cpu.cs+’:’+VM.cpu.ip+’ ‘+msg);
};
var ops = 0;
debug(‘Start!’);
while(!halt) {
ops++;
var pcp = (VM.cpu.cs*16)+VM.cpu.ip;
var inst =  VM.mem[pcp];
var opcode = (inst>>5) & 7;
var mod = (inst >> 4) & 1;
var op1 = 15 & inst;
var op2 = VM.mem[pcp+1];

var setIx = function(op1,val) {
if (op1 == 0) {
VM.cpu.r0 = val;
} else if (op1 == 1) {
VM.cpu.r1 = val;
} else if (op1 == 2) {
VM.cpu.r2 = val;
} else if (op1 == 3) {
VM.cpu.r3 = val;
} else if (op1 == 4) {
VM.cpu.cs = val;
} else if (op1 == 5) {
VM.cpu.ds = val;
} else {
halt = true;
debug(“Invalid setIx “+opcode+’:’+mod+’:’+op1+’:’+op2);
throw ‘Invalid operation!’;
}
};

var getIx = function(op1) {
if (op1 == 0) {
return VM.cpu.r0;
} else if (op1 == 1) {
return VM.cpu.r1;
} else if (op1 == 2) {
return VM.cpu.r2;
} else if (op1 == 3) {
return VM.cpu.r3;
} else if (op1 == 4) {
return VM.cpu.cs;
} else if (op1 == 5) {
return VM.cpu.ds;
} else {
debug(“Invalid getIx “+opcode+’:’+mod+’:’+op1+’:’+op2);
throw “Invalid Operation!”;
halt = true;
}
};

//alert(inst+’:’+opcode+’:’+mod+’:’+op1);
switch(opcode) {
case 0:  // jmp
if (mod) {
var v1 = op2;//getIx(op2);
var v2 = op1;//getIx(op1);
debug(‘jmp ‘+op2+’:’+op1+’ #’+v1+’:’+v2);
VM.cpu.cs = v1;
VM.cpu.ip = v2;
} else {
var val = getIx(op1);
debug(‘jmp r’+op1+’ #’+val);
VM.cpu.ip = val;
}
break;
case 1: // movr
if (mod) { // rx,   imm
setIx(op1,op2);
debug(‘movr r’+op1+’, ‘+op2);
} else {  //r1, r2
var val = getIx(op2);
setIx(op1,val);
debug(‘movr r’+op1+’, r’+op2+’ #’+val);
}
VM.cpu.ip += 2;
break;
case 2:  // movm
if (mod) { // [ds:r1], r2
VM.mem[(VM.cpu.ds * 16)+getIx(op1)] = getIx(op2);
debug(‘movm [ds:r’+op1+’], r’+op2);
} else { //r1, [ds:r2]
var val = VM.mem[(VM.cpu.ds * 16)+getIx(op2)];
setIx(op1,val);
debug(‘movm r’+op1+’, [ds:r’+op2+’] #’+val);
}
VM.cpu.ip += 2;
break;
case 3: // add
var op2 = VM.mem[pcp+1];
if (mod) { // r1,   imm
var val = (getIx(op1)+op2) & 255;
setIx(op1,val);
debug(‘add r’+op1+’, ‘+op2+’ # ‘+val);
} else { // r1, r2
var val = (getIx(op1)+getIx(op2)) & 255;
setIx(op1,val);
debug(‘add r’+op1+’, r’+op2+’ #’ + val);
}
VM.cpu.ip += 2;
break;
case 4:   //xor
if (mod) { // r1,   imm
var val = getIx(op1) ^ op2;
setIx(op1,val);
debug(‘xor r’+op1+’, ‘+op2+’ # ‘+val);
} else { // r1, r2
var val = getIx(op1) ^ getIx(op2);
setIx(op1,val);
debug(‘xor r’+op1+’, r’+op2+’ # ‘+val);
}
VM.cpu.ip += 2;
break;
case 5:  //cmp

if (mod) { //r1,   imm
if (getIx(op1) == op2) {
VM.cpu.fl = 0;
} else if (getIx(op1) < op2) {
VM.cpu.fl = 0xff;
} else {
VM.cpu.fl = 1;
}
debug(‘cmp r’+op1+’, ‘+op2);
} else {  //r1, r2
if (getIx(op1) == getIx(op2)) {
VM.cpu.fl = 0;
} else if (getIx(op1) < getIx(op2)) {
VM.cpu.fl = 0xff;
} else {
VM.cpu.fl = 1;
}
debug(“cmp r’+op1+’, r’+op2+'”);
}
VM.cpu.ip += 2;
break;
case 6:  //jmpe        | r1               | r2:r1

if (VM.cpu.fl == 0) {
if (mod) {
var op2 = VM.mem[pcp+1];
var val2 = getIx(op2);
var val2 = getIx(op1);
debug(‘jmpe r’+op2+’:r’+op1+’ # ‘+val1+’:’+val2);
VM.cpu.cs = val1;
VM.cpu.ip = val2;
} else {
var val = getIx(op1);
debug(‘jmpe r’+op1+’ # ‘+val);
VM.cpu.ip = val;
}

} else {
debug(‘jmpe # noop’);
if (mod) {
VM.cpu.ip += 2;
} else {
VM.cpu.ip += 1;
}
}
break;
case 7:
alert(“halt”);
halt = true;
break;
}
}

return;
}

};

//————————————————————————————————–

try
{
VM.exec();
}
catch(e)
{
alert(‘nError: ‘ + e + ‘n’);
}

//————————————————————————————————–

[/code]

Sweet! It worked. So I download the .exe file produced by the virtual machine.

Challenge #3

Well, this is annoying. Their exe file requires cygwin.  I haven’t used cygwin in years, and I really don’t want to download it. Hmm… I guess I’ll just google it. So I googled the exe filename and found a lot of forum posts about this file. Well, I’m not going to trust these people; I don’t know who they are, I guess I’ll just install cygwin. So I did and ran the program, and what do you know, another error. Invalid license.  Hmm. So I need to crack a software license? What type of legal government hacking would ever involve cracking software licenses??? What a mess. So I tried to download the license file from the can you crack it site, but no luck. They really want you to crack the license. So I did some more googling and I found that someone has already cracked the license and published the results online. Well, there’s no point in wasting my time cracking a license when its already been done. I went to the site posted in the forums and its just a link to a page advertising a  job posting. Bah! It was just viral marketing trying to fill a job position, no calls from secret government agencies or anything, just a job posting that you could probably find without going through all this hassle. What a waste…

Oh well, at least I cracked one of the challenges without any help, not bad for a lazy hacker.

 

SHARE
Previous articleWeb Security Tools Plugin for WordPress
Next articleMaking a Stand Against Anonymous Hackers and WordPress
Programming is my passion, and I am constantly working on making my mark in this industry by creating new technologies which open doors to new capabilities. While some of my projects are experimental, most of it is grounded in standard compliant design with a constant focus on security.

LEAVE A REPLY

Please enter your comment!
Please enter your name here