Immunity

05-18-11

Image by Fleky_Lude. Used under the terms of the Creative Commons Non-Commercial Attribution Share Alike license. http://www.flickr.com/photos/fleky_lude/4924635894/in/photostream/

Image by Fleky_Lude

A lot has been said about the supposed immunity of Apple products to malware. If I had a nickle for every time I heard that “Macs can’t get viruses”, I’d be a rich man. Even Apple perpetuates this lie, but hidden inside the Apple Care agreement is the truth: officially, Apple disclaims any responsibility to help you remove any malware that infects your shiny new computer. This is boilerplate as far as computer care agreements go, but wait! What malware? Macs can’t get viruses! Can they? How about the recent epidemic.

Apple and the fanboys would like us to believe that all things Mac are somehow magically safe from attack. The truth couldn’t be further. At the end of the day, an operating system must be designed to run software. The dirty little secret of malware is that in many respects it looks just like other legitimate software. The only way to guarantee that you can identify a specific bad program is to get a sample from the wild and find a “fingerprint” that uniquely identifies that software: in other words, you can’t REALLY stop an attack until it has already hit a large number of computers.

Most antivirus developers try to work around the limitations of fingerprints with something else known as “heuristics” (Hue-wrist-ticks). A heuristic is a good guess made by taking a number of data points that are normally strong indicators of a specific type of problem. For example, if IE has a new flaw that a hacker can use to silently infect your PC, the AV developer might write a heuristic to look for code sequences that would likely be part of exploiting that flaw. Anything containing these code sequences is probably evil, and your antivirus will block it.

Heuristics may sound clever, but they have their own problems. One issue with heuristics is known as a “false positive”. Spend any significant time in the software development world and you’ll encounter a false positive. This happens when a heuristic happens to match a legitimate product. When this happens the legitimate software will be blocked, which is frustrating to both the developers and users of that product. Another problem with heuristics is that, like fingerprints, they are a lot like running a race perpetually in second place. Before you can write a heuristic, you have to have an idea of what type of attack you are looking for, which probably means that someone already did it. The last, and greatest, problem with heuristics is that they aren’t very effective. The actual detection rates are very low, some say as low as 30%. This means that 70% of the malware will get right through. Even worse, any attacker worth their salt will spend a little time making sure that their attack will bypass all the current heuristics for the major AV solutions on the target platform.

So what does this have to do with the recent Mac outbreak? Everything, and nothing. Antivirus solutions are very good at exactly one thing: stopping an outbreak. Once a virus hits the wild, the clock starts ticking as the major AV vendors start developing fingerprints and heuristics to shut it down, then deploying those to their users. On protected PCs the attack can be over in a matter of days. Mac viruses however are running almost completely unopposed. Mac users, having bought into the lie that they are immune, have neglected nearly every form of security on their computers. If you ask a PC user whether they are running an Antivirus, they’ll either confirm that they are, or hang their head in guilt and say that they aren’t. Ask a Mac user? 9 times out of 10 they’ll proudly and ignorantly claim that they don’t need one, because Macs can’t get viruses.

“Now John,” some of you are asking, “are you saying that it is impossible to create an immune system?”

Really, did you have to ask? Today’s “impossible thing” is a twofer. It should be possible to turn this around, making a system that is fundamentally secure, and forcing any would be hackers to play catchup with the operating system, rather than forcing AV solutions to try to catch up to the hackers. We’ll call this setup our “Immune System” (pun intended). To achieve such a setup, we need to:

Never Trust the Developer

Developer errors are perhaps the most problematic attack vector, because a wormable viral developer error (one that can be used to silently pass on the attack to other machines) can come from anywhere. It only takes one of these to ruin trust in the system. The only way I see to prevent this is to require all development to be done in a language that forces developers to write code that cannot be attacked. Most of the required mechanisms for this exist in various languages, but so far no language has all of them. Our theoretical “Immune System” would be designed to only run apps written in this single secured language. The main required language features (technical jargon warning) are:

  1. Taint Detection – Taint detection is a system that keeps track of how a value can be used. The overwhelming majority of security flaws in software stem from using a value without properly preparing it for the location where it will be used. For example, if a webpage is going to say “Last comment by: John”, it needs to prepare my “name” for display before using it: otherwise I could write some JavaScript code for a virus, tell the site that this code is my name, and visitors would be running the virus each time the site tries to show someone my name. The preparation is simple, and after preparation the site would display the code for the virus, rather that running the code for the virus. Taint detection makes it obvious to developers when they have failed to prepare a value, and makes it painful for them to ignore the unprepared value when they find it.
  2. Type Safety – Type safety is a mechanism in some languages that forces developers to be specific about what each value is. In type safe languages, a number is always a number, text is always text (developers call text values “strings”). In non-typesafe languages there is no guarantee, a value could be any type unless extra code is added to check the type. Type safety reduces bugs, but more importantly in this case, it can be connected to the taint metadata to force developers to define and manage their taint.
  3. No Raw Memory Access – Raw memory access is fine, so long as developers never make a mistake, but as soon as a mistake is made, it leads to problems such “buffer overflow” attacks, where a hacker injects machine code by simply entering data that is too long to fit somewhere. Most scripting languages eliminate all raw memory access. This can have some performance problems, but it is safer, and computers are getting faster, so it isn’t as big of a problem.
  4. Eliminate “Unsafe” methods – Most languages have a host of methods that will do bad things if they get a bad input. Most of these can be fixed by reworking the language so that it isn’t possible to provide a bad input (for example, the Mongo query language, as opposed to SQL.) The immune language would need to eliminate unsafe methods by design, and in the few cases where that isn’t possible, secure them by taint checking.

This list isn’t exhaustive, but just the 4 items above would almost completely secure the average app, preventing it from being used as a gateway for hackers.

Never Trust The Software

Developing software on a secure foundation prevents hackers from using a flaw as a backdoor to attack the user, but this doesn’t help if the software itself is directly malicious (such as the “Mac Defender” software currently hitting Apple lovers everywhere.) Fixing this is actually reasonably easy. This is really a question of managing software identity and restricting software permissions. On older operating systems, (Windows, Mac, Linux, etc.) software operates largely anonymously. Specifically, the same software can operate under more than one identity. Additionally the software might do anything, and there isn’t really any warning.

To fix this you have to identify the software, restrict the software, and empower the user. Android is actually closer than any other product to successfully pulling this off. Each type of “sensitive” operation (like accessing contact data, the memory card,  the internet, or the current location) requires the application to explicitly declare that it will perform that action. The user then has to approve the types of actions that will be performed.

To identify the software, nothing is better than an App store, so this is the first line of defense. Sometimes an app store is too limiting though, and direct installation needs to be possible. Direct app installation should be allowed if they are signed using an appropriate certificate. Direct installation of unsigned or self signed apps should not be allowed at all unless the user has enabled an obscure “development” mode, and even then, it should give massive warnings with lots of color and scary words like “hacker” and “virus”.

Finally, it needs to be trival to report bad applications. Applications that have gotten more than a handful of reports should automatically start warning users (again, using the scary words) until they can be reviewed and either cleared or removed. Because the identity is managed, the offending apps can either be removed from the app store, or the code signature revoked. Either way, malware can be shut down in an instant.

Different devices are closer to achieving this than others, but so far the various mobile platforms seem to be the closest. This represents a major step forward for security.

Never Trust The User

A favorite attack vector lately is known as “Social Engineering”, which means “get the user to do something that is not in their best interest”. Some of the most clever attacks are entirely social engineering based.

All the security in the world is no good if you can convince the user to do something bad on their own. I don’t need a keylogger if I can send an email that convinces you to give me your bank account information.

Left alone, users will make bad decisions. Closing the social engineering vector is only possible if you empower the user to protect themselves. Some of this is handled by the “Approve the types of actions” paradigm in mobile devices, but it doesn’t go far enough. The user needs a strong “danger level” indication, and it needs to be based on more than just what the app does:

  1. Apps from unknown countries, or from countries where attackers can’t be prosecuted are more dangerous than apps from countries like (for example) the USA, where prison time is the likely result if you distribute a virus.
  2. Apps that are brand new are more dangerous than apps that have been in the system a while
  3. Apps that have gotten a number of “malware” reports from the community are more dangerous than apps that haven’t gotten any such reports.

Does it work?

The $64 question is this: would such a system have prevented the recent malware epidemic on the Mac? Yes it would have! In this case the attack was social engineering, so empowering the users to make good decisions would have detected and prevented infection early. Rather than the Apple care folks spending time removing infections, they could have just blacklisted the software. Since the identity is absolute, the software couldn’t circumvent the blacklist. New installations would be impossible, immediately stopping the spread of infection, and the system could even be designed to push to any machines that did get infected, allowing the infection to be removed immediately.

Is there a way around it?

Of course there is. Physical access to the device isn’t addressed (although there are systems that could partially fix that too.) There are certainly ways that hackers could sneak past this too, depending on the specific implementation details. There are a few absolutes though:

  1. The system prevents insecure software (software that creates back doors and security holes) from being created.
  2. The system prevents malware from being propagated anonymously.
  3. The system makes it possible to “kill” any software that is determined to be malicious.
  4. The system empowers users to detect attempts to infect their machines before they actually get infected. As a result, malicious software in the wild may be detected and blocked before even a single user has actually been infected.
  5. The system dramatically raises the bar for malware, and dramatically reduces the potential lifetime of an attack. Since most malware is designed either for money or glory, this makes our “Immune System” an unattractive platform to attack. There is neither good money nor significant glory in infecting a dozen computers, then getting permanently shut off.

The interesting thing is that the door doesn’t have to be completely closed, it just needs to be closed enough that attacks are not cost effective, likelihood of detection of high, penetration low, and the hazards of detection (I.E. prison and such) high. In addition, ensuring that attacks can never be silent makes it possible to even secure the most paranoid business needs by leaving a clear audit trail. This would almost entirely shut down the malware industry (and it is an industry). Cut the snake off the head and we can return to the good old days where there was just an occasional glory hacker.

Will We Ever See Such A System?

Yes. Count on it. Just don’t count on it being your computer’s operating system (at least not any time soon). The changes (especially the “one language” requirement) are simply too radical to pull off on current operating systems, given the need to support legacy systems.

Actually, the internet is perhaps the best positioned to pull this off. A vast majority of web sites are developed against exactly the same language stack (HTML, CSS, JavaScript, and PHP). In fact, only one of these languages (PHP) varies at all between web sites. HTML and CSS are non-procedural, so they have no inherent problems. Javascript is flexible enough that with only minor adjustment, it should be possible to lock down. PHP could also be locked down with only minor effort (in fact, most of the work has already been done.)

Application trust on the web is assumed to be zero in all cases. Web sites always operate completely sandboxed. This is problematic sometimes, but it guarantees that no matter what happens, the site cannot directly affect your computer (unless your browser has a bug, which is an excellent reason to NOT run old versions of IE).

Even without operating system help, browsers could adopt additional security alerts and standards to protect users from downloading malware, and raise all sorts of warnings when downloading any script or software that doesn’t have a fixed identity, making social engineering attacks against the native OS through the browser mostly impossible.

Ironically, although the web environment is the best positioned to ensure security, it is also perhaps the furthest environment from it. Due to the high connectivity, use of scripting languages, and heavy use of low quality developers, it is typically much less work to breach a web site than a native application. In addition, the high connectivity makes it easier to spread a successful attack. As a result, attacks online are widespread and more often than not will yield large quantities of high quality information. Even so, I expect that the web will, several years from now, be the first major environment to adopt a complete architecture of immunity.

This entry was posted on Wednesday, May 18th, 2011 at 10:36 pm and is filed under Impossible Things, Programming, Web Development. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

Leave a Reply

 
WordPress SEO fine-tune by Meta SEO Pack from Poradnik Webmastera