Google Chrome as Root - The Revenge
Posted: Wed 19 Oct 2011, 15:54
Here's something I just wrote.
It's a simple launcher for Google Chrome that tricks it into thinking you're not root, so it lets you run it even if you're root.
In order to use it, install the package and use "puppy-chrome" instead of "google-chrome" in order to run Chrome.
There are two reasons why I wrote it:
1) Freedom! It's MY computer and I'll do whatever I want, no matter if Google doesn't want me to.
3) If we want to build PET packages out of Google's official binary package (which has the updater), we can do this without having to patch the Chrome binary or edit any files (using conventional tools like sed).
How it Works
It's simple, very simple. I executed Google Chrome with strace (a tool which lists calls to system calls) to find out which system calls it uses to find out who's the user who executed it.
I assumed the name of the function it uses starts with "get":
Here's the output, which doesn't mean much:
These two lines tell us everything we need to know:
They say Google Chrome runs a function called DetectRunningAsRoot in order to detect whether it's running as root and that function uses geteuid for that.
I wrote a simple library that implements a fake geteuid that never returns 0 (which is, root's user ID, always). That's how Chrome detects whether it's root, of course.
Here's the library code:
To build it, use this:
This library needs to get loaded into Google Chrome, so it overrides the legitimate geteuid and therefore tricks Google Chrome. That's where LD_PRELOAD aids us.
The LD_PRELOAD environmental variable contains a list of libraries that are loaded into any process executed; in this case, we force Google Chrome to run with our evil library loaded it to it, which overrides the C library's geteuid().
And if you wondered, that's what puppy-chrome does, of course:
A very simple approach can be used against any application that hates root - I was able to get rid of the warning message in the vanilla ROX-Filer this way, too. I just had to override getgid instead of geteuid.
It's a simple launcher for Google Chrome that tricks it into thinking you're not root, so it lets you run it even if you're root.
In order to use it, install the package and use "puppy-chrome" instead of "google-chrome" in order to run Chrome.
There are two reasons why I wrote it:
1) Freedom! It's MY computer and I'll do whatever I want, no matter if Google doesn't want me to.
3) If we want to build PET packages out of Google's official binary package (which has the updater), we can do this without having to patch the Chrome binary or edit any files (using conventional tools like sed).
How it Works
It's simple, very simple. I executed Google Chrome with strace (a tool which lists calls to system calls) to find out which system calls it uses to find out who's the user who executed it.
I assumed the name of the function it uses starts with "get":
Code: Select all
strace -q -s google-chrome 2>&1 | grep get
I decided to dive into the source code and found something interesting: this, the wonderful moment when the code that checks whether you're root was added to Chromium.-nan 0.000000 0 1 getpid
-nan 0.000000 0 1 getppid
-nan 0.000000 0 1 getpgrp
-nan 0.000000 0 38 gettimeofday
-nan 0.000000 0 2 getdents
-nan 0.000000 0 1 sched_getparam
-nan 0.000000 0 1 sched_getscheduler
-nan 0.000000 0 2 sched_get_priority_max
-nan 0.000000 0 1 sched_get_priority_min
-nan 0.000000 0 4 getrlimit
-nan 0.000000 0 7 getuid32
-nan 0.000000 0 5 getgid32
-nan 0.000000 0 6 geteuid32
-nan 0.000000 0 5 getegid32
-nan 0.000000 0 1 getresuid32
-nan 0.000000 0 1 getresgid32
-nan 0.000000 0 14 getdents64
-nan 0.000000 0 1 gettid
-nan 0.000000 0 1 clock_gettime
-nan 0.000000 0 1 clock_getres
-nan 0.000000 0 1 getpeername
-nan 0.000000 0 1 shmget
These two lines tell us everything we need to know:
Code: Select all
void BrowserMainPartsGtk::DetectRunningAsRoot() {
if (geteuid() == 0) {
I wrote a simple library that implements a fake geteuid that never returns 0 (which is, root's user ID, always). That's how Chrome detects whether it's root, of course.
Here's the library code:
Code: Select all
/* a fake UID; root's UID is always 0 and that's how Chrome find out who we
* are */
#define FAKE_UID (1)
/* a fake geteuid() function that returns the fake UID instead of root's one */
int geteuid() {
return FAKE_UID;
}
Code: Select all
gcc -shared -o libpuppygc.so libpuppygc.c
The LD_PRELOAD environmental variable contains a list of libraries that are loaded into any process executed; in this case, we force Google Chrome to run with our evil library loaded it to it, which overrides the C library's geteuid().
And if you wondered, that's what puppy-chrome does, of course:
Code: Select all
LD_PRELOAD="/usr/lib/libpuppygc.so" google-chrome