Nick
Nick

Reputation: 37

embedding security information (username and password) inside a C executable program

I have hard-coded a list of user-names and passwords into a C++ array program and deliver the executable program to everybody. How difficult is it for a user to decode the executable to get the actual username and password?

The username and password is very long and guessing/brute-force is computationally not feasible.

I have zero background in security coding, thus by putting the user-name and password hard-coded inside an executable program,. the only way for hacker to gain the information is by decoding the executable. I would like to know how difficult is the process and how to make it more difficult.

Upvotes: 2

Views: 1602

Answers (2)

Serge Ballesta
Serge Ballesta

Reputation: 149115

Well there is a command in GNU tools whose name is strings that exactly does that:

GNU strings prints the printable character sequences that are at least 4 characters long (or the number given with the options below) and are followed by an unprintable character. By default, it only prints the strings from the initialized and loaded sections of object files; for other types of files, it prints the strings from the whole file.

And there is the equivalent tool in Microsoft's world, not speaking of a number of binary (or hexadecimal editors).

And even the good old vim can open a binary file and allows to look inside it as character and hexadecimal format.

That means that the only hard thing for the user will be to guess what strings are the user names and what are the passwords and which corresponds to which. But if you coded them as 2 arrays, it could be easy to guess.

On a security point of view, it is bad to store secrets in an uncrypted file. So the correct way would be to use an asymetric engine, ask each user for its public key, encrypt the passwords with it and let user decrypt it with its private key. That way each user can only decode his set of passwords.

If you cannot do that (too complex design) you are only left with poor security solutions that will just harden the task for an attacker but could be enough if the risk is low to medium. You could try to build a primary key with an almost trivial algorythm (bitwise operations) from several variables, and use that key to encode the passwords with a symetric algorythm. That way, none of the keys are directly readable in the executable, and you can use a good algorythm to store the passwords. But you are still vulnerable to 2 attacks:

  • if the attacker executes the program under a debugger, he could easily guess what are the usernames and password at the moment they are used - this can partially mitigated by determining whether the program is runned under a debugger, but hardware debuggers cannot be identified.
  • if the attacker reads the memory of the running program, the passwords or the primary key could be directly readable - this can be mitigated by resetting the memory to random or zero after computing a password

But anyway, never store really sensitive data that way.


BTW, above assumed that you really need the actual passwords in the program for example to access third part data protected with usernames and passwords that you do not want to communicate to your own users. And even in that case a proxying mechanism would be more secure if relevant. But if you only need to authenticate users against that base of usernames and password, just store the hashes. For a local database, bcryp is a good choice:

  • it is not inversible
  • it is time consuming so very resistant against brute force attacks - with configurable strength

Upvotes: 3

Leandros
Leandros

Reputation: 16825

How difficult? It's just one command.

strings path/to/executable

Example:

$ cat main.c
int main(void)
{
    char* foo = "zyxwvu";
    return 0;
}

$ gcc -o main main.c
$ strings main
zyxwvu

The string is saved in the binaries .text / .data / .cstring (depends on binary format) section, which looks like:

100000f8a:   7a 79                   jp     100001005 <_main+0x95>
100000f8c:   78 77                   js     100001005 <_main+0x95>
100000f8e:   76 75                   jbe    100001005 <_main+0x95>

0x7a is z, 0x79 is y, etc.

Upvotes: 3

Related Questions