Hijacking .NET
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.
Use a memory hex editor!
Rocket science is easy. Neurosurgery, now *that's* difficult.
If you code in a Microsoft programming language, you can't even trust your own code!
Is this a limitation of C# or of .NET?
.NET programs? I thought it was supposed to be possible to run .NET programs in a sandbox, protecting you from malicious code. It seems that being able to access private members in the .NET framework opens up a whole new world of possibilities for security holes...
What does this mean for the security of
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.
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...
In Java, the bytecode interpreter makes sure you can't access private class members. This is needed for security - creating the 'sandbox' which is most well-known from applets, and IMHO isn't used enough elsewhere.
.NET you don't have the same raw hardware access, but it looks like for speed Microsoft omitted to check access qualifiers at run time. But I wonder, is this part of the .NET specifications, or is it just an implementation oversight? Does the same trick work on Mono for example?
OTOH in C++ the public/protected/private distinction is enforced solely by the compiler, and code has full access to the machine.
Obviously in
-- Ed Avis ed@membled.com
Anyone who's looking into reflection at any depth knows that private members can be found and used without too much trouble. The only thing he's done here is actively tried to use the private functions of code he didn't right. What a genuis :-/
This is nothing new - you can do the same thing in C++. It's easy to access private variables or functions by manipulating a pointer.
So what's the big deal?
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.
..and is a very old technique.
Java, Modula2, Lisp and smalltalk all allow
this.
RTFM
...and here I thought thatd den_member> = 0; was bad style.
((<sneaky_private_type_I_wanna_access> *)<void_starish_opaque_handle>)-><ha_take_that_hi
You could've hired me.
I suspect the most common use of this is not attempts at bypassing poorly thought out security. I hope MSFT programmers are not hiding passwords in .NET classes. The most common usage will be "tweaks" and such that will be dependent on a specific .NET framwork version/release.
.NET framework version 1.0 for Windows 2000/XP, but come next release, these tweaks are likely to break. That's why private members of classes are private, because they are not part of the documented API.
By delving into the private classes, you might be able to get speedups on a specific (or common) platform, say MSFT's
Standard users, using standard techniques are only allowed to use public members and this is correct.
I think you'll find that if you're willing to write your own compiler, you can access provate methods in any language you care to name.
As such, this artile is irrelevant, an really just another pathetic excuse for a load of whingers to make cheap attacks on MS when they could *actually be contributing some effort* to the OS movement.
Carry on guys, good work.
-- Will program for bandwidth
So, a private member is not private.
All this fighting for Intellectual Property, for information privacy, DRM, to discover that actually, behind the scenes, in the Microsoft world,
a private member is not private
Look, ma, we'll sell this slow API, and on our side we'll use undocumented features, make private members public, get a performance boost and say afterwards we've got a better product and that it was all fair play.
Innovation, would say Ballmer.
Read on for more of Matt's review of this guide to tricking private members to do your bidding.
In related news, Washington State has banned the sale of this book because of gratuitous discussion of "private members".
This will be done using reflection. It's pretty easy to instantiate private objects, and call private members using the reflection functions in .net (System.Reflection) I'll post an example if anyone is that interested, but there are quite a few examples kicking around on the net.
.net only allows you to make these reflection calls if your application is running in "full trust". There is a very finely grained security model in .net, and applications can be trusted to make certain calls depending on the location they're running from (eg over the internet from an http:// address, on a network share, on the local disk); on whether the application is signed; by the vendor of the application; or even down to just a single program.
.net programmers mostly assume they're running in full trust mode (which if its on the local hard disk, they are). But this is a poor assumption which will fall by the wayside in the future as .net takes off.
However, the security model of
At the moment
To do other "unsafe" things (like use pointers, or interop into unmanaged code, generate dynamic code) you also need high permission levels.
Now let's compare this with the unmanaged world. I can load up a DLL and call what the hell I want. I can even jump right into the middle of a function if I want. I can over-run buffers and blow my stack. I can do what the hell I want within my virtual address space. I can send messages to other applications and make them do screwy things. And I'm probably running as a local administrator so I can do things to other processes too.
So is this a security concern? I don't think so.
I must admit, I haven't read the book - and I'm not going to shell out $10 to find out if I'm right.
Private members aren't for hiding code or data from other malicious programs; if they're being used in that way that's a flaw.
.class file from another app.
It's simply a compile-time verification that you're using the object through it's intended public interface instead of relying on the internal implementation. If you disregard it you just end up throwing away a lot of the benefits of OO and you build fragile apps.
That said, people should be aware of this so they don't mistakenly think that "private string m_password" is a secure way to store data.
BTW: A long time ago I did this in Java by programmatically altering the bytecode of a
I can finally call the BSOD member! uh.. nevermind...
This is NOT a security issue... A number of other languages allow this, most notably Java.
.NET, unless MS says that in fact they want to doubly use the private mechanism as a security measure. No other language that I'm aware of does this, you could even argue that it would be a plus in .NET's favor.
.NET, your simply ignorant or just want to toss mud.
Making a member private is NOT a security mechanism. It is a DESIGN mechanism. The point is to enforce a public interface to a class, not absolutely securing internal data or functions from external callers. Yes, they are similar and in some cases pretty damn close to synonymous, but they are still different goals.
This isn't a flaw in
If you want to say this design pattern is stupid, by all means do so. I would tend to agree. But if you want to use this as an opportunity to simply bash MS and
If a pion (n-) collides with a proton in the woods & noone is there to hear it, does lamdba decay into the source pa
The declaration of something as private, or not exported, or static, or the analog provided by your favorite programming language is a tool for the programmer, not the computer. It tells the programmer that this interface or piece of data is not be used by anyone but the author. It means that the interface or data could change at any time, and any use of it is a hack in the classic sense. It will probably work, in appearance or in actuality, but it will break unpredictably.
Private declarations may be enforced with varying vigor by compilers or runtimes, but usually there is a way around such enforcements. At the extreme, you can usually just directly access the memory in question, if the kernel allows that (or even if it doesn't, in the case of a super-user).
typically, a language ensures that a member marked as private is hidden from anyone who doesn't have your source code,
.NET), and that has a clear and readable bytecode (like .NET or Java), then you should use an obfuscator if you don't want anyone to be able to see your code.
.NET compile to x86 assembly language? .NET assemblies in escrow on behalf of their authors, releasing them only to trusted parties?
No, typically the process of compilation does that for a compiled language that is naturally hard to read, and an obfuscator is used to do it for interpreted languages that keep type information or are otherwise easy to read.
If you use a language that stores lots of rich metadata in the executable (like
This being slashdot, though, naturally it's all Microsoft's fault. But there's still an element of fun in deciding *why* it's all their fault! Is it:
1 -- MS's fault for not obfuscating code by default?
2 -- MS's fault for including metadata?
3 -- MS's fault for not having
4 -- MS's fault for not simply holding all compiled
5 -- MS's fault for not changing the nature of information itself to make this particular information hard to interpret?
Whence? Hence. Whither? Thither.
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.
You'll be arrested for breaking the DMCA!! After all what is a private method? Code that has access protection!
Besides, it's impolite to access stranger's privates if you weren't supposed to. If you're a 'friend', on the other hand, you presumably have access to all the privates of interest.
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.
Today Microsoft announced a major new feature in their .NET c# language. They have introduced a new keyword "really". To be used with the "private" keyword. By declaring something "really private" you can make sure that it will not be exported in a "blatantly obvious" manner.
For added security you can use the "really" keyword multiple times to define your level of security. So "really private" is less secure then "really really private".
Use of this keyword with other keywords such as "public" can have unpredictable results.
Invalid Checksum. Retrying.
No and no. Example:Looks like you need to brush up your C++ knowlege.
OO coders have known this for a couple of decades, I think. (I forget; when was the "private member" invented?)
Private members are a reliability measure, preventing subclasses from accessing members in dangerous ways, but certainly are not a security feature, because it's always possible to troll the object code.
Oh, and BTW: The Internet is not secure, either. "Internet Security" is a security blanket, not a security door.
The best "C" book out there is (was) "The C Programmer's Handbook" by Bolsky (AT&T Bell Laboratories). 84 pages. Small. Designed as a reference. C Syntax, precedence rules, a few funtions, ascii table, etc.
They used to include the book with each 3B (and other) unix box.
It was written to be useful, not to be big.
Invalid Checksum. Retrying.
How could this ever be a problem?
.net development model, is going open source!
This implies that Microsoft, in switching to the
Unofficially, of course. And people who implement it without being registered members of the Department of Homeland Security *could* be branded terrorist hijackers. But not to worry: only the evil ones will be. The others will accept automatic induction into the DHL framework.
Correct Horse Battery Staple: 72 bits of entropy. Enter "Correct H" into google. When it generates the phrase, that's
Good heavens! I'm a little startled at the thread so far -- all of these people stoutly declaring that violation of private class member access is not a security issue. I frankly thought that the Slashdot crowd understands these things a little better. If this matter is really so poorly understood, then the state of software security is in pretty bad shape.
Enforcement of access levels is an important feature of the security inherent in a programming language. Yes, you can trick your way around private in C++, and that is a security weakness of C++. Access to private members means that you have access to the internal implementation of a class, which the programmer specifically did not mean to let you have. To be sure, the fields you can manipulate may not do anything very interesting, and a hacker might not find a way to use them to compromise a whole system; but then again, may he can. You just can't know for sure any more. Generally, any code that can be made to execute instructions that the programmer did not intend is a potential security weakness. C programmers who write sprintf without bounds checking may be exposing their machine to a buffer overflow exploit; you just don't know.
Here's an example from Scott Oaks in Java Security: Suppose I'm using a shopping cart application that I downloaded from www.goodguys.com, and I trust it with my credit card number. Suppose they implement it by storing a CreditCard object as a member field. Suppose I'm also playing a game downloaded from www.badguys.com, and it's running in the same virtual machine; so it could conceivably access classes of the other application. I certainly hope that the first application prevents access to the CreditCard object, and I certainly hope that the virtual machine enforces that restriction very strictly.
Always keep a sapphire in your mind
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.
.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.
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
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.
Naturally even with rudimentary decompilers (and even the Java reflection API) you can find out what private fields and methods are defined for a given Java class.
.NET exploit advertises itself to be much different. Sure, you can still find out what private stuff you want.
.NET, it appears you can actually _invoke_ those methods, methods which are probably meant to be hidden under a separate security API layer, etc.
However if they are private, you can't actually find out the values of those fields for a given object, or call those methods. You get an IllegalAccessException.
This
But under
MORTAR COMBAT!
- Appleman's claim to fame are his efforts to bring advanced techniques to Visual Basic developers.
- His approach was basically this: OK, this is how you dereference a pointer in VB. Get it? But wait - that's unsafe!. So click on this link to buy my SuperDuper Pointer Dereferencing Library for VB, priced to go at $99.
- Appleman's "samples" were always flawed and biased, designed specifically to sell his ActiveX libraries and controls. He lost all credibility right after he published an essay on how to do multithreading from VB5, an essay that was also flawed in its premises and was also designed to sell his multithreading library. This "essay" was immediately slammed by the very people who wrote VB, including folks like Matt Curland.
- So now this guy (who used to work for Desaware - surprised?) does a "review" of Appleman's essay on how to "hijack"
.NET.
- What Mr. Dan "The Wiz" Appleman is doing here is nothing more insecure than calling class members directly using a vtable in a C++ application. Member visibility in C# (and in any other language) is a OO feature, not a security one. I'm not going into a discussion of
.NET app domain security - I'm sure anyone who is interested can head on over to MSDN and look by themselves. Suffice it to say that where it matters, you can't do this. And quite a few other things.
- This "evil technique" can also be applied to C++ and it can also be applied to Java. Wow!
- The only reason Slashdot posted this article is to reinforce the perception that
.NET sucks and is "insecure".
Witness the numerous clueless post on how "oh, I'm not surprisedComing soon - a story entitled "m$ .nyet 'sploid", by "h^xx0r". Read more (40 characters in body).
Well... you can jump through hoops in Perl to make something _really_ private if you want:
{
my $private_val = 4;
my $private_sub =
sub { return "whee" };
sub public_accessor {
print %$private_sub . $private_val;
}
}
As long as you declare your private subs as code references and use my, then no one can call them from outside that scope. Since Perl doesn't allow you to do pointer arithmetic the values are not accessible (unlike C++) (well, unless you have so craaazy lib loaded, then people can circumvent. But hell, you can always read the raw memory too).
-ben
Now, in Java, acecss to private class members is strictly forbidden by the JVM.
.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...
.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.
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
The point is that
There is no longer anything that can be done with computers that is nontrivial and clearly legal. -- Paul Phillips
It is not possible in Java. Otherwise you could access parts of java.lang.SecurityManager, which itself is written in Java. Not sure about .Net, but in Java you could do a lot of really nasty stuff if this was possible.
If this was possible in Java, Micrsosoft would have published at least three big reports on how insecure Java is (of course through some "independant" third party consulting companies)
Signature deleted by lameness filter.
If the alternative to writing tons of code is accessing private functions of the internal API, then the API was designed very poorly.
Everybody seems to agree that a quick ACL changer is useful. The code already exists in private functions. If the private functions should not be public because they bypass data reliability checks, the API designers should provide a public function that provides a safe method to call the private function.
Encapsulation should be an absolute law. The maintenance headaches of ignoring encapsulation should be too great to encourage bypassing it.
Providing useful functionality in private functions without allowing the functionality through public functions is security through obscurity. It either enourages programmers to write poor code, or forces the programmers to do extra work. The whole point of "platforms" is that they greatly reduce the amount of code needed to implement an application while providing basic functionality such as security and networking.
Imagine if Apache did not exist and every application needed to implement a web server. Every web project would require much more code. Now imagine if the only method to get Apache to display a web page was to use tricks to access private functions. Everybody would do it. Now imagine MS wrote the API. Oops, that is what we have here. Really basic and useful functionality is hidden from the programmer. "Luckily" the platform security is so poor that everybody knows how to access the functions anyway.
Apparently these tricks are posted on Microsoft's web site (based on from other posts since I am not going to check.) Apparently MS knows the functions are useful. Apparently MS knows the language is broken.
Will MS fix the API?
Will MS fix the language?
Will MS encourage these tricks?
Will MS break the code that uses these tricks?
Will MS reduce the amount of work necessary to write apps on their platform?
Will MS divide programmers between the
- experienced ones who know the illegal tricks,
- newbies who thought documentation was complete, and
- good programmers who expect MS to fix the code someday and are not willing to risk using these tricks?
I am happy I am not one of those programmers who is faced with the choice to write good code or write MS code.
I spend my life entertaining my brain.
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.
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
Check the documentation on the ReflectionPermissionFlag Enumeration to see what's going on. By default, for code that you're running on your own machine, you can do anything that you want. You can modify the settings with the framework configuration applet, or with some command line programs.
The end result is, you can turn this feature off.
I'm tired of /. being used to sell sh!t in posts.
The author is promoting bad programming practice, if his code becomes in common use he will force Microsoft to lock the internal implementation of the objects, which will make them inefficient and may lock in bugs. If his code is not popular than Microsoft will probably change it under him and break all his code, and this is perfectly within their rights, as the whole point of "private" is that this portion is not part of the API and it may change!
Another place it's use is in design by contract (the Digital Mars C++ compiler has it), where you make "promises" about the state of an object, can you can only break that promise within a private member. Note, though, that like the private keyword this is a compiler enforced directive on the developer, NOT a security model! It's to help you write bug-free code, not to keep someone from accessing your private data.
A private member indicates that it's used to provide internal functionality to a class - that it shouldn't be used from outside that class. Private members are subject to change, because they're an implementation detail.
...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
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
As many people have already pointed out, this is not a security hole in the
That being said, let me show how this can be done, and how using code access security, you can prevent this. Note that the default policies for code from the Internet and Intranet zones will not allow this code to run.
Note that if you want to prevent member access, the
As many have already pointed out, calling someone else's internal member is an excellent way of making your application fragile and adding a source of potentially incorrect behavior. There's no guarantee that someone else's private members will be there or work the same way in a future version (including a service pack) - that's why they're private.
The author's point of using P/Invoke declarations from the
About the only good reason to use Reflection to call private members is for hiding details of a Reflection-based set of functionality where the details of a particular implementation aren't interesting to users. An example would be TypeConverters. Here there's a general design pattern and you may write a TypeConverter for your type, yet you could mark it private if it is really not worth seeing in an object browser or Intellisense. Using Reflection, an instance of this class could be created. However, this isn't a generally recomended technique.
With this being said, here's an example of how to use Reflection to call private members, and shows that the