views:

474

answers:

8

Hi,

I need to write a small program that can detect that it has been changed. Please give me a suggestion!

Thank you.

+8  A: 

The short answer is to create a hash or key of the program and have the program encrypt and store that key within itself. From time to time the program would make a checksum of itself and compare it against that hash/key. If there is a difference then handle it accordingly.

There are lots and lots of ways to go about this. There are lots of very smart engineers out there that know how to work around it if that is what you are trying to avoid.

Nick Gerakines
That all goes away if someone just completely replaces 'foo' with 'badfoo' :)
Tim Post
There are ways of obscuring the validation hash/key but then it becomes a balance of functionality vs effort.
Nick Gerakines
Yeah, but if path/to/foo is over-written by /path/to/badfoo (i.e. by a rootkit) but is still named 'foo' .. In other words, the executable is replaced.
Tim Post
I'm under the impression that the questioner is talking about binary changes to the executable or process memory as a means of circumventing an authentication or licensing process.
Nick Gerakines
Uhh, if an executable hashes itself and then stores the hash in itself, then surely the next check will be false because the executable had changed itself! I find this challenge somewhat similar to the "write a program that prints itself" problem.
wilhelmtell
Well, if you know the length, size and attributes of the hash, you can account for them when signing the application. This isn't a new concept.
Nick Gerakines
I'm not following you. Can you please post a sample code of an executable that checks itself for whether it has changed?
wilhelmtell
Not without violating an NDA.
Nick Gerakines
If the executable is overwritten, killed and restarted this whole conversation becomes pointless. If not killed but modified while running in memory this can help but anything having privileges to do that would likely sooner just re-write and re-start it.
Tim Post
NDA for what? This is interesting...
Dalin Seivewright
Moreover, how expensive is it to check this hash before every call?? Nick, this sound interesting but brutal, or the seventh layer of mmap hell. Furthermore, how do you make this agreeable and portable across various linkers? Ah well, maybe in XX years when the NDA expires. Really, very interesting!
Tim Post
+3  A: 

Do you mean that program 'foo' should be able to tell if some part of it was modified prior to / during run time? That's not the responsibility of the program, its the responsibility of the security hooks in the target OS.

For instance, if the installed and trusted 'foo' has signature "xyz1234" , the kernel should refuse to run a modified (or completely new) 'foo'. The same goes for 'foo' while its currently running in memory. Look up 'Trusted Path Of Execution', aka TPE to start.

A better question to ask would be how to sign your released version of 'foo', which depends upon your target platform.

Tim Post
A: 

try searching for "code signing"

Chris Nava
A: 

The easiest way would be for the program to detect its own md5 and store that in a separate file, but this isn't totally secure. An MD5 + CRC might work slightly better.

Or as others here have suggested, a sha1, sha2 or sha3 which are much more secure than md5 currently.

Max
SHA1 sums are much more secure than MD5.
Ben Alpert
Second'ed on SHA1 instead of MD5.
Jeff Hubbard
A: 

I'd ask an external tool to do the check. This problem reminds me of the challenge to write a program that prints itself. In Bash you could do something like this:

#!/bin/bash
cat $0

which really asks for an external tool to do the job. It's kind of solving the problem by getting away from solving the problem...

wilhelmtell
+4  A: 

The simplest way would be to use a hash function to generate a short code which is a digest of the whole program and then check this.

It would be fairly easy to debug the code and replace the hash value to subvert this.


A better way would be to generate a digital signature using your private key and with the public key in the program to check it.

This would then require changing the public key and the hash as well as understanding the program, or changing the program code itself to subvert the check.


All you can do in the case described so far is make it more difficult to subvert but it will be possible with a certain amount of effort. I'd suggest looking into cryptographic techniques and copy protection for more information to suit your specific case.

pro
A: 

The best option is going to be code signing -- either using a tool supplied by your local friendly OS (For example, If you're targeting Windows, you probably want to take a look at Authenticode where the Operating System handles the tampering), or by rolling your own option storing MD5 hashes and comparing

It is important to remember that bets are off if someone injects a thread into your process (to potentially kill your ongoing checks, etc.), or if they tamper with your compiled application to bypass said checks.

Rowland Shaw
A: 

An alternative way which wasn't mentioned is to use a binary packer such as UPX.
If the binary gets changed on the disk then the unpacking code is likely to fail.
This however doesn't protect you if someone changes the binary while it is in memory.

shoosh