Skip to content

Instantly share code, notes, and snippets.

@Nullreff
Last active December 20, 2015 15:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Nullreff/6151701 to your computer and use it in GitHub Desktop.
Save Nullreff/6151701 to your computer and use it in GitHub Desktop.
// 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...
@Nullreff
Copy link
Author

Nullreff commented Aug 5, 2013

Still wouldn't work, since you can't be sure you arrived at the correct key because you happened to get the right key/content combination, or happened to find some other combination that worked.

No one has been able to produce a SHA1 collision. Even so, it would narrow the potential answer space down to the point where you could manually verify each result.

And even if you exclude that, you still have a huge space to iterate over. So... this is no "less secure" than standard file crypto.

True, I think I'm just arguing for the sake of arguing now...

@chmarr
Copy link

chmarr commented Aug 5, 2013

No one has been able to produce a SHA1 collision. Even so, it would narrow the potential answer space down to the point where you could manually verify each result.

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).

True, I think I'm just arguing for the sake of arguing now...

What? That never happens on the internet! :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment