• LCrawford (unregistered)

    Of course, the random characters are to foil blind decryption algorithms. For those hackers who haven't discovered Javascript. And aFbsbjbtataktpsfjarmye

  • frist (unregistered)

    I see the issue.The line: ivRnd = Math.floor(Math.random() * 26)

    Should have read ivRnd = Math.floor(Math.Frist() * 26)

  • randome (unregistered)

    Question: How did they replace Math.random?

  • siciac (unregistered)

    Why are there random numbers involved in their “hashing” algorithm?

    This algo is essentially the same as sending a random string and the XOR of the password with it. (At least, the last two bits of it...)

    It's obfuscation so that when their pentester consultant scans for a plaintext password they won't find it. It's also probably enough to get most of those guys to sign off on the site.

  • Charles F. (unregistered)

    Here's the real WTF: if, in fact, they were sending the request over a TLS-encrypted connection, it would be perfectly fine to send it in cleartext, as it's encrypted at the transport layer. This "encryption" is not merely stupid, it's pointless.

  • fanguad (unregistered)

    The reason they have their weird "less than 158 characters" bit at the start is because they try to encode the length of the password as a character at the end as (char)(password length + 96)... if the length is > 158 they would get overflow so to prevent this... they just send the password in plaintext.

  • Obfuscator (unregistered)
    function Decode(sFog) {
    var sDecoded="";
    var iDecodeLength = sFog.charCodeAt(sFog.length - 1) - 96; // Last char relates to len of _encoded_ string
    for (i=0; i < iDecodeLength; i++) {
    	var iCharCode = sFog.charCodeAt(i * 2 + 1);
    	var iOffset = sFog.charCodeAt(i * 2) - 97;
    	sDecoded += String.fromCharCode(iCharCode - iOffset);
    return sDecoded;

    I hope there aren't any massive WTFs in my code. The special encoding for space etc. seem not to need any special decrypt handling.

  • LCrawford (unregistered)

    Found on the server:

    `function DeFogger(svInput) { // Any changes must be duplicated in the client-side version of this function. var svOutput = ""; var ivRnd; var i; var ivLength = svInput.length;

    if (ivLength == 0 || ivLength > 161) { svInput = svInput.replace(/"&qt;"/g,'"'); return svInput; }

    ivLength = svInput.charCodeAt(ivLength-1) - 96;

    for (i = 0; i < ivLength; i++) { ivRnd = Math.floor(Math.random() * 3); if (svInput.charCodeAt(i) == 32 || svInput.charCodeAt(i) == 34 || svInput.charCodeAt(i) == 62) { ivRnd = 1; } if (svInput.charCodeAt(i) == 33 || svInput.charCodeAt(i) == 58 || svInput.charCodeAt(i) == 59 || svInput.charCodeAt(i) + ivRnd > 255) { ivRnd = 0; }

        ivRnd = svInput.charCodeAt(i*2)-97;
        svOutput += String.fromCharCode(svInput.charCodeAt(i*2+1)-ivRnd);


    return svOutput; }`

  • (nodebb) in reply to Charles F.

    Absolutely agree. Client-side "encryption" is pointless, whether you're using SSL/TLS or not. Anyone sniffing the traffic can not only see your credentials, they can see the JavaScript code that was used to do the "encryption." It doesn't take a genius to reverse engineer the algorithm or manipulate the JavaScript before it hits the client.

  • Gumpy Gus (unregistered)

    Funny you should mention that- at my current POE, they were for decades sending pages with http:// and Authentication: base64 which is basically no security at all, a simple copy-paste into the base64 command shows the plain-text password. And sending session-keys back in the clear too. Talk about low-hanging fruit?

  • Koen van Dratel (unregistered) in reply to fanguad

    Using XORs when plain subtraction does the job would just be server-side obfuscation. Since the [1..158] cases take great care to avoid any special html-characters I wouldn't be surprised if an input like <&11;=>...(159+) would fail.

  • (nodebb)

    Sending a random string plus the password xored with it was the recommended defense a few years ago to a MITM attack on TLS (BREACH and CRIME). The idea is that if an attacker can't break your TLS, but can force the client to repeatedly (try to) authenticate and can add an arbitrary string to the request (e.g. as a query parameter), they can inspect the size of the compressed request or response and determine if there was overlap between their string and the password. If the password is xored with a different string every time, this attack doesn't work (and I imagine there are other hypothetical attacks this could thwart too.)

  • Koen van Dratel (unregistered) in reply to fanguad

    Sorry, the XOR bit (no pun intended) was triggered by the considerations of "siciac". Your plain text comment triggered the next bit.

  • The Saint (google)

    This is almost as good as one of those plastic secret decoder rings. implementation: https://s3-us-west-1.amazonaws.com/bogohash/bogoHash.html

  • James (unregistered)

    When your encryption can be decrypted by hand with a minimal understanding of the code (and probably even without it) . . .

  • anonymous (unregistered) in reply to Charles F.

    Things may have changed more recently but AFAIK it is accepted practice to send passwords in plaintext over SSL and I have never seen recommendations to the contrary. (The exception to this is services like ProtonMail that use the password in an unconventional manner.)

    Client-side hashing of a password achieves nothing when SSL is used. If you're in a situation where the SSL connection is intercepted, an attacker can just as easily insert extra code into the page to read back the password in plaintext (because they have direct access to the form field where the user has entered their plaintext password). And even if you can't get the plaintext password, you'll probably have a pass-the-hash vulnerability (where the attacker can just pass the same hash back again to authenticate again as the same user without knowing the password used to generate the hash).

    You might try to encrypt the password, but even then the attacker could replace the encryption key given by the server with their own encryption key. The only real solution is to always use SSL, carefully control access to your private SSL keys/certificates, and educate users to always verify the SSL certificates before logging in (fortunately most browsers do this automatically these days).

  • löchlein deluxe (unregistered)

    Huh. Now that's giving me mean ideas… enforce your password policy by randomly mangling the hash for non-conforming suggestions. Oh yeah, you can use any password you like, but if you want it to actually work, here's the guidelines to stick to: …

  • siciac (unregistered) in reply to anonymous

    Client-side hashing of a password achieves nothing when SSL is used.

    It prevents the password from ever leaving the client. If someone breaches your service, they can't harvest passwords that way. (For an insider threat, it's generally easier for someone to log in to a server and set up a process quietly harvesting passwords, whereas to muck with the client, they have to deploy a code change which is much easier to track and detect.)

  • SImonk (unregistered)

    The "iv" random value is an initialization vector - standard practice to ensure that encrypting the same value multiple times does not always produce exactly the same output. When used with hashing, the term "salt" is more commonly used. Of course you need to include the chosen iv/salt along with the encrypted/hashed value, which the code does.

    The code itself doesn't seem to me like a real WTF, as long as it is acknowledged to be a "fallback in case we screw up the proper security". Though of course a proper hash algorithm would be better.

  • Tek (unregistered)

    "What. The. Fuck." indeed.

  • fa (unregistered) in reply to fanguad

    A few days late, but this is interesting. I'd be really tempted to try to send a string containing a quote mark. The if (..) statements also prevent quotes in the encoded version. If SQL used double quotes I'd be sure it's an SQL injection "defense", but in this case, maybe they haven't got around to using SQL yet.

  • doubting_poster (unregistered) in reply to SImonk

    Nice attempt, but the 'iv' is clearly some botched hungarian notation meaning something along the lines of 'integer value', and the 'sv' standing for 'string value'.

  • tlhonmey (unregistered) in reply to Craig_Wagner

    Client-side encryption is not entirely pointless. Use the JS libraries that do asymmetric encryption and it doesn't matter if the attacker knows the algorithm, he can't read the password with a simple sniffer. He has to set up to actually intercept and alter traffic between the server and the client, which is both more difficult and more noticeable. And if each client has its own, locally stored private key which must be used to add a second layer of encryption, then he has to compromise the client machine itself, at which point he may as well just install a keylogger and be done with it.

Leave a comment on “Foggy about Security”

Log In or post as a guest

Replying to comment #:

« Return to Article