Hijacking .NET 561
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.
I've never used ebooks, but this sounds worth it (Score:0, Informative)
Mod me ignorant if you like, but this sounds like one damned nifty book and something MS certainly can't be proud of.
C++ (Score:5, Informative)
So what's the big deal?
Duh. Its called reflection (Score:5, Informative)
Java, Modula2, Lisp and smalltalk all allow
this.
RTFM
More version incompatible program (Score:4, Informative)
By delving into the private classes, you might be able to get speedups on a specific (or common) platform, say MSFT's
Unbiased?!? review (Score:1, Informative)
You can find out more about the rest of the Desaware team on the help file on the CD-ROM: Stjepan Pejic, Roan Bear, Marian Kicklighter, Karyn Duncan, Josh Peck, Levy Ring, Edo Mor, Michael Dickman, and Matt Solnit-thank you all for your help.
Matt Solnit (the reviewer)
How it's done (Score:5, Informative)
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.
Re:Duh. Its called reflection (Score:2, Informative)
Re:Is this a C# or a .NET problem? (Score:5, Informative)
Just because you can find out some "inner state" of an object doesn't mean that you're God now.
Oh, and the same "exploit" can be done with C++ - does this have a negative affect on security? No.
Encapsulation was never meant to be a security feature.
Re:Private methods and (Score:3, Informative)
Re:So .Net is like C++? (Score:1, Informative)
Security (Score:5, Informative)
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
Stop the anti-MS BS all the damned time (Score:5, Informative)
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
Re:So .Net is like C++? (Score:5, Informative)
The
The key point is that
Re:Is this a C# or a .NET problem? (Score:5, Informative)
The
Not a security issue (Score:4, Informative)
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).
Re:Is this a C# or a .NET problem? (Score:5, Informative)
Re:Duh. Its called reflection (Score:2, Informative)
Access can be controlled by a security manager; but the default for a java application is to allow access.
Re:Posted on BugTraq (Score:5, Informative)
No, not really, the private keyword is not meant to be a security mechanism. If you want to secure the data from program access you have to do it at the Kernel level.
You can view this info in the debugger if you have the source for the class.
The reason for making a method private is that the programmer does not undertake to preserve the API contract in future releases. So basically what this guy is doing is no different from those early MSDOS programs that bypassed the BIOS calling interface to call code directly. It was fast, you avoided the overhead of the context switch. However it also meant that the code was likely to fail on the next release of the PC.
Re:Stop the anti-MS BS all the damned time (Score:1, Informative)
Uh, if you put an intemperate heading over your post, perhaps it would be better if you refrain from putting nonsense into its body.
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, since the serialized form must respect the class definition, and deserialization must restore objects to their original state. The default serialization code makes it possible, but cautious programmers can prevent serialization from exposing private members by writing their own readObject() or readResolve() methods. (See chapter 10 of Joshua Bloch's Effective Java.)
And yes, exposing private members certainly is a security issue, because it gives client code the ability to manipulate the implementation of a class, which is meant to be encapsulated. The code can be made to do things that the programmer did not intend, and that is one of the things that makes software insecure.
It is all by design... (Score:4, Informative)
Re:Is this a C# or a .NET problem? (Score:5, Informative)
Ridiculous.
class hidden
{
private:
int frotz;
int ozmoo;
};
class hack_o_matic
{
public:
int frotz;
int ozmoo;
};
int main(void)
{
hidden H;
hack_o_matic *V = (hack_o_matic *) (ampersand) H;
printf("Hidden frotz member = %d",V->frotz);
}
The poster above who pointed out that both the review and its subject are goofy is correct. Data-hiding is an OOP convention, not a security feature.
C++ is a particularly good example (for values of 'good' that approximate 'horribly broken'), because the only way you can expose a class's public functionality is through a declaration of the entire class that includes all of its private members, which can subsequently be accessed through pointer hacks like the above. If you want to hide data for security purposes, as opposed to hiding data for design purposes, you have no choice but to use wrappers.
Re:But (Score:2, Informative)
Re:Duh. Its called reflection (Score:5, Informative)
For instance, to set the private field "x" on a Component:
import java.awt.*;
import java.lang.reflect.*;
public class YouAreWrong {
public static void main(String[] arg) throws Exception {
Button youAreWrong = new Button();
System.out.println("Button.getX() == " + youAreWrong.getX());
Field x = Component.class.getDeclaredField("x");
x.setAccessible(true);
x.set(youAreWrong, new Integer(5));
System.out.println("Button.getX() == " + youAreWrong.getX());
}
}
Go try it and see what happens.
C++ will let you do anything! (Score:5, Informative)
No and no. Example: Looks like you need to brush up your C++ knowlege.
Private members are not a security feature. (Score:3, Informative)
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.
Re:Is this a C# or a .NET problem? (Score:5, Informative)
- Jalil Vaidya
Flamebait alert (Score:5, Informative)
Coming soon - a story entitled "m$ .nyet 'sploid", by "h^xx0r". Read more (40 characters in body).
Re:By design? (Score:2, Informative)
Private Perl [was Re:Conclusion] (Score:3, Informative)
{
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
Re:Conclusion (Score:2, Informative)
Re:Conclusion (Score:2, Informative)
I haven't actually read Conway - maybe I should.
Depends on the current settings (Score:4, Informative)
Check the documentation on the ReflectionPermissionFlag Enumeration [microsoft.com] 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.
Re:Even easier... (Score:1, Informative)
#define private public
#define protected public
#define class struct
Struct and classes are essentially the same in C++; however, structs have public visibility by default.
Re:Classes (Score:3, Informative)
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.
No Security Hole - Just a Hideous Idea (Score:2, Informative)
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
Re:Conclusion (Score:3, Informative)
So what is the target demographic, mechanics? Albino carpet cleaners? Of course it's Perl and C programmers.
Give me a break. MS isn't going to make much money coming up with the next Perl or C. Perl is used for two very good reasons: devotion of the user base, and the CPAN. MS couldn't replicate either of those under any circumstances, and there isn't much money to be made in trying. C, on the other hand, is primarily used for writing Unix software. (Note that I did not say C++.) Not much of a market for Microsoft either.
.NET is targetting the Java market, pure and simple.