Slashdot Mirror


Hijacking .NET

Matt Solnit writes "What can I say - Dan Appleman never fails to please. In this e-book, he takes a look at 'hijacking' .NET by accessing private members in .NET classes. Private members are, in essence, pieces of code that you don't want other programmers to access. You use them to support your own code, and you make public the pieces that you want to make available to other developers. Typically, a language ensures that a member marked as private is hidden from anyone who doesn't have your source code, but Appleman shows how in .NET it's not so." Read on for more of Matt's review of this guide to tricking private members to do your bidding. Hijacking .NET - Volume 1 author Dan Appleman pages 46 publisher Dan Appleman rating 10 reviewer Matt Solnit ISBN (N/A) summary An eye-opening look at how you can use undocumented and private features from the .NET framework.

In the .NET Framework, it's possible to access a private member of any class -- your own, another developer's, or even the classes in the .NET Framework itself! Appleman demonstrates this with a great example that uses private members to get the list of groups that the current user is a member of -- in a single line of code -- by accessing a private member that is not exposed by the .NET Framework.

Appleman also explains the tradeoffs of using this technique. The code you're using is not documented, and it's not guaranteed to be present in future versions. He describes how to deal with these problems, and how to make the most of the technique while remaining relatively safe.

Once the basic technique is explained, Appleman takes you into how to find out what private members are available, and how to call them. He shows how to use the object browser available in Visual Studio .NET and the Microsoft IL Disassembler, freely available in the Framework SDK, to discover the private members in a class and determine how to call them correctly.

The example is great -- Dan shows you how he used "hijacking" with a collection of private members to develop a FileAccessControlList class that can be used to manipulate ACL's on Windows files. This is a piece of functionality that is not included with the .NET Framework, but developers have a need for all the time. To write the code from scratch would take days, including translating Windows API declarations to C# or another .NET language and poring over MSDN documentation. As it turns out, all the pieces are in the Framework -- they're just not public. Appleman accomplishes the task in under 200 lines of code, all of which is included with the e-book. As a bonus, you get a great introduction to how Windows security works, and how the example could be extended to other ACL-controlled things like Registry keys.

The fact that private in .NET isn't really private is something that isn't well known, and even if you're not interested in security, this e-book is worth a read just to get some insight into what you can do with the .NET framework, and what other people might someday try to do to your code.

As far as the author's writing style, I will say that Dan has a great knack for intuiting what needs to be explained and what doesn't. His laid-back approach makes everything seem fun -- this is a book you could read on a Saturday afternoon in a hammock.

This e-book is not for beginning .NET programmers, but should be easy for intermediate developers to understand. The whole text weighs in at just under 50 pages, and is well worth the cost of $9.95. Sample code is provided in both C# and VB .NET.

This e-book can be purchased and downloaded immediately from amazon.com or through the author's web site.

25 of 514 comments (clear)

  1. Make any private member acessible. by D4MO · · Score: 2, Insightful

    Use a memory hex editor!

    --

    Rocket science is easy. Neurosurgery, now *that's* difficult.
  2. Posted on BugTraq by oliverthered · · Score: 3, Insightful

    Isn't this a security bug, you think that you've hidden some code, but infact it isn't.

    --
    thank God the internet isn't a human right.
  3. By design? by DrTentacle · · Score: 4, Insightful

    Is this behaviour by design, or merely a side effect of the implementation? If it's a side effect, then don't rely on the support for this "feature" to continue in future releases of the .NET framework. MS has a nasty habit of changing undocumented features...

  4. Maybe the title should be changed by julesh · · Score: 5, Insightful

    Maybe the title of this book should be changed to "1001 ways to write bad code". Relying on undocumented private members of classes violates encapsulation and pretty much guarantees that your code will not work with (a) compatible implementations on other platforms, and probably also (b) future versions on the same platform. Just Say No, is my advice.

    1. Re:Maybe the title should be changed by Jerf · · Score: 3, Insightful

      If the alternative to writing a quick ACL changer is multiple days of intense hacking, vs. a couple hours with the right pokes at private members, it will take a lot of internal interface changes before the amount of time spent tracking the internal API exceeds the time it would have taken to do it right the first time. Since the capability doesn't officially exist, your (a) point is meaningless (even this platform doesn't officially support it) if you can assert that everybody will use the same platform, and given we're talking .Net the odds that a an awful lot of .Net programs will run only on Microsoft's implementation anyhow is pretty high, and odds are (b) doesn't bother you because it may never happen (changing the internals like that also implies work for that developer, so it's not a bad bet they won't be in a hurry to change the internals for their own sake), and even if it doesn your probably still ahead.

      Encapsulation is not an absolute law, it's a risk that must be analysed like any other risk, and treating it like an absolute law will sometimes cause you to do sub-optimal things. I can't be 100% certain with the given information, but odds are that the choice to use internal private methods and data to do ACL manipulation are a good bet. Yes, you may lose, but implementing ACL manipulations yourself may lose too: If the ACL system changes, you have to track it yourself, while the odds are decent that the internal private members will automatically track the changes!

      Violating encapsulation is almost always bad, but that's a long way from "always bad".

  5. Re:Private methods and by yatest5 · · Score: 2, Insightful

    Er, write your own VM then. Client-side security is no security at all i.e. you're free to fuck up your own computer any which way you want.

    --
    • Mod parent up! [a] by Anonymous Coward (Score:5) Thurs, June 31, @13:37
  6. Re:So .Net is like C++? by patniemeyer · · Score: 5, Insightful

    In the first chapter of my book, Learning Java I make this comparison and show an example of how trivial it is to forge a pointer in C++.

    The thing that many people still just don't get about Java is that it was designed to supply this kind of safety *without* impacting performance. In Java byte code verification happens statically, before the code is executed using a kind of theorem prover.

    With certain concessions from the byte code you can prove that various types of problems (stack overflows/underflows, incorrect casts, etc.) cannot happen and you don't have to check for them at runtime. Of course in OO languages let you do things that require runtime checks, but at the bottom level Java can be statically compiled and optimized amost as far as C/C++ (only runtime array bounds checks are required) and because Java contains so much more information at runtime the new generation of profiling runtimes can do further optimizations dynamically that cannot be done in C/C++ (e.g. optimistically inlining methods and profiling garbage collection routines).

    Pat Niemeyer
    Author of Learning Java, O'Reilly & Associates and the BeanShell Java scripting language.

  7. Re:Conclusion by JanneM · · Score: 5, Insightful

    I thought so too at first, but I believe it's not really the same thing here. Neither Perl nor C stuff depends on this encapsulation for any security stuff. For instance, Perl has sandboxing through taint checking and the safe module, and they do not assume that the potentially malicious code cannot access private members. Indeed, the filosophy in Perl is quite different - you are free to access any member function you want, or even 'private' data; it is assumed, though, that you know what you're doing in that case and won't come crying if things break for you as a result.

    --
    Trust the Computer. The Computer is your friend.
  8. Re:Duh. Its called reflection by Ageless · · Score: 1, Insightful

    No, it doesn't. With Java reflection you can access the exact same methods that you can access via compiled code. It's just done at runtime. The article/book points out a flaw in .Net that allows code to access private methods that it would not normally be able to access through normal access control. This flaw does not exist in Java.

  9. Re:Is this a C# or a .NET problem? by Anonymous Coward · · Score: 5, Insightful

    This whole story is hilarious. All (decent) languages let you hide implementation details from the end user. Finding them isn't `hacking` - its `stupid` as it means that if a chunk of code is changed to use, say, a doubly linked list rather than an array, your code would break, whereas it wouldn't if you accessed only the public methods/variables.
    This `exploit` is laughable, pointless and ultimately going to waste your time. The sort of coders who could use it would have the skill to figure it out in the first place anyway.

  10. Completely Irrelevant by sethamin · · Score: 5, Insightful
    Oh for god's sakes people, this is just dumb. There's no real reason to take the performance hit and enforce this at run-time, because the protection of private member variables are there for your benefit. If you want to access undocumented variables that were never meant to be exposed, you're just asking for bugs and future incompatibility.

    Oh, and BTW, this has nothing to do with actual security. Relying on access level specifiers to protect sensitive data in memory is lunacy. The standard coding technique for dealing with things like passwords is to keep them around for as short a period of time as possible and then overwrite that memory afterwards with random bits. If you're storing them long term cleartext in memory then you've got bigger problems.

  11. I Love Short Books by jetkust · · Score: 2, Insightful

    The whole text weighs in at just under 50 pages

    Good. I always hate books that are 1000 pages long just so the author can meet some type of quota. When in reality, the book is just full of extra fluff,and is much less useful as a learning tool because of it. To me, the best programming books are short. You can read them,learn, flip through them with your thumb, and each page has a lot of information. Once it gets too long it looses focus. And at this point, searching the internet and reading online help files starts seeming like a way better idea.

  12. Re:Stop the anti-MS BS all the damned time by Delirium+Tremens · · Score: 4, Insightful
    Java certainly does not allow access to private class members from client code. That will cause a compiler error, end of story. The only way it could conceivably be done is through object serialization and deserialization... [Pedantic emphasis added]
    Ever heard of AccessibleObject, JVMPI or Custom ClassLoaders? There, you have at least 3 ways to access private fields in Java besides your 'only way'.
  13. Re:Duh. Its called reflection by Anonymous Coward · · Score: 1, Insightful

    In C#, to call a private method "privateMethod" in Class2:

    (typeof(Class2)).GetMethod("privateMethod",Bindi ng Flags.NonPublic|BindingFlags.Instance).Invoke(Acti vator.CreateInstance((typeof(Class2))),null);

  14. private != secure by Vicegrip · · Score: 3, Insightful

    The point of private declarations was never to provide security. It was to get users of said code to access an object through a defined interface.

    A program, as far as the OS is concerned, has legal access to its entire process address space. So, whilst it's true that the virtual machine might be able to control access to private members by code written to run on top the vm, that data is still in memory and can be accessed by anything that can bypass the memory manager in the virtual machine. A linked library written in your favorite natively-compiled language of choice fills this bill nicely.

    In this case, the .NET manager does not completely protect private members. This is, at most, only ugly from a language purity sense. Probably it's a function of running natively through a jit compiler instead of on-top a VM.

    Summary: these new virtual machines do a decent job of protecting private members, but nobody in their right mind should rely on the mechanism for security.

    --
    Do not spread "09 F9 11 02 9D 74 E3 5B D8 41 56 C5 63 56 88 C0" over the internet, thank you.
  15. Re:Conclusion by ProfKyne · · Score: 3, Insightful

    Neither Perl nor C stuff depends on this encapsulation for any security stuff.

    Perl and C programmers are not target demographic of the .NET initiative.

    --
    "First you gotta do the truffle shuffle."
  16. Re:Isn't this a security issue? by tshak · · Score: 2, Insightful

    Now, in Java, acecss to private class members is strictly forbidden by the JVM.

    No, it's not. Please read up in this thread to see a few posts with examples of how to access private members in Java.

    But a lot of the .NET classes that Microsoft provides are written in C/C++ and have to access the system - and by messing up the private variables in these classes, there's no end to what you could possibly do...C#/.NET is supposed to be able to run in a sandbox...


    The point is that .NET does run in a sandbox of sorts, and the accessability of a class member can not circumvent that. So what if I can access a private member of some class that can delete system files? The runtime will detect that you aren't allowed to access the system files regardless of the accessibility of the method attempting to do so. Even if it's "Microsoft's code", it's not trusted because it's part of your program and running under it's security context, so the same security restrictions are placed on Microsoft's code as is yours, since your program is the one accessing it.

    --

    There is no longer anything that can be done with computers that is nontrivial and clearly legal. -- Paul Phillips
  17. Re:Conclusion by MSBob · · Score: 2, Insightful

    Depends on your security policy settings. You can restrict your policies so that nobody can get private member/field access through reflection.

    --
    Your pizza just the way you ought to have it.
  18. Re:Is this a C# or a .NET problem? by Anonymous Coward · · Score: 5, Insightful

    Sounds more like FUD from the *nix crowd.

    "The C++ access control mechanisms provide against accident - not against fraud. Any programming language that supports access to raw memory will leave data open to deliberate tampering..." The Annotated C++ Reference Manual, p 239.

    Encapsulation has NOTHING to do with security.

  19. getting around IllegalAccessException by fizbin · · Score: 3, Insightful

    Sure you do, if you try to access them without first calling setAccessible .

    However, it's pretty easy to turn that exception off unless there's a SecurityManager installed.

    Conclusion? Don't make any java code a security boundary without putting a SecurityManager properly in place. This also implies that java code at security boundaries has trouble being fast, but that's the case with any code at security boundaries.

  20. Some clarifications by DanAppleman · · Score: 2, Insightful
    I've enjoyed reading the many comments so far (well, most of them). Just a few clarifications:

    1. I am not anti-Microsoft. I thoroughly enjoy coding in .NET. The eBook is not anti-Microsoft or anti-.NET

    2. This eBook does not break .NET security or demonstrate a flaw in .NET security. It does, however, teach an important point - that member visibility is not a security boundary. Failure to consider this could result in a developer doing a security Assert within a private member and inadvertantly create an exploitable security flaw in their code - which is an extremely serious issue.

    3. This is not a design flaw in .NET. Private member access is necessary for object serialization in .NET and is itself secured via code-access security.

    Dan

    1. Re:Some clarifications by The+Bungi · · Score: 2, Insightful
      The eBook is not anti-Microsoft or anti-.NET

      Then perhaps you shouldn't have named it 'Hijacking .NET', eh? What's wrong with '.NET Internals' or something that didn't smack of evil unauthorized and insecure hacking?

  21. Re:C++ by anshil · · Score: 2, Insightful

    """Should we choose our tools based on how free they are, or on how useful they are to us"""

    Well in the case is the freedom not just a special kind of usefullness? Especially if usefullness is weighted in a longer term

    --

    --
    Karma 50, and all I got was this lousy T-Shirt.
  22. subtitled... by Royster · · Score: 2, Insightful

    ...How to Write Code Guaranteed to Work Only with Microsoft's Implementatyion of .NET and Not Mono.

    --
    I have discovered a truly marvelous sig, unfortunately the sig limit is too small to contain i
  23. El Stupido... by Lodragandraoidh · · Score: 3, Insightful

    Seems like a bad thing to implement an interface to a non-documented API for mission essential code.

    The problem with this is that Microsloth can easily change their non-public interface without telling anyone and your code will break. Other than the lack of security implied by accessing things that are supposed to be secure, this interoperability issue will come back to haunt anyone who implements these 'tricks' IMHO.

    Don't put this in mission essential code, or you will recieve a phone call late one night by your operations staff for unknown reasons...you have been warned.

    --

    Lodragan Draoidh
    The more you explain it, the more I don't understand it. - Mark Twain