jeudi 16 juin 2016

Creating a backdoor in PAM in 5 line of code

Under Linux (and other Oses), authentification of users is made through Pluggable Authentication Module, aka PAM. Having centralized authentication is a good thing. But it has a drawback: if you trojanize it, you get key for everything. Trojan once, pwn evrywhere!

1/ Intro

Pam has three concepts: username, password and service. Its role is authenticate people to a service with a password.

Pam configuration is done under /etc/pam.d/ directory where each service has its own file:
 root@dojo:/etc/pam.d# ls  
 atd             common-password        lightdm-greeter       polkit-1      sudo  
 chfn            common-session         login       ppp       systemd-user  
 chpasswd        common-session-noninteractive      runuser   vmtoolsd  
 chsh            cron                   newusers    runuser-l xscreensaver  
 common-account  lightdm                other       sshd  
 common-auth     lightdm-autologin      passwd      su  

Basically, each one of those file calls a shared library, where the authentication or other kind things related to auth is done:
 root@dojo:/etc/pam.d# head login  
 # The PAM configuration file for the Shadow `login' service  
 # Enforce a minimal delay in case of failure (in microseconds).  
 # (Replaces the `FAIL_DELAY' setting from login.defs)  
 # Note that other modules may require another minimal delay. (for example,  
 # to disable any delay, you should add the nodelay option to pam_unix)  
 auth    optional delay=3000000  

And that'st he same kind of config files for all services. As I said, we want to backdoor PAM. We don't want to backdoor everything, we just want to be able to succeed in authentication with a choosen password, independantly of the real password of the user.

Almost all services include the common-auth file, and you can guess what is done here by its name.

2/ Backdooring in common-auth

The common-auth file has many directives, but the only important line here is the one checking the password of a user:
auth       [success=1 default=ignore] nullok_secure  

The common-auth file calls the shared library and authentication of user is done here. The logic of this file is easy to understand:
  • get username
  • get password
  • calls a subfunction to validate password against username
So, why don't add an if statement?
  • get username
  • get password
  • if password == "0xMitsurugi" then grant access, else calls the legitimate subfunction
Let go to the sources of PAM (depends on your distro, take the same version number as yours..) and look around line numbers 170/180 in the pam_unix_auth.c file:

mitsurugi@dojo:~/chall/PAM/pam_deb/pam-1.1.8$ vi modules/pam_unix/pam_unix_auth.c

Let's change this by:

Recompile the pam_unix_auth.c, end replace the file:
 mitsurugi@dojo:~/chall/PAM/pam_deb/pam-1.1.8$ make  
 mitsurugi@dojo:~/chall/PAM/pam_deb/pam-1.1.8$ sudo cp \  
  /home/mitsurugi/PAM/pam_deb/pam-1.1.8/modules/pam_unix/.libs/ \  

3/ Profit !

Try with login, with ssh, with sudo, with su, with the screensaver, your access will be granted with "0xMitsurugi" password. Open access for all accounts \o/

The best part of this is that everything else works as usual. Put your real password, it works. Put a bad one, it fails. Users can change their password, you can audit the strength of the shadow file, you can check for hidden files, you can check for config file modified, open ports, "weird logs", you'll get nothing, but attacker can still get in. Another great advantage of this is that it can remain undetected for a long time.

You can also add logging features in order to catch all password entered, that's an exercise left to the reader.

4/ Enjoy responsibly

Real friends don't backdoor theirs friend's machines.

No one can take Soul Edge from me!

1 commentaire: