-
Password Checker
I was mostly wondering, not that I will do such a thing. Lets say you want to make a simple program that asks for a password, you enter it, if correct it launches an application. My question is what security factors will you have to think of? Lets say the code is like this:
Code:
<iostream>
using namespace std;
#define PASS "hey"
int main(void)
{
string str;
cin >> str;
cin.ignore();
if (str == PASS)
system(something);
}
How could somebody try to hack the program? If he has access lets say to the .exe file, under windows. What security measures could you take in order for a simple password checker program to be safe?
-
If all your program does is a system call, why can't the "hacker" make this system call without your program?
-
> How could somebody try to hack the program?
1. Do a hex dump of the .exe, and see the string "hey"
2. Run the code in a debugger, stop at the string comparison, and change BEQ into BNE. In other words, any incorrect guess is success.
> What security measures could you take in order for a simple password checker program to be safe?
None?
Sure you can raise the bar a little to hamper "curious noob", but if someone wants it enough, they'll get it.
-
Encrypt the password in the file and encrypt the password entered. That will raise the bar for anyone trying to crack it.
-
Encryption is good, but someone can just check the encryptor/decryptor method/program, right?
Is there a way not to be able to view an .exe file, so no hex dumb? Be able just to execute it? Of course then somebody could "look" into the main memory where it is loaded I guess.
In any case, what is generally a good method to make such a program? Does this concerns more "OS security", thus protecting files and stuff, or the actual code of the program will make it safer and more hard to crack?
-
Assume that the opponent has everything except the key. Even to the point of you giving them the source code.
exe packers and encrypters just make it harder.
Relying on the OS to make an executable "execute only", which will stop a number of people as well. But again, if your opponent is admin/root on their own machine, you're still not much better off.
Obfuscation and hiding don't work for real security.
-
Let's look at Linux's su program. su is installed for root as suid, which means it will run with root privileges no matter who calls it. It then queries the user for the root password and if it matches, launches a shell running as root.
Venues of attack:
1) Search the executable for the password. You can't do this, because the password is in the authentication mechanism's password store, not in the executable. For the traditional shadow pwdb, this is the file /etc/shadow. You cannot read this file, since it's readable only by root.
2) Modify the executable to not check the password. The executable is only writeable by root, so you can't do this.
3) Attach a debugger and change the code at runtime. You can't attach a debugger to a process running with higher privileges than you.
Thus, su is secure against cracking.
-
Okay, I get your points. So it has mostly to do with the OS than "programming in a safe way", so I guess this hasn't much to do with C++ programming, so I might move the subject in a more appropriate place. Thanks
-
It has a lot to do with how you write your program, certainly.
For example, even doing an MD5 of the input, and compare it to a pre-MD5'ed version of the password is more secure. Though it may be a sluggish way of encrypting a password depending on length.
Using a system() call is nearly always a security flaw. The only way around this is to call an exact path. However, the means used to determine exact paths are always platform specific enough that one could typically also use a platform specific means by which to spawn a new process.
Cornedbee is demonstrating a secure program. By no means does that mean that you have to be running *nix to have security (though I will debate many who argue otherwise). Even on windows you can make an honest effort at securing your data. In my experience, it is almost universally better to never allow a user direct access to any of the data that is used for comparison. I.e. have an offsite host that does password checks. Though this may not always be possible or even reasonable, I like this approach. But even doing this means at some point your data is sent and again vulnerable.... Its not easy dude. That is why there is money in security.
-
First of all, use a hash of the password, rather than a password itself. That is, find a non reversible algorithm that you can apply to the password that will yield a unique enough result. Java's string hashCode algorithm is sufficient. This is a minimum. Don't ever store passwords, its not safe, and there's no point given the alternative.
Second, system calls are simply not safe. It is usually possible to see what system calls were made and repeat them. Alternately a process can be made to run in a modified environment that will trace the system call. Even if you manage to hide the system call, the fact is that the program still does not prevent somebody from from trying to guess at the system call directly, circumventing the call.
If you want you program to be the only access point to whatever other program you are indirectly calling, you need to somehow make that program dependent on yours. If you do not have access to the program source, then the only way to do this is to encrypt that program. Encryption will ensure that only your program can decrypt the target.
But you can't just hide the decryption key in your program, because then somebody can just read the executable and get it. You have to make it dependent on the password. But this adds vulnerability because your short password is too simple to encrypt large amounts of predictable data.
So even after all that work, your program would still be vulnerable, and more vulnerable then may at first be guessed.
-
I have had to remake code by disassembling a program before. Yeah its work, and no it isn't fun. If I can do that in order to get the basic jist of my code so I can rewrite it, what makes you think someone more savvy with disassembly cannot just reverse engineer your entire program?
I know that sometimes these things sound rediculously unlikely enough that you would not even consider them. Sometimes you have to make considerations for the 0.00001% of the population that will do something highly ambitious with your programs.
-
The bottom line is - you just can't make a program safe from everything. Yes, you can take precautions, but there will always be someone who can hack your program.
A very good example of this is DRM. They create them to very difficult to get around or reverse engineer, yet people do crack them.
-
You can't make data or a program safe if the cracker has physical access to the machine on which it resides. At some level of technical understanding, it's always possible to crack the security. This is the problem DRM faces. It tries to restrict the abilities of the person who has the protected data in his hands. It goes to absurd lengths for that. But it all relies on somehow hiding a key from the user, and that's just not possible in the long run.
Now, securing something over a network is possible and considerably easier. Security holes over the network are always shortcomings of the programmer, be it in design or implementation of the software.
-
> Security holes over the network are always shortcomings of the programmer, be it in design or implementation of the software.
Beautiful. That is my thinking about this subject too. Though even one way hashes that are sent over a network still suffer potential cracking by someone with direct access to the program executing the algorithm. Granted it takes some disassembling genious. But where there is a will... there is a way.
-