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.
Make any private member acessible. (Score:2, Insightful)
Re:Make any private member acessible. (Score:2)
Conclusion (Score:4, Funny)
Re:Conclusion (Score:5, Insightful)
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
Re:Conclusion (Score:4, 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.
Re:Conclusion (Score:4, Interesting)
-B
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 mar
Re:Conclusion (Score:3, Interesting)
Re:Conclusion (Score:4, Interesting)
Perhaps there are still ways to get round this security by something more lowlevel, like peeking directly into RAM, but they certainly aren't at all easy.
Re:Conclusion (Score:3, Funny)
So as long as I run it here, I'm OK. Is that what you are saying?
Re:Conclusion (Score:3, Insightful)
Is this a C# or a .NET problem? (Score:4, Interesting)
What does this mean for the security of
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:Is this a C# or a .NET problem? (Score:5, Insightful)
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.
finding them? sure. calling them? no. (Score:5, Interesting)
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
getting around IllegalAccessException (Score:4, Insightful)
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.
Re:Is this a C# or a .NET problem? (Score:5, 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:Is this a C# or a .NET problem? (Score:5, Informative)
- Jalil Vaidya
C++ will let you do anything! (Score:5, Informative)
No and no. Example: Looks like you need to brush up your C++ knowlege.
Re:Is this a C# or a .NET problem? (Score:5, Informative)
The
Not a problem at all (Score:4, Funny)
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.
Re:Is this a C# or a .NET problem? (Score:5, Insightful)
"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.
This is NOT a problem! (Score:3, Interesting)
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
Posted on BugTraq (Score:3, Insightful)
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.
By design? (Score:4, Insightful)
Re:By design? (Score:4, Interesting)
The problem is the same like the old one which let you disassemble VisualBasic programs back to the sourcecode about some years ago.
If you put a trade secret inside your code, it is now much easier to access by an outsider because she doesn't have to rely on the binary code alone, but can spy on the structure of the program. This gives her a pretty good clue which algorithm was used and which data structures were used.
Basicly it makes everything you do in
Re:By design? (Score:2)
So .Net is like C++? (Score:5, Interesting)
OTOH in C++ the public/protected/private distinction is enforced solely by the compiler, and code has full access to the machine.
Obviously in
Re:So .Net is like C++? (Score:5, Informative)
The
The key point is that
Re:So .Net is like C++? (Score:5, Insightful)
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.
Re:So .Net is like C++? (Score:2)
Unless you use one that doesn't
Re:So .Net is like C++? (Score:2)
It's mostly a set of renamed technologies and concepts and MS is trying to push it as being totally new and previously unheard of. This is why Sun is pissed at MS for the whole Microsoft & Java issue, as .
Dan 'Obvious' Appleman (Score:5, Interesting)
C++ (Score:5, Informative)
So what's the big deal?
Re:C++ (Score:4, Interesting)
But I think most open-sourcers are a little more sedate than that; they like C++ because C++ is completely free and nonproprietary (gcc is GPL, and C++ has been an ANSI standard for way over a decade, hasn't it?). So, in a sense, it's a language that no one can ever take away from you, and which has been more or less frozen in its current state (new functionality is generally handled with additional libraries) for years. C# and Java, on the other hand, are proprietary languages, so it is theoretically possible for the companies that own those technologies to change them on a whim, or even kill them off. I sympathize with this view somewhat, but I don't fully agree with it.
Is the "freeness" of a tool enough to support its use? Should we choose our tools based on how free they are, or on how useful they are to us? How do you pick a compiler, really? It's interesting.
I like Java, personally. It has pretty nice features and a rich API. I lust after C# somewhat, but my boss won't let me use it (he likes VB.Net -- pity me).
Re:C++ (Score:3, Insightful)
Well in the case is the freedom not just a special kind of usefullness? Especially if usefullness is weighted in a longer term
Re:C++ (Score:2)
Microsoft maybe in deeeeeep trouble now (Score:4, Funny)
public method doStuff ( &task ) {
if ( (int) (Math.rand() * 10) == 8) {
throwError(BSOD);
} else {
actuallyDoStuff ( &task );
}
}
}
private method actuallyDoStuff ( &task ) {
...
}
LOL! (Score:2, Insightful)
Heh!
Re:Microsoft maybe in deeeeeep trouble now (Score:3, Funny)
Unsure... (Score:4, Funny)
Maybe the title should be changed (Score:5, Insightful)
Re:Maybe the title should be changed (Score:2)
Re:Maybe the title should be changed (Score:2)
Re:Maybe the title should be changed (Score:4, Insightful)
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".
Duh. Its called reflection (Score:5, Informative)
Java, Modula2, Lisp and smalltalk all allow
this.
RTFM
Re:Duh. Its called reflection (Score:2, Informative)
Re:Duh. Its called reflection (Score:2, Interesting)
If you're running a
Re:Duh. Its called reflection (Score:2, Insightful)
Re:Duh. Its called reflection (Score:2)
You were saying?
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: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.
Harumph (Score:5, Funny)
((<sneaky_private_type_I_wanna_access> *)<void_starish_opaque_handle>)-><ha_take_that_hi
Re:Harumph (Score:2)
It gets the job done, but there are a lot of ugly fat people out there... do you really want to look at them naked too?
(In defense of the political incorrectness in this post, I will hastily admit that I am an ugly skinny person).
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
Re:More version incompatible program (Score:2)
Private methods and (Score:5, Interesting)
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.
Re:Private methods and (Score:3, Informative)
Re:Private methods and (Score:2, Insightful)
Re:Private methods and (Score:2)
If you write your own compiler, as you say, then you need the source code. The fact that reflection gives you private member access at
Justin.
Maybe a trust issue... (Score:2)
How about this:
Yay!
Microsoft Security (Score:4, Funny)
Re:Microsoft Security (Score:5, Interesting)
Why should they always bypass logic? (Score:3, Funny)
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.
Washington Strikes Again (see prior story) (Score:5, Funny)
In related news, Washington State has banned the sale of this book because of gratuitous discussion of "private members".
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.
Not unique to .NET (Score:2)
People who rely on protected/private to be a security featu
Re:Not unique to .NET (Score:2)
On
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
Sweet! (Score:3, Funny)
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:Stop the anti-MS BS all the damned time (Score:5, Insightful)
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).
Sigh (Score:5, Interesting)
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?
Completely Irrelevant (Score:5, Insightful)
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.
Don't do that!!!! (Score:2, Funny)
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.
It is all by design... (Score:4, Informative)
Idea - I'll use this to..... (Score:2)
Oh wait........ That's already been done before.
This is one of the main ways a debugger is written, right?
Oh, The Irony... (Score:2)
I Love Short Books (Score:3, Insightful)
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.
New .NET keyword (Score:2, Funny)
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
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.
Security (Score:3, Interesting)
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.
private != secure (Score:4, Insightful)
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.
Flamebait alert (Score:5, Informative)
Coming soon - a story entitled "m$ .nyet 'sploid", by "h^xx0r". Read more (40 characters in body).
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.
subtitled... (Score:3, Insightful)
El Stupido... (Score:4, Insightful)
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.
Re:and the point being? (Score:2)
similarly, i think that if you are going through these steps you are well aware of what you are doing and would understand the pitfalls of utilising other private member functions.
of course the fact does remain that its possible to do at all which, at first glance, i thought was scary. but other, more hardcore coders i
Re:and the point being? (Score:2)
What's really damning here is that this wasn't the intent, apparently. It's not lik
But (Score:3, Insightful)
Yes, you may say "Microsoft has just reinvented the wheel," but hopefully you'll agree that they've made a better version of the wheel in the process.
Re:But (Score:2, Informative)
Re:.Net is Java! (Score:4, Insightful)
After all, you ahve mod_perl, which does the same as servlets.
Perl runs most anywhere now-a-days.
Perl does XML with many various API's...
perl does OO too!
But wait, you can do the same thing with ASM. It's all a game. Java does business stuff really well. So can C# supposedly. Perl/php can be forced to do that, but truth is, they don't hold up, in terms of syntax and other things. php/perl doesn't FORCE OOP and business like objects. They just provide it. Java (and C# seems) to force the issue down your throat.
Re:.Net is Java! (Score:2, Interesting)
If Web Forms were servlets they would take longer to load, database accesses would take longer, server side processing would be slower, and high demand would crash your server.
If Web Forms were Servlets it would take several days to setup, configure and tune a new servlet environment a.k.a Web Form environment.
If C# were Java, you wouldn't have delagates and a fully event driven programming model. If C# were Java then you would have to sacrifice properply built objects and methods in ord
Re:Isn't this a security issue? (Score:3, Insightful)
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
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,
Re:Some clarifications (Score:3, Insightful)
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?