I am creating an archive which contains HTML/CSS/JS files for my C++ application, and I don't want users to have access to these files. So, i decided to encrypt archive with password.
My first thought was to store a password inside a program via preprocessor macro (through CMake). But, is it safe?
Can you access the password back from compiled application? (exe, in my case)
And if you can, how to protect from it? Is it technically possible or i should give up and leave it as is?
If the macro is actually used in the application then yes, it's accessible in the executable file -- it has to be for the program to use it.
Any credential you embed in your program can be recovered by a sufficiently-motivated attacker. There is no encryption mechanism you can use to prevent this, as you would need to provide the decryption key for the program to function.
The proof is very simple: if the program itself can obtain the credential without any user input, then the executable file must contain the key, or all of the information needed to produce/derive the key. Therefore, it must be possible for anyone (with the requisite expertise) to produce the credential with only the information in the executable file.
This could be done by inspecting the executable. It could also be done by running the executable under the supervision of a debugger and watching what it is doing.
This is the same reason DRM schemes are pointless -- the consumer must be in possession of a key to use the material, and if they can get their hands on the key (they must be able to in order for them to consume the content) then they scheme doesn't work. (Of course, in newer DRM schemes the key is buried in a chip that is designed to destroy the key if it is opened, but that just means it's difficult to get the key, not impossible.)
tl;dr: It's never a question of whether it's possible to recover an embedded key. It's always possible. It's a question of how much effort it will take to recover that key.
Related
I am writing a C++ program for Linux which creates some files on the disk during the work. These files contain information about program's internal objects state, so that the next time the program is started it reads these files to resume previous session. Some of these files are also being read/written to during the execution to read/write some variables values. The problem is that modifying/renaming/deleting these files would lead in undefined behavior, segmentation faults and other surprises causing the program to crash. I am certainly not going to restrict the user in accessing files on his/her machine, but inside the program I can always check if a file has been modified before accessing it to at least prevent the program from crash. It would involve many extra checks and make the code larger though.
The question is what is a good practice to deal with such issues? Should I even be so paranoid, or just expect the user to be smart enough to not mess with program's files?
First, check your resources and if it is worth the effort. Will the user be even tempted to trace and edit these files?
If so, my advice is this: Don't be concerned whether or not the file has been modified. Rather you should validate the input you get (from the file).
This may not be the most satisfying answer, but error handling is a big part of programming, especially when it comes to input validation.
Let assume you are writing into a ~/.config/yourApp/state.conf.
Prepare defaults.
Does the file exist? If not use defaults.
Use some well known structure like INI, JSON, YAML, TOML, you name it, that the user can understand and the application can check for integrity (libraries may help here). If the file is broken use defaults.
In case the user does delete a single entry, use the default value.
Some values deserve special checking in case a out of bound access would lead to undefined behavior. If the values is out of bounds, use a default.
Ignore unknown fields.
In case you can't recover from a malformed input, provide a meaningful error message, so the user may be able to restore a save state (restore from a backup or start over from the beginning).
If using files are really important to your codebase then you can simply hide those files by adding dot "." before them. This way the user will not be able to know the files are there unless checked specifically.
If you want to access those files from anywhere in the system you can also store these files in some temp hidden folder which can be accessed easily.
eg: ~/.temp_proj/<file>
This way the folder will be hidden from the user and you can use it for your own program.
I have a C++ DLL, foo.dll, that provides API methods that give cleartext answers to encrypted data. I want to come up with a robust solution to only allow friendlies (eg. user.dll) to load this DLL and use its functions.
This is not a problem of DLL spoofing, but rather a question of how to hobble a DLL to only work in certain contexts. I'm in a potentially non-networked context on multiple platforms, so phoning home or relying on a system call is not a likely solution.
Something I've considered is a home brewed initialization step sharing a 'magic key' for initialization. With security, 'roll your own' is often bad.
Any advice of accepted practices for this kind of DLL level security?
The only way to protect encrypted data is by ensuring that it requires a very long, unpredictable and secret key to decrypt it. The security comes not from obscuring the method of decryption, but the key itself.
You cannot prevent someone from calling into your DLL but the functions in the DLL can require that the caller provide a decryption key as a parameter.
This way, only clients that know the secret key will be able to decrypt the contents.
You can try to cheat by embedding the decryption key somewhere in your DLL, but it can then be found simply by loading the DLL into a debugger. So don't do that.
It's well known that dlls produced by .NET can be easily decompiled. This means that sensitive information (e.g. encryption keys) should not be stored in .NET binaries.
Would it be a sensible alternative to store sensitive data in (for example) C++ binaries which could be consumed by my .NET code? I don't yet know anything about interop stuff, but am curious about whether this could be an avenue worth pursuing. I guess to clarify, my questions are:
Could a binary produced in C++ (or C) be readily decompiled to access sensitive string data?
Is this a totally harebrained idea, either because it wouldn't work, would be very difficult to accomplish, or because a far better alternative exists which I haven't encountered yet?
The answer is no. Whilst its true a .NET dll can be trivially decompiled to its original structure, and a C/C++ dll can only be decompiled to a monster mess that a compiler would love, the data that's stored in there will be placed in a big, un-mangled, bucket so anyone who knew which part to look at (and, ok, all that data is crammed up close to each other so it becomes difficult to know which bit is which) but the data will be there for all to see.
Google for data segment which is where the static data in a native windows binary gets placed.
quick edit: of course, you can store encrypted information in your C++ binary, pre-encrypt it but you will have to use something else to store the decrypt key (eg your windows user password or similar). .NET allows you to store sensitive information in a config file and will easily encrypt it on first-run or install, this encrypts and decrypts it based on the user account details the app runs under (so don't change it, and keep a copy of the un-encrypted config file somewhere :-) )
String literals can be read from native(c c++ code compiled) binary (exe or dll)
There's always a way to sniff out the sensitive information in your binary file. The differences between .NET binaries and native binaries are the complexity of their reverse analysis (the root cause is NET code is run on process virtual machine (VM), so the protection mechanisms of .NET barely do some tricks beyond the VM). As you mentioned, .NET binaries can be easily decompiled, even you obfuscated your binary file by some obfuscator, such deobfuscators like de4dot can deobfuscate it easily. But the reverse analysis of native binaries is more difficult than the former. There are plenty more effective protection mechanisms in this field, such as anti-debugging, the virtual machine obfuscation and so on. These techniques could make your code more secure, of course this is a relative thing.
The answer is YES. Sensitive data can be stored in C++ compiled binaries. People who don't know anything about security do it all the time.
There are various degrees of security with different costs and inconveniences to users. Storing keys in code is fairly common but not very secure. Since you are using .NET that implies Windows and you might want to look into the data protection API (DPAPI). It encrypts data using your Windows user id password as the key.
Many laptops and servers includes a Trusted Platform Module (TPM) chip which will do encryption for you and protect the key for you.
I created an unmanaged C++ DLL that I'd like to provide to a 3rd-party. The DLL will be distributed publically but I don't want anyone else to be able to call methods in the DLL. What's a good way to restrict access?
FWIW - the DLL will be used on both Mac and Windows.
Ultimately, you can't stop somebody who's determined, but you can do a few things to make life difficult for unauthorized users.
The obvious would be to encrypt (at least most of) the code in the DLL. Have a single entry point that the user has to call to get (for example) a table of pointers to the real functions. When the entry point is called, a key has to be supplied and that is used to decrypt the rest of the content, and then the pointers are returned. If the user supplies the wrong key, they get pointers, but the data won't be decrypted correctly, so when they try to call it, it doesn't work.
That's not foolproof by any means. Just for an obvious example, if somebody runs the authorized program under a debugger they can see what key is passed, and simply re-use it. If you want to make life a bit trickier for an attacker, you can do something like having the DLL do a checksum on the executable, and use that as the key (and the user will have to embed some data to get the checksum to come out right). That can still be figured out, but it will at least take some work.
Edit: The exact encryption doesn't matter a lot. I'd probably use AES, simply because it's easy to find an implementation and it runs pretty fast, so there's not much reason to use something else.
As far as how the calling code would work, it would be something like this:
struct functions {
rettype1 (*func1)(args1);
rettype2 (*func2)(args2);
rettype3 (*func3)(args3);
// ...
};
void entry_point(key_type key) {
functions f;
decrypt(data_block);
f.func1 = data_block.offset1;
f.func2 = data_block.offset2;
// ...
return f;
}
In the calling code you'd have initialization something like:
functions f = entry_point(myKey);
and then calling a function would be something like:
f.whatever(arg1, arg2, arg3);
In essence, you're re-creating a small piece of object oriented programming, and having your entry point return an "object" of sorts, with the DLL's real functions as "member functions" of that "object".
As far as getting the checksum goes, I haven't thought through it in a lot of detail. Basically just just want the address where the executable is stored. You can walk through modules with VirtualQuery, or you can use GetModuleHandle(NULL).
Anyone with access to the dll will be able to inspect it, load it, and get pointers to functions in the dll. I'm not sure you strictly mean dll though as you say:
FWIW - the DLL will be used on both Mac and Windows.
Dlls aren't a Mac thing--they are a Windows specific implementation of a runtime loaded/linked library. So you're real question, I'm assuming, must simply be about limiting access to a library for only certain 3rd parties. To achieve your goal, some other options may be more appropriate:
Instead of a dll, compile everything into a single monolothic exe. Run that exe as a service or a second process on the box. Have the 3rd party connect to it through sockets/named pipes/whatever other forms of interprocess communication. Authenticate the users of the service so that only the 3rd party software with the right credentials can access the service. Everyone else gets denied access.
Create an account for the 3rd party application. The 3rd party application can only run when that account is logged in. Place the dll (or dylib in the case of Mac) in a folder only accessible to that account. Noone else has access to that location, so no other applications can run it barring those run as administrator.
Is there anyway for a program to know if it has been modified since it was compiled and built?
I'd like to prevent the .exe from being modified after I build it.
You could use a private key to sign the EXE, and public key to check that signature. I haven't worked with the EXE file format in nearly 20 years, but as I recall there are spaces where you could store such a signature. Of course, the portion of the file that you're checking would have to exclude the signature itself.
However, if you're trying to do this to prevent cracking your EXE, you're out of luck: the cracker will simply patch out the code that validates the signature.
even if you know.. the person who knows you had such a prevent, will change computer time to your build time than modify this exe..
so it can not be a prevention..
Is it possible for a program to know if it has been modified since it was built?
Yes. A checksum of the rest of the program can be stored in an isolated resource string.
Is it possible for a program to know if it was maliciously modified since it was built?
No. The checksum, or even the function that executes and compares it, could be modified as well.
Are you talking about Tamper Aware and Self Healing Code?
The article demonstrates detecting
hardware faults or unauthorized
patches; back patching the executable
to embed the expected hash value of
the .text section; and demonstrates
the process of repairing the effects
of hostile code (for example, an
unauthorized binary patcher). The
ideas presented in the article work
equally well whether the executable
was patched on disk or in-memory.
However, the self repair occurs in
memory.
Most popular compilers have a switch to fill in the "Checksum" field of the PE header, or, you can leave it blank and supply your own custom vale. At any rate this is the 'standard' place to store such data.
Unfortunately there's no real way to stop someone tampering with a binary, because you'll have to put checks inside the exe itself to detect it, at which point they can be patched out.
One solution to this problem is to encrypt certain functions and use the checksum of some known data as the key (for example the checksum of another function). Then, when you leave the function you reencrypt it. Obviously you'll need to come up with your own prologue/epilogue code to handle this. This is not really suitable if your program is heavily multi-threaded, but if you're single-threaded or only lightly threaded (and can serizalize access to the functions and control all entry points) then this will 'raise the bar' if you will.
That is a step above most 'packers' which simply encrypt the .text/.data/.rdata/etc sections and decrypt it all at runtime. These are very easy to 'dump', as all you have to do is run the program, suspend all its threads, then dump the memory to a file. This attack works against Themida for example (one of the most aggressive packers). From there all you need to do is rebuild the IAT, fix up some relocs, etc.
Of course it's still possible for the attacker to use a debugger to dump out the unencrypted code and hence 'unpack' the exe, but obviously nothing is foolproof.