Quiz: Who can access your state? (Answer)
Wow – a ton of responses, thanks. The reason I chose it is because it is fairly deceptive. At one level Malicious can’t access the data Child stores in _password, that would be “wrong”. But then you realize that _password is just a protected member of base and by pure OO rules I should be able to access it from Malicious. In fact even C++ allows you to do exactly that. But alas those deeply versed with the C# or more correctly the CLI specs will note that you have to access those protect members via an instance of your own type. That is if it had been:
public String StealPassword(Malicious child)
Malicious would have been able to access _password, but then of course there would be no exploit.
So, that lends us to actually trying this out. As many of you noted, you get a compiler error:
foo.cs(32,18): error CS1540: Cannot access protected member 'Base._password' via
a qualifier of type 'Child'; the qualifier must be of type 'Malicious'
(or derived from it)
But, that is just the C# compiler enforcement. A real hacker would not let that stop them, right? So with a little help from ILASM.exe and ILDASM.exe I was able to produce an assembly that is roughly equivalent to what the code would be if it could be compiled. I checked it out with peverify.exe and sure enough the verifier rejected it:
[IL]: Error: [d:\documents and settings\brada\foo.exe : Malicious::StealPassword
] [offset 0x00000001] [opcode ldfld] Field is not visible.
1 Errors Verifying foo.exe
But, the real test, I copy it to a network drive (to ensure the verifier runs) and try to execute it… As expected:
Unhandled Exception: System.Security.VerificationException: Operation could dest
abilize the runtime.
at Malicious.StealPassword(Child child)
at Program.Main(String[] args)
Good to know this one is covered by the runtime!
ps – sorry for the long delay, it has been a crazy week…