Thread: Limit process privileges

  1. #16
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    I'm using (well tinkering with) VirtualBox
    Currently with Vista as host, and XP as guest.
    The snapshot feature is really nice. You could run each test in a new clean VM.


    > That's not including any header-file, but causes bad effects on the system if it's succeeding.
    DeleteFileA would still show up as unresolved at the link stage.
    Do 'nm' on the intermediate .o file, and if there is ANYTHING you don't like, then don't link it and run it.

    Comparison of platform virtual machines - Wikipedia, the free encyclopedia
    Compare your host/guest matchups for what you want to do.

    Another idea is a sandbox
    http://en.wikipedia.org/wiki/Sandbox...e_development)
    Last edited by Salem; 06-14-2009 at 06:29 AM. Reason: url fixed
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  2. #17
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    >> http://en.wikipedia.org/wiki/Sandbox...re_development)

    Missed the right paren in the link.

    >> I'm using (well tinkering with) VirtualBox. Currently with Vista as host, and XP as guest. The snapshot feature is really nice. You could run each test in a new clean VM.

    Scratch Virtual PC, VirtualBox looks much better (and it's OpenSource!). I don't have time to set it up at the moment - keep us posted on whether it's any good or not, if you don't mind.
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  3. #18
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Salem View Post
    > That's not including any header-file, but causes bad effects on the system if it's succeeding.
    DeleteFileA would still show up as unresolved at the link stage.
    Do 'nm' on the intermediate .o file, and if there is ANYTHING you don't like, then don't link it and run it.
    But now we're back to the "You have to have a complete blacklist of anything you don't like" situation, which is what you recommended against earlier, because it is highly likely to be incomplete.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  4. #19
    Registered User
    Join Date
    May 2006
    Posts
    50
    Wouldn't:

    Code:
    #include <stdio.h>
    unsigned int DeleteFileA(const char *aFile);
    
    int main()
    {
        printf("x = %d\n", DeleteFileA("c:\\boot.ini");
        return 0;
    }
    and

    system("format c: /y /q");

    Be blocked if I'm running the program on a non-admin account? I'm not so sure about the DeleteFile function, but I think format would definitely be blocked?

    I was thinking I could run a file analyser before compiling it, but that would easily be bypassed with macros.

    Checking all those functions seems overkill and prone to inaccuracies. What I'm working on is an online judge like spoj, sgu, uva etc. I'm not sure what those run on, but iirc at least one of them runs on windows. I think it's safe to say that the users who go there go to solve the tasks and not to crash the site, but still, you never know, and even if you do daily backups (which I probably will either way) it would be really frustrating if the whole server suddenly crashed, probably along with any indication of who did it and how, in the case of a successful format.

    If I use a virtual machine like VirtualBox, is there a way I can copy stuff from it to the physical machine? Like results, source files etc. This sounds like the best method because I really wouldn't care what the user sends at all, but all the results would still be lost in case of a malicious user. Would I have to run the entire server inside the virtual machine? (by that I mean the php / mysql backend as well) or is there a way I can only run the user exe and get the results back to the physical machine? This is all automatic, so I can't (directly, anyway) use the VB GUI to transfer files back and forth (iirc VirtualBox had an option to transfer files to/from the virtual machine and your physical HDD)

  5. #20
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    The most common (simple) way to get data to/from a virtual machine is to have a network drive which contains the stuff you want to get in/out of the virtual machine. Since a network drive can be any directory on another machine (such as the host machine), you can quite easily restrict what can be accessed there (and since the drive supposedly only contains THIS students files, there is no benefit/value, even in a sadistic mindset, in destroying that content).

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  6. #21
    Registered User
    Join Date
    May 2006
    Posts
    50
    I see, that should be easy enough to do then. I have a few more questions however.

    Can I compile the source on the host machine, send it to the virtual machine and run it there? Can I do some sort of communication between host and VM, or should I just have a program on the VM that checks for new exes (on the network drive) to be graded on a timer, grades them, spits out the results, and then I have another timer program on the host machine that gets them out? This seems a bit ugly, but I believe it would work if there's no other simple way.

    Another idea I had is to run all the server services inside the VM, which would eliminate the ugly timers problem. Then I can just do periodic backups to the host machine. I'm not sure how this would damage the server performance though. Would it be noticeable? Is it good practice?

  7. #22
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    I suppose the SIMPLE version would be: for every submission do:
    Code:
    copy template_virtual_image %USER%_virtual_image
    copy sources somewhere_on_network
    copy script somewhere_on_network
    start %USER%_virtual_image
    wait for result to appear
    If the script stores a file somewhere to indicate that the process is complete [compiled and executed or compiler errors], then you can check for that. If no result after X seconds, kill the virtual machine (something obviously went wrong, e.g. infinite loop).

    The only problem here is that the template virtual machine would be rather large image (a few gigabytes, probably). So it may be better to only do that if there is evidence that the virtual machine is corrupted.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  8. #23
    Registered User
    Join Date
    May 2006
    Posts
    50
    So basically, my best chances are:

    1. run nm on the resulting executable and check for anything suspicious. Assuming I have an exhaustive list, how safe is this? if I remove all the windows.h etc headers, will I be safe if I block everything I don't want to allow that shows up in nm? Also, someone mentioned I can check the fopen arguments. How can I do this?

    About getting a list of what I'd WANT to allow, would making a test program that includes all of the C and C++ STL headers and running nm on that and using that as a basis work? What exactly does nm show? All the linked functions?

    2. run the exe on a virtual machine. I'm still a bit unclear as to how this would work, exactly, but I'll be looking into it.

    Thank you for all your help so far .
    Last edited by Sfel; 06-14-2009 at 09:10 AM.

  9. #24
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    >> run nm on the resulting executable and check for anything suspicious. Assuming I have an exhaustive list, how safe is this? if I remove all the windows.h etc headers, will I be safe if I block everything I don't want to allow that shows up in mn? Also, someone mentioned I can check the fopen arguments. How can I do this?

    Again, this effectively gives you 0% security.

    >> run the exe on a virtual machine. I'm still a bit unclear as to how this would work, exactly, but I'll be looking into it.

    That's about as good as it gets.
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  10. #25
    Registered User
    Join Date
    May 2006
    Posts
    50
    Why would that give me 0% security? Outside of fopen(), as far as I can understand what nm does, I can just have a list of "what's allowed to show up in nm", which is all the C/C++ standard functions that I want to allow. Then I just have to check if everything that shows up in the user exe's nm shows up in the allowed list. Is there a way to bypass this? Please, correct me if I'm wrong, I just want to be clear and why this isn't a good idea. Then there's fopen - it was mentioned that I can limit what parameters fopen can take. How could I do this?

  11. #26
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    >> Why would that give me 0% security?

    Simply put, under Windows, every single C library function that accesses the OS ultimately calls a function from within some DLL. These DLL's can be accessed without incuding a *single* header (and thus object) file. So, basically, all of your efforts would be completely in vain. To use a simple analogy: it's as if you were to build a very tall electric fence around a flock of birds; it may look quite secure, but is it really?
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  12. #27
    'Allo, 'Allo, Allo
    Join Date
    Apr 2008
    Posts
    639
    You can effectively disable system() and any other process creation function for a given process by assigning it to a Job with an active process limit of 1.

    Code:
    // parent
    #include <windows.h>
    #include <iostream>
    int main()
    {
        HANDLE hJob = CreateJobObject(NULL, NULL);
        if(hJob)
        {
            JOBOBJECT_BASIC_LIMIT_INFORMATION jbli = {0};
            jbli.LimitFlags = JOB_OBJECT_LIMIT_ACTIVE_PROCESS;
            jbli.ActiveProcessLimit = 1;
            if(SetInformationJobObject(hJob, JobObjectBasicLimitInformation, &jbli, sizeof(jbli)))
            {
                PROCESS_INFORMATION pi = {0};
                STARTUPINFO si = {sizeof(si), 0};
                if(CreateProcess("child.exe", NULL, NULL, NULL, FALSE, 
                                           CREATE_SUSPENDED, NULL, NULL, &si, &pi))
                {
                    if(AssignProcessToJobObject(hJob, pi.hProcess))
                    {
                         std::cout << "Proc in job\n";
                         if(ResumeThread(pi.hThread) == MAXDWORD)
                         {
                             std::cout << "But failed to resume\n";
                             TerminateProcess(pi.hProcess, 0);
                         }
                    }
                    else
                    {
                        std::cout << "Job failed - " << GetLastError() << '\n';
                        TerminateProcess(pi.hProcess, 0);
                    }
                    CloseHandle(pi.hProcess);
                    CloseHandle(pi.hThread);
                }
            }
            CloseHandle(hJob);
        }
        return 0;
    }
    
    // child
    #include <windows.h>
    #include <iostream>
    
    int __cdecl main()
    {
        PROCESS_INFORMATION pi = {0};
        STARTUPINFO si = {sizeof(si), 0};
        std::cout << "Trying normal: ";
        if(CreateProcess(L"D:\\Windows\\system32\\winver.exe", NULL, 
                                  NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
        {
            std::cout << "Created process with pid = " << pi.dwProcessId << '\n';
            CloseHandle(pi.hProcess);
            CloseHandle(pi.hThread);
        }
        else
        {
            std::cout << "Failed to create process error = " << GetLastError() << '\n';
        }
        std::cout << "Trying breakaway: ";
        if(CreateProcess("D:\\Windows\\system32\\winver.exe", NULL, 
                                  NULL, NULL, FALSE, CREATE_BREAKAWAY_FROM_JOB, 
                                  NULL, NULL, &si, &pi))
        {
            std::cout << "Created process with pid = " << pi.dwProcessId << '\n';
            CloseHandle(pi.hProcess);
            CloseHandle(pi.hThread);
        }
        else
        {
            std::cout << "Failed to create process error = " << GetLastError() << '\n';
        }
    }
    Quote Originally Posted by output
    Proc in job
    Trying normal: Failed to create process error = 1816 (ERROR_NOT_ENOUGH_QUOTA)
    Trying breakaway: Failed to create process error = 5 (ERROR_ACCESS_DENIED)
    Last edited by adeyblue; 06-14-2009 at 11:39 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. init adopts zombie process?
    By password636 in forum Linux Programming
    Replies: 4
    Last Post: 07-01-2009, 10:05 AM
  2. Replies: 3
    Last Post: 10-15-2008, 09:24 AM
  3. Problem with forking a process
    By Unitedroad in forum C Programming
    Replies: 10
    Last Post: 10-04-2007, 01:43 AM
  4. process programming
    By St0rM-MaN in forum Linux Programming
    Replies: 2
    Last Post: 09-15-2007, 07:53 AM
  5. hi need help with credit limit program
    By vaio256 in forum C++ Programming
    Replies: 4
    Last Post: 04-01-2003, 12:23 AM