Take the 2-minute tour ×
Information Security Stack Exchange is a question and answer site for Information security professionals. It's 100% free, no registration required.

I suppose that if a file is executable by anyone, in other words, if a user has enough permissions to execute an executable in Windows, it will be possible to read the contents of the executable and copy it in another directory in one way or another. However, I have tried to give just execution permission and not read permission to an executable and I've been able to do it when the file is an EXE but not when the executable is a .NET file.

In that case I used this combination of permissions:

enter image description here

Is it possible to just allow the execution of a .NET executable and disable copying the file to another directory or opening it with a dissassembler or debugger?

share|improve this question

3 Answers 3

up vote 7 down vote accepted

(Warning: here I am making some "educated guesswork", notably by analogy with what happens in other operating systems.)

The behaviour you describe is normal: a .NET executable is actually a kind of script. From the point of view of the operating system kernel, there is no ".NET". The kernel knows of executable files. For the kernel, a file can be accessed for reading (an application opens the file and then read the bytes with calls like ReadFile()) or for executing (see CreateProcess()). When executing some binary files, the file contents are mapped into RAM through the MMU; at the MMU level, pages have both read and execute rights enabled. However, if the file to execute is a script, then the binary file which actually gets mapped into RAM is not the script file itself, but the interpreter. The interpreter then reads the script contents as data.

Thus, when an executable file is a script, then the actually required access rights are "execute" on the interpreter, and "read" on the script file. The OS will also require the "execute" right on the script file before accepting to locate and launch the interpreter.

A .NET executable file is, from the point of view of the Windows kernel, a kind of script; its interpreter is the CLR virtual machine. For the kernel, the CLR is nothing special. The CLR will read the .exe contents, find the bytecode and interpret it (that "interpretation" will include some JIT compilation but that's another story).

In any case, even if a user has only the "execute" right on a binary file but not the "read" right, then chances are that the user can attach to the resulting process and then read the file that way -- because, at the MMU level, the pages containing the code will be both executable and readable. It seems most unwise to rely on these access rights to prevent reverse-engineering.

share|improve this answer
    
Minor nitpick: A .Net executable contains at least a small stub of real executable code. It's this small stub which starts the interpreter. See also stackoverflow.com/questions/6101388/…. And your suspicion is right: the user can also read an executable via LoadLibrary() instead of ReadFile. –  MSalters Jul 10 '13 at 14:52
    
@MSalters I'm pretty sure that newer versions of windows don't use that stub anymore and contain direct .NET support. –  CodesInChaos Sep 1 at 14:30

Not directly, in order for a program to be executed, it must be read. What you can do however is setup a program to run as a user and only give that user permission to read/execute. Then I believe you might be able to authorize a user to run the link, but not have them be able to access the executable that is being run by the link.

Update: It appears I may have been mistaken about the ability to do this with a shortcut. You can setup a service to run as a particular user but there does not appear to be a way to cache credentials for a desktop shortcut. I also don't think it would be possible to get the service running in a different context to interact with the user's desktop without some fancy programing. In theory, you might be able to have a service running in a different users context do the secure stuff by some kind of remoting, but that is going to be really complex and beyond the scope of what I could actually describe here. (I'd have to research it quite a bit myself.)

share|improve this answer
1  
I'm sorry but I don't see your point. How are you going to "setup a program to run as a user"? In fact, my question is trying to solve this question and the only way I have found is by using specific permissions but when I put that permissions the file can't be executed if it is a .NET executable. Can you elaborate a bit further? –  kinunt Jul 3 '13 at 16:33
    
-1 I don't see how you (and/or the two upvoters) think this would work. –  Adnan Jul 3 '13 at 17:40
    
@Adnan - Windows supports configuring a program to run as a different user. The process is initialized within the user context of that cached user. The program thus has access to things that the user would normally not have access to. You might have to use a launcher though as the first executable being called may need to be readable, I'm not 100% sure of how the credential caching works. –  AJ Henderson Jul 3 '13 at 17:53
    
Err, doing some more digging, I could only find ways to do this for a service. Not sure if there is a way to do it with a normal program shortcut. I thought there was, but I may have been mistaken. –  AJ Henderson Jul 3 '13 at 17:57
using System.IO;
using System.Security.AccessControl;
using System.Security.Principal;
using System.Reflection;

static void Main()
{
    //////////// Security Prolog
    var codeBase = Assembly.GetExecutingAssembly().CodeBase;
    var uri = new UriBuilder(codeBase);
    var folderImage = Uri.UnescapeDataString(uri.Path);

    var fs = File.GetAccessControl(folderImage);
    var rules = fs.GetAccessRules(true, true, typeof(NTAccount));

    foreach (AuthorizationRule rule in rules)
    {
        if (rule is FileSystemAccessRule)
            fs.RemoveAccessRule((FileSystemAccessRule)rule);
    }

    fs.SetAccessRuleProtection(true, false);
    File.SetAccessControl(folderImage, fs);

    //////////// Startup Main
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new Form1());

    //////////// Security Epilog
    foreach (AuthorizationRule rule in rules)
    {
        if (rule is FileSystemAccessRule)
            fs.AddAccessRule((FileSystemAccessRule)rule);
    }

    fs.SetAccessRuleProtection(false, false);
    File.SetAccessControl(folderImage, fs);
}
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.