tags:

views:

425

answers:

8

I have a (planned) commercial program that is writing out a usage log. As part of their license, users will be required to submit the log back to the company every few weeks. How can I ensure the file has not been tampered with?

System is being written in C# and Winforms or WPF.

Update: Hmmm... quite surprised that How to make a file tamper proof? is considered an "exact duplicate" of What technique can protect a secret from a fully trusted user? Anyway, the tribe has spoken.

+2  A: 

You could put the file in a directory that the users do not have permission to view. Of course, if the user has full, unrestricted access, there is nothing you can do. Nothing. There will always be a way for them to get at the file (even if it's obtuse and awkward).

You could encrypt it but they could open it in a text editor and make a mess of it (even if they don't know what the contents are, adding a single character would ruin the file).

FrustratedWithFormsDesigner
And how are they going to submit the log back? ;)
Lucero
But the administrator will have access to it. This is his problem...
Earlz
@Lucero: Well, he could have some process run with elevated privileges and do the submission on the user's behalf. Or the sysadmin can do it manually.
FrustratedWithFormsDesigner
Local access = root access. As said before, if someone is determined enough he can attach the kernel debugger and go snooping everywhere in the VM of every process. Even not going that far, every administrator has the SE_DEBUG_NAME privilege, so, given enough knowledge, he can debug your application even if it's in an elevated process. Since you're running in an untrustworthy environment (attacker with root access) you *can't* build a perfect protection mechanism. As said before, just make it "secure enough" and don't waste too time on it.
Matteo Italia
+2  A: 

Use some cryptology - e.g. sign the log file.

It may be sufficient to append a MD5 hash generated from the file contents and some "secret" only known to your application (note that this could be circumvented easily by reverse-engineering the application). Of course, there are more secure approaches involving certificates or other stuff, this all depends on your security requirement.

Lucero
That can't prevent tampering if the user has full access to the computer where the log file is being created.
Daniel Pryden
@Daniel is correct. To sign the log requires a private key, which you would have to store somehow with the application, and thus the user can hack the app, gain the private key, tamper with the file, then resign the tampered file with the stolen key.
AaronLS
+1, but there's still the problem that the signing key would have to stay in the executable (or, anyhow, in the executable there would be the code to obtain and use that key), so a malicious user could disassemble the exe to look for it. Obfuscating the executable would make the search much more difficult, but if your app doesn't use cryptography elsewhere a simple search for System.Security.Cryptography would lead an attacker to the signing code. Moral of the history: if someone is determined enough, he will break it; just make it "secure enough" to deter a casual attacker. EDIT Too late...:P
Matteo Italia
True, but that is a fundamental problem. While you cannot get a 100% secure solution here, one can get pretty good security, for instance by installing a certificate issued by your own CA with a non-exportable private key in the machine or user certificate store during installation, and using this to sign or encrypt the log.
Lucero
+4  A: 

You can have the application produce a digital signature for the file, but this means the application must contain the private key somehow, and thus the user could potentially hack the application such that they can circumvent this system.

The fact is the user has full control over their system, and you can't prevent them from doing particular things on their system. I would suggest you invest more effort into adding useful features to your software that increases the level of appreciation for your software, such that users are less likely to pirate the software.

AaronLS
+4  A: 

The only way I see still is making the application contact a remote server. Encrypting a file will be pointless because the attacker has the program to create the encrypted file.

So why not make the application contact a remote server for every time it needs to log something? (and if the server can't be contacted, the application bail out). The program can also use some basic key verification also because well...

Say the program tells the server "I'm doing stuff" and the server sends back "Ok" with a signed PGP for verification. In this case, the private key would be secure and kept on the server and the public key would be on the client and ensure that the server isn't being spoofed by the client's network.

I assume you are trying to log usage of your program or something like that.

Earlz
This would probably be more difficult to crack than the other suggestions, but it can still be cracked by disabling the code that performs the verification against the server.
AaronLS
Of course so, even more so with it being compiled to IL, but still.. idk.. maybe if it actually relied on the result from the server to direct it's next action.... Here though we are getting into the realm of impossible to prevent attacks..
Earlz
Yeh, LOL even the big boys like Adobe have yet to make an uncrackable licensing system.
AaronLS
PDF "licensing" does not count as an attempt at encryption. They set one single bit in the file telling PDF readers "Whatever you do, don't show this plain text to the user. Prompt them for the password firsT"
Earlz
Assuming it connects to example.com on port 666, something like the following will fix the verifier (uses custom cmds, but you get the idea): `dnsbind example.com 127.0.0.1` `background { yes "Ok" | serve 666 }`
David X
Yea, but not if you combine public and private keys where the private key is on the server and verified by the client with the public key. (along with a timestamp with the "OK" so that you can't just get the message and resend it a lot)
Earlz
Then I open the program in a hex editor and overwrite the offending public key with one I know the private key for, and use that to sign the "Ok"s. If it needs to talk to the server I can resign the data with the old key and forward it.
David X
hmm... Well played. lol.
Earlz
@earlz, thanks, I can keep this up all day.
David X
+8  A: 

Isn't this just another case of the DRM problem, i.e., you're giving users a key and a lock and trying to make sure they don't use it in a way you don't want?

Even if you could guarantee the log file hasn't been touched, how are you going to guarantee the binary that generated it hasn't been touched? There's no end to this. If your code is running on a computer entirely under their control, you're SOL.

(The good news is that you probably don't care. Just put it in the contract. Small users won't want to put up with submitting a log file. Big businesses won't want to run afoul of a contract because there's a lot of money at stake.)

Ken
+2  A: 

Any chance you can send the data online, and not store it in a file first? That would keep the data off the users' system, and require them to hack a running program if they're going to hack anything.

John Saunders
I like this idea. It would take a bit more infrastructure but would definitely work (Very few people would be dedicated enough to hack the running code).
ChaosPandion
A: 

As Ken mentioned, this is the same problem that DRM systems have. They use a variety of techniques to store keys where users won't (easily) be able to find them. You'd be combining a digital signature scheme with an overly-complex scheme for storing the key. Split it into multiple pieces, scattered over the user's system - some parts in the registry, some in files on the filesystem, some encoded in the modification dates and filenames of various innocent-looking files. Also, make the DRM subsystem of your code intentionally obscure, and difficult to debug.

Another alternative would be to send signature data to some remote system periodically (if you can depend on having an internet connection).

Mark Bessey
+2  A: 

Slightly related, but look at my question Generating a Tamper Proof Signature of some data?

The consensus seems to be that you need an external source to generate a signature/secure timestamp that you can use to sign your data, and that you are mostly out of luck if the application is completely internal as the customer can just reverse engineer any checksum mechanism.

Of course, maybe an approach where you encrypt the data before writing to disk is "good enough" - depending on your customers and the importance of getting untampered logs.

Michael Stum