#TLDR: Описание формата LNK
Формат
Формат LNK файлов - — бинарный, файл начинается с последовательности «
4c 4c 00 0000 0000». Файлы LNK состоят из заголовка и набора опциональных структур данных, которые определяются флагами в заголовке.
- SHELL_LINK_HEADER;
- [LINKTARGET_IDLIST];
- [LINKINFO];
- [STRING_DATA] — RELATIVE_PATH, WORKING_DIR, COMMAND_LINE_ARGUMENTS, ICON_LOCATION;
- *EXTRA_DATA.
SHELL_LINK_HEADER (заголовок)

Структура ShellLinkHeader
Заголовок LNK-файла. Фиксированный блок размером 76 байт (0x4C), начинающийся с магических байтов:
- HeaderSize — 0x0000004C.;
- LinkCLSID —GUID {00021401-0000-0000-C000-000000000046;
- LinkFlags — битовые флаги, указывающие на наличие последующих структур (например, HasTargetIDList, HasArguments, HasIconLocation);
- FileAttributesFlags — атрибуты целевого файла (READONLY, HIDDEN и т.д..);
- CreationTime/AccessTime/WriteTime — временные метки в формате FILETIME.;
- FileSize — размер целевого файла.;
- IconIndex — индекс иконки.;
- ShowCommand — режим окна (SW_SHOWNORMAL, SW_SHOWMAXIMIZED, SH_SHOWMINNOACTIVE);
- HotKey и зарезервированные поля (10 байт).
Пример ShellLinkHeader
LINKTARGET_IDLIST
Присутствует в LNK, если указан флаг
HasLinkTargetIDList в поле
LinkFlags заголовка.
Содержит совокупность структур
IDList, указывающих на путь к целевому файлу. Описывается в так называемом формате
Shell Item.
Особенность в том, что
IDList могут быть различного типа: это может быть файл, том или даже объект с
CLSID (например, «Мой компьютер», «Панель управления» и т.п.).
Пример LinkTargetIDList
Формат сложный, конкретная структура
Shell Item очень сильно
зависит от типа. Слабо документирован и может меняться от версии операционной системы. Большинство информации о формате получено путём
обратной разработки по имеющимся примерам файлов.
Согласно восстановленному описанию
формата, выделяются следующие типы
IDList:
- ROOT — содержит идентификатор GUID папки, отображаемое имя зависит от операционной системы и настроек локали («Мой компьютер», «This PC» etcи т.д.);
- VOLUME — содержит имя логического тома и дополнительные флаги (например, что он съёмный);
- FILE — содержит имена файла или директории, а также даты в формате DOSDATETIME и атрибуты файлового объекта;
- NETWORK — содержит часть пути до сетевой папки (DOMAIN/Workgroup, Server UNC, Share UNC);
- URI — содержит URI или FTP-ссылку к удаленному удалённый серверу;
- Control Panel — содержит GUID одного из элементов панели управления.
Кроме LNK,
Shell Item ещё много где
используется и полезен для криминалистического анализа.
Самое важное, что можно получить из
Shell Item в контексте LNK:
- Информацию о временных метках файлов и директорий, когда последний раз открывался LNK;
- Атрибуты файлов и директорий;
- Размер целевого файла, когда он последний раз открывался через LNK;
- Пути к сетевым папкам;
- Реквизиты доступа к FTP и даты последнего обращения к ним.
LINKINFO
Присутствует в
LNK, если указан флаг
HasLinkInfo в
LinkFlags заголовка.
Содержит информацию для получения пути к целевому файлу и позволяет его найти, если он не обнаружен по изначальному пути. Содержит тип, имя, серийный номер и букву логического тома,
UNС для пути к файлу.

Серийный номер диска в LINKINFO
STRING_DATA
Для описания остальных элементов
LNK используется структура
STRING_DATA. Она содержит длину строки и саму строку в кодировке по умолчанию или в
UNICODE. Чаще всего в
UNICODE. Строка должна завершаться ненулевым байтом.
struct STRING_DATA
{ uint16_t wCountCharacters; wchar_t String[];
}
Это структурой описываются следующие элементы
LNK:
- NAME_STRING — если указан флаг HasName в заголовке, содержит описание LNK файла;
- RELATIVE_PATH — eсли указан флаг HasRelativePath, содержит путь к целевому файлу относительно расположения LNK;
- WORKING_DIR — если указан флаг HasWorkingDir, содержит путь к рабочей директории при запуске LNK;
- COMMAND_LINE_ARGUMENTS— если указан флаг HasArguments, содержит дополнительные аргументы для запуска целевого файла;
- ICON_LOCATION — eсли указан флаг HasIconLocation, содержит путь к файлу с иконкой для LNK.

Структура STRING_DATA
ICON_LOCATION использовалась для эксплуатации множества
уязвимостей в ходе Zero-click атак. Для эксплуатации уязвимости необходимо было только открыть папку, в которой находился специально подготовленный LNK-файл.
А в
COMMAND_LINE_ARGUMENTS злоумышленники обычно скрывают аргументы для запуска и исполнения вредоносного кода.

Пример от HeadMare
EXTRA_DATA
Структура LNK, которая содержит дополнительную информацию, необходимую для активации ярлыка. Состоит за набора структур, которые определяют, как LNK взаимодействует с операционной системой при открытии.
В
EXTRA_DATA могут появляться следующие блоки данных:
- CONSOLE_PROPS;
- CONSOLE_FE_PROPS;
- ENVIRONMENT_PROPS;
- ICON_ENVIRONMENT_PROPS;
- KNOWN_FOLDER_PROPS;
- PROPERTY_STORE_PROPS;
- SHIM_PROPS;
- SPECIAL_FOLDER_PROPS;
- TRACKER_PROPS;
- VISTA_AND_ABOVE_IDLIST_PROPS.
CONSOLE_PROPS
Блок
ConsoleDataBlock (0xA0000002) создаётся, если целевой файл — консольное приложение (например,
cmd.exe или
powershell.exe). Блок определяет размеры окна, шрифты, цветовую таблицу и запуск в полноэкранном режиме.
Злоумышленник может в этом блоке указать параметры для сокрытия окна, выставив минимальный размер окна или прозрачность.
CONSOLE_FE_PROPS
Блок
ConsoleFEDataBlock (0xA0000004) в дополнение к предыдущему определяет кодовую страницу для поддержки восточноазиатских языков.
Может косвенно указать на языковую принадлежность автора (например, использование китайской локали по умолчанию).
DARWIN_PROPS
Блок
DarwingDataBlock (0xA0000006) создаётся, если целевой файл был установлен через MSI. При этом в
LinkFlags указывается
HasDarwinID.
Хранит «
Darwin ID» (Compressed Feature GUI), который позволяет Windows восстановить или доустановить приложение, если оно повреждено. Обычно такие ярлыки можно найти в меню «Пуск».
ENVIRONMENT_PROPS
Блок
EnvironmentVariableDataBlock (0xA0000001) содержит строку пути в формате среды окружения (Environment Variables), которая дублирует или заменяет основной путь к целевому файлу.
Используется для обеспечения переносимости ярлыков. Windows автоматически заполняет эту структуру при создании ярлыка, в котором используются переменные окружения.

Пример EnvironmentVariableDataBlock
Блок должен присутствовать, если указан
HasExpString в
LinkFlags заголовка. Если в LinkFlags установлен флаг
DisableLinkPathTracking, то данный блок игнорируется.
Может использоваться злоумышленником для обхода средств анализа. В
этом случае содержимое структуры отличается от LinkInfo.
ICON_ENVIRONMENT_PROPS
Блок
IconEnvironmentDataBlock (0xA0000007) используется для хранения информации об иконке. Должен присутствовать, если указан флаг
HasExpIcon в заголовке. Путь к иконке использует переменные окружения по аналогии с блоком
EnvironmentVariableDataBlock.
KNOWN_FOLDER_PROPS
Блок
KnownFolderDataBlock (0xA000000B) хранит идентификатор
GUID известной папки и его смещение в
IDList.
Если в
LinkFlags указан
DisableKnownFolderTracking, то данный блок игнорируется при открытии ярлыка.

Пример KnownFolderDataBlock
PROPERTY_STORE_PROPS
Структура
PropertyStoreDataBlock (0xA0000009) содержит метаданные файла, сведения об авторе и системные свойства. Информация хранится в виде наборов пар «ключ-значение». Должен быть, если указан флаг
EnableTargetMetadata в заголовке.
Здесь часто хранятся данные о приложении, для которого был создан ярлык. Могут оставаться артефакты от языкового пакета операционной системы (например, «Приложение»), оригинальный путь к файлу и его название.

Пример PropertyStoreDataBlock
Кроме этого, здесь может быть сохранён идентификатор пользователя
SID, который создал файл ярлыка, и
Volume Id.
SHIM_PROPS
Согласно описанию формата, блок
ShimDataBlock (0xA0000008) используется механизмом совместимости приложений. Позволяет запускать приложение в режиме совместимости с более старой версией Windows. В действительности изменение параметров совместимости ярлыка никак не влияет на появление данного блока в
EXTRA_DATA и найти ярлык, в котором есть данный блок данных, довольно проблематично.
Должен быть, если указан флаг
RunWithShimLayer в заголовке.
SPECIAL_FOLDER_PROPS
Блок
SpecialFolderDataBlock (0xA0000005) является устаревшим аналогом
KnownFolderDataBlock. Хранит идентификатор
SpecialFolderID и смещение в
IDList.

Пример SpecialFolderDataBlock
Игнорируется, если указан флаг
DisableKnownFolderTracking в заголовке, и не записывается в ярлык при пересохранении.
TRACKER_PROPS
Блок
TrackerDataBlock (0xA0000003) используется для поиска файла, если система его не нашла по изначальному пути. Для поиска используется DLT — системная служба Windows. При создании любого файла на NTFS служба DLT присваивает ему уникальный идентификатор. Если создать ярлык на такой файл, то в
EXTRA_DATA в блоке
TrackerDataBlock будет хранится информация, которая содержит:
- NetBIOS — имя машины, на которой расположен целевой файл;
- уникальный идентификатор тома (диска);
- уникальный идентификатор самого файла.

Пример TrackerDataBlock
Данный блок игнорируется, если указан флаг
ForceNoLinkTrack в заголовке.

Пример TrackerDataBlock
VISTA_AND_ABOVE_IDLIST_PROPS
Блок
VistaAndAboveIDListDataBlock (0xA000000C) используется для указания альтернативного
IDList и может использоваться только на операционных системах старше Windows XP и Windows Server 2003.
В Windows XP и более ранних версиях для поиска цели использовался основной
LinkTargetIDList. Однако с выходом Vista структура проводника сильно усложнилась: появились виртуальные папки, библиотеки, новые способы отображения сетевых ресурсов и глубокая интеграция с пользователями (
C:\Users вместо
Documents and Settings).
Старый формат
IDList не всегда мог корректно передать эти новые типы объектов. Поэтому Microsoft добавила
VistaAndAboveIDListDataBlock как «современную копию» списка идентификаторов. Он позволяет хранить
IDList с учётом расширенных свойств и метаданных, которые недоступны в более старых ОС. Если Windows находит этот блок в
EXTRA_DATA, то отдаёт ему приоритет при поиске целевого файла.