Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

__libc_start_main can be overrided without -nostdlib option #3

Closed
virusdefender opened this issue Jan 19, 2016 · 2 comments
Closed

Comments

@virusdefender
Copy link

As is described in the document

 long as gcc/g++ is invoked without the -nostdlib option, any attempt by the untrusted code to define an entry point (_start function) will result in a linker error, because the name _start will conflict with the real _start function defined in crt1.o

However, as I tested, there is no linker error.

#define _BSD_SOURCE // readlink
#include <dlfcn.h>
#include <stdlib.h> // exit
#include <string.h> // strstr, memset
#include <link.h>   // ElfW
#include <errno.h>  // EPERM
#include <unistd.h> // readlink
#include <seccomp.h>
#include <stdio.h>
typedef int (*main_t)(int, char **, char **);

#ifndef __unbounded
# define __unbounded
#endif

int __libc_start_main(main_t main, int argc, 
    char *__unbounded *__unbounded ubp_av,
    ElfW(auxv_t) *__unbounded auxvec,
    __typeof (main) init,
    void (*fini) (void),
    void (*rtld_fini) (void), void *__unbounded
    stack_end)
{

    int i;
    ssize_t len;
    void *libc;
    int (*libc_start_main)(main_t main,
        int,
        char *__unbounded *__unbounded,
        ElfW(auxv_t) *,
        __typeof (main),
        void (*fini) (void),
        void (*rtld_fini) (void),
        void *__unbounded stack_end);

    // Get __libc_start_main entry point
    libc = dlopen("libc.so.6", RTLD_LOCAL  | RTLD_LAZY);
    if (!libc) {
        exit(1);
    }

    libc_start_main = dlsym(libc, "__libc_start_main");
    if (!libc_start_main) {
        exit(2);
    }
    printf("Hijacked\n");    
    return ((*libc_start_main)(main, argc, ubp_av, auxvec,
                 init, fini, rtld_fini, stack_end));
}

int main()
{
    printf("Heloo world");
    return 0;
}
gcc 1.c -ldl -o test && ./test

gcc version 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04)

Although run this code with EasySandbox will get a segment fault, I think it maybe an way to bypass sandbox.

Maybe we can disable -ldl option to prevent using dlopen function.

@virusdefender virusdefender changed the title __libc_start_main can be override_without -nostdlib option __libc_start_main can be overrided without -nostdlib option Jan 19, 2016
@daveho
Copy link
Owner

daveho commented Mar 3, 2017

I will update the documentation to emphasize that linking with -ldl allows the application to bypass the sandbox. Thanks for the catch!

I think in general it is assumed that EasySandbox will only be used for executables where the compilation is controlled.

@daveho
Copy link
Owner

daveho commented Mar 3, 2017

I updated the README to advise against allowing untrusted code to link with -ldl.

@daveho daveho closed this as completed Mar 3, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants