LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Faking uids (https://www.linuxquestions.org/questions/programming-9/faking-uids-917910/)

eric.frederich 12-09-2011 09:46 AM

Faking uids
 
Is it a security problem that I can trick applications into thinking I'm someone else by using LD_PRELOAD to load a library that overrides getuid and geteuid?

I found this trick to work on a 3rd party application that lets you log in without a password if a username exists in the system that matches the OS's username.

This trick however does not work, for example, when using ls trying to see the contents of a folder with permissions 700.

So is there a better way for applications to tell who is running them than to trust the value returned from getuid (as it can be overridden)? I'd like to report the problem to the application vendor with a suggested fix.

Thanks,
~Eric

anomie 12-09-2011 10:48 AM

Quote:

Originally Posted by eric.frederich
Is it a security problem that I can trick applications into thinking I'm someone else by using LD_PRELOAD to load a library that overrides getuid and geteuid?

I'd say any mechanism that allows you to authenticate as someone you're not represents a security problem.

Quote:

Originally Posted by eric.frederich
So is there a better way for applications to tell who is running them than to trust the value returned from getuid (as it can be overridden)? I'd like to report the problem to the application vendor with a suggested fix.

At this point I'm mainly curious about why your "workaround" is effective on the third-party app only. Have you tried writing a simple program to confirm that getuid() and geteuid() are tricked in this way?

MTK358 12-09-2011 11:03 AM

Quote:

Originally Posted by eric.frederich (Post 4545925)
Is it a security problem that I can trick applications into thinking I'm someone else by using LD_PRELOAD to load a library that overrides getuid and geteuid?

I'm not sure what you mean. You can create a fake library that tells the application that it's running under a different user account, but that doesn't mean that's it's actually running under that account as far as the OS is concerned.

eric.frederich 12-09-2011 11:12 AM

Quote:

Originally Posted by anomie (Post 4545980)
At this point I'm mainly curious about why your "workaround" is effective on the third-party app only. Have you tried writing a simple program to confirm that getuid() and geteuid() are tricked in this way?

Sample program: test.c
Compile with gcc -o test test.c

Code:

#include <stdio.h>
#include <unistd.h>

int main(int argc, char* argv[]){
    printf("Hello %d\n", getuid());
    return 0;
}

Wrapper: runas.sh
Compiles a library overriding getuid and geteuid, puts it in LD_PRELOAD, and then runs a command.
Example: ./runas.sh johndoe ./test

Code:

#!/bin/bash

THE_USER=$1
THE_UID=`id -u $1`

echo "The User: $THE_USER"
echo "The UID : $THE_UID"

cat << 'EOF' > /tmp/libbecome${THE_USER}.c
int geteuid() {
  return FAKE_UID;
}

int getuid() {
  return FAKE_UID;
}
EOF

gcc -DFAKE_UID=`id -u $THE_USER` -shared -fPIC -o /tmp/libbecome${THE_USER}.so /tmp/libbecome${THE_USER}.c
rm /tmp/libbecome${THE_USER}.c
export LD_PRELOAD="/tmp/libbecome${THE_USER}.so"

shift 1
$*

rm /tmp/libbecome${THE_USER}.so


eric.frederich 12-09-2011 11:15 AM

Quote:

Originally Posted by MTK358 (Post 4545996)
I'm not sure what you mean. You can create a fake library that tells the application that it's running under a different user account, but that doesn't mean that's it's actually running under that account as far as the OS is concerned.

Exactly. This would be why I can't use this trick to run the ls command on a directory I don't have access to... because I'm not fooling the OS.

I am however, fooling the application and I'm wondering if there is a better way for the application to check the ID rather than just trusting the returned value of getuid.

Cedrik 12-09-2011 03:07 PM

Use syscall 24 directly ?
Code:

#include <stdio.h>

int main()
{
    int uid;

    __asm__ ("mov $24, %%eax;"
        "int $0x80;"
        "movl %%eax, %0;"
        : "=r"(uid));
           
    printf("uid: %i\n", uid);
    return 0;
}


eric.frederich 12-10-2011 07:32 AM

Thanks Cedrik
 
That worked. I'm assuming this fix is for x86 Linux only?

Is it foolproof? Is there no way to override this syscall?

Cedrik 12-10-2011 07:43 AM

yes it's for x86 Linux only.
You could make kernel module to fool syscalls, but it requires root privileges to insert module

SigTerm 12-10-2011 10:03 AM

Quote:

Originally Posted by Cedrik (Post 4546164)
Use syscall 24 directly ?

Good one. But isn't it still possible to bypass this by debugging program being launched?
It looks like there are routines for attaching to process, debugging it and modifying its memory.

Proud 12-10-2011 11:08 AM

You could also just run it in a VM. The app can always be fooled by just being able to obtain a copy of it. The OS can't without root/physical access.

Your app really need only trust what the OS/launch environment is telling it. If the binary itself contains some secret and a malicious user gets a copy of it to run so as to trick it to reveal the secret when running, they can also just extract the secret without usual execution. If it's an app that accesses some secret stored elsewhere, it's just a client, and you defer to server-side authentication.


All times are GMT -5. The time now is 01:30 AM.