Last active
December 20, 2015 15:08
-
-
Save Nullreff/6151701 to your computer and use it in GitHub Desktop.
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
// Called whenever you press "Reload Comic" | |
function reload_comic(){fetch_and_set("http://prizes.prequeladventure.com/wlf2/qwtake-control-data.json", '#comic', "#votes", ".comicadjustment");} | |
function fetch_and_set(url, target, votes, domadjust ) { | |
jQuery.getJSON(url, function (data) { | |
/* Data is: | |
* f: Url with a bunch of data, seems to always be: | |
* "http://prizes.prequeladventure.com/wlf2/qwtake-control-crypt.txt" | |
* | |
* Passed into the 'pd' function along with the data taken for 'f' url: | |
* i: IV used to decode: https://code.google.com/p/crypto-js/#Custom_Key_and_IV | |
* k: decryption key | |
* l: Number of parts to remove from the start | |
* | |
* Uninteresting: | |
* msg: Not used | |
* v: Number of votes so far | |
* | |
* | |
*/ | |
jQuery.get(data.f, function (ct) { | |
// Part that displays the comic | |
jQuery(target).html(pd(ct, data.l, data.k, data.i)); | |
// And a bunch of other crap we don't care about | |
if ( votes ) { jQuery(votes).text(data.v); } | |
if ( domadjust ) { | |
jQuery(domadjust).filter('.notcomplete').toggle(data.l>0).end().filter('.complete').toggle(data.l<=0); | |
} | |
}); | |
}); | |
} | |
// This does all the decryption | |
function pd(data, start, key, iv) { | |
// https://code.google.com/p/crypto-js/ | |
var C=CryptoJS, cts=[]; | |
iv = C.enc.Hex.parse(iv); | |
key = C.enc.Base64.parse(key); | |
// The comic is stored as Base64, AES encrypted chunks taken from | |
// http://prizes.prequeladventure.com/wlf2/qwtake-control-crypt.txt | |
// when it's pulled in, all the parts are split up then all the ones | |
// we haven't "unlocked" yet are removed from the start | |
jQuery.each(data.split(/\r?\n/).slice(start), function (i, v) { | |
// So it decodes the first one using the key (which changes every | |
// time new stuff is unlocked) and IV (which appears to be constant). | |
var ct = C.AES.decrypt( | |
C.lib.CipherParams.create({ciphertext: C.enc.Base64.parse(v)}), | |
key, | |
{ iv: iv } | |
).toString(C.enc.Latin1); | |
// Save it to the array (comic data comes in reverse order). | |
cts.unshift(ct); | |
// TRICKY, generates a new key using the stuff it just decrypted | |
// so each part has a different decryption key that is generated | |
// using the previous part and its decryption key. So you only | |
// have to send one key and the rest of the comic decrypts itself | |
key = C.SHA1(ct + key); | |
}); | |
return cts.join(""); | |
} | |
// So in order to unlock the entire comic, you need the key for the first part | |
// and then set 'start' to 0. Very simple but requires knowing the key. | |
// | |
// If anyone can brute force the key for "XUkMfuNkgNnR2KWckpPDTA=="(base64), | |
// the whole comic is available. Although by the time you do, it's probably | |
// already going to have enough votes... |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
With a larger file you can do that anyway: If after 2 or 3 blocks the decrypted result is still in the ASCII range, you effectively confirmed you have the right key (or, technically, a key/iv combination).
What? That never happens on the internet! :)