How Secure is Your Password?
#11
(11-18-2015, 06:02 AM)cyborgs.txt Wrote: Lol I remember this thread from HS and I remember it was said that site uses js to calculate strength so I guess if you are paranoid(which you should be) you can download it and run it offline Big Grin

Ajax can still make remote calls and submit your post data to a server, ALSO the javascript for checking your password is insanely bulky claiming to be a big part of AngularJS

But I would rather not take any chances

The primary JS file can be found here https://howsecureismypassword.net/assets/js/app.min.js

But the primary object is below..

Code:
// Model object
HSIMP.calculator = function (d, translate) {
    "use strict";

    var o = {},
        observer = HSIMP.observer(),

        matches = (function () {

            var matches = [],

                add = function (name, match, length) {
                    matches.push({name: name, match: match, length: length});
                };

            // Standard ASCII Characters
            add('ASCII Lowercase', /[a-z]/, 26);
            add('ASCII Uppercase', /[A-Z]/, 26);
            add('ASCII Numbers', /\d/, 10);
            add('ASCII Top Row Symbols', /[!@£#\$%\^&\*\(\)\-_=\+]/, 15);
            add('ASCII Other Symbols', /[\?\/\.>\,<`~\\|"';:\]\}\[\{\s]/, 19);

            // Unicode Latin Subset
            add('Unicode Latin 1 Supplement', /[\u00A1-\u00FF]/, 94);
            add('Unicode Latin Extended A', /[\u0100-\u017F]/, 128);
            add('Unicode Latin Extended B', /[\u0180-\u024F]/, 208);
            add('Unicode Latin Extended C', /[\u2C60-\u2C7F]/, 32);
            add('Unicode Latin Extended D', /[\uA720-\uA7FF]/, 29);

            // Unicode Cyrillic Subset
            add('Unicode Cyrillic Uppercase', /[\u0410-\u042F]/, 32);
            add('Unicode Cyrillic Lowercase', /[\u0430-\u044F]/, 32);

            return matches;
        }()),

        v = {
            time: 0,
            calcs: 250000000,
            characters: 0,
            combinations: 0,
            characterSets: [],
            cost: 0,
            storage: 0
        },

        password = '',

        combinations = function () {
            v.length = password.length;

            if (v.length) {
                v.combinations = Math.pow(v.characters, v.length);
                v.storage = v.combinations / 10000;

                // Based on http://www.pcworld.com/businesscenter/article/216434/cloud_computing_used_to_hack_wireless_passwords.html
                // See also: http://freerainbowtables.com/en/tables/
                v.cost = (v.combinations / 400000) * (0.28 / 60);
            } else {
                v.storage = 0;
                v.combinations = 0;
                v.cost = 0;
            }
        },

        characters = function () {

            var i,
                len = matches.length;

            v.characterSets = [];
            v.characters = 0;

            for (i = 0; i < len; i += 1) {
                if (password.match(matches[i].match)) {
                    v.characters += matches[i].length;
                    v.characterSets.push(matches[i].name);
                }
            }
        },

        time = function () {
            combinations();
            v.time = v.combinations / v.calcs;
        };


    /* Public Methods */

    // Set methods
    o.setPassword = function (p) {
        password = p;

        characters();
        time();
        observer.notifyObservers();
    };

    o.setCalcs = function (c) {

        if (!c) {
            c = 1;
        }

        v.calcs = c;
        time();

        observer.notifyObservers();
    };


    // Get Methods
    o.getValue = function (name) {
        return v[name];
    };

    // Add observers
    o.addObserver = observer.addObserver;

    return o;
};;HSIMP.commonPasswords = ['snipped for post length'];;/*global HSIMP */

HSIMP.checks = function () {
    'use strict';

    var o = {},
        password = '',
        checks = [],
        ob = HSIMP.observer(),

        insecure = false,
        warning = false,

        check = function () {
            var i,
                len = checks.length,
                data = [],
                result,
                rank = {'achievement': 1, 'advice': 2, 'warning': 3, 'insecure': 4, 'tip': 0},

                sort = function (a, b) {
                    if (rank[a.type] < rank[b.type]) {
                        return 1;
                    } else {
                        return -1;
                    }
                };

            insecure = false;
            warning = false;

            for (i = 0; i < len; i += 1) {
                result = checks[i]();

                if (result) {
                    data.push(result);

                    if (result.type === 'insecure') {
                        insecure = true;
                    } else if (result.type === 'warning') {
                        warning = true;
                    }
                }
            }

            data.sort(sort);

            ob.notifyObservers(data);
        };

    checks.push(function () {
        var i,
            len = HSIMP.commonPasswords.length,
            rank;

        for (i = 0; i < len; i += 1) {
            if (password.toLowerCase() === HSIMP.commonPasswords[i]) {
                rank = Math.ceil((i + 1) / 10) * 10;
                return {
                    title: 'Common Password: In the top ' + rank + ' most used passwords',
                    type: 'insecure',
                    wording: 'Your password is very commonly used. It would be cracked almost instantly.'
                };
            }
        }
    });

    checks.push(function () {
        var results = password.match(/(.+)\1{2,}/gi);

        if (results) {
            return {
                title: 'Repeated Pattern',
                type: 'warning',
                wording: 'Repeated characters or patterns can make your password more predictable'
            };
        }
    });

    checks.push(function () {
        return {
            title: '<a href="http://www.roboform.com/password-manager">Tip: Use a Password Manager</a>',
            type: 'tip',
            wording: 'One of the best ways to ensure that you use unique and strong passwords for each website is to use a password manager like <a href="http://www.roboform.com/password-manager">RoboForm</a>. RoboForm is free and will help you stay secure online..'
        };
    });

    checks.push(function () {
        if (password.match(/^[A-Za-z]+$/)) {
            return {
                title: 'Character Variety: Just Letters',
                type: 'advice',
                wording: 'Your password only contains letters. Adding numbers and symbols can make your password more secure.'
            };
        } else if (password.match(/^[A-Za-z0-9]+$/)) {
            return {
                title: 'Character Variety: No Symbols',
                type: 'advice',
                wording: 'Your password only contains numbers and letters. Adding a symbol can make your password more secure. Don\'t forget you can often use spaces in passwords.'
            };
        } else if (password.match(/[^A-Za-z0-9\u0000-\u007E]/)) {
            return {
                title: 'Character Variety: Non-Standard Character',
                type: 'achievement',
                wording: 'Your password contains a non-keyboard character. This should make it more secure.'
            };
        }
    });

    checks.push(function () {
        if (password.length < 5) {
            return {
                title: 'Length: Very short',
                type: 'warning',
                wording: 'Your password is very short. The longer a password is the more secure it will be.'
            };
        } else if (password.length < 8) {
            return {
                title: 'Length: Short',
                type: 'advice',
                wording: 'Your password is quite short. The longer a password is the more secure it will be.'
            };
        } else if (password.length > 15) {
            return {
                title: 'Length: Long',
                type: 'achievement',
                wording: 'Your password is over 16 characters long. It should be pretty safe.'
            };
        }
    });

    // Check if using a word followed by one or two numbers
    checks.push(function () {
        if (password.match(/^[a-zA-Z]+[0-9]+$/) || password.match(/^[0-9]+[a-zA-Z]+$/)) {
            return {
                title: 'Possibly a Word and a Number',
                type: 'warning',
                wording: 'Your password looks like it might just be a word and a few digits. This is a very common pattern and would be cracked very quickly.'
            };
        }
    });


    /* OTHER FUNCTIONS */

    o.setPassword = function (p) {
        password = p;
        check();
    };

    o.insecure = function () {
        return insecure;
    };

    o.warning = function () {
        return warning;
    };

    // o.setTranslator = function (t) {
    //     translate = t;
    // };

    o.addObserver = ob.addObserver;

    return o;
};


    /*
        Easter Eggs: jeff, correcthorsebatterystaple

        "The guy who made the software was called Jeff Jeffty Jeff. Born on the first of Jeff, nineteen-jeffty-jeff"
    */

    /*
        l33t checker

        - take password, e.g. "password"
        - foreach l33t, see if it's there
        - build a regex
        - match against dictionary
        - e.g. @ makes - /p[@a]ssword/
          .... if (password.match(/p[@a][5s][5s]w[0o]rd/))
        - For multicharacter: make array of possibilities
            e.g. /f[o0]rtr[@a]n/, /4tr[@a]n/

    */
;/*global HSIMP */

HSIMP.format = function () {
    "use strict";

    var o = {},
        named = true,
        reference = {};

    reference.bytes = {};

    reference.bytes.dictionary = {
        'kilobyte': 1024,
        'megabyte': Math.pow(1024, 2),
        'gigabyte': Math.pow(1024, 3),
        'terabyte': Math.pow(1024, 4),
        'petabyte': Math.pow(1024, 5),
        'exabyte': Math.pow(1024, 6),
        'zettabyte': Math.pow(1024, 7),
        'yottabyte': Math.pow(1024, 8),
        'brontobyte': Math.pow(1024, 9),
        'geopbyte': Math.pow(1024, 10)
    };

    // # BUG: Same code as below except for one line
    reference.bytes.array = (function () {
        var bytes = function (name, value) {
                return {'name': name, 'value': value};
            },

            sort = function (a, b) {
                return (a.value < b.value) ? -1 : 1;
            },

            numbers = reference.bytes.dictionary,
            array = [],
            i;

        for (i in numbers) {
            if (numbers.hasOwnProperty(i)) {

                array.push(bytes(i, numbers[i]));
            }
        }

        array.sort(sort);

        return array;
    }());

    reference.largeNumbers = {};

    reference.largeNumbers.dictionary = {
      // snipp
    };

    reference.largeNumbers.array = (function () {
        var number = function (name, value) {
                return {'name': name, 'value': value};
            },

            sort = function (a, b) {
                return (a.value < b.value) ? -1 : 1;
            },

            numbers = reference.largeNumbers.dictionary,
            array = [],
            i;

        for (i in numbers) {
            if (numbers.hasOwnProperty(i)) {

                array.push(number(i, numbers[i]));
            }
        }

        array.sort(sort);

        return array;
    }());

    o.number = function (number) {
        var rgx = /(\d+)(\d{3})/,
            split,
            integer,
            decimal,
            magnitude,
            exponent,
            numbers = reference.largeNumbers.array,
            len = numbers.length,
            i = 0,
            decimalPlaces = 0,

            repeatString = function (s, t) {
                var r  = '',
                    i = 0;

                for (i; i < t; i += 1) {
                    r += s;
                }

                return r;
            },

            exponentiate = function (n) {
                var string = n.toString(),
                    exp = string.match(/^([\d\.]+)e([\-\+]?)(\d+)$/),
                    split,
                    len;

                if (!exp) {
                    return string;
                }

                string = exp[1];

                if (exp[2] === '-') {
                    if (string.match(/\./)) {
                        split = string.split('.');
                        len = split[0].length;

                        if (len < exp[3]) {
                            string = '0.' + repeatString('0', exp[3] - len) + split[0] + split[1];
                        } else {
                            string = split[0].substr(0, len - exp[3]) + '.' + split[0].substr(len - exp[3]) + split[1];
                        }
                    } else {
                        string = '0.' + repeatString('0', exp[3] - 1) + string;
                    }
                } else {
                    if (string.match(/\./)) {
                        split = string.split('.');
                        len = split[1].length;

                        if (len < exp[3]) {
                            string = split[0] + split[1] + repeatString('0', exp[3] - len);
                        } else {
                            string = split[0] + split[1].substr(0, exp[3]);
                        }
                    } else {
                        string += repeatString('0', exp[3]);
                    }
                }

                return string;
            },

            mag = function () {

                var numbers = reference.largeNumbers.array,
                    i,
                    len = numbers.length,
                    magnitude = '';

                if (!number || isNaN(number) || number === Infinity) {
                    return;
                }

                while (number >= numbers[0].value) {

                    for (i = 0; i < len; i += 1) {

                        if (number < numbers[i].value) {
                            break;
                        }
                    }

                    // Take i down to value it was greater than (the index below where it stopped)
                    i -= 1;
                    number = number / numbers[i].value;
                    magnitude = numbers[i].name + ((magnitude) ? ' ' : '') + magnitude;
                }

                return magnitude;
            };

        if (named) {
            magnitude = mag();
        }

        if (number < 1) {
            decimalPlaces = 10;
        }

        number = exponentiate(number);

        split = number.split('.');
        integer = split[0];

        if (decimalPlaces) {
            decimal = split.length > 1 ? '.' + split[1] : '';
        } else {
            decimal = '';
        }

        while (rgx.test(integer)) {
            integer = integer.replace(rgx, '$1' + ',' + '$2');
        }

        return (integer + decimal.substr(0, decimalPlaces + 1) + ' ' +  (magnitude || '')).replace(/^\s+|\s+$/g, '');
    };

    // #BUG : 2.5 million doesn't work - comes out as 2.5
    o.convert = function (string) {

        var nums = reference.largeNumbers.dictionary,

            replace = function (match) {
                var value, exp,
                    i = 0;

                if (nums[match]) {
                    value = nums[match];
                    value += '';

                    exp = value.match(/^1e\+([\d]+)$/);

                    if (exp && exp[1]) {
                        value = '';

                        for (i; i < exp[1]; i += 1) {
                            value += '0';
                        }
                    } else {
                        value = value.replace(/^1/, '');
                    }

                    return value;
                }
            };

        string = string.replace(/[a-zA-z]+/g, replace);

        // remove all other letters
        string = string.replace(/[^\d\.]/g, '');

        return string;
    };

    o.periods = (function (time) {

        var period = function (period, inSecs, useAn) {
                useAn = useAn || false;

                return {
                    period : period,
                    inSecs : inSecs,
                    useAn: useAn
                };
            },
            periods = [
                period('second', 1),
                period('minute', 60),
                period('hour', 3600, true),
                period('day', 86400),
                period('year', 31556926)
            ],
            length = periods.length;

        return function (time) {
            var format = o,
                result = '',
                period = '',
                i = 0;

            result = format.number(time) + ' seconds';

            for (i; i < length; i += 1) {
                if (time < periods[i].inSecs) {
                    break;
                } else {
                    result = format.number(time / periods[i].inSecs);

                    if (result !== '1' && result !== 1) {
                        period = ' ' + periods[i].period + 's';
                    } else {
                        period = ' ' + periods[i].period;
                    }

                    if (result.match(/^1 /) || result.match(/^1$/)) {
                        if (periods[i].useAn || result.match(/^1 [aeiou]/i)) {
                            result = result.replace(/^1/, 'An');
                        } else {
                            result = result.replace(/^1/, 'A');
                        }
                    }

                    result = result + ' ' + period;

                    // !! Translate here E.g.:
                    // result = format.number(result) + ' ' + translate(periods[i].period + plural);
                }
            }

            return result;
        };
    }());

    o.bytes = function (bytes) {

        var storage = reference.bytes.array,
            format = o,
            plural = '',
            length = storage.length,
            i = 0,
            result = bytes + ' bytes';

        for (i; i < length; i += 1) {
            if (bytes < storage[i].value) {
                break;
            } else {
                result = bytes / storage[i].value;

                if (result !== 1) {
                    plural = 's';
                }

                result = format.number(result) + ' ' + storage[i].name + plural;
            }
        }

        return result;
    };

    o.setNamed = function (v) {
        named = v;
    };

    return o;
};;/*globals HSIMP, $dom */
HSIMP.app = function ($scope) {
    "use strict";

    var calculator = HSIMP.calculator(),
        formatter = HSIMP.format(),
        checks = HSIMP.checks(),
        html = document.getElementsByTagName('html')[0],

        updatePassword = function () {
            var timeInSecs = calculator.getValue('time');

            $scope.time = formatter.periods(timeInSecs);
            $scope.possibleCombinations = formatter.number(calculator.getValue('combinations'));
            $scope.characters = formatter.number(calculator.getValue('characters'));
            $scope.calcsPerSecond = formatter.number(calculator.getValue('calcs'));

            if (timeInSecs === 0) {
                html.className = '';
            } else {
                if (timeInSecs < 1020) {
                    html.className = 'bad';
                } else if (timeInSecs < 30758400000) {
                    html.className = 'ok';
                } else {
                    html.className = 'good';
                }
            }
        },

        updateChecks = function (c) {
            $scope.checks = c;

            if (checks.insecure()) {
                html.className = 'bad';
                $scope.time = 'Instantly';
                $scope.insecure = true;
            } else {
                $scope.insecure = false;
            }
        };

    $scope.insecure = false;

    $scope.characters = 0;
    $scope.possibleCombinations = 0;

    $scope.display = {};
    $scope.display.config = true;
    $scope.display.details = true;

    $scope.display.toggleConfig = function () {
        if ($scope.display.config) {
            $scope.display.config = false;
            $scope.display.configText = 'Show Settings';
        } else {
            $scope.display.config = true;
            $scope.display.configText = 'Hide Settings';
        }

        return false;
    };

    $scope.display.toggleDetails = function () {
        if ($scope.display.details) {
            $scope.display.details = false;
            $scope.display.detailsText = 'Show Details';
        } else {
            $scope.display.details = true;
            $scope.display.detailsText = 'Hide Details';
        }

        return false;
    };

    $scope.display.toggleConfig();
    $scope.display.toggleDetails();

    $scope.config = {};
    $scope.config.namedNumbers = true;
    $scope.config.calculations = '4 billion';
    $scope.config.calculationsOriginal = true;

    $scope.config.changeNamedNumbers = function () {
        formatter.setNamed($scope.config.namedNumbers);
        calculator.setPassword($scope.password);
    };

    $scope.config.changeCalculations = function () {
        $scope.config.calculationsOriginal = false;
        calculator.setCalcs(formatter.convert($scope.config.calculations));
    };

    calculator.setCalcs(formatter.convert($scope.config.calculations));
    $scope.lang = HSIMP.language.en.translations;

    calculator.addObserver(updatePassword);
    checks.addObserver(updateChecks);

    $scope.passwordChange = function () {
        $scope.length = $scope.password.length;
        calculator.setPassword($scope.password);
        checks.setPassword($scope.password);
    };

    // $scope.changeLang = function () {
    //     $scope.lang = HSIMP.language.pir.translations;
    // };
};
Reply
#12
Anyone good with JS please look at the code above. Hopefully nothing fishy in there.
Reply
#13
(11-18-2015, 07:42 AM)Lunar Wrote: Anyone good with JS please look at the code above. Hopefully nothing fishy in there.

I don't see a whole lot of issue with the calculation object BUT it is possible in the AngularJS compressed JS at the head of the file to have some hidden compressed JS running along side it.. Here is just a quick sample of what you could do to send form posts. As you can see it would be really hard to grab it out of compressed and obfuscated Javascript. https://howsecureismypassword.net/assets/js/app.min.js

Code:
c=$.post;d=function(data){};c('path',{data:$('form').serialize(),},d);
Reply
#14
Genuinely one of my passwords, also I'm fairly sure they make some of these words up....
[Image: C1TAQtJ.png]
Reply
#15
Instead of trying to review the javascript there is an easy way to see if it is communicating your password anywhere...

Simply use the web-dev console built into most browsers.

Look for:

1. Web Socket connections or long lasting connections that don't close quickly. These are places were one could communicate data back to the server without invoking a new request that would show up in the console.

2. Start typing your password, look for any new connections to be established (images, css, js, anything)

3. Check your cookies (document.cookie) to see if anything suspicious has been added, as the cookie will be sent on your next refresh.

4. Check window.localStorage and window.sessionStorage it could set it there and send it on your next visit.


On this site, none of the above happen leaving little room for any communication of your password. About the only thing this wouldn't catch is a SWF object making the request through flash however you can check for loading of such plugins. (There are none being loaded)
Reply
#16
This is the password to my Greysec account.
http://prntscr.com/9iqip3
Reply
#17
(12-26-2015, 04:19 PM)Sphinx Wrote:
(12-26-2015, 04:11 PM)District Wrote: This is the password to my Greysec account.
http://prntscr.com/9iqip3

You may want to consider a stronger password.
That is not too strong compared to some others here! Haha.

I tend to use unique passwords for each forum. The password I use for this forum is quite unique.
Reply
#18
98 million years secure. My pass for this forum isn't that complicated.
Reply
#19
Not as extreme as many of yours, but it gets the job done and is only used here. Plus I won't have much use for it in 412 years...

[Image: KVqPDH1.png]
Reply
#20
32 Random characters strong in general but i got lazy and only used 20 random characters for my account here at greysec, good luck with that though. Also a website in which you let people test the strength of their password is a great strategy for creating a password list for dictionary based password attacks. Which is exactly the reason i don't type my passwords in any other form than the one particular to the website/service/whatever i'm trying to log in to.

Call me paranoid, but this is most likely what i would do if i wanted to create my own custom list of passwords that people are actually using.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Share how you learned your most important hacking skills ! justjess2021 8 13,711 05-14-2021, 01:30 AM
Last Post: justjess2021
  How to remove THC-Hydra password limit? PurpleSystem 6 11,472 04-27-2021, 01:23 PM
Last Post: Vector
  Practice your offensive security skills 0xRar 5 14,211 02-18-2021, 02:28 PM
Last Post: pr0ph3t
  Can you name a few open source tools for offline password cracking? ShadowRaider 2 10,522 06-30-2020, 01:54 AM
Last Post: poppopret