- Feature Articles
- CodeSOD
- Error'd
- Forums
-
Other Articles
- Random Article
- Other Series
- Alex's Soapbox
- Announcements
- Best of…
- Best of Email
- Best of the Sidebar
- Bring Your Own Code
- Coded Smorgasbord
- Mandatory Fun Day
- Off Topic
- Representative Line
- News Roundup
- Editor's Soapbox
- Software on the Rocks
- Souvenir Potpourri
- Sponsor Post
- Tales from the Interview
- The Daily WTF: Live
- Virtudyne
Admin
I've seen this sort of thing more than once.
I have a system that I'm currently dealing with where the coder decided to store the pass to the admin system in a cookie (this is a bit better than the JS code, in that if you never use a public machine to log in the pass is not disseminated), and check the cookie each time the db was altered. He realized that this was insecure. So he encrypted the pass before storing it in the cookie, so it would not be possible to discover the pass from the cookie, and then decrypted it on the server- this of course meant that many extra modules had to be installed on the target system, and a fair bit of load is implied in admin functions- not an issue cause admin use is small compared to user access.
The thing that gives me pause is this- having the _encrypted_ pass in the cookie is all that is required to access the admin pages... in a very real sense, the encrypted pass is the pass, since sending it to the server allows access. This guy is supposedly a very experienced coder, and some of his code is pretty sophisticated. But he clearly lacks judgement. I find it much more frightening to find things like this in the work of a guy with 15 years of experience, much of it doing tricky stuff, than to find it in the code of an obvious amateur. Oh, did I mention that the site is, for reasons that NDAs keep me from explaining, a magnet for attackers? Guy also never heard of prepared statements, and didn't even bother to escape single quotes. I am going to have to rewrite the entire thing soon- the WTFs don't stop there. I mean, they really don't stop there... of course the stupidities involved in the data structures make recovering the last two years of data entry a challenge. I'm amazed that the system works, and serves a million or so users a day. Contractors...
No matter how stupid it is, it's probably real.
Admin
I wrote a site a while back and in the beta 0.1 not-for-release versions it was quite buggy. But then i am young ( in high school ) and had never done things like this before. I am often amazed when people who get paid for this cant fix problems like quotes / cookies+password / performance. That said i still have lots of "room" for improvements. Some thing that often upsets me is when contractors/paid professionals think that just because they get paid for doing this they know everything. They arent paid to think the know everything they are paid to know what is reasonable and learn / find what is required for the project to be of an acceptable quality.
If me, who had never seen PHP/MySQL/Apache before could write a site with safe-SQL, uuid for logins ( 128 bit values stored in cookies for each login ) why can they do it ?
Admin
Best code sample, I've got yet, I googled best methods of implementing security and passwords and it took me right to this code snippet.... I want to congratulate the programmer on this piece of astonishing code, I am implementing it as soon as I'm done with this post, please inform me how much I need to pay for this, surely it can't be free, come too think of it we've got a vacancy at our company, we need ingenious people - where can I get a hold of such a fine programmer... You need to give yourself a great big pat on the back for this...<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p></o:p>
kind regards and many thank you in advance - getting big bonus for implementing this code<o:p></o:p>
Admin
Because most people in the IT contracting business are either crap at coding, or used to be good but are tired of learning new stuff. The thing that successful contractors have is the ability to convince others:
1) that they can do the job (at the interview)
2) they are doing the job
3) when something goes wrong that it's someone else's fault.
Even though you may be technically gifted and actually intersted in coding, you MUST learn the first 2 skills and learn to stop people from doing number 3 to you.
Admin
Oh man oh man, but how do such people get a job where they're actually paid rather than paying for, man... I think my brain just exploded, lol
PS: I'm sure the password is "secret" [I]
Admin
I wouldn't call that unfortunate, I mean if you give the wrong password you have no business being on the right page, even though the password validates. Just let the file system do the pass checking for you and return a 404 when the password was not right. Brillant paradigm really.
Admin
It has, really, nothing to do with which languages you know. The encrypting the pass in the cookie thing I mentioned is fantastically stupid, no matter the language you use to set the cookie. It just makes no sense...
How do they get paid- they work it, one way or another. This was pretty much a case of nepotism.
Admin
Nope, that's not the real tragedy at all.
Admin
I just can't help wonder if this guy is professinal programmer, or just some WTF moment in his lifetime.
Admin
Admin
Totally breathtaking, I've never seen nor heard of any login use Javascript to verify the password.
As for hacking old web logins, you'd be surprised how many websites had a login of "admin/admin" or "webmaster/webmaster" and in the case of adult sites, "howard/stern" has been very common too.
Not to mention all the fun you could have using Google or Altavista to search for "htpasswd" and "/etc/passwd".
Admin
I just did that (google for "htpasswd"), and no less than FOUR of the 10 first results are friendly sites that offer the useful service of encrypting your password for use in .htpasswd - FOR FREE! Isn't that wonderful?!
Admin
Given that they don't know on which site you'll be using the password -- I don't see the problem.
Admin
Letting the file system do the pass checking is not that uncommon for stuff that is not really sensitive and not particularly interesting to anyone who doesn't know the correct url. Just have the file sitting on the server don't link to it and few will find it. Then hand out the correct url to those who need access.
Admin
I myself wrote a small script protecting a directory index in PHP once. It was supposed to be very simple, quick and dirty passwords-in-the-code type of thing. It looked something like this:
$users["user1"] = "qwerty";
$users["user2"] = "asdfg";
//etc...
$username = $_POST["username"];
$password = $_POST["password"];
if($users[$username] == $password)
{
//Allow access
}
else
{
die("get out");
}
Now spot the WTF.
Admin
I had to look up what exactly DCMA stands for.
What does the Dutch Mariah Carey Association have to do with this? :-)
Admin
in case anyone was wondering: http://www.paidsurveysonline.com/user576.htm took about 3 mins.
Admin
You get in by giving an unknown (or no) username and no password? Brillant!
Admin
You need to check if the key actually exists
Admin
And note the url of the roster. Now try pasting that url into a new browser that hasn't logged into anything. Woo!
Admin
Truly, your wisdom is great. I literally could not have phrased it better myself. Observe my own personal experience:
Then permit me to acquaint you with a website I am forced to use which contains names, addresses, phone numbers, email addresses, etc.
function foo() {
var whatever = prompt("Password Required:", "")
var bar = whatever + ".htm";
this.location.href = bar;
}
When I confronted the person in charge about this alleged "protection", he just shrugged it off.
Yeah, well, it's called "security through obscurity" and has been held in extremely low esteem for decades, and rightfully so.
If it's not sensitive, don't pretend you're protecting it. If you tell people you're protecting it, then for $DEITY's sake DO SO PROPERLY
with at least "basic auth" in a valid .htaccess file, if nothing else. I mean, it's not that much more work than the crap Javascript
shown above! Why not do it right?
ok
dpm
Admin
Ah, I get it. The problem is that you named your array for its domain ($users), rather than, as is more commonly done, its range ($passwords)!
Admin
Any links from that "hidden page" to anywhere else, are going to end up in referral logs and eventually a search engine.
Admin
Hahaha, you're totally right. I don't program VB, but in most languages a successful assignment would register as true, so really, the only security in this whole WTF is the lines checking for string length, and >value <VALUE.<BR>
I wonder if he added those lines because the code wasn't working without them...
Admin
Woops I'm an idiot. I was thinking of the VB WTF above this one. Well, yea, Javascript assignment = true. I don't get how he used it right once, then blew it later.
</VALUE.>
Admin
Breaking this simple scheme just takes a little time. The first thing to note is that the username can be completely ignored since you are redirected to "password+'.htm'".
To begin breaking this, we first define our acceptable range of values for each character. For this, I took valid characters to be those between 32 (space) and 126 ("~"), excepting all the uppercase characters (65 to 90) as the password string is converted to lowercase in the code. I ignore the extended characters, in the assumption that the author has done the same.
Next, we need to establish bounds on the length of the password in question. To do so, we take the logarithm of the number to the base of the lower bound of our range of acceptable values to get the maximum length it can be:
Log(24386094146700)/Log(32) = 8.89422
The password cannot be any longer than eight characters (if we use more than eight characters, even if every character in the string is the lowest possible one we can use, we'll go over our target number). Next, we get the lower bound by using the upper bound of our range of acceptable values:
Log(24386094146700)/Log(126) = 6.37371
The password cannot be any shorter than seven characters (if we use less than seven characters, even if every character in the string is the maximum possible one we can use, we still can't reach our target number).
Now that we know the bounds for our password string, we move on to the next step. We take our target number and determine its prime factorization (I cheated here and used Mathematica):
FactorInteger[24386094146700] = {{2,2}, {3,6}, {5,2}, {11,1}, {13,1}, {19,1}, {23,1}, {53,1}, {101,1}}
In other words, we have 2 two's, 6 three's, 2 five's, 1 eleven, 1 thirteen, 1 nineteen and 1 twenty-three. We then take these numbers as coefficients to produce numbers that are within our acceptable range of values:
101: 101
53: 53; 106
23: 115; 46; 92
19: 95; 57; 114; 38
13: 39; 117; 52
11: 55; 110; 33; 99; 44
5: 50; 100; 45; 60; 120
3: 54; 108; 36
2: <none>
Knowing this, we throw together some very quick and dirty code to loop through all possible combinations for each array of values and check whether their product produces our target number. Doing so reveals that when all eight are taken, no combination can produce the value. Next, we begin trying combinations for a seven character password by removing each array, one at a time, from the computation. Doing so reveals that removing any but two of the arrays will not produce the number. We can only produce our target number if we remove the values either for 3 or for 5.
Removing the values for 3 produces six combinations, all of which use odd symbols. This may be right, but we keep looking. Removing the values for 5 produces much more sensible input. Among the nine combinations, four contain only alphanumeric text with no symbols. Among those four:
el7u9s5
e6nu9s5
e67urs5
e67u9sj
one appears to contain a word:
e67urs5
appears to contain the word "user". We take a guess that the numbers are all together either at the beginning or at the end of the password, so we start trying all of the six different combinations of "675" at the beginning and then at the end. After a few attempts, we discover that the password is user576.
Admin
Ha, good one! Especially the 'let the file system do the pass checking'.
Admin
Well, it is old people. But my God! I am such a freaking egg. I saw your sig in a later wtf, and spent ages trying to get damned collections to work in VBA to crack such elegant algorithims as -
z=23;
y=28;
for (x=0; x<10; x++){
f[x]=x<<9
f[x]+=23
}
for (x=10; x<36; x++){
y=y<<1
v= Math.sqrt(y)
v = parseInt(v,16)
v+=5
f[x]=v
y++
}
for (x=36; x<62; x++){
z=z<<1
v= Math.sqrt(z)
v = parseInt(v,16)
v+=74
f[x]=v
z++
which is then mapped to [0-9A-Za-z] (via two for... loops and two arrays, I guess Javascript doesn't have dictionaries/associative arrays/hashes) and then employs this ingenious mechanism to check the password -
for (l=1; l<lpass; l++){
K[l]=pass.charAt(l)
}
var transmit=0;
for (y=1; y<lpass; y++){
for(x=0; x<62; x++){
if (K[y]==base[x]){
transmit+=f[x]
transmit*=y
}
}
}
if (transmit==parseInt(actn1))
go()
This reminds me of why I hate Javascript. Especially Javascript embedded in source code.
Admin
They know the IP address the request is coming from - in many cases the password will be on a site hosted on the same or a nearby IP address.
Besides, if those are being collected and circulated on IRC channels frequented by hackers, they'll get added to word lists used for dictionary attacks by a lot of attackers.
Finally, it's just stupid. Apache comes with a tool to compute the encrypted password - why not USE that?
Admin
I see why they check for the length! You wouldn't want some idiot to enter with the password 90210.0 or 90210.00, would you? Imagine, that would permit an infinite number of passwords, and that, like, you know, would be very bad security...
Admin
I agree with this post
Admin
Thank you for your insight.
Admin
Let's take it a step farther.. a real consultant, for job security, would have done:
var fa1se=true;
if pass == 0 return false
if pass == 1 return false
.
.
if pass == 90209 return false
if pass == 90210 return fa1se
if pass == 90211 return false
if pass == 90212 return false
etc
(or something similar...)
Admin
Now if the username and the password contains a zero as in the character code ..
Admin
"It would appear so, or someone else checked it. The code's been changed to something a *little* more obscure. But the password still works!"
The code is changed to a very collision-prone hash function, which is once again adding and multiplying. You will find the "hashed" password of 71104 in the source code.
Basically what it's doing is taking the 62 [0-9][a-z][A-Z] and translating them all into integers between "A"=12 and "Z"=278810, then on each translated letter (skips the first one) is added to the accumulated hash and multiplied by the array index 1..n
"4" is 2071, "0" is 23, "1" is 535, and "7" is 3607,
4*((3*((2*((1*2071)+23))+535))+3607) == 71104
Admin
This is definetly the WTF post of the day....
Security through obsurity IS NOT security, a weak login on a page you don't know the name of isn't really any more secure than a weak login on the front page of a site.
And Google has proven in the past that you don't have to link to a page for it to be findable. I'd like to point out that .htpasswd and /etc/passwd aren't always linked to and they still appear in the search results.
Also anybody that doesn't see .htpasswd indexing as a problem obviously doesn't realize most people put their .htpasswd in the same directory as the protected page. ANd I don't need to bring up the poor use of passwords people use, and how easily unix hashes can be dictionary cracked (minutes), especially if you use rainbow cracking (seconds).
Admin
Yes, it most certainly and obviously is. The resulting total level of security may be grossly insufficient, but it is still higher than without the obscurity.
"Security through obscurity is no security at all" was originally meant to apply exclusively to cryptographic algorithms, because widely-known and secure algorithms are easily available while the security gained by using an obscure algorithm (if a flaw in the widely-known one is found, the obscure one may not be vulnerable) is minuscule compared to the risk of having flaws in the obscure algorithm (getting a good cryptographic algorithm right is VERY difficult).
In other areas, security through obscurity CAN work, if used only as a supplement for other security measures. The less an attacker knows about your system, the less targeted his attacks can be and the more effort he has to spend on attacks that won't work but may get noticed by the victim.