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…

Comments (4)

  1. Why not just reflect against Child?

  2. Carl Daniel [VC++ MVP] says:

    The behavior of C++ (at least Standard conforming C++) is exactly as you describe for C# – Malicious does NOT have access to the Base part of a Derived instance.

    Make the obvious changes to your example to make it legal C++ and compile it with VC 7.1:

    >cl -c -GX protected0904.cpp

    Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 13.10.3077 for 80×86

    Copyright (C) Microsoft Corporation 1984-2002. All rights reserved.


    protected0904.cpp(24) : error C2248: ‘Base::_password’ : cannot access protected member declared in class ‘Base’

    protected0904.cpp(7) : see declaration of ‘Base::_password’

    protected0904.cpp(5) : see declaration of ‘Base’