-
-
Save kao-was-here/939db256d91cb74c8f5cdab67b53e3ad to your computer and use it in GitHub Desktop.
Solver for Flareon5 challenge 6, "dirty" version
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
using System.IO; | |
namespace ConsoleApplication1 | |
{ | |
class Program | |
{ | |
//rc4 | |
public static byte[] RC4(byte[] data, byte[] pwd) | |
{ | |
int a, i, j, k, tmp; | |
int[] key, box; | |
byte[] cipher; | |
key = new int[256]; | |
box = new int[256]; | |
cipher = new byte[data.Length]; | |
for (i = 0; i < 256; i++) | |
{ | |
key[i] = pwd[i % pwd.Length]; | |
box[i] = i; | |
} | |
for (j = i = 0; i < 256; i++) | |
{ | |
j = (j + box[i] + key[i]) % 256; | |
tmp = box[i]; | |
box[i] = box[j]; | |
box[j] = tmp; | |
} | |
for (a = j = i = 0; i < data.Length; i++) | |
{ | |
a++; | |
a %= 256; | |
j += box[a]; | |
j %= 256; | |
tmp = box[a]; | |
box[a] = box[j]; | |
box[j] = tmp; | |
k = box[((box[a] + box[j]) % 256)]; | |
cipher[i] = (byte)(data[i] ^ k); | |
} | |
return cipher; | |
} | |
// Table for CRC calculation | |
static readonly uint[] crcTable = new uint[256] { | |
0x00000000u, 0x77073096u, 0xee0e612cu, 0x990951bau, 0x076dc419u, | |
0x706af48fu, 0xe963a535u, 0x9e6495a3u, 0x0edb8832u, 0x79dcb8a4u, | |
0xe0d5e91eu, 0x97d2d988u, 0x09b64c2bu, 0x7eb17cbdu, 0xe7b82d07u, | |
0x90bf1d91u, 0x1db71064u, 0x6ab020f2u, 0xf3b97148u, 0x84be41deu, | |
0x1adad47du, 0x6ddde4ebu, 0xf4d4b551u, 0x83d385c7u, 0x136c9856u, | |
0x646ba8c0u, 0xfd62f97au, 0x8a65c9ecu, 0x14015c4fu, 0x63066cd9u, | |
0xfa0f3d63u, 0x8d080df5u, 0x3b6e20c8u, 0x4c69105eu, 0xd56041e4u, | |
0xa2677172u, 0x3c03e4d1u, 0x4b04d447u, 0xd20d85fdu, 0xa50ab56bu, | |
0x35b5a8fau, 0x42b2986cu, 0xdbbbc9d6u, 0xacbcf940u, 0x32d86ce3u, | |
0x45df5c75u, 0xdcd60dcfu, 0xabd13d59u, 0x26d930acu, 0x51de003au, | |
0xc8d75180u, 0xbfd06116u, 0x21b4f4b5u, 0x56b3c423u, 0xcfba9599u, | |
0xb8bda50fu, 0x2802b89eu, 0x5f058808u, 0xc60cd9b2u, 0xb10be924u, | |
0x2f6f7c87u, 0x58684c11u, 0xc1611dabu, 0xb6662d3du, 0x76dc4190u, | |
0x01db7106u, 0x98d220bcu, 0xefd5102au, 0x71b18589u, 0x06b6b51fu, | |
0x9fbfe4a5u, 0xe8b8d433u, 0x7807c9a2u, 0x0f00f934u, 0x9609a88eu, | |
0xe10e9818u, 0x7f6a0dbbu, 0x086d3d2du, 0x91646c97u, 0xe6635c01u, | |
0x6b6b51f4u, 0x1c6c6162u, 0x856530d8u, 0xf262004eu, 0x6c0695edu, | |
0x1b01a57bu, 0x8208f4c1u, 0xf50fc457u, 0x65b0d9c6u, 0x12b7e950u, | |
0x8bbeb8eau, 0xfcb9887cu, 0x62dd1ddfu, 0x15da2d49u, 0x8cd37cf3u, | |
0xfbd44c65u, 0x4db26158u, 0x3ab551ceu, 0xa3bc0074u, 0xd4bb30e2u, | |
0x4adfa541u, 0x3dd895d7u, 0xa4d1c46du, 0xd3d6f4fbu, 0x4369e96au, | |
0x346ed9fcu, 0xad678846u, 0xda60b8d0u, 0x44042d73u, 0x33031de5u, | |
0xaa0a4c5fu, 0xdd0d7cc9u, 0x5005713cu, 0x270241aau, 0xbe0b1010u, | |
0xc90c2086u, 0x5768b525u, 0x206f85b3u, 0xb966d409u, 0xce61e49fu, | |
0x5edef90eu, 0x29d9c998u, 0xb0d09822u, 0xc7d7a8b4u, 0x59b33d17u, | |
0x2eb40d81u, 0xb7bd5c3bu, 0xc0ba6cadu, 0xedb88320u, 0x9abfb3b6u, | |
0x03b6e20cu, 0x74b1d29au, 0xead54739u, 0x9dd277afu, 0x04db2615u, | |
0x73dc1683u, 0xe3630b12u, 0x94643b84u, 0x0d6d6a3eu, 0x7a6a5aa8u, | |
0xe40ecf0bu, 0x9309ff9du, 0x0a00ae27u, 0x7d079eb1u, 0xf00f9344u, | |
0x8708a3d2u, 0x1e01f268u, 0x6906c2feu, 0xf762575du, 0x806567cbu, | |
0x196c3671u, 0x6e6b06e7u, 0xfed41b76u, 0x89d32be0u, 0x10da7a5au, | |
0x67dd4accu, 0xf9b9df6fu, 0x8ebeeff9u, 0x17b7be43u, 0x60b08ed5u, | |
0xd6d6a3e8u, 0xa1d1937eu, 0x38d8c2c4u, 0x4fdff252u, 0xd1bb67f1u, | |
0xa6bc5767u, 0x3fb506ddu, 0x48b2364bu, 0xd80d2bdau, 0xaf0a1b4cu, | |
0x36034af6u, 0x41047a60u, 0xdf60efc3u, 0xa867df55u, 0x316e8eefu, | |
0x4669be79u, 0xcb61b38cu, 0xbc66831au, 0x256fd2a0u, 0x5268e236u, | |
0xcc0c7795u, 0xbb0b4703u, 0x220216b9u, 0x5505262fu, 0xc5ba3bbeu, | |
0xb2bd0b28u, 0x2bb45a92u, 0x5cb36a04u, 0xc2d7ffa7u, 0xb5d0cf31u, | |
0x2cd99e8bu, 0x5bdeae1du, 0x9b64c2b0u, 0xec63f226u, 0x756aa39cu, | |
0x026d930au, 0x9c0906a9u, 0xeb0e363fu, 0x72076785u, 0x05005713u, | |
0x95bf4a82u, 0xe2b87a14u, 0x7bb12baeu, 0x0cb61b38u, 0x92d28e9bu, | |
0xe5d5be0du, 0x7cdcefb7u, 0x0bdbdf21u, 0x86d3d2d4u, 0xf1d4e242u, | |
0x68ddb3f8u, 0x1fda836eu, 0x81be16cdu, 0xf6b9265bu, 0x6fb077e1u, | |
0x18b74777u, 0x88085ae6u, 0xff0f6a70u, 0x66063bcau, 0x11010b5cu, | |
0x8f659effu, 0xf862ae69u, 0x616bffd3u, 0x166ccf45u, 0xa00ae278u, | |
0xd70dd2eeu, 0x4e048354u, 0x3903b3c2u, 0xa7672661u, 0xd06016f7u, | |
0x4969474du, 0x3e6e77dbu, 0xaed16a4au, 0xd9d65adcu, 0x40df0b66u, | |
0x37d83bf0u, 0xa9bcae53u, 0xdebb9ec5u, 0x47b2cf7fu, 0x30b5ffe9u, | |
0xbdbdf21cu, 0xcabac28au, 0x53b39330u, 0x24b4a3a6u, 0xbad03605u, | |
0xcdd70693u, 0x54de5729u, 0x23d967bfu, 0xb3667a2eu, 0xc4614ab8u, | |
0x5d681b02u, 0x2a6f2b94u, 0xb40bbe37u, 0xc30c8ea1u, 0x5a05df1bu, | |
0x2d02ef8du | |
}; | |
// Calculate CRC based on the old CRC and the new bytes | |
// See RFC1952 for details. | |
static public uint UpdateCrc32(byte[] buffer, int length) | |
{ | |
uint crc32 = 0xffffffffU; | |
for (int i = 0;i<length;i++) | |
{ | |
crc32 = crcTable[(crc32 ^ buffer[i]) & 0xFF] ^ (crc32 >> 8); | |
} | |
crc32 ^= 0xffffffffU; | |
return crc32; | |
} | |
static byte[] SolveCrc(UInt32 target, uint count1) | |
{ | |
byte[] result = null; | |
for (UInt64 xx = 0; xx < 0x100000000; xx++) | |
{ | |
result = BitConverter.GetBytes((UInt32)xx); | |
uint calcCrc = UpdateCrc32(result, (int)count1); | |
if (calcCrc == target) | |
break; | |
} | |
return result; | |
} | |
static byte SolveFibo(UInt64 target) | |
{ | |
UInt64 result1 = 1; | |
UInt64 result2 = 1; | |
int i = 0; | |
while (result1 != target) | |
{ | |
i++; | |
UInt64 q = result2; | |
result2 = result1+result2; | |
result1 = q; | |
} | |
return (byte)i; | |
} | |
static void TestB64() | |
{ | |
byte[] lookupTable = new byte[] { | |
0x2A,0x39,0x5F,0x64,0xC2,0xA7,0x46,0x23,0x53,0x6B,0x74,0x47,0x28,0x4D,0x70,0x42,0x49,0x25,0x52,0x6A,0x62,0x38,0x40,0x4A,0x69,0x45,0x44,0x59,0x2D,0x31,0x24,0x50,0x67,0x79,0x54,0x21,0x4C,0x76,0x71,0x66,0x2B,0x63,0x68,0x6D,0x51,0x57,0x4F,0x30,0x65,0x4E,0x5A,0x34,0x75,0x6E,0x33,0x6C,0x37,0x48,0x26,0x32,0x77,0x61,0x7A,0x4B,0x56 | |
}; | |
UInt64 buf = 0; | |
int count1 = 3; | |
byte[] expect = new byte[] { 0x53, 0x23, 0x76, 0x30 }; | |
byte[] output = new byte[] { 0, 0, 0, 0 }; | |
for (int j = 0; j <= count1; j++) | |
{ | |
buf <<= 6; | |
byte b3 = (byte)expect[j]; | |
uint i3 = (uint)Array.IndexOf(lookupTable, b3); //53->8; | |
buf |= i3; | |
} | |
if (count1 == 3) | |
{ | |
output[2] = (byte)(buf & 0xFF); | |
buf >>= 8; | |
output[1] = (byte)(buf & 0xFF); | |
buf >>= 8; | |
output[0] = (byte)(buf & 0xFF); | |
} | |
else if (count1 == 2) | |
{ | |
buf >>= 2; | |
output[1] = (byte)(buf & 0xFF); | |
buf >>= 8; | |
output[0] = (byte)(buf & 0xFF); | |
} | |
else if (count1 == 1) | |
{ | |
buf >>= 4; | |
output[0] = (byte)(buf & 0xFF); | |
} | |
else | |
throw new Exception("crap"); | |
} | |
static void Main(string[] args) | |
{ | |
TestB64(); | |
//Console.WriteLine("{0:X}", SolveFibo(0x12062F76909038C5)); | |
//byte[] data = File.ReadAllBytes(@"F:\flare2018\06-magic\core.11288"); | |
byte[] data = File.ReadAllBytes(args[0]); | |
//int dataOffset = 0x5100; | |
//uint rva2offText = 0; | |
//uint rva2offData = 0; | |
//int dataOffset = 0x6C10; //in core.11288 | |
//int dataOffset = 0x1F44; //in core.11288 | |
uint rva2offText = 0xB10; | |
uint rva2offData = 0x5B10-0x4000; | |
int dataOffset = 0; | |
/* | |
// decode methods. DONT NEED! | |
for (int i = 0; i < 0x21; i++) | |
{ | |
UInt32 offset = BitConverter.ToUInt32(data, dataOffset + i * 0x120 + 0); | |
offset -= 0x400000; | |
offset += rva2offText; | |
UInt32 size = BitConverter.ToUInt32(data, dataOffset + i * 0x120 + 8); | |
UInt32 keyOffset = BitConverter.ToUInt32(data, dataOffset + i * 0x120 + 0x18); | |
keyOffset -= 0x600000; | |
keyOffset += rva2offData; | |
Console.WriteLine("decrypting adr={0:X} size={1:X} key={2:X}", offset, size, keyOffset); | |
for (int j = 0; j < size; j++) | |
{ | |
data[offset+j] ^= data[keyOffset + j]; | |
} | |
} | |
File.WriteAllBytes(@"F:\flare2018\06-magic\core.11288-dec", data); | |
*/ | |
Dictionary<UInt32, string> methods = new Dictionary<UInt32, string>(); | |
methods.Add(0x84, "xor2A"); | |
methods.Add(0x7C, "memcpy"); | |
methods.Add(0x147, "fibo"); | |
methods.Add(0x326, "base64"); | |
methods.Add(0x8F, "plusD"); | |
methods.Add(0x2FE, "rc4-2FE"); | |
methods.Add(0xB3, "crc"); | |
// now process all entries, print type and etc.. | |
char[] key = new char[0x45]; | |
for (int i = 0; i < 0x45; i++) | |
{ | |
key[i] = '?'; | |
} | |
for (int i = 0; i < 0x21; i++) | |
{ | |
UInt32 size = BitConverter.ToUInt32(data, dataOffset + i * 0x120 + 8); | |
UInt32 idx1 = BitConverter.ToUInt32(data, dataOffset + i * 0x120 + 0xC); | |
UInt32 count1 = BitConverter.ToUInt32(data, dataOffset + i * 0x120 + 0x10); | |
//Console.WriteLine("method{0:X2} = {1}({2:X},{3:X})", i, methods[size], idx1, count1); | |
switch (size) | |
{ | |
case 0x7C: | |
//copy | |
for (int j = 0; j < count1; j++) | |
{ | |
byte b = (byte)(data[dataOffset + i * 0x120 + 0x20 + j]); | |
key[idx1 + j] = (char)b; | |
} | |
break; | |
case 0x84: | |
// xor2a | |
for (int j = 0; j < count1; j++) | |
{ | |
byte b = (byte)(data[dataOffset + i * 0x120 + 0x20 + j] ^ 0x2A); | |
key[idx1 + j] = (char)b; | |
} | |
break; | |
case 0x8F: | |
for (int j = 0; j < count1; j++) | |
{ | |
byte b = (byte)(data[dataOffset + i * 0x120 + 0x20 + j] - 0xD); | |
key[idx1 + j] = (char)b; | |
} | |
break; | |
case 0xB3: | |
//crc | |
UInt32 target = BitConverter.ToUInt32(data, dataOffset + i * 0x120 + 0x20); | |
byte[] bb = SolveCrc(target, count1); | |
for (int j = 0; j < count1; j++) | |
{ | |
key[idx1 + j] = (char)bb[j]; | |
} | |
break; | |
case 0x147: | |
//fibo | |
for (int j = 0; j < count1; j++) | |
{ | |
UInt64 target2 = BitConverter.ToUInt64(data, dataOffset + i * 0x120 + 0x20 + j * 8); | |
byte b = SolveFibo(target2); | |
key[idx1 + j] = (char)b; | |
} | |
break; | |
case 0x2FE: | |
//rc4 | |
byte[] zeroes= new byte[0x256]; | |
byte[] rc4key = Encoding.ASCII.GetBytes("Tis but a scratch."); | |
byte[] enczeroes = RC4(zeroes, rc4key); | |
for (int j = 0; j < count1; j++) | |
{ | |
byte b = (byte)(data[dataOffset + i * 0x120 + 0x20 + j] ^ enczeroes[j]); | |
key[idx1 + j] = (char)b; | |
} | |
break; | |
case 0x326: | |
//custom base64 | |
byte[] lookupTable = new byte[] { | |
0x2A,0x39,0x5F,0x64,0xC2,0xA7,0x46,0x23,0x53,0x6B,0x74,0x47,0x28,0x4D,0x70,0x42,0x49,0x25,0x52,0x6A,0x62,0x38,0x40,0x4A,0x69,0x45,0x44,0x59,0x2D,0x31,0x24,0x50,0x67,0x79,0x54,0x21,0x4C,0x76,0x71,0x66,0x2B,0x63,0x68,0x6D,0x51,0x57,0x4F,0x30,0x65,0x4E,0x5A,0x34,0x75,0x6E,0x33,0x6C,0x37,0x48,0x26,0x32,0x77,0x61,0x7A,0x4B,0x56 | |
}; | |
UInt64 buf = 0; | |
for (int j = 0; j <= count1; j++) | |
{ | |
buf <<= 6; | |
byte b3 = (byte)(data[dataOffset + i * 0x120 + 0x20 + j]); | |
uint i3 = (uint)Array.IndexOf(lookupTable, b3); //53->8; | |
buf |= i3; | |
} | |
if (count1 == 3) | |
{ | |
key[idx1 + 2] = (char)(buf & 0xFF); | |
buf >>= 8; | |
key[idx1 + 1] = (char)(buf & 0xFF); | |
buf >>= 8; | |
key[idx1 + 0] = (char)(buf & 0xFF); | |
} | |
else if (count1 == 2) | |
{ | |
buf >>= 2; | |
key[idx1 + 1] = (char)(buf & 0xFF); | |
buf >>= 8; | |
key[idx1 + 0] = (char)(buf & 0xFF); | |
} | |
else if (count1 == 1) | |
{ | |
buf >>= 4; | |
key[idx1 + 0] = (char)(buf & 0xFF); | |
} | |
else | |
throw new Exception("crap"); | |
break; | |
} | |
} | |
Console.Write(new string(key) + '\xA' + '\x0') ; | |
} | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment