NFsec Logo

Podsumowanie ucieczek z sudo: GTFOBins (skaner)

14/03/2021 w Bezpieczeństwo Brak komentarzy.  (artykuł nr 776, ilość słów: 1106)

Jest to ostatni wpis odnośnie ucieczek (1, 2, 3, 4) z sudo. Aktywnie utrzymywana, wyselekcjonowanych plików binarnych oraz skryptów Linuksa, których można użyć do ominięcia lokalnych ograniczeń bezpieczeństwa w źle skonfigurowanych systemach jest zawarta w projekcie GTFOBins (alternatywa dla systemu Windows to LOLBAS). Projekt gromadzi wykorzystanie zaimplementowanych funkcjonalności *niksowych plików binarnych, które mogą być wykorzystane do wyłamywania się z ograniczeń powłok, poleceń sudo, eskalacji uprawnień, czytania zastrzeżonych plików, czy uruchamiania powłok zwrotnych. Należy mieć na uwadze, że nie jest to lista eksploitów, a programy wymienione w GTFOBins same w sobie nie są podatne na ataki. Raczej projekt ten jest kompendium wiedzy o tym, jak wykorzystać je jeśli, któreś z nich uruchamiane jest z prawami administratora lub w ograniczonych środowiskach / powłokach.

Przedstawioną listę możemy również wykorzystać w “dobrym” celu. Na przykład napisać prosty “skaner”, który będzie przeszukiwał naszą infrastrukturę w celu weryfikacji, czy inni administratorzy przez przypadek nie dodali jednego z wymienionych plików do programu sudo lub nadali im prawa setuid. Pierwszym komponentem skanera będzie skrypt w powłoce bash, który stworzy nam dwie listy. Pierwsza posłuży do przeszukiwania pliku /etc/sudoers, a druga do plików SUID:

#!/usr/bin/env bash
set -Eeuo pipefail

GTFOBINS="GTFOBins.github.io"

if ! command -v git $> /dev/null
then
  echo "git command not found."
  exit 1
else
  if [ -d GTFOBins.github.io ]
  then
    echo "GTFOBins repository already exists."
  else
    git clone https://github.com/GTFOBins/$GTFOBINS
  fi
  > gtfobins_sudo.txt
  > gtfobins_suid.txt
  for f in `ls -1 $GTFOBINS/_gtfobins`
  do
    if grep -i sudo $GTFOBINS/_gtfobins/$f > /dev/null 2>&1
    then
      echo -e "${f%.md}" >> gtfobins_sudo.txt
    fi
    if grep -i suid $GTFOBINS/_gtfobins/$f > /dev/null 2>&1
    then
      echo -e "${f%.md}" >> gtfobins_suid.txt
    fi
  done
fi

Ponieważ ściągamy repozytorium z serwisu github, powinniśmy mieć w systemie zainstalowany pakiet git. Po uruchomieniu skryptu, który pozwoliłem sobie nazwać: create_list.sh – w bieżącym katalogu powinny powstać dwa pliki: gtfobins_sudo.txt oraz gtfobins_suid.txt. Po ich zawartości możemy sobie iterować sprawdzając odpowiednie ścieżki w systemie. Za taki iterator możemy wykorzystać ansible, który bardzo fajnie sprawdza się do pisania różnych scenariuszy wykonujących zadania na serwerach:

---
- name: "This playbook scans system for GTFOBins presence."
  hosts: "{{ servers }}"
  gather_facts: no
  serial: 1
  tasks:
    - name: "Check GTFOBins in /etc/sudoers entries."
      lineinfile:
        path: /etc/sudoers
        state: absent
        regexp: '^[^#].*{{ item }}.*'
      check_mode: yes
      register: sudoers
      loop: "{{ lookup('file', 'gtfobins_sudo.txt').splitlines() }}"

    - name: "Find SUIDs files in system."
      shell: find / -perm /4000 -print 2>/dev/null > /tmp/suids; chmod 640 /tmp/suids
      register: findsuids

    - name: "Check GTFOBins in SUID entries."
      lineinfile:
        path: /tmp/suids
        state: absent
        regexp: '.*\/{{ item }}$'
      check_mode: yes
      register: suids
      loop: "{{ lookup('file', 'gtfobins_suid.txt').splitlines() }}"

    - name: "Remove SUIDs file list from system."
      file:
        path: /tmp/suids
        state: absent

Tak zapisany playbook pod nazwą: scan_gtfobins.yml możemy uruchomić na wybranej grupie serwerów, którą chcemy sprawdzić:

agresor@darkstar:~$ ansible-playbook scan_gtfobins.yml --extra-vars "servers=web" \
--diff -u secops --become --ask-become-pas --ask-pass

W przypadku trafienia powinniśmy zobaczyć je na ekranie, co daje nam możliwość jego weryfikacji:

TASK [Check GTFOBins in SUID entries.] ***

--- before: /tmp/suids (content)
+++ after: /tmp/suids (content)
@@ -1,6 +1,5 @@
 /bin/ping
 /bin/su
-/bin/cat
 /bin/fusermount
 /bin/umount
 /usr/lib/openssh/ssh-keysign

changed: [web-farm1.dc66.lan] => (item=cat)

Niestety ze względu na fakt, że próbujemy dość uniwersalnie łapać dopasowania do wpisów w pliku /etc/sudoers (które mogą mieć różne formy zapisu) na nim może zostać wygenerowanych najwięcej trafień typu false positive:

TASK [Check GTFOBins in /etc/sudoers entries.] ***

--- before: /etc/sudoers (content)
+++ after: /etc/sudoers (content)
@@ -7,7 +7,6 @@
 # See the man page for details on how to write a sudoers file.
 #
 Defaults	env_reset
-Defaults	mail_badpass

 # Host alias specification

changed: [web-farm1.dc66.lan] => (item=ss)

Na szczęście z kolejnymi uruchomieniami możemy poddawać ewolucji przyjęte warunki w scenariuszach, co finalnie powinno przybliżyć nas do bardzo małej liczby pomyłek:

-         regexp: '^[^#].*{{ item }}.*'
+         regexp: '^[^(#|Defaults)].*{{ item }}.*'

Dla pełni podstawowego szkieletu skanera pozostaje jeszcze obsługa dodatkowych plików programu sudo skonfigurowanych za pomocą dyrektywy: #includedir (standardowa wartość to: /etc/sudoers.d):

    - name: "Get #includedir value from /etc/sudoers."
      command: grep -oP '(?<=#includedir ).*' /etc/sudoers
      register: checksudoers
      changed_when: False

    - name: "Get sudoers files from {{ checksudoers.stdout }}"
      find:
        paths: "{{ checksudoers.stdout }}"
        file_type: file
      register: sudoers_files
      changed_when: False
      when: checksudoers.rc == 0

    - name: "Check GTFOBins in {{ checksudoers.stdout }}"
      lineinfile:
        path: "{{ item[0].path }}"
        state: absent
        regexp: '^[^(#|Defaults)].*{{ item[1] }}.*'
      check_mode: yes
      register: multisudoers
      with_nested:
        - "{{ sudoers_files.files }}"
        - "{{ lookup('file', 'gtfobins_sudo.txt').splitlines() }}"
      when:
        - checksudoers.rc == 0
        - sudoers_files.files | length < 0

Jeśli używamy innego rozwiązania automatyzującego zadania to nic nie szkodzi na przeszkodzie byśmy do tego celu wykorzystali np. fabric, puppet, chef, czy SaltStack.

Więcej informacji: man sudoers

Kategorie K a t e g o r i e : Bezpieczeństwo

Tagi T a g i : , , , , , , ,

Komentowanie tego wpisu jest zablokowane.