What is the best way to generate a unique hardware ID on Microsoft Windows with C++ that is not easily spoofable (with for example changing the MAC Address)?
Windows stores a unique Guid per machine in the registry at:
HKEY_LOCAL_MACHINE\Software\Microsoft\Cryptography\MachineGuid
This used to be the CPU serial number but today there are many types of motherboards and this factor is not accurate. MAC address can be easily forged. That leaves us with the internal hard drive serial number. See also: http://www.codeproject.com/Articles/319181/Haephrati-Searching-for-a-reliable-Hardware-ID
There are a variety of "tricks", but the only real "physical answer" is "no, there is no solution".
A "machine" is nothing more than a passive bus with some hardware around.
Although each piece of iron can provide a somehow usable identifier, every piece of iron can be replaced by a user for whatever bad or good reason you can never be fully aware of (so if you base your functionality on this, you create problems to your user, and hence -as a consequence- to yourself every time an hardware have to be replaced / reinitialized / reconfigured etc. etc.).
Now, if your problem is identify a machine in a context where many machines have to inter-operate together, this is a role well played by MAC or IP addresses or Hostnames. But be prepared to the idea that they are not necessarily constant on long time-period (so avoid to hard-code them - instead "discover then" upon any of your start-up)
If your problem is -instead- identify a software instance or a licence, you have probably better to concentrate on another kind of solution: you sell licences to "users" (it is the user that has the money, not his computer!), not to their "machines" (that users must be free to change whenever they need/like without your permission, since you din't licence the hardware or the OS...), hence your problem is not to identify a machine, but a USER (consider that a same machine can be a host for many user and that a same user can work on a variety of machines ..., you cannot assume/impose a 1:1 relation, without running into some kind of problems sooner or later, when this idiom ifs found to no more fit).
The idea should be to register the users in a somewhat reachable site, give them keys you generate, and check that a same user/key pair is not con-temporarily used more than an agreed number of times under a given time period. When violations exceed, or keys becomes old, just block and wait for the user to renew.
As you can see, the answer mostly depends on the reason behind your question, more than from the question itself.
There are various IDs assigned to hardware that can be read and combined to form a machine key. For example, you could get the ID of the hard drive where the software is stored, the proc ID, etc. Some of these can be set more easily than others, but part of the strength is in combining multiple pieces together that are not necessarily strong enough by themselves.
Here is a program (also available as DLL) that can read and show your computer/hardware ID: http://www.soft.tahionic.com/download-hdd_id/index.html
Use Win32 System HDS APIs.
Don't read the registry, it has no sense at all.
Related
I have a dilemma. I do not know what is the best approach to the following scenario and then if it makes sense to invest time on developing a kernel module.
I have hardware (FPGA) that is exposed like many modules (around 30). Each module can be defined like:
Base address of the module;
Fields' offset (from base address);
The maximum number of fields per modules is around 10;
Each field has its own type like uint32_t, float32_t, uint32_t[] etc;
Some fields are read/write only and other read only;
Usually a module is ready as is. I mean that it is not necessary to implement any logic to check if it is possible to write to a field (except in few cases).
On the target device there is a custom Linux distribution (built from Yocto).
What do you think is better?
Application in user space that uses mmap (/dev/mem to map all
modules) and then reads/writes directly from/to memory. I have a C++
implementation and it is working but maybe it is not the best
solution... I need to set manually all offsets, using many
reinterpret_cast<> to read data properly and if something it is
wrong the application crashes;
Implement a character device
driver to expose each module like /dev/module1, /dev/module2 etc?
and use in user space open/write/read/release/ioctl. I have just
started to read a huge manual about Linux kernel development and I
am not so sure if a character device is a good idea here, especially
how to expose so many modules with so many fields to user space;
Other.
Thank you a lot for any ideas.
Using /dev/mem is quite straightforward, however it also causes some serious security issues. You either have to run your application as root or make the /dev/mem file accessible for other users, which are both unwelcome in designs that at some point will become products. If a malicious process can access the /dev/mem file it can possibly access any secret stored in RAM or corrupt any application - including the kernel itself. Even if your application is the only one able to access this file, any security concern of your code becomes the security concern of the whole system.
Preparing the driver is obviously not an easy task, but allows you to separate the (usually simple) privileged code from the applications in user space. In a simplest case you only have to provide some register read and write methods (through ioctl). These should check if the address is well aligned and constrained to the device address space. Additionally, the driver usually performs any additional address translation - so the client application does not need to know under which physical address was your device mapped (which is the case e.g. with PCI Express).
I would not recommend writing the driver from scratch, but to repurpose some existent code. In the mentioned case of PCI Express I have used two sources of inspiration - the Xilinx driver described here: https://www.xilinx.com/support/answers/65444.html (sources included) and more complicated 'pcieuni' and 'gpcieuni' from ChimeraTk project (https://github.com/ChimeraTK).
I want to make a program for some people, so i make the program again for each person, and if someone gives the program to other guy, he can't use it.
How can I do that?
Without any internet connection.
Does any PC has some unique id or something like that, that i can make him a program to get it, so he will send me, and in my program i'll check if is the same, if not the program will stop.
Something like hwid will work?
Is the hardware id unique and cannot be changed?
If so, how can I get it? I found a lot of questions, but without any good answers..
Take a look at these:
Uniquely identify PC based on software/hardware
C++ API : license management to protect a software
Generating a Hardware-ID on Windows
Restrict functionality to a certain computer
How to get unique hardware/software signature from a windows pc in c/c++
If you want something a bit harder to spoof than whatever the machine itself can tell you, you'll probably need a USB dongle dedicated for this purpose.
There are several ways to identify a computer from where a program runs:
WMI - Windows provides a set of classes that can be used for most hardware enumeration and identification tasks, which is named WMI or Windows Management Instrumentation. These are extensions to the Windows Driver Model (WDM).
CPU ID - The solution that seems to be the best choice is to sample the CPU unique identification number (or CPU ID). However, there are several problems that makes it impossible to rely on reading the CPU ID.
To begin with, most CPUs with the exception of the old Pentium III, don't have a unique CPU Serial Number. Intel has removed this feature for privacy reasons.
It is still possible to generate a unique ID from the motherboard as a whole. That certainly works but the huge number of different types of motherboards and manufacturers makes it next to impossible to generate a unique ID that will cover all of them.
MAC address based hardware ID
The next choice for obtaining such a unique ID would be sampling the MAC address. To begin with, what is the "MAC address"? It stands for Media Access Control. The MAC address is 48 bits long (6 bytes). The GetMACAddress code sample explains how to obtain the MAC address.
However, there is one problem with this approach: the MAC address can be easily changed into a new one...
Hard Drive serial number
It seems that the only reliable solution for obtaining a machine ID would be using the serial number of the main Hard Drive. The second example, GetHDSerialNumber, shows how to obtain this ID. From my experience, this approach is the best one and the most reliable for generating a unique machine based hardware ID.
See also this article.
Like others have said, it is really hard to do this reliably.
You CAN use things like hardware dongles or licensing software to try to restrict use. For anyone sufficiently motivated this is a speed bump, not much more.
Another aspect of this is that the more secure you try to make it, the higher the risk that it'll be too restrictive. That is, it might end up accidentally blocking legitimate use, which is a really bad thing to do if you want to keep users happy.
This was tried many, many times when the PCs became popular. Each time a dismal failure. It even interferes with rights the law grants the user (keep backup copies). It also turned out that the hassle for the user was enough for many of them to just don't use the "copy protected" programs.
Today this is done successfully by the various gaming consoles, but there the provider of the console has a very tight control over the machine and the software. By force, those can't be used as regular computing platforms by the user, they are single-purpose. No wide range of software available.
The only ones to pull of this feat on regular machines have been expensive programs like Mathlab or Autocad, mostly through some sort of "license server" under tight control of the network administrator, tied to the specific server on which it runs by some long-winded procedure. And even so, it isn't too hard to get pirated ("unlocked") copies.
I'm working on a C++ application which is keeping some user secret keys in the RAM. This secret keys are highly sensitive & I must minimize risk of any kind of attack against them.
I'm using a character array to store these keys, I've read some contents about storing variables in CPU registers or even CPU cache (i.e using C++ register keyword), but seems there is not a guaranteed way to force application to store some of it's variables outside of RAM (I mean in CPU registers or cache).
Can anybody suggest a good way to do this or suggest any other solution to keep these keys securely in the RAM (I'm seeking for an OS-independent solution)?
Your intentions may be noble, but they are also misguided. The short answer is that there's really no way to do what you want on a general purpose system (i.e. commodity processors/motherboard and general-purpose O/S). Even if you could, somehow, force things to be stored on the CPU only, it still would not really help. It would just be a small nuisance.
More generally to the issue of protecting memory, there are O/S specific solutions to indicate that blocks memory should not be written out to the pagefile such as the VirtualLock function on Windows. Those are worth using if you are doing crypto and holding sensitive data in that memory.
One last thing: I will point out that it worries me is that you have a fundamental misunderstanding of the register keyword and its security implications; remember it's a hint and it won't - indeed, it cannot - force anything to actually be stored in a register or anywhere else.
Now, that, by itself, isn't a big deal, but it is a concern here because it indicates that you do not really have a good grasp on security engineering or risk analysis, which is a big problem if you are designing or implementing a real-world cryptographic solution. Frankly, your posts suggests (to me, at least) that you aren't quite ready to architect or implement such a system.
You can't eliminate the risk, but you can mitigate it.
Create a single area of static memory that will be the only place that you ever store cleartext keys. And create a single buffer of random data that you will use to xor any keys that are not stored in this one static buffer.
Whenever you read a key into memory, from a keyfile or something, you only read it directly into this one static buffer, xor with your random data and copy it out wherever you need it, and immediately clear the buffer with zeroes.
You can compare any two key by just comparing their masked versions. You can even compare hashes of masked keys.
If you need to operate on the cleartext key - e.g. to generate a hash or validate they key somehow load the masked xor'ed key into this one static buffer, xor it back to cleartext and use it. Then write zeroes back into that buffer.
The operation of unmasking, operating and remasking should be quick. Don't leave the buffer sitting around unmasked for a long time.
If someone were to try a cold-boot attack, pulling the plug on the hardware, and inspecting the memory chips there would be only one buffer that could possibly hold a cleartext key, and odds are during that particular instant of the coldboot attack the buffer would be empty.
When operating on the key, you could even unmask just one word of the key at a time just before you need it to validate the key such that a complete key is never stored in that buffer.
#update: I just wanted to address some criticisms in the comments below:
The phrase "security through obscurity" is commonly misunderstood. In the formal analysis of security algorithms "obscurity" or methods of hiding data that are not crytpographically secure do not increase the formal security of a cryptographic algorithm. And it is true in this case. Given that keys are stored on the users machine, and must be used by that program on that machine there is nothing that can be done to make the keys on this machine cryptographically secure. No matter what process you use to hide or lock the data at some point the program must use it, and a determined hacker can put breakpoints in the code and watch when the program uses the data. But no suggestion in this thread can eliminate that risk.
Some people have suggested that the OP find a way to use special hardware with locked memory chips or some operating system method of locking a chip. This is cryptographically no more secure. Ultimately if you have physical access to the machine a determined enough hacker could use a logic analyzer on the memory bus and recover any data. Besides the OP has stated that the target systems don't have such specialized hardware.
But this doesn't mean that there aren't things you can do to mitigate risk. Take the simplest of access keys- the password. If you have physical access to a machine you can put in a key logger, or get memory dumps of running programs etc. So formally the password is no more secure than if it was written in plaintext on a sticky note glued to the keyboard. Yet everyone knows keeping a password on a sticky note is a bad idea, and that is is bad practice for programs to echo back passwords to the user in plaintext. Because of course practically speaking this dramatically lowers the bar for an attacker. Yet formally a sticky note with a password is no less secure.
The suggestion I make above has real security advantages. None of the details matter except the 'xor' masking of the security keys. And there are ways of making this process a little better. Xor'ing the keys will limit the number of places that the programmer must consider as attack vectors. Once the keys are xord, you can have different keys all over your program, you can copy them, write them to a file, send them over the network etc. None of these things will compromise your program unless the attacker has the xor buffer. So there is a SINGLE BUFFER that you have to worry about. You can then relax about every other buffer in the system. ( and you can mlock or VirtualLock that one buffer )
Once you clear out that xor buffer, you permanently and securely eliminate any possibility that an attacker can recover any keys from a memory dump of your program. You are limiting your exposure both in terms of the number of places and the times that keys can be recovered. And you are putting in place a system that allows you to work with keys easily without worrying during every operation on an object that contains keys about possible easy ways the keys can be recovered.
So you can imagine for example a system where keys refcount the xor buffer, and when all key are no longer needed, you zero and delete the xor buffer and all keys become invalidated and inaccessible without you having to track them down and worry about if a memory page got swapped out and still holds plaintext keys.
You also don't have to literally keep around a buffer of random data. You could for example use a cryptographically secure random number generator, and use a single random seed to generate the xor buffer as needed. The only way an attacker can recover the keys is with access to the single generator seed.
You could also allocate the plaintext buffer on the stack as needed, and zero it out when done such that it is extremely unlikely that the stack ever leaves on chip cache. If the complete key is never decoded, but decoded one word at a time as needed even access to the stack buffer won't reveal the key.
There is no platform-independent solution. All the threats you're addressing are platform specific and thus so are the solutions. There is no law that requires every CPU to have registers. There is no law that requires CPUs to have caches. The ability for another program to access your program's RAM, in fact the existence of other programs at all, are platform details.
You can create some functions like "allocate secure memory" (that by default calls malloc) and "free secure memory" (that by default calls memset and then free) and then use those. You may need to do other things (like lock the memory to prevent your keys from winding up in swap) on platforms where other things are needed.
Aside from the very good comments above, you have to consider that even IF you succeed in getting the key to be stored in registers, that register content will most likely get stored in memory when an interrupt comes in, and/or when another task gets to run on the machine. And of course, someone with physical access to the machine can run a debugger and inspect the registers. Debugger may be an "in circuit emulator" if the the key is important enough that someone will spent a few thousand dollars on such a device - which means no software on the target system at all.
The other question is of course how much this matters. Where are the keys originating from? Is someone typing them in? If not, and are stored somewhere else (in the code, on a server, etc), then they will get stored in the memory at some point, even if you succeed in keeping them out of the memory when you actually use the keys. If someone is typing them in, isn't the security risk that someone in one way or another, forces the person(s) knowing the keys to reveal the keys?
As others have said, there is no secure way to do this on a general purpose computer. The alternative is to use a Hardware Security Module (HSM).
These provide:
greater physical protection for the keys than normal PCs/servers (protecting against direct access to RAM);
greater logical protection as they are not general purpose - no other software is running on the machine so no other processes/users have access to the RAM.
You can use the HSM's API to perform the cryptographic operations you need (assuming they are somewhat standard) without ever exposing the unencrypted key outside of the HSM.
If your platform supports POSIX, you would want to use mlock to prevent your data from being paged to the swap area. If you're writing code for Windows, you can use VirtualLock instead.
Keep in mind that there's no absolute way to protect the sensitive data from getting leaked, if you require the data to be in its unencrypted form at any point in time in the RAM (we're talking about plain ol' RAM here, nothing fancy like TrustZone). All you can do (and hope for) is to minimize the amount of time that the data remains unencrypted so that the adversary will have lesser time to act upon it.
If yours is an user mode application and the memory you are trying to protect is from other user mode processes try CryptProtectMemory api (not for persistant data).
As the other answers mentioned, you may implement a software solution but if your program runs on a general purpose machine and OS and the attacker has access to your machine it will not protect your sensitive data. If you data is really very sensitive and an attacker can physically access the machine a general software solution won't be enough.
I once saw some platforms dealing with very sensible data which had some sensors to detect when someone was accessing the machine physically, and which would actively delete the data when that was the case.
You already mentioned cold boot attack, the problem is that the data in RAM can be accessed until minutes after shut down on general RAM.
I've never had formal training in this area so I'm wondering what do they teach in school (if they do).
Say you have two programs in written in two different languages: C++ and Python or some other combination and you want to share a constantly updated variable on the same machine, what would you use and why? The information need not be secured but must be isochronous should be reliable.
Eg. Program A will get a value from a hardware device and update variable X every 0.1ms, I'd like to be able to access this X from Program B as often as possible and obtain the latest values. Program A and B are written and compiled in two different (robust) languages. How do I access X from program B? Assume I have the source code from A and B and I do not want to completely rewrite or port either of them.
The method's I've seen used thus far include:
File Buffer - Read and write to a
single file (eg C:\temp.txt).
Create a wrapper - From A to B or B
to A.
Memory Buffer - Designate a specific
memory address (mutex?).
UDP packets via sockets - Haven't
tried it yet but looks good.
Firewall?
Sorry for just throwing this out there, I don't know what the name of this technique is so I have trouble searching.
Well you can write XML and use some basic message queuing (like rabbitMQ) to pass messages around
Don't know if this will be helpful, but I'm also a student, and this is what I think you mean.
I've used marshalling to get a java class and import it into a C# program.
With marshalling you use xml to transfer code in a way so that it can be read by other coding environments.
When asking particular questions, you should aim at providing as much information as possible. You have added a use case, but the use case is incomplete.
Your particular use case seems like a very small amount of data that has to be available at a high frequency 10kHz. I would first try to determine whether I can actually make both pieces of code part of a single process, rather than two different processes. Depending on the languages (missing from the question) it might even be simple, or turn the impossible into possible --depending on the OS (missing from the question), the scheduler might not be fast enough switching from one process to another, and it might impact the availability of the latest read. Switching between threads is usually much faster.
If you cannot turn them into a single process, then you will have to use some short of IPC (Inter Process Communication). Due to the frequency I would rule out most heavy weight protocols (avoid XML, CORBA) as the overhead will probably be too high. If the receiving end needs only access to the latest value, and that access may be less frequent than 0.1 ms, then you don't want to use any protocol that includes queueing as you do not want to read the next element in the queue, you only care about the last, if you did not read the element when it was good, avoid the cost of processing it when it is already stale --i.e. it does not make sense to loop extracting from the queue and discarding.
I would be inclined to use shared memory, or a memory mapped shared file (they are probably quite similar, depends on the platform missing from the question). Depending on the size of the element and the exact hardware architecture (missing from the question) you may be able to avoid locking with a mutex. As an example in current intel processors, read/write access to 32 bit integers from memory is guaranteed to be atomic if the variable is correctly aligned, so in that case you would not be locking.
At my school they teach CORBA. They shouldn't, it's an ancient hideous language from the eon of mainframes, it's a classic case of design-by-committee, every feature possible that you don't want is included, and some that you probably do (asynchronous calls?) aren't. If you think the c++ specification is big, think again.
Don't use it.
That said though, it does have a nice, easy-to-use interface for doing simple things.
But don't use it.
It almost always pass through C binding.
With my basic knowledge of C++, I've managed to whip together a simple program that reads some data from a program (using ReadProcessMemory) and sends it to my web server every five minutes, so I can see the status of said program while I'm not at home.
I found the memory addresses to read from using a program designed to hack games called "Memory Hacking Software." The problem is, the addresses change whenever I move the program to another machine.
My question is: is there a way to find a 'permanent' address that is the same on any machine? Or is this simply impossible. Excuse me if this is a dumb question, but I don't know a whole lot on the subject. Or perhaps another means to access information from a running program.
Thanks for any and all help!
There are ways to do it such as being able to recognise memory patterns around the thing you're looking for. Crackers can use this to find memory locations to patch even with software that "moves around", so to speak (as with operating systems that provide randomisation of address spaces).
For example, if you know that there are fixed character strings always located X bytes beyond the area of interest, you can scan the whole address space to find them, then calculate the area of interest from that.
However, it's not always as reliable as you might think.
I would instead be thinking of another way to achieve your ends, one that doesn't involve battling the features that are protecting such software from malicious behaviour.
Think of questions like:
Why exactly do you need access to the address space at all?
Does the program itself provide status information in a more workable manner?
If the program is yours, can you modify it to provide that information?
If you only need to know if the program is doing its job, can you simply "ping" the program (e.g., for a web page, send an HTML request and ensure you get a valid response)?
As a last resort, can you convince the OS to load your program without address space randomisation then continue using your (somewhat dubious) method?
Given your comment that:
I use the program on four machines and I have to "re-find" the addresses (8 of them) on all of them every time they update the program.
I would simply opt for automating this process. This is what some cracking software does. It scans files or in-memory code and data looking for markers that it can use for locating an area of interest.
If you can do it manually, you should be able to write a program that can do it. Have that program locate the areas of interest (by reading the process address space) and, once they're found, just read your required information from there. If the methods of finding them changes with each release (instead of just the actual locations), you'll probably need to update your locator routines with each release of their software but, unfortunately, that's the price you pay for the chosen method.
It's unlikely the program you're trying to read will be as secure as some - I've seen some move their areas of interest around as the program is running, to try and confuse crackers.
What you are asking for is impossible by design. ASLR is designed specifically to prevent this kind of snooping.
What kind of information are you getting from the remote process?
Sorry, this isn't possible. The memory layout of processes isn't going to be reliably consistent.
You can achieve your goal in a number of ways:
Add a client/server protocol that you can connect to and ask "what's your status?" (this also lends itself nicely to asking for more info).
Have the process periodically touch a file, the "monitor" can check the modification time of that file to see if the process is dead.