Last active
July 1, 2017 09:05
-
-
Save pentaphobe/e2709b77912b2e1e187b9d95b7ae3d63 to your computer and use it in GitHub Desktop.
Demonstration of scanning xor-encrypted data
This file contains hidden or 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
/** | |
* This is an insultingly simple demo due to nerd rage | |
* | |
* There are claims of people using static XOR keys to hide shell code in malware | |
* | |
* The only thing more embarrassing than this is that it supposedly prevent detection. | |
* | |
*/ | |
/** | |
* generates an Int8Array containing random bytes and the specified signature/key somewhere within | |
*/ | |
function generateBuffer(key) { | |
let result = new Int8Array(Math.max(key.length * 2, 256)); | |
for (let i=0; i < result.length; i++) { | |
result[i] = ~~(Math.random() * 256); | |
} | |
let last = result.length - key.length - 1; | |
let offs = ~~(Math.random() * last); | |
for (let i=0; i < key.length; i++) { | |
result[offs + i] = key.charCodeAt(i); | |
} | |
return result; | |
} | |
/** | |
* builds an Int8Array of inter-byte xor'd deltas from a signature/key | |
*/ | |
function buildMatchDelta(key) { | |
let deltas = new Int8Array(key.length-1); | |
for (let i=1; i < key.length; i++) { | |
deltas[i-1] = key.charCodeAt(i) ^ key.charCodeAt(i-1); | |
} | |
return deltas; | |
} | |
/** | |
* Performs the actual scanning | |
*/ | |
function scanFor(buffer, deltaArray) { | |
const last = buffer.length - deltaArray.length; | |
function isAt(index) { | |
for (let i=0; i < deltaArray.length; i++) { | |
let delt = buffer[index+i+1] ^ buffer[index+i]; | |
if (delt != deltaArray[i]) return false; | |
} | |
return true; | |
} | |
for (let i=0; i < last; i++) { | |
if (isAt(i)) return i; | |
} | |
return -1; | |
} | |
// | |
//////// EXAMPLE | |
// | |
let buff = generateBuffer('hello'); // a buffer with 'hello' and some random padding bytes | |
let delts = buildMatchDelta('hello'); // a "magical" matcher which finds "encrypted" keys | |
let matchPos = scanFor(buff, delts); | |
if (matchPos !== -1) { | |
console.log('matched at position:', matchPos); | |
} | |
// arbitrary encryption of buffer | |
// choose a static key | |
const xorKey = ~~(Math.random() * 256); | |
// encrypt our buffer | |
for (let i=0; i<buff.length; i++) { | |
buff[i] ^= xorKey; | |
} | |
// should find the data at the same position, regardless of the random key | |
if (matchPos !== -1) { | |
console.log('matched at position:', matchPos); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment