home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / magazine / drdobbs / 1990 / 10 / switzer.asc < prev    next >
Text File  |  1990-08-16  |  14KB  |  321 lines

  1. _CLOSING DOS'S BACKDOOR_
  2. by John Switzer
  3.  
  4. [LISTING ONE]
  5.  
  6.              TITLE - BACKDOOR.SYS - closes DOS's backdoors
  7.              PAGE 60,132
  8.              .RADIX 16
  9.  
  10. ; BACKDOOR.SYS closes two "backdoors" into the MS-DOS INT 21h function
  11. ; dispatcher that could be used by a virus or trojan horse to cause damage.
  12. ; It also filters INT 21h directly to reject a special case of function 13h
  13. ; which could destroy all data on a disk.
  14. ; For use with MASM 5.1
  15. ; MASM BACKDOOR;
  16. ; LINK BACKDOOR;
  17. ; EXE2BIN BACKDOOR.EXE BACKDOOR.SYS
  18. ;
  19.         ASSUME CS:CSEG, DS:CSEG
  20. CSEG    SEGMENT PARA PUBLIC 'CODE'
  21.              ORG 0000h                 ; device driver starts at 0
  22.  
  23.              DW 0FFFFh,0FFFFh          ; far pointer to next device
  24.              DW 8000h                  ; character device driver
  25.              DW offset DEV_STRAT_RTN   ; pointer to the strategy routine
  26.              DW offset DEV_INT_RTN     ; pointer to the interrupt routine
  27.              DB "B"+80h,"ACKDOOR"      ; device name with high bit set will
  28.                                        ; avoid any filename conflicts
  29. INSTALL_MSG  DB 0Dh,0Ah
  30.              DB "BACKDOOR is installed at $"
  31.  
  32. DEV_HDR_BX   DW 0000                   ; pointer for ES:BX for device
  33. DEV_HDR_ES   DW 0000                   ; request header
  34.  
  35. ORIG_INT21_OFF DW 0000                 ; 
  36. ORIG_INT21_SEG DW 0000                 ; 
  37.  
  38. TEMP         DW 0000                   ; used for temporary storage
  39.  
  40. REFUSE_RQST  PROC FAR                  ;
  41.              POP AX                    ; get rid of flags on stack 
  42.              POP AX                    ; get the return segment
  43.              POP CS:TEMP               ; and save offset 
  44.              PUSH AX                   ; save the return address in proper
  45.              PUSH CS:TEMP              ; order
  46.              STC                       ; return STC for error 
  47.              MOV AX,0FFFFh             ; return AX=-1
  48.              RET                       ; and do FAR RET back to caller
  49. REFUSE_RQST  ENDP
  50.  
  51. NEW_INT21    PROC NEAR
  52.              PUSH AX                   ; save original registers first thing
  53.              PUSH BX
  54.              CMP AH,13h                ; is this the DELETE FCB function?
  55.              JNZ CONT_ORIG_INT21       ; no, so continue on 
  56.              MOV BX,DX                 ; point BX to the FCB
  57.              CMP byte ptr DS:[BX],0FFh ; got an extended FCB?
  58.              JNZ CONT_ORIG_INT21       ; no, so continue on 
  59.              CMP byte ptr DS:[BX+6],1Fh; yes, so got the special attribute?
  60.              JNZ CONT_ORIG_INT21       ; no, so continue on
  61.              CMP word ptr DS:[BX+8],"??"; yes, so filename starts with "??" ?
  62.              JNZ CONT_ORIG_INT21       ; no, so continue on 
  63.              CMP word ptr DS:[BX+0Ah],"??"; yes, so filename = "??" ?
  64.              JNZ CONT_ORIG_INT21       ; no, so continue on 
  65.              CMP word ptr DS:[BX+0Ch],"??"; yes, so filename = "??" ?
  66.              JNZ CONT_ORIG_INT21       ; no, so continue on 
  67.              CMP word ptr DS:[BX+0Eh],"??"; yes, so filename = "??" ?
  68.              JNZ CONT_ORIG_INT21       ; no, so continue on 
  69.              CMP word ptr DS:[BX+10h],"??"; yes, so filename = "??" ?
  70.              JNZ CONT_ORIG_INT21       ; no, so continue on 
  71.              CMP byte ptr DS:[BX+12h],"?"; yes, so filename ends with "??" ?
  72.              JNZ CONT_ORIG_INT21       ; no, so continue on 
  73.              POP BX                    ; yes, so reject it altogether
  74.              POP AX                    ; 
  75.              MOV AL,0FFh               ; return match not found
  76.              STC                       ; STC just for the heck of it 
  77.              RETF 0002                 ; and IRET with new flags
  78.  
  79. CONT_ORIG_INT21:
  80.              POP BX                    ; restore original registers
  81.              POP AX                    ; 
  82.              JMP dword ptr CS:ORIG_INT21_OFF; continue with original handler
  83. NEW_INT21    ENDP
  84.  
  85. DEV_STRAT_RTN PROC FAR                 ; 
  86.              MOV CS:DEV_HDR_BX,BX      ; save the ES:BX pointer to the 
  87.              MOV CS:DEV_HDR_ES,ES      ; device request header 
  88.              RET                       ; 
  89. DEV_STRAT_RTN ENDP
  90.  
  91. DEV_INT_RTN  PROC FAR                  ; 
  92.              PUSH AX                   ; save all registers 
  93.              PUSH BX                   ; 
  94.              PUSH CX                   ; 
  95.              PUSH DX                   ; 
  96.              PUSH DS                   ; 
  97.              PUSH ES                   ; 
  98.              PUSH DI                   ; 
  99.              PUSH SI                   ; 
  100.              PUSH BP                   ; 
  101.              PUSH CS                   ; 
  102.              POP DS                    ; point DS to local code
  103.              LES DI,dword ptr DEV_HDR_BX; ES:DI=device request header
  104.              MOV BL,ES:[DI+02]         ; get the command code
  105.              XOR BH,BH                 ; clear out high byte 
  106.              CMP BX,00h                ; doing an INSTALL?
  107.              JNZ DEV_IGNORE            ; no, so just ignore the call then 
  108.              CALL INSTALL_BACKDOOR     ; yes, so install code in memory
  109.  
  110. DEV_IGNORE:                            ; 
  111.              MOV AX,0100h              ; return STATUS of DONE  
  112.              LDS BX,dword ptr CS:DEV_HDR_BX; DS:BX=device request header
  113.              MOV [BX+03],AX            ; return STATUS in the header
  114.              POP BP                    ; restore original registers 
  115.              POP SI                    ; 
  116.              POP DI                    ; 
  117.              POP ES                    ; 
  118.              POP DS                    ; 
  119.              POP DX                    ; 
  120.              POP CX                    ; 
  121.              POP BX                    ; 
  122.              POP AX                    ; 
  123.              RET                       ; and RETF to DOS 
  124. DEV_INT_RTN  ENDP
  125.  
  126. INSTALL_BACKDOOR PROC NEAR             ; 
  127.              CALL CLOSE_BACK_DOOR      ; install new handler to close back 
  128.                                        ; door 
  129.              CALL HOOK_INT21           ; and hook INT21 filter 
  130.              MOV AH,09h                ; DOS display string 
  131.              MOV DX,offset INSTALL_MSG ; show installation message
  132.              INT 21h                   ; via DOS 
  133.              MOV AX,CS                 ; display current code segment 
  134.              CALL OUTPUT_AX_AS_HEX     ; output AX as two HEX digits 
  135.              MOV AL,3Ah                ; now output a colon
  136.              CALL DISPLAY_TTY          ; to the screen 
  137.              MOV AX,offset REFUSE_RQST ; show new handler's offset 
  138.              CALL OUTPUT_AX_AS_HEX     ; output AX as two HEX digits 
  139.              CALL DISPLAY_NEWLINE      ; output a newline to finish display
  140.              LES DI,dword ptr DEV_HDR_BX; ES:DI=device request header
  141.              MOV Word Ptr ES:[DI+0Eh],offset INSTALL_BACKDOOR; this is the 
  142.              MOV ES:[DI+10h],CS        ; end of resident code 
  143.              RET                       ; 
  144. INSTALL_BACKDOOR ENDP
  145.  
  146. CLOSE_BACK_DOOR PROC NEAR              ;
  147.              PUSH ES                   ; save original registers 
  148.              PUSH AX                   ; 
  149.              PUSH BX                   ; 
  150.              XOR AX,AX                 ; point ES to the interrupt vector 
  151.              MOV ES,AX                 ; table 
  152.              MOV BX,00C1h              ; install new handler at INT30 + 1
  153.              MOV AX,offset REFUSE_RQST ; get new offset for the handler 
  154.              MOV ES:[BX],AX            ; save it in interrupt vector table
  155.              MOV AX,CS                 ; get the segment for the handler
  156.              MOV ES:[BX+02],AX         ; and save it, too
  157.              POP BX                    ; restore original registers
  158.              POP AX                    ; 
  159.              POP ES                    ; 
  160.              RET                       ; and RET to caller
  161. CLOSE_BACK_DOOR ENDP
  162.  
  163. HOOK_INT21   PROC NEAR
  164.              PUSH AX
  165.              PUSH BX
  166.              PUSH ES
  167.              MOV AX,3521h              ; get current INT21 vector
  168.              INT 21h                   ; via DOS
  169.              MOV CS:ORIG_INT21_OFF,BX  ; save the offset
  170.              MOV BX,ES                 ; 
  171.              MOV CS:ORIG_INT21_SEG,BX  ; and the segment
  172.              PUSH CS
  173.              POP DS                    ; make sure DS=local code
  174.              MOV DX,offset NEW_INT21   ; point to new handler
  175.              MOV AX,2521h              ; install new handler
  176.              INT 21h                   ; via DOS 
  177.              POP ES                    ; and restore original registers
  178.              POP BX                    
  179.              POP AX
  180.              RET                       ; and RET to caller
  181. HOOK_INT21   ENDP
  182.  
  183. OUTPUT_AX_AS_HEX PROC NEAR             ; 
  184.              PUSH AX                   ; save original registers 
  185.              PUSH BX                   ; 
  186.              PUSH CX                   ; 
  187.              PUSH AX                   ; save number for output 
  188.              MOV AL,AH                 ; output high byte first
  189.              CALL OUTPUT_AL_AS_HEX     ; output AL as two HEX digits 
  190.              POP AX                    ; output low byte next 
  191.              CALL OUTPUT_AL_AS_HEX     ; output AL as two HEX digits 
  192.              POP CX                    ; restore original registers 
  193.              POP BX                    ; 
  194.              POP AX                    ; 
  195.              RET                       ; and RET to caller
  196. OUTPUT_AX_AS_HEX ENDP
  197.  
  198. OUTPUT_AL_AS_HEX PROC NEAR             ; 
  199.              PUSH AX                   ; save original registers 
  200.              PUSH BX                   ; 
  201.              PUSH CX                   ; 
  202.  
  203.              PUSH AX                   ; save the number for output (in AL)
  204.              MOV CL,04h                ; first output high nibble 
  205.              SHR AL,CL                 ; get digit into low nibble 
  206.              ADD AL,30h                ; convert to ASCII
  207.              CMP AL,39h                ; got a decimal digit?
  208.              JBE OUTPUT_FIRST_DIGIT    ; yes, so continue 
  209.              ADD AL,07h                ; no, so convert to HEX ASCII
  210.  
  211. OUTPUT_FIRST_DIGIT:                    ; 
  212.              CALL DISPLAY_TTY          ; output it via BIOS
  213.              POP AX                    ; get number back
  214.              AND AL,0Fh                ; keep only low digit now
  215.              ADD AL,30h                ; convert to ASCII
  216.              CMP AL,39h                ; got a decimal digit?
  217.              JBE OUTPUT_SECOND_DIGIT   ; yes, so continue 
  218.              ADD AL,07h                ; no, so convert to HEX ASCII 
  219.  
  220. OUTPUT_SECOND_DIGIT:
  221.              CALL DISPLAY_TTY          ; output it via BIOS
  222.              POP CX                    ; restore original registers
  223.              POP BX                    ; 
  224.              POP AX                    ; 
  225.              RET                       ; and RET to caller
  226. OUTPUT_AL_AS_HEX ENDP
  227.  
  228. DISPLAY_NEWLINE PROC NEAR              ; 
  229.              PUSH AX                   ; save original AX
  230.              MOV AL,0Dh                ; first do CR
  231.              CALL DISPLAY_TTY          ; output it via the BIOS
  232.              MOV AL,0Ah                ; do LF next
  233.              CALL DISPLAY_TTY          ; output it via the BIOS
  234.              POP AX                    ; restore original AX
  235.              RET                       ; and RET to caller
  236. DISPLAY_NEWLINE ENDP
  237.  
  238. DISPLAY_TTY  PROC NEAR                 ; 
  239.              PUSH AX                   ; 
  240.              PUSH BX                   ; 
  241.              MOV AH,0Eh                ; display TTY 
  242.              MOV BX,0007h              ; on page 0, normal attribute
  243.              INT 10h                   ; via BIOS
  244.              POP BX                    ; 
  245.              POP AX                    ; 
  246.              RET                       ; 
  247. DISPLAY_TTY  ENDP
  248.  
  249. CSEG    ENDS
  250.         END
  251.  
  252.     
  253.  
  254. [Examplσ 1║ Aε alternativσ entr∙ poin⌠ int∩ MS-DOS 3.30 ]
  255.  
  256. ALT_DOS_ENTRY:
  257.              POP AX      ; get rid of flags
  258.              POP AX      ; save caller's segment
  259.              POP CS:TEMP     ; save caller's offset
  260.              PUSHF         ; save flags
  261.              CLI         ; kill interrupts
  262.              PUSH AX     ; save caller's segment
  263.              PUSH CS:TEMP     ; save caller's offset
  264.              CMP CL,24h     ; is CL < max #?
  265.              JA REFUSE_RQST  ; no, so invalid 
  266.              MOV AH,CL     ; yes, AH=function #
  267.              JMP CONT_INT21  ; and continue INT21
  268.  
  269.  
  270. [Examplσ 2║ ┴ fa≥ jum≡ execute≤ thσ cal∞ anΣ thσ dispatche≥ ì
  271. return≤ t∩ thσ stack]
  272.  
  273.     MOV AX,offset RETURN      ; get return address' offset
  274.     PUSH AX           ; push flags and return address 
  275.     PUSH CS           ; onto stack in reverse order 
  276.     PUSHF              ;
  277.     MOV CL,9          ; display DOS string
  278.     MOV DX,offset MSG      ; this is the message
  279.     PUSH CS
  280.     POP DS              ; verify that DS = local code
  281.     JMP dword ptr ALT_DOS_PTR ; and execute the function
  282.  
  283. RETURN:
  284.     MOV AH,4Ch          ; terminate a process 
  285.     INT 21h           ; via DOS 
  286.  
  287. ALT_DOS_PTR  DW 00C0h,0000      ; entry point for alternative
  288.                   ; DOS handler (0:00C0h)
  289.  
  290. MSG      DB  0Dh,0Ah,"Example  of  backdoor   MS-DOS   "
  291.       DB "function call.",0Dh,0Ah,7,"$"
  292.  
  293.  
  294. [Examplσ 3║ Aε FC┬ functioε caε deletσ files« NOTEí Callinτ thi≤ ì
  295. functioε whilσ a⌠ thσ roo⌠ director∙ wil∞ obliteratσ al∞ file≤ oε ì
  296. thσ disk¼ requirinτ ver∙ tediou≤ worδ witΦ you≥ favoritσ disδ ì
  297. edito≥ t∩ restorσ them« ]
  298.  
  299.     MOV AX,offset RETURN      ; get return address' offset
  300.     PUSH AX           ; push flags and return address 
  301.     PUSH CS           ; onto stack in reverse order 
  302.     PUSHF              ;
  303.     MOV CL,13h          ; DELETE FCB function
  304.     MOV DX,offset FCB      ; this is the special FCB
  305.     PUSH CS p73 
  306.     POP DS              ; verify that DS = local code
  307.     JMP dword ptr ALT_DOS_PTR ; and execute the function
  308.  
  309. RETURN:
  310.     MOV AH,4Ch          ; terminate the process 
  311.     INT 21h           ; via DOS 
  312. ALT_DOS_PTR  DW 00C0h,0000      ; entry point for alternative 
  313.                   ; DOS handler (0:00C0h)
  314.  
  315. FCB     DB 0FFh          ; extended FCB
  316.      DB 5 dup(0)          ; reserved bytes
  317.      DB 1Fh           ; all attribute bits set
  318.      DB 0              ; default drive ID
  319.      DB "???????????"      ; match all files
  320.      DB 19h dup(0)          ; rest of FCB
  321.