Slashdot Mirror


Secure Services on Virtual Machines?

Matt2000 asks: "With the growing number of package updates that cross my inbox for my redhat systems, and with the vast majority being buffer overflows, or overflows of some kind doesn't it strike anyone that there must be a better way? Instead of spending time auditing every piece of software for mechanically preventable bugs, why isn't there a common, audited virtual machine that people can build net facing services on? I would guess that sshd, httpd, and sendmail would be good candidates to start, as they are the most common and the most exploited. And please don't freak out performance junkies, if you run a website that serves 70,000 people a second and need to run native apache, then do so. Just accept that it will be less secure."

61 comments

  1. So you want? by Neck_of_the_Woods · · Score: 1



    and OS version of auto-update? Just kidding...

    --
    Neck_of_the_Woods
    #/usr/local/surf/glassy/overhead
  2. Why do you need a VM? by 0x0d0a · · Score: 2, Interesting

    You've got chroot. Both sandbox the server from the rest of the system. Chroot is just a lot easier to make performance-efficient.

    1. Re:Why do you need a VM? by Hanashi · · Score: 2, Insightful
      I think the original poster is talking about a whole different level of sandboxing. True, chroot environments keep you from playing with other files outside the jailed environment, but they do nothing to address (for example) your ability to install and run a network sniffer on the target.

      A good virtual machine, on the other hand, could let you have this level of security because the hardware is virtualized too. VMWare allows you to assign a number of different types of network interfaces to each VM, and using NAT you can prevent the VM's NIC from seeing traffic to/from any other host.

      Also, on a more philosophical level, the deeper your defenses are, the better. It's possible to break out of chroot jails (though it's difficult). It may be even harder to break out of a VM. The jury is still out on this, but it's certainly an unexpected move that would probably throw most crackers for a loop.

      --
      Check out my eclectic infosec blog at InfoSecPotpou
    2. Re:Why do you need a VM? by ComputerSlicer23 · · Score: 2, Informative
      Yeah, the only problem is go out to any hacker site, and look for details on how to break out of a chroot jail. Hell just put in "break out chroot" as search terms into google, and 5000+ pages come up. While chroot's nice, it's not the almighty security tool most people believe it is. (I'm not sure that having a VM that runs your software would be). UML might be better, or possibly another VM layer. The problem is, you need your VM to be completely audited for all interactions to make sure nobody can break thru to a layer above it, as soon as they can, game over. I'd rather seem UML get more support then chroot. I think chroot is of very limited utility, where UML seems to have a lot more applications, both interms of security (honeypots and as a jail for specific services) and virtual servers/services. However, chroot is more production ready then UML is, so there you have it.

      Kirby

    3. Re:Why do you need a VM? by 0x0d0a · · Score: 2, Informative

      True, chroot environments keep you from playing with other files outside the jailed environment, but they do nothing to address (for example) your ability to install and run a network sniffer on the target.

      Well...that's true, if you're running a chroot jail with, say apache running as root. But if you don't have any suid binaries in the jail (apache is running as "httpd" or whatever) and your kernel is secure, it should keep you from putting a sniffer on the thing.

      VMWare allows you to assign a number of different types of network interfaces to each VM, and using NAT you can prevent the VM's NIC from seeing traffic to/from any other host.

      Hmm. I'm not saying VMWare doesn't work, but I've seen the VMWare site more and more lean toward trying to sell VMWare as a corporate solution to security. VMWare was always kind of a solution without a problem , and I have a sort of nasty feeling that VMWare (and VMs) are going to be the new stupidly-oversold-to-corporate-IT-people product, like firewalls were before them.

    4. Re:Why do you need a VM? by Webmonger · · Score: 1

      Right, but the point is with a VM, you don't need a secure kernel, and you CAN run Apache (or Sendmail, or Bind) as suid root.

    5. Re:Why do you need a VM? by Matt2000 · · Score: 1


      It's not so much isolating the services from the rest of the system, but making it possible to completely remove the chance of a buffer overflow type exploit. This means we don't have to waste our time auditing server applications for those types of holes (which seem to make up the majority), we can just audit the virtual machine once.

      By virtual machine, I'm talking about a Java or .NET runtime, one that controls access to the memory for all programs that run on it.

      --

    6. Re:Why do you need a VM? by 0x0d0a · · Score: 1

      With a VM, the VM has to be secure.

      And using suid root + a VM doesn't give you much functionality that not suid root + no VM doesn't.

    7. Re:Why do you need a VM? by 0x0d0a · · Score: 1

      So basically, this is a call to use bound-checked languages.

    8. Re:Why do you need a VM? by Webmonger · · Score: 2, Interesting

      Yes, something does need to be secure.

      But there is functionality to be gained from VM+SUID root. Sendmail needs root to use port 25. It would be useful to create a virtual machine that just ran Sendmail, POP and IMAP. Most email users would only have accounts on that VM. Or it would be useful to have a virtual machine that just ran BIND.

      I suppose you can use packet-filtering to remap port 53 and 25 to high ports (say, 8053 and 8025), so you don't have to run Sendmail and Bind as root.

      But the other a VM is that you don't have to worry about someone getting a local logon through non-root Sendmail and then using privilege escalation exploits to get root on your whole box. The most they'd get access to would be your mail system.

      Anyhow, security isn't black-and-white, and defence-in-depth is a reasonable technique. VM+NOSUID+CHROOT would be a very secure config.

  3. StackGuard by drdink · · Score: 4, Interesting
    You might want to check out StackGuard:
    StackGuard is a compiler that emits programs hardened against "stack smashing" attacks. Stack smashing attacks are the most common form of penetration attack. Programs that have been compiled with StackGuard are largely immune to stack smashing attack. Protection requires no source code changes at all.
    --
    Beware, Nugget is watching... See?
    1. Re:StackGuard by Matt2000 · · Score: 2, Interesting


      Could I compile existing software, like sendmail, with this and that would remove buffer overflow style explots? If so that's very interesting, how come the binary RPMs that Redhat and crew aren't already compiled with a tool like this?

      --

    2. Re:StackGuard by Tom7 · · Score: 1

      StackGuard is good, and it would be better if distros included stackguard-compiled binaries by default.
      Unfortunately, it only protects against a certain (common) kind of stack buffer-overflow. It does not protect against heap overflows, integer overflows of most sorts, double-frees, printf-style attacks, etc. Unfortunately, many of the recent exploitable bugs have been of this sort. StackGuard does help some, but it wouldn't help as much as a virtual machine, or simply a safe language.

    3. Re:StackGuard by stevey · · Score: 1

      Yes that's what distributions like Immunix do, but notice that even with the extra protection they offer they still update their packages everytime a new hole is discovered.

      Stackguard isn't a magic bullet, and isn't gonna stop you from being 0wn3ed. Typically it just means that the released exploits won't work, and that's also the case for odd architechtures like Alpha - most of the released exploits are for intel, so avoiding that gives you as much protection as the stack guard compiler.

      The same with the no-exec patch from Solar Designer, which Linus keeps vetoing for Linux; it gives you protection from the commonly released exploits, but via return-into-libc attacks, etc, you can still be rooted.

      Use it if you like, but don't think it protects you completely..

  4. red pill by David_Bloom · · Score: 2, Funny

    Just hope the client doesn't take the red pill. I'd think a virtual machine would be more vulnerable, as there is potential to trick it to run code "outside the box".

    --

    Karma: Excellent (fuck, even in the future moderation doesn't work!)
  5. User-mode Linux by quakeslut · · Score: 4, Interesting

    Is this what you're looking for?

    quoted from page:
    User-Mode Linux is a safe, secure way of running Linux versions and Linux processes. Run buggy software, experiment with new Linux kernels or distributions, and poke around in the internals of Linux, all without risking your main Linux setup.

    User-Mode Linux gives you a virtual machine that may have more hardware and software virtual resources than your actual, physical computer. Disk storage for the virtual machine is entirely contained inside a single file on your physical machine. You can assign your virtual machine only the hardware access you want it to have. With properly limited access, nothing you do on the virtual machine can change or damage your real computer, or its software.

    1. Re:User-mode Linux by Matt2000 · · Score: 1


      That's not quite what I was getting at. User mode linux is a more safe way to run services that might suffer from overflow style exploits, but it still doesn't stop those exploits from occuring.

      I'm looking for one place to prevent those exploits (in a VM), and then build secure services on top of that.

      --

  6. I think there is by (trb001) · · Score: 2, Informative

    Isn't Trusted Solaris basically just this? At an OS level, you associate trust levels that permeate throughout your network. Two (or more) people can work on the same box at the same time and view completely different boxes because of their trust level. One trust level can't talk to or look at another's processes without the proper authorization. Like Unix file privs only much, much more controllable.

    Actually, trusted computing is a pain in the ass for standard development...we always wound up creating a super user program that can run stuff anything to get around priv issues during development. I can see using a system such as this post beta development or for production, but developing under it is a bitch.

    --trb

    1. Re:I think there is by Muggins+the+Mad · · Score: 1

      > Isn't Trusted Solaris basically just this? At an OS level, you associate trust levels that permeate throughout your network.

      I think this kind of approach is better than creating virtual machine sandboxes that still run the old weak UNIX security model. If someone 0wns your sandboxed apache, they can still likely cause
      a DoS with it, or propogate worms, or pretty much anything really.

      Good use of iptables and linux "capabilities" can help a lot with limiting what an application can do, but still don't go far enough, IMHO.

      Look at projects like SELinux, LIDS, RSBAC, LOMAC
      for examples of "free software" alternate security models.

      And yeah, they're a pain for development, but then so is trying to program securely :)

      - MugginsM

    2. Re:I think there is by Froggie · · Score: 1

      Isn't Trusted Solaris basically just this? [...] Two (or more) people can work on the same box at the same time and view completely different boxes because of their trust level.

      Plan9 has the ability to isolate 2 processes completely from each other, since all they have in common is accessed via the FS and mounts are process-specific in Plan9. Hurd presumably has the same ability given that it's based on the same principles.

      The concept is a better one than Unix has - Unix has the FS in common between processes, protectable via the chroot() syscall, which is adequate but not as capable as Plan9's mount() - but it also publicly shares out PID space, network interfaces and lots of other odds and sods of kernel data, and has the problem that you can't really prevent a process from knowing about and striving to attain root privs. Plan9 and Hurd can both put multiple levels of interference between you and any useful privileged options on the box.

      And I'm not advocating this as a real-world solution; I just like the design concept.

  7. One word by Anonymous Coward · · Score: 0

    java

  8. A matrix of jails by mnmn · · Score: 1


    How about a list of J2EE servers each in its own chroot jail and the apps executing in Java. How much security is too much???

    I personally think the BSDs are secure enough, and if Sendmail is replaced with qmail and apache constantly patched, there are no worries. No need to go to such extremes for production environments. After all. Performance is an issue as well.

    --
    "Give orange me give eat orange me eat orange give me eat orange give me you." -Nim Chimpsky
  9. a better answer by larry+bagina · · Score: 1
    Check out the -fbounds-check flag for gcc. The x86 architecture even includes a bound instruction for this purpose.


    ISO Pascal requires all array accesses do boundary checking (although most compilers let you disable that for performance reasons).

    --
    Do you even lift?

    These aren't the 'roids you're looking for.

    1. Re:a better answer by 0x0d0a · · Score: 1

      From the gcc 3.2.2 man page:

      -fbounds-check
      For front-ends that support it, generate additional code to check
      that indices used to access arrays are within the declared range.
      This is currenly only supported by the Java and Fortran 77
      front-ends
      , where this option defaults to true and false respec-
      tively.

      Does rather decrease the utility of the thing.

  10. Virtual machine by PD · · Score: 1

    A VM won't give you any security that you can't get from the OS, because it will still need to have access to things to do its job. That means that a hole in the VM or the program it's running can be just as bad as a hole in a C program.

    What you're really looking for is services written in a language that make buffer overflows and the normal security problems more difficult. That means that you're looking for mail servers, web servers, etc. written in languages with built in string types and garbage collection. You should be able to easily find these sorts of things written in Java or Python by doing a search on Sourceforge. Replace all your services with the ones you find, and you're done.

    1. Re:Virtual machine by Matt2000 · · Score: 1


      You can effectively make a VM buffer overflow immune by auditing just the same as you can with any other program, but the difference is that then anything that gets writte on the VM is immune to that class of problem as well - a great gain in security.

      --

  11. A VM is only as secure as the OS it's running by Deagol · · Score: 3, Interesting
    Unless I misunderstand your post, I don't think isolating an application inside a VM will do all that much good. I mean, I can run Apache on Red Hat under a VMWare virtual server. However, it can still be broken into the same as a real machine.

    Still, there's some merrit to the idea that having each service isolated in its own VM. At least there's some partitioning, and one "captured" service may not interfere with another. Though I'd argue that you should do this same partitioning by using real hardware.

    Here's what I do, and it doesn't require that much more overhead:

    At the IP level, I use iptables for a default-deny setup. Nothing gets in or out unless I explicity account for it, logging everything that violates policy and then silently dropping the packet.

    At the kernel level, I use the grsecurity patch to shore up generic, known weaknesses (stack smashing, buffer overruns), as well as the various randomizations of PIDs, socket numbers, etc. I tried using StackGuard and libsafe for this kind of stuff, but found them too troublesome (plus, grsecurity addresses most of this stuff).

    At the application level, I chroot what I can. I then use tcp_wrappers (for apps that use it) in a default-deny config, plus any ACLs that the application itself manages.

    Of course, I try to keep up with gaping security holes in services I run. However, I don't find myself scrambling out of fear that my boxes are in much danger when there is an advisory.

    These many layers add up to a pretty secure box, that's functional and no more of a hassle to admin that a stock installation.

    1. Re:A VM is only as secure as the OS it's running by dubl-u · · Score: 1

      That's a good list. The only thing I'd add is to suggest using something like LIDS. The basic notion is that you add something to the kernel so that root is no longer a trusted account. Instead, you give very specific permissions to each program that needs them.

      That way even if somebody does compromise, say, named, they won't be able to screw with much. And since LIDS logs attempts to violate security, as soon as they try to, say, view the password file or alter the logs, I'll know about it.

    2. Re:A VM is only as secure as the OS it's running by Matt2000 · · Score: 1


      That's not quite what I was getting at. I was asking why things aren't run in a virtual machine that can provide one place to audit to protect against buffer overflows. Meaning that if you are 99% certain that your virtual machine is safe, then anything that runs on top of it will also be 99% safe from those types of attacks. This is in contrast to having to be 99% sure of each and every native mode application that you run on your machine.

      This is the fundamental difference between trying to protect your root accounts and priveleges against a whole pile of potentially compromised services, and instead guarding all memory access at one control point via a VM.

      --

    3. Re:A VM is only as secure as the OS it's running by Deagol · · Score: 1
      I think I follow you now. What you're looking for is a binary sandbox, just like (as you state in another post) Java bytecode apps are run in virutal isolation, with the Java "VM" keeping strict tabs on the system calls the application makes.

      The idea sounds pretty neat. But is sounds like a pretty tough challenge. You may just as well ask for a complete overhaul of the way unix systems work (all-powerful root account is evil, etc.). As others have pointed out, the best bet seems to be the various ACL packages to limit what certain users and applications can read/write. LIDS, medusa, grsecurity, and rsbac (to name a few) do these kinds of things.

    4. Re:A VM is only as secure as the OS it's running by Matt2000 · · Score: 1


      Not quite. I'm not advocating user permission isolation or resitrction by the VM, just memory control. For example, in Java there are no pointers and all bounds checking is done by the VM, so buffer overflows are non-existant.

      If you managed to hack the password on an app running on the VM you'd still have that user's level of access, but we can be fairly certain that hack would not occur as a result of an overflow style attack.

      --

    5. Re:A VM is only as secure as the OS it's running by Twylite · · Score: 1

      What you are asking for cannot be done. Worse, it is a dangerous route to go down, because it gives an illusion of safety.

      From a VM level you cannot know what a program it up to unless that program obeys certain rules. When dealing with x86 architecture (specifically), those rules are not sufficiently verbose to allow for the sort of checking you are after.

      While a VM could intercept all stack access and prevent modification to the return address (presenting stack smashing attacks), it cannot tell if a malicious attack has caused values within a valid range in the stack or heap to be altered in a way that is not supposed to happen. Thus a VM approach would suffer all of the deficiencies of StackGuard.

      So while you may be able to protect against a classic buffer overflow attack (overwrite the return address on the stack and jump to your own code), there is no guarantee against arbitrary modification of the behaviour of the software by adjusting variables.

      The dangerous part is that you are trying to partition security and look at one aspect of it in isolation. This is shortsighted.

      Using permissions, a binary running in a user acocunt is less of a threat to overall system security than a binary running as root -- irrespective of whether there are exploitable vulnerabilities in that binary or not.

      Tools like the ptrace-derived sandbox further improve this situation -- an arbitrary binary could be denied access to the file and IO functions in the kernel, preventing a malicious intruder from reading or modifying the hard drive. Or those open function could be filtered by directory. Network access could be restricted, denying the opportunity of using the vulnerability as a springboard to probe behind a firewall.

      There is an interesting Usenix paper relating to these issues. There is a list of sandbox possibilities plus another one here, and you should also check out Medusa. this article also points to several resources on ACLs.

      --
      i-name =twylite [http://public.xdi.org/=twylite], see idcommons.net
  12. Writing secure software by Electrum · · Score: 3, Interesting

    Monolithic, buggy programs like sendmail will always be a security nightmare. That doesn't mean that secure code can't be written in C. qmail, for example, is completely secure. If more programmers followed good coding practices, we would see fewer security disasters. A good start would be to stop using C strings and to start using the stralloc concept.

    1. Re:Writing secure software by Matt2000 · · Score: 1


      I don't doubt secure C programs can be written, but we must ensure that everyone that writes a C program does write them in a secure manner. However, if people write their programs to a virtual machine then all we need to ensure is that the VM is written in a secure manner. That will lead directly to a more secure now, and in case new applications show up that you want to run. You don't need the qmail security guarantee to prove that there aren't buffer overflows, you know that the virtual machine has that security guarantee already.

      --

  13. CHROOT by Roadmaster · · Score: 1

    chrooting can accomplish much of what you want. Even if the process in question has an exploit, it is used, and the process gets compromised, the damage is contained to the chroot jail. And it's easy to find chrooted versions of popular (vulnerable) services. ftp, httpd, probably even sendmail.

  14. Safe languages are not necessarily secure by jovlinger · · Score: 1

    Just because you are running a VM doesn't mean too much - in fact, it may be a bad thing, as security becomes less of a concern (no need to upgrade, doesn't matter if I am hacked).

    Imagine a Java sendmail installation running on a JVM. I may be able to compromise jsendmail, and while this won't give me local root, I may be able to use the compromised sendmailer to implement social engineering hacks.

    Also, if the VM is designed to run "safe" languages that rely on static type checking for safety (such as java) a non-too-impossible attach on the machine it is running to randomly corrupt memory could be used to compromise the underlying system. See the recent paper by Appel and Govindavajhala.

    Which isn't to say I don't think this is a great idea. Writing your servers in a safe language is the easiest way to avoid rampant overflow errors, making jsendmail that much harder to compromise.

    Also, don't forget that all those malformed-request attacks against poorly written PERL CGIs that fail to validate strings passed to a subshell: perl runs in a VM, but does no good when the attack slips by the VM to the base hardware.

    1. Re:Safe languages are not necessarily secure by Matt2000 · · Score: 1


      I totally agree that it's not a "solve-all" solution to the problem, I just was thinking it would be a way to greatly reduce or eliminate a whole (large) class of security problems in one step.

      And yes, the programs are only as secure as the VM, but at least then you can focus on the VM for audits.

      --

  15. Chasing your tail by djmitche · · Score: 1

    I hope somebody takes the time to audit the VM. No, I hope a lot of people take the time to audit the VM.

  16. use openbsd by HakuMage · · Score: 0, Troll

    use openbsd, base system (with httpd, sendmail, named, ...) is audited:
    3.3 as stack protection, propolice,W^X, and more
    see openbsd.org & misc@

  17. There is no need to have a VM for safety by Tom7 · · Score: 1


    I wish people didn't (for whatever reason) equate Virtual Machines with language-level safety. It's true that Java was the first mainstream OO language with C-like syntax, but is this really the only experience that anyone has with safe languages?

    Let me try to set the record straight: The features of Java that make it good for writing secure code are independent from the VM. Those features are things like array bounds checking, lack of pointer arithmetic, checked casts, and garbage collection. All of these things can be, and are, done in native code. The VM is not what makes your code safe, it's what allows you to check a binary that you download to make sure it is safe. If you're compiling the code yourself, you can easily target native code and pay very little performance overhead.

    For instance, mlton (mlton.org) is a high performance native code compiler for Standard ML. It doesn't use a virtual machine, but it's impossible to write code with exploitable buffer overflows, integer overflows, double-frees, etc.. (In my opinion, it's also a much cooler language than C or Java). O'caml is another good language in the same family that can target either bytecode or native code. There exist native compilers for Java, though I've never used them.

    VM => portable byte code.
    safe language => secure code.

    Be wary of people who tell you that all we need is properly written C code. The days of grepping for "strcpy" are long gone -- the new age of exploitable holes are trickier things, usually living in hand-written parsing routines. C programmers will always have to live with buffer overflows, integer overflows, and double-frees.

    1. Re:There is no need to have a VM for safety by Twylite · · Score: 2, Insightful

      This is complete bullshit. The Java VM is exactly what makes the language safe. Even if you use Java assembler you can't overflow an array boundary, because the VM knows what an array is, knows its limits, and executes the instruction to set an element of the array on your behalf. Most of the RuntimeExceptions and all of the Errors in Java are thrown directly from the VM, not from code libraries.

      This means that you can take an arbitrary, untrusted Java executable and run it, and it will not be subject to traditional buffer overflow vulnerabilities.

      With a non-interpreted language like C, you can only get this level of trust if you compile the binary. Even then, you can only fully trust C if there is no use of pointer arithmetic, and all pointers are to data of a defined size. Without this knowledge it is not possible to generate code that can check (for example) array bounds.

      For example, char* c = (char*)malloc(1000); cannot be statically checked by the compiler. It is possible to develop a compiler that knows of every mechanism that can be used to allocate memory, and annotate a variable with the memory allocated to it, but there are numerous problems with this approach.

      It is certainly quite possible to take any sufficiently constrained language and compile it to native code such that it is not susceptible to buffer overflows. But this is quite different from a language-aware VM (like that of Java) where even a malicious binary cannot cause a buffer overflow.

      As for C programmers having to live with the various problems you describe -- there are many techniques for avoiding these problems. It is possible to use garbage collection in C++, and get away from direct memory management. Using sized data instead of arbitrary mallocs, and creating classes to represent arrays allows you to overload operators to behave in a safe fashion. The simplest of attention to initialising variables instead of making assumptions because you can squeeze out an extra instruction cycle addresses many string problems.

      --
      i-name =twylite [http://public.xdi.org/=twylite], see idcommons.net
    2. Re:There is no need to have a VM for safety by Anonymous Coward · · Score: 0

      you can only fully trust C if there is no use of pointer arithmetic

      I am afraid that is complete bullshit also. The bad thing about pointer arithmetic is that it can be confusing, or at least more confusing than using indexing.

    3. Re:There is no need to have a VM for safety by Tom7 · · Score: 1


      The VM is not what makes the *language* safe, unless by language you mean Java Bytecode. Java the language specifies array bounds checks and garbage collection, etc., and if you compile it natively, it is still safe. Why is this bullshit? (I happen to be resesarching programming languages for my PhD, so I do know what I'm talking about, here...)

      > It is certainly quite possible to take any sufficiently constrained language and compile it to native code such that it is
      > not susceptible to buffer overflows. But this is quite different from a language-aware VM (like that of Java) where even a
      > malicious binary cannot cause a buffer overflow.

      This is exactly my point. There is no need to be concerned with malicious binaries when I am running network daemons on my system. If I didn't trust them, I would already be in a lot more shit than I would be from an exploitable buffer-overflow: sshd could leak keys, and let anyone log on without a password, named could DoS-flood other name servers, etc. Rather, the scenario is that I download (or write) a program whose intent I trust but implementation I don't. Natively compiled code runs safely without the overhead of a VM -- it's faster and perhaps more secure (because we don't need to worry about bugs in the VM).

      > As for C programmers having to live with the various problems you describe -- there are many techniques for avoiding these
      > problems.

      Well, maybe I wouldn't have such a problem with C code if people actually did this. But all of the C/C++ network daemons I know of are filled with hand-coded parsing routines and manual memory management, and many have had exploitable holes as a result.

    4. Re:There is no need to have a VM for safety by Twylite · · Score: 1

      The issues we are contending are based on the understandings of two concepts: what is Java, and what is a VM? These sound like easy questions to answer, but they are not.

      Java does not refer to the grammer, nor does it refer to the VM. Java refers to a platform. The grammar, execution machine and a basic set of libraries are all included in the specification, and cannot be meaningfully separated without altering the behaviour of the thing we call Java. This is perhaps most clear when you consider that there is a Java assembler, and that it is possible using that assembler to generate byte code that the VM will not execute, as it violate data or logic safety.

      The concept of a virutal machine, on the other hand, is also rather blurred. In its most obvious form it is a layer of emulation that presents a complete environment to whatever runs on top of or within it. But almost all modern languages have some level of runtime environment, wihout which they canot function. Any interpretted language must rely on some emulation layer, or be compiled and no longer interpretted.

      So when we look at the Java specification and say that it provides for array bounds checks and garbage collection, what is really providing this? It is a combination of the grammar, which facilitates declaring variables in sufficient detail, and the runtime environment, which dynamically checks that the constraints are obeyed.

      When compiled to "native code", the scenario is no different. In order to provide array bounds checking and garbage collection, some runtime is required. Whether that runtime is a complete emulation layer, or a set of library routines that are called implicitly, it is still there, moderating and monitoring the behaviour of the software.

      So, getting back to the original discussion. Java the grammar and Java the base class libraries make requirements of their execution environment. These can only be satisfied by an execution machine (real or virtual) or a "runtime".

      Whether or not we choose to call this runtime a virtual machine does not change the fact that it exists and it presents to the code that uses it an environment that is different from the underlying reality. If you really want to stir the pop, throw in the fact that a virtual machine must be implemented in native code on a real machine (or in in another virtual environment), or the idea that just-in-time compiling in a virtual machine compiles on-the-fly to native code. Does this mean you are no longer running in a virtual environment? To go really over the top, the concept of protected memory and privledged instructions - as used on x86 architecture to enable safe multitasking in operating systems - is often referred to as a virtual machine, and the "native code" doesn't really have full access to the hardware.

      So does all of this matter to security? Well, it can. Any code that you run is constrained by the environment in which it is executing. For "native code" that environment is a real machine in which certain privledges have been restricted by the OS in conjunction with the CPU or other hardware. For code in a virtual machine, the VM defines the limits of that environment.

      So, taking a program written in any language and compiling it to run as native code, you get instructions that are constrained only by the permissions laid down by the operating system. So, on an x86 architecture where the OS does not force a non-executable heap and/or stack, this makes it possible to "execute data". Targetting a VM such as the Java VM with the same program, and assuming it were possible to inject arbitrary data into the program, it would still be impossible to execute that data, as the VM is aware of what is code and what is data. Even if you could inject and execute arbitrary instructions on Java VM, you could not automatically gain access to all data within that VM or all privledges the VM enjoys in its own execution context, as the VM enforces object-level access controls.

      That's

      --
      i-name =twylite [http://public.xdi.org/=twylite], see idcommons.net
    5. Re:There is no need to have a VM for safety by Twylite · · Score: 1

      You may wish to read my statement in the context of the entire post, rather than on its own. Use of pointer arithmetic makes it impossible for a tool for analyse a program and determine when it is behaving incorrectly. It is thus impossible for a compiler to automatically insert protective code that will prevent the program from being coerced into behaving badly.

      At best you can annotate regions of memory to prevent overflowing them -- but within stricter typing you cannot determine what the correct contents of those regions are.

      A trivial example is the BSTR type, which is a NUL terminated wide character string prefixed with a length. The minimum allocatable memory for this type is the length of the string plus 6 bytes (4 for the length, 2 for the wide NUL). It is therefore entirely possible, even with memory range checking, to assign to the BSTR a pointer that points to the length (rather than the first character) or to the terminating NUL. Both are valid values for the pointer, but make the value of the BSTR invalid.

      Other examples include buffers that begin with offset tables -- while it may be reasonable to assume that a compiler could have intimate knowledge of a significant type (on Windows) such as BSTR, it is unreasonable to assume that a compiler can have knowledge of every form of UDT that may use offsets. Unless you can force some sort of annotation of every value, and ensure it is not treated as some other type (which completely destroys the use of pointers), you can never protect your memory properly.

      I am in no way arguing that C/C++ is being used incorrectly, or that it could be used correctly, or that it is confusing.

      --
      i-name =twylite [http://public.xdi.org/=twylite], see idcommons.net
    6. Re:There is no need to have a VM for safety by Tom7 · · Score: 1

      OK, I'm with you here. When I say Java I mean the source language (since it is so easy to separate from the rest, if you ignore things like class loaders and reflection), but I'm sure Sun would agree with you. But:

      It's true that the safety in a program is often manifest somewhere in the "runtime" or "VM". A good example is garbage collection -- surely, even in natively compiled code, there is a runtime system that implements GC. But stuff like array bounds checks are not necessarily part of this. For instance, a compiler that compiles this code:

      int x = 0;
      int arr[100];
      arr[x] = 5; ... is perfectly free to generate code without a bounds check, and now there really is no check, anywhere. The compiler has generated safe code without the help of any protection layers (including the virtual memory hardware). You can make a similar argument for other things that compilers can check for you, like integer overflow.

      Now, it's true that compilers can be buggy, but in my experience it is pretty difficult to make a mistake in a compiler that leads to exploitable holes. It's really easy to write bounds-checking array accesses (when the language is amenable to it); usually only a few lines out of the entire compiler. (Also observe that C and C++ programmers must worry about compiler bugs *in addition* to their own bugs!) On the other hand, while a VM does add a second layer of checking, it also adds a second layer for potential mistakes.

      > As I said in my original post, it is possible to compile any sufficiently constrained language to create a binary that was
      > safe from buffer overflows. From a security viewpoint this is a very limited statement. A buffer overflow is not the only way
      > to exploit buggy software...

      That's true, of course, but I think that the class of bugs that safe languages make unexploitable (buffer overflows, double-frees, integer overflows) are extremely common--the most common--among security holes. I think it is well worth not having to worry about these, since (for one thing) it gives us more time to think about more insidious errors.

      Anyway, I am all for the idea of using Java on a VM to write security-critical applications. I would definitely run these daemons over their C counterparts and sleep more soundly at night. But even the poster who suggested the idea had the knee-jerk reaction that doing so would impose a serious performance penalty, presumably because VMs are thought of as inefficient. The point of my post is to claim that safety (the property we're looking for here) is independent from Virtual Machines, and can be gotten without all of the performance penalty.

  18. Mistaken reasoning by Tom7 · · Score: 2, Insightful

    > Imagine a Java sendmail installation running on a JVM. I may be able to compromise jsendmail, and while this won't give me
    > local root, I may be able to use the compromised sendmailer to implement social engineering hacks.

    How do you expect to compromise jsendmail? If sendmail were written in java, then the 2 most recent bugs would not have been exploitable. Part of the point is that safe languages like Java are not vulnerable to buffer overflows, double-frees, etc.

    > Also, if the VM is designed to run "safe" languages that rely on static type checking for safety (such as java) a
    > non-too-impossible attach on the machine it is running to randomly corrupt memory could be used to compromise the underlying
    > system. See the recent paper by Appel and Govindavajhala.

    This is a total red herring. The situation described in their paper is where the attacker gets to supply the program (and also has the ability to induce memory faults on the target). While I might buy the argument that memory faults happen randomly as well, the attacker surely doesn't get to install his own trojaned jsendmail on my computer. (If he did, he could do a lot more damage anyway!) A C program is equally dangerous on a computer with faulty memory--Appel's paper is irrelevant in this scenario.

    > Also, don't forget that all those malformed-request attacks against poorly written PERL CGIs that fail to validate strings
    > passed to a subshell: perl runs in a VM, but does no good when the attack slips by the VM to the base hardware.

    I'm with you here. perl is "safe" in some sense and is interpreted, but is still susceptible to easy security holes. I think this is mostly due to its interpreted and highly dynamic nature, as well as due to some misfeatures in the language (allowing "|/bin/rm" as a filename, etc.). In my (informed, but not substantiated) opinion, statically-typed compiled languages are not typically susceptible to easy-to-make security holes like these. (For instance, to spawn a process in SML, you give the path to the process, and a list of its arguments -- there is no shell globbing to screw up.) I really think that such languages would go a long long way towards making more secure computing environments, and in fact they don't need to run in a VM (see my other post), giving us the best of both worlds!

  19. Why a virtual machine? Why not just user perms? by melquiades · · Score: 1

    There's a lot of confusion on this thread as to why you'd *want* a virtual machine when you can always just run your servers with isolated privileges. Good question. I'll take a stab at that:

    The two are both excellent ideas, and are essentially orthogonal. Privileges protect a server's interactions with other processes and the rest of the system. They limit its use of the file system, network ports, and sensitive APIs.

    However, permissions can't limit a program's interactions with itself -- and that's where a VM comes in. Obviously, a buffer overflows exploit doesn't instantly get you root if you're using the exploit on a server running as user www. But most buffer overflows don't work that way; instead, one uses that exploit to tweak some part of the system which the server might perfectly well need access to, in order to open a wider door.

    No amount of privilege-futzing can prevent buffer overflows, stack smashing, etc. Setting privileges is good because it contains the damage, but a virtual machine may also be good, because it prevents much of the damage in the first place. That's one of the things I like about programming in Java: private members are truly private, and it's physically impossible for other code to access them, except as I expose them. If I design objects with a tight, well-defined contract, then I get automatic closure of that contract over all interactions with all other objects, guaranteed. And of course Java isn't the only language that offers guarantees like this.

    So I think the author has a point: why not sacrifice some of the raw speed of C++ for security when 20% slower performance is acceptable?

    (Of course, VMs can't fix the logical errors that invariably crop up in messy code; programmers unfortunately still have to think about what they're doing!)

  20. Why not hardware bounds checking? by Anonymous Coward · · Score: 0

    I am constantly amazed that there is no discussion of hardware enforced bounds checking. This isn't anything new, some architectures had it in the '70s. It can be done (with a little difficulty) in x86 architecture(or so I have read). It WOULD mean that C programmers couldn't play so fast and loose with pointers, but that would be a good thing, IMO. This discussion isn't new either.

    http://bugtraq.inet-one.com/dir.1998-07/msg00215 .h tml

  21. Re:Why a virtual machine? Why not just user perms? by Matt2000 · · Score: 1


    You neatly summed up the debate for me there. Most of the posts on here have confused user permissions with what I was getting at with the virtual machine angle.

    Perhaps I wasn't clear enough by not providing an example, but as I'm a Java programmer too I didn't want this to immediately devolve into a language war. I don't need to have everything I run on my system be written in Java, but it'd be nice if they were on a common secured runtime.

    Wow, that's starting to sound like .NET

    --

  22. Let me see if I get this straight by Moonwick · · Score: 1

    Uhm, so what happens when someone compromises apache and replaces your website with the goatse guy?

    Whole lot of good that jail/UML/whatever virtual system did you then.

    Either keep your software up to date, or turn in your sysadmin badge...

    --
    Only on slashdot can a posting be rated "Score -1, Insightful".
  23. Re:Why a virtual machine? Why not just user perms? by icklemichael · · Score: 1

    > That's one of the things I like about programming
    > in Java: private members are truly private, and
    > it's physically impossible for other code to
    > access them, except as I expose them.

    What you mean you can't do this?

    // Make it accessible
    privateField = String.class.getDeclaredField("value");
    privateField.setAccessible(true);

    String foo = new String("foo");

    // Read it

    Object oldValue = privateField.get(foo);

    // Change it

    privateField.setValue(foo, new char[] {'b', 'a', 'r'});
    (to non java peeps, this will make the private field in the String class accessible, read it, and then change it via reflection)

    I do agree whole heartedly with the point you're making though! :)

  24. Re:Why a virtual machine? Why not just user perms? by melquiades · · Score: 1

    Wow. I am flabberghasted. That's utter nonsense, and it works!

  25. Aha. by melquiades · · Score: 1
    I was wondering how this was even remotely reasonable. Here's the answer:
    If there is a security manager, its checkPermission method is called with a ReflectPermission("suppressAccessChecks") permission.
    So you still have complete private field sealing, but only if you explicitly turn it on. It's more than a little disturbing that this permission is enabled by default. Still, I suppose if you're writing a security-sensitive server, you'll configure your security manager to be very secure.

    Does anybody know if Sun has released a recommended "high security" configuration for a security manager?
  26. Proof your code? by Uber+Banker · · Score: 0

    When i was in university we used to prove our code - it was hell, box logic diagrams recurrring over each other with an in-out structure down to a central point. Now this was at a pretty fundamental level. We could use libraries as one of these central points...

    Note, when I mean proved, I mean one input results in one output, using mathematical proof, which therefore cannot be got around (randomness could exist within this mathematical framework).

    Damn, don't get me wrong, I know this will be damn labour intensive and hardware specific. But isn't a one-off investment worth it if this hardware-software solution can last a sufficient period of time?

    So why not prove your programs are secure, bottom up building on proofed instruction sets (though these are system-specific) gone before. C could be seen as just a language to write in which would then be compiled over these proved-secure components.

    You could use virtual machine (suggested in previous posts), a virtual machine which had been proved before, so anything which runs on it cannot get below this unhackability...

    The fact is, it is possible to prove code, it is possible to have unbreakable/perfectly predictable code. It is just damn hard work and very hardware specific. The main thing I see is the cost of investment on hardware which quickly moves on, needing a new proof... this is just a theoretical solution. [you could have an increased cluster of older hardware to give extendability].

  27. Good security is multi-layered by dwight_hubbard · · Score: 1

    I see lots of post that various stuff is better or good enough. I think that's missing the big picture. A truly secure system doesn't rely on only one security methodology.

    I think VMs are a very useful and valuable for setting up secure servers. But like most other aspects of security they don't make a secure system on their own.

    They provide another method of isolation of individual applications that potentially have buffer overflows. There's no reason for example a user mode linux install couldn't be built that has named built with stackguard running in a chroot session.

    Hack detection is much harder to fool. I.E. have the main OS run tripwire against the VM. So the tripwire database isn't stored on the VM disk image...

    Recovery from a hacked system is easier. It's just a matter of taking the backup copy of the original VM image, installing a patch to fix the exploit and putting the service back into operation. This is certainly much easier than rebuilding a server.

    Using multiple VM sessions also means that installing patches, security or otherwise to one VMs services isn't going to screw up the other services. This is of course real handy for testing.

  28. Valgrind? by JJC · · Score: 1

    When I read this I thought of Valgrind. It's a program designed to find memory management problems such as memory leaks and using unitialised memory. The program being tested runs under Valgrind so it is very much like a virtual machine. I've never thought of running a server under it, but if you can stand the (probably substantial) performance hit it would probably do what you're intending.