TGViewer
ESCalator ESCalator @ptescalator · 8.16K subscribers
Post #325 3.98K
А вы знали, что злые люди не любят парсеры LNK-файлов? 👿

В марте мы писали об атаках XDSpy на российские организации. LNK-файлы, которые использовались в этой атаке, были модифицированы так, что при их обработке многие парсеры «падали». Например, это касается LECmd, LnkParse3 и ExifTool, который используется на VirusTotal (скриншот 1).

Разберемся, в чем кроется проблема и как ее исправить 🔧

В общих чертах структура LNK-файла выглядит следующим образом:

1. SHELL_LINK_HEADER с интересующим нас значением LinkFlags. Оно задает присутствие тех или иных структур в LNK-файле и выглядит так:

typedef struct
{
uint32 HasLinkTargetIDList : 1; // есть LINKTARGET_IDLIST
uint32 HasLinkInfo : 1; // есть LINKINFO
uint32 HasName : 1; // есть STRING_DATA
uint32 HasRelativePath : 1; // есть STRING_DATA
uint32 HasWorkingDir : 1; // есть STRING_DATA
uint32 HasArguments : 1; // есть STRING_DATA
uint32 HasIconLocation : 1; // есть STRING_DATA
uint32 IsUnicode : 1; // строки в UTF-16
// ... skipped
} LinkFlags;


2. [Optional] LINKTARGET_IDLIST.
3. [Optional] LINKINFO.
4. [Optional] STRING_DATA.

STRING_DATA — это массив структур StringData, каждая из которых имеет следующий формат:

• CountCharacters (количество символов в строке, поэтому для юникода количество байт будет CountCharacters × 2).
• String (строка, которая в соответствии с документацией MUST NOT be NULL-terminated).

Структура STRING_DATA содержит Description (Name), RelativePath, WorkingDir, Arguments и IconLocation в том порядке, который указан в LinkFlags.

🫱 Именно в CountCharacters и кроется проблема для парсеров, которые на него полагаются. Чтобы их «уронить» добрые дяденьки устанавливают большое значение в CountCharacters, например 0xFFFF. String делают длиной до 260 символов, а следующую StringData располагают ровно через 260 символов (в UTF-16 это 520 байт).

Как оказалось, Windows «под капотом» ограничивает длину строк Description, RelativePath и WorkingDir 260 символами. В итоге мы имеем следующее:

• Парсеры «падают» из-за некорректных значений (считают смещение 0xFFFF и попадают на бессмысленные байты).

• Windows ограничивается 260 символами, правильно попадая на следующую StringData, и запускает LNK-файл без проблем.

• Ограничение в 260 символов точно подразумевается для Description, что было неочевидно, RelativePath и WorkingDir.

• Для Arguments такого ограничения нет или порог сильно выше, что уже логично. При этом в свойствах LNK-файла при нажатии правой кнопкой будет отображаться только 260 первых символов команды.

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

🕵️‍♀️ В варианте LNK-файла от XDSpy атакующие «сломали» таким образом строку WorkingDir и установили ее значение в C:\Windows\System32\<пробелы> с длиной 260 символов (скриншот 2). Здесь можно посмотреть, как выглядит такой файл на VT (скриншот 3).

---- WorkingDir ----
0x0 CountCharacters (0XFFFF)
0x2 String (до 0x208) // C:\Windows\System32_______
---- Arguments ----
0x20A CountCharacters // Парсер Windows идет сюда
0x20C String // Arguments
...
0xFFFF RandomData // Обычные парсеры идут сюда


Чтобы исправить это недоразумение, нужно проверять размер CountCharacters для релевантных строк и ограничивать смещение до следующей StringData 260 символами с учетом флага isUnicode.

#tip #win
@ptescalator
  • 🔥 20
  • 👍 15
  • ❤ 5
  • 👏 5
  • 😁 2
  • 😢 1
More from @ptescalator
  1. Sep 29, 2026Post #787
  2. Sep 29, 2026Как исследовать угрозы с PT Fusion Сегодня в 14:00 (мск) проведем вебинар, на котором разб…
  3. Sep 28, 2026Post #785
  4. Sep 28, 2026Post #784
  5. Sep 25, 2026Мы помогли Apple устранить уязвимость в ядре ее операционных систем Эксперт PT ESC Михаил…
  6. Sep 23, 2026Восстановление EVTX-записей: методы карвинга 🧩 При расследовании инцидентов, когда злоумы…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →