Jump to content
dejavu4u2

Some mischievous fun

Recommended Posts

I played a little trick a few years ago on a colleague of mine. I'd long since forgotten about this until we migrated to a new system & hadn't sync'd my little LD intercept, and things finally started to break for him. He claims he hadn't noticed anything unusual in the last 2 years ;-) This is a relatively harmless prank, but it may affect the user's mail and/or cron.

 

/*
 * getpwuid.c <grant.byers AT gmail.com>
 * Lets have some fun!
 */
#include <stdlib.h>
#include <string.h>
#include <dlfcn.h>
#include <pwd.h>

static struct passwd * (*o_getpwuid)(uid_t uid);


char *
rstr(char *s, int n)
{
	int i;
	char *buf;

	if ((buf = malloc(n))) {
		for (i = 0; n; i++)
			buf[i] = s[--n];
	}
	return buf;
}


struct passwd *
getpwuid(uid_t uid)
{
	struct passwd *pw;

	if (!o_getpwuid) {
		o_getpwuid = (struct passwd *(*)(uid_t))dlsym(RTLD_NEXT,"getpwuid");
		if (dlerror()) {
			return(NULL);
		}
	}

	if (pw = o_getpwuid(uid)) {
		int n = strlen(pw->pw_name);
		char *pb = rstr(pw->pw_name,n);
		if (pb) {
			while (--n >= 0)
				pw->pw_name[n] = pb[n];
			free(pb);
		}
	}
	return pw;
}

Now compile this as a shared object and disguise it in a relatively inconspicuous location.

 

sudo gcc -shared -o /home/... -D_GNU_SOURCE -ldl getpwuid.c

Add some LD_PRELOAD magic to /etc/profile (or a particular users .profile/.bash_profile/etc.). Something like the following will prevent it being set for root. Use your imagination.

 

if [ "X$LOGNAME" != "Xroot" ]; then
  LD_PRELOAD=/home/...; export LD_PRELOAD
fi

 

Now login as a non-root user (or the user you targetted) and observe some peculiar behaviour ;

 

1. session with LD_PRELOAD unset ;

grantb@weazle:~$ ls -l getpwuid.c
grantb@weazle:~$ ls -l /usr/bin/at
-rwsr-sr-x 1 daemon daemon 42752 2010-06-28 05:36 /usr/bin/at

grantb@weazle:~$ ps uxww|grep $$
grantb   28424  0.0  0.1   9480  6252 pts/3	Ss   19:42   0:01 -bash
grantb   32562  0.0  0.0   4008   760 pts/3	S+   20:33   0:00 grep --color=auto 28424

2. session with LD_PRELOAD set ;

grantb@weazle:~$ ls -l getpwuid.c
grantb@weazle:~$ ls -l /usr/bin/at
-rwsr-sr-x 1 nomead daemon 42752 2010-06-28 05:36 /usr/bin/at

grantb@weazle:~$ ps uxww|grep $$
btnarg   28377  0.1  0.1   9464  6192 pts/4	Ss   20:27   0:00 -bash
btnarg   32256  0.0  0.0   4020   772 pts/4	S+   20:33   0:00 grep --color=auto 28377

 

While this example sets LD_PRELOAD for all users (except root), i'd recommend you just target a single person by setting up LD_PRELOAD in their .profile, .bash_profile, etc.

 

Depending on your system configuration, executables with SGID/SUID bits set complain loudly when LD_PRELOAD is set. This doesn't appear to be the case with a largely vanilla ubuntu 10.10, but it certainly is the case with at least Solaris 10. If the user is running BASH, you may be able to use the preexec() function to intercept & temporarily unset LD_PRELOAD depending on the permissions of the file being executed.

 

 

Have fun!

Share this post


Link to post
Share on other sites

Sneaky! I had no idea about LD_PRELOAD. Is there a similar call back when a program exits, or would that require modifying exit()?

 

Clearly your colleague hasn't needed to use ps much the last two years :)

Edited by wilsontc

Share this post


Link to post
Share on other sites

To quote Andrew Tridgell, LD_PRELOAD is a hack. But a very useful one, for instance he gave a talk using it to intercept open/read/write/close calls between VirtualBox and a USB device to reverse-engineer a program for a digital multimeter.

Share this post


Link to post
Share on other sites

This looks quite interesting, but for a non-coder like me, what does it achieve?

 

I use LD_PRELOAD for v4l2 with xawtv and my webcam.

Share this post


Link to post
Share on other sites

This looks quite interesting, but for a non-coder like me, what does it achieve?

 

I use LD_PRELOAD for v4l2 with xawtv and my webcam.

It allows you to load a program or library which the program wasn't originally going to load. The security implications are enormous.

 

In this case, anything that requires getpwuid() is going to use this function instead, and thus print usernames in reverse...

Share this post


Link to post
Share on other sites

Yep, LD_PRELOAD is definitely a good thing, but can easily be used for bad. It often proves an invaluable tool when you need to fix a problem in proprietory software that the vendor refuses to fix themselves.

 

For a real world example, consider this. You have several nodes in a cluster & each of these nodes has a number of physical interfaces. Some of these NICs are used in a redundant failover group. On Solaris, you may use IPMP, which requires each of the physical interfaces in the redundant group to have test addresses (unless these NICs are directly connected to a single destination). These test addresses should be non-routable, so services should never bind to them. On top of these test addresses, you have a logical group address. This address is likely the primary address of the system (the one hostname/uname -n resolves to). On top of this, you have logical cluster addresses for some resource groups. Any of these logical addresses may exist on either node. Now, you may have some proprietory closed source daemon that you'd like to cluster, but it insists on either binding to the address of the first interface, or to the primary address of the system. What you'd like it to do is either bind to all addresses, or just to a particular cluster address. Using LD_PRELOAD, you could load a shared object that overrides the bind(2) call & rewrites the address passed in the struct sockaddr pointer to 0.0.0.0. You'd then start the faulty service/daemon with LD_PRELOAD set to your shared object overriding bind. Your service now works as expected, and if your lucky, reporting your fix to the vendor may convince them to fix this problem.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×