Talk: UNIX opgaver

From Teknologisk videncenter
Revision as of 10:10, 15 September 2009 by Tcj (talk | contribs) (Tomas løsning på SNMP1)
Jump to: navigation, search

fra kbso

#!/usr/bin/bash

## Roed opgave
## Lav et script der finder forsg p at logge ind p maskinen via kopi af logfilen /tmp/auth.log
## Jeg kunne tnke mig at vide hvor mange mislykkede login forsg der er

# Log fil
LOG="/tmp/auth.log"

# vis indhold af $log, find antal invalid logins, sorter i paa antal linjer
LINJER=`cat $LOG | grep Invalid | wc -l | tr -s "\t" ' '`
echo "Der var$LINJER invalide login forsoeg i alt.
"


## Gul opgave
## Hvor mange mislykkede forsg p at logge er der om dagen. En linie pr. dato i rapporten

PERDAG=`cat $LOG | grep Invalid | tr -s ' ' | cut -d' ' -f1-2 | sort | uniq -c | sort -rn`
echo "Invalide login forsoeg per dag:
$PERDAG"


## Groen opgave

NAVNE=`cat $LOG | grep 'Invalid' |rev | cut -d ' ' -f 3| rev | sort | uniq -c | sort -r -n`
echo "Anvendte brugernavne ved invalide logins:
$NAVNE" | less

Besvarelse fra Tomas

  1 #!/usr/bin/bash
  2 
  3 ## Scriptet læser antal fejlede logins
  4 ## De fejlede er: Hacking forsøg (reverse mapping)
  5 ##			"        (Did not recieve ident)
  6 ##                Forkert bruger (Invalid user)
  7 ##		  Forkert password men rigtig bruger (Failed keybord)
  8 ##		  Anden fejl (error: PAM)
  9 
 10 ##### INITIAL VÆRDIER #####
 11 LOGFIL=/tmp/auth.log
 12 DD=`date`
 13 
 14 ##### FUNKTIONER #####
 15 
 16 
 17 function overskrift {
 18 ## Header
 19 # Udskriv en header
 20 # input: $1 = dagsdato
 21 # input: $2 = logstart
 22 # input: $3 = logslut
 23 
 24 cat << HEADER
 25 Fejlede SSH logins på mars.tekkom.dk
 26 ====================================
 27 
 28 Rapporten genereret: $1
 29 
 30  ------------------------------------------------------------------------------------
 31  Data opsamlet er fra perioden den $2 til den $3
 32  ------------------------------------------------------------------------------------
 33 HEADER
 34 }
 35 
 36 function startdato {
 37   ## Find start dato i logfil
 38   #  input: $1 = filnavn
 39   #  output: dato som tekst
 40 
 41   head -n 1 $1 | sed 's/  / /g' | cut -d' ' -f1-3 
 42 }
 43 
 44 function slutdato {
 45   ## Find slut dato i logfil
 46   #  input: $1 = filnavn
 47   #  output: dato som tekst
 48   tail -n 1 $1 | sed 's/  / /g' | cut -d' ' -f1-3
 49 }
 50 
 51 function loginfejl {
 52   ## Find alle linier, hvor en given tekst findes. 
 53   # input: $1 = filnavn
 54   # input: $2 = søgetekst
 55   # output: antal fundet
 56 
 57   ## Forklaring:
 58   # grep "$2" $1    : Find linier med en given tekst
 59   # cut -d':' -f4-  : Fjern tidsstempel og andet junk
 60   # sed 's/^ *//'   : Fjern eventuelle  indledende mellemrum
 61   # wc -l           : Tæl linier
 62   # sed 's/^ *//'   : Fjern indledende mellemrum
 63   grep "$2" $1 | cut -d':' -f4- |  sed 's/^ *//' |  wc -l | sed 's/^ *//'
 64 }
 65 
 66 function dage {
 67   ## Find dage i logfilen
 68   # input : $1 = filnavn
 69   # output: liste over dage i filen
 70   #         listen er newline sepereret. Hver linie indeholder en blanktegnsepereret
 71   #         dato: "mnd dato"
 72   cut -b1-6 $1 | sort | uniq
 73 }
 74 
 75 function invalidusr {
 76 ## Find de ip adresser, der laver mere end 10 invalid user
 77 # input: $1 = filnavn
 78 # output: liste med antal og adresser
 79 
 80 grep Invalid $1 | sed 's/  / /' | cut -d' ' -f10|sort|uniq -c| while read c i ; do \
 81                                                                  if [ $c -gt 10 ] ; then
 82 								   echo "$c $i"
 83 								 fi
 84 							       done
 85 }
 86 
 87 function reversemap {
 88 ## Find de ip adresser, der laver mere end 10 reverse mapping checking 
 89 # input: $1 = filnavn
 90 # output: liste med antal og adresser
 91 grep reverse $1 | sed 's/  / /' | cut -d' ' -f 12 | sort | sed -e 's/\[//g' -e 's/\]//g' | \
 92   uniq -c | while read c i ; do
 93     if [ $c -gt 10 ] ; then
 94       echo "$c $i"
 95     fi
 96   done
 97 }
 98 
 99 #######################
100 ######## MAIN #########
101 #######################
102 
103 
104 overskrift "$DD" "`startdato $LOGFIL`" "`slutdato $LOGFIL`"
105 
106 echo -e "\nROED OPGAVE ==========\n"
107 ## Find loginfejl: Did not receive identification string from xxx
108 DIDNOT=`loginfejl $LOGFIL "Did not"`
109 echo "Antal: Did not receive identification string from xxxx    : $DIDNOT"
110 ## Find loginfejl: Failed keyboard-interactive/pam for invalid user
111 FAILKEYB=`loginfejl $LOGFIL "Failed keyboard-interactive"`
112 echo "Antal: Failed keyboard-interactive/pam for invalid user   : $FAILKEYB"
113 ## Find loginfejl: Invalid user xxx from yyyy
114 INVALUSR=`loginfejl $LOGFIL "Invalid user"`
115 echo "Antal: Invalid user                                       : $INVALUSR"
116 ## Find loginfejl: error: PAM: authentication error for xxx from yyyy
117 ERRPAM=`loginfejl $LOGFIL "error: PAM:"`
118 echo "Antal: error: PAM: authentication error for xxx from yyyy : $ERRPAM"
119 ## Find loginfejl: reverse mapping checking POSSIBLE BREAK-IN ATTEMPT!
120 REVMAP=`loginfejl $LOGFIL "reverse mapping"`
121 echo "Antal: reverse mapping checking POSSIBLE BREAK-IN ATTEMPT!: $REVMAP"
122 
123 IALT=`expr $DIDNOT + $FAILKEYB + $INVALUSR + $ERRPAM + $REVMAP`
124 echo "Ialt fejlede dette antal loginforsøg                      : $IALT"
125 
126 echo -e "\nGUL OPGAVE ========\n"
127 echo "Fejlede logins fordeler sig således over dage:"
128 # mnd = måned
129 # dag = dag
130 dage $LOGFIL| while read mnd dag ; do
131    
132    cnt=`grep "$mnd *$dag" $LOGFIL | \
133    grep -E 'Did not|Failed keyboard-interactive|Invalid user|error: PAM:|reverse mapping'| \
134    wc -l | sed 's/^ *//'`
135 
136    printf "D. %2s. %3s er der afvist %s ssh login\n" $dag $mnd $cnt
137 done
138 
139 echo -e "\nGROEN OPGAVE =========\n"
140 echo "Følgende sikkerhedsproblemer er fundet:"
141 ## Her er lidt quick and dirty programmering.
142 # -Reverse mapping antyder at den der logger på ikke er den vedkommende påstår den er.
143 #  Det kan også være at vedkommende ikke har en A-record i dns'en.
144 # -Invalid user er 95% bruteforce hacking forsøg!Hvis det kun er en enkeltstående, er
145 #  det en slåfejl (fejl 40).
146 # -Failed keyboard-interactive/pam er, når det er enkeltstående fejl tastefejl hos 
147 #  bruger.
148 #
149 ## Jeg sætter følgende grænser:
150 #  reverse og invalid: Samme ip mere end 10 gange er et angreb på ssh servicen.
151 ## Aktion:
152 #  Der sendes en mail med advarsel og løsningsforslag.
153 
154 invalidusr $LOGFIL | while read cnt ip ; do
155 cat << BREV
156 to: ttt@infected.com
157 from: warning@infected.com
158 ==========================
159 #     WARNING HACKED???  #
160 ==========================
161 
162 $ip har forsøgt $cnt gange atlogge ind via ssh med brute force.
163 - Enten luk for $ip i firewallen
164 - Eller indsæt $ip i /etc/host.deny
165 BREV
166 echo -e "\n"
167 done
168 reversemap $LOGFIL | while read cnt ip ; do
169 cat << ANDETBREV
170 to: ttt@infected.com
171 from: warning@infected.com
172 ==========================
173 #     WARNING HACKED???  #
174 $ip har forsøgt $cnt gange at logge ind via ssh med en ipadresse der ikke har
175 en A-Record i DNSen.
176 - Enten luk for $ip i firewallen
177 - Eller indsæt $ip i /etc/host.deny
178 ANDETBREV
179 echo -e "\n"
180 done
Hej Tomas - Som sædvanlig en rigtig god og let læselig løsning. Henrik Thomsen 12:13, 2 September 2009 (CEST)
Har du ikke et større projekt i skuffen vi kunne starte ud på


Tomas løsning på SNMP1

 1 #!/usr/bin/bash
 2 #
 3 # Programmet finder de 10 porte, hvor der er mest trafik.
 4 #
 5  
 6 ## INITIAL
 7 # Noder der skal scannes. mellemrum sepereret
 8 switch="192.168.22.201 192.168.22.202"
 9 
10 ## FUNKTIONER ##
11 #
12 function SNMPPortCnt {
13   ## Aflaeser trafikken for en given port
14   # input:  $1 = ip adresse på node
15   # input:  $2 = portnr (1-24)
16   # output: Tekst : "cnt:port:node" (port er i klartekst)
17 
18   cnt=`snmpget -v 2c -c public $1 IF-MIB::ifInOctets.$2 | sed 's/.*:[ \t]*//'`
19   int=`snmpget -v 2c -c public $1 IF-MIB::ifDescr.$2 | cut -d':' -f4 | sed 's/^ //'`
20   echo "$cnt:$int:$1"
21 }
22  
23 ####################
24 #     MAIN         #
25 ####################
26 for node in $switch ; do
27   # rend gennem alle switch
28   for (( port=1 ; port<=24; port+=1 )) ; do
29     # port 1 til 24
30     SNMPPortCnt $node $port
31   done
32 # Pipe over i while, som udskriver pænt
33 done | sort -rn | head -n10 | \
34   while read max ; do
35     c=`echo $max | cut -d ':' -f1`
36     p=`echo $max | cut -d ':' -f2`
37     i=`echo $max | cut -d ':' -f3`
38     # udskriv resultat
39     printf "Bruger paa %-15s port %-16s har sent %s bytes\n" $i $p $c
40   done

--Tomas Christian Jensen 13:56, 3 September 2009 (CEST)

Tomas Løsning på SNMP2

 1 #!/usr/bin/bash
 2 
 3 # Chech for 1 parameter
 4 if ! [ $# -eq 1 ] ; then
 5   echo "Der mangler et linienr"
 6   echo "Brug: linie <linienr>"
 7   exit 255
 8 fi
 9 
10 function findlinie {
11   # Find linie i /tmp/linienumre
12   # Input : Linienummer
13   # output: interface ip-aderesse
14 
15   nummer=`grep -w ^$1 /tmp/linienumre | cut -d ' ' -f2,3`
16   if [ "$nummer" != "" ] ; then
17     echo "$nummer"
18   else
19     echo "ikke fundet"
20   fi
21 }
22 
23 function portstatus {
24   # input : $1 = ip
25   # input : $2 = interface
26   # output: Oppe/Nede Oppe/Nede
27 
28   port=`echo $2 | cut -d'/' -f2`
29 
30   # kald switch
31   adminstatus=`snmpget -v 2c -c public $1 IF-MIB::ifAdminStatus.$port | cut -d' ' -f4`
32 
33   operstatus=`snmpget -v 2c -c public $1 IF-MIB::ifOperStatus.$port | cut -d' ' -f4`
34 
35   if [ "$adminstatus" == "up(1)" ] ; then
36     adminstatus="Oppe"
37   else
38     adminstatus="Nede"
39   fi
40 
41   if [ "$operstatus" == "up(1)" ] ; then
42     operstatus="Oppe"
43   else
44     operstatus="Nede"
45   fi
46 
47   echo "$adminstatus $operstatus"
48 }
49 
50 ###### MAIN ######
51 
52 # Find Linie
53 l=`findlinie $1`
54 if [ "$l" == "ikke fundet" ] ; then
55   echo "Linie $1 er ikke fundet!!!"
56   exit 1
57 else
58   ps=`portstatus $l`
59 
60   interface=`echo $l | cut -d' ' -f2`
61   ip=`echo $l | cut -d' ' -f1`
62 
63   as=`echo $ps | cut -d' ' -f1`
64   os=`echo $ps | cut -d' ' -f2`
65 
66   echo "Linie $1 er $interface paa $ip"
67   echo "Administrativ status er: $as"
68   echo "Operationel status er  : $os"
69 fi

--Tomas Christian Jensen 10:10, 15 September 2009 (CEST)

Et eksempel på løsning af fotoopgaven

Her er så min løsning.

  1 #!/usr/bin/bash
  2 
  3 ## Programmet konverterer billeder i et eller flere kataloger, således at 
  4 ## længste side på billedet er max 800px. Aspekt forholdet bibeholdes.
  5 ## Hvis længste side er < 800px, skal størrelsen ikke ændres.
  6 ## Billedet skal komprimeres til 75%.
  7 ## EXIF data må ikke ændres/fjernes (Kun info billedstørrelsen).
  8 ## Det konverterede billede flyttes til et andet katalog.
  9 
 10 ## INITIAL
 11 
 12 ## Original Billedrod
 13 PICTROOT=/tmp/billeder
 14 
 15 ## Behandlede Billeder rod
 16 CONVROOT=/home/tcj/Billeder
 17 
 18 ## Maximal sidelaengde
 19 MAXLEN=800
 20 
 21 ###################
 22 #   FUNCTIONER    #
 23 ###################
 24 
 25 function dimension {
 26   ## Finder størrelse og aspekt forholdet paa et billede
 27   # input : $1 = filnavn paa billede
 28   # output: tekst: "X Y aspectforhold"
 29 
 30   # Find stoerrelsen
 31   pictinfo=`rdjpgcom -verbose $1 | grep "JPEG image" | cut -d' ' -f4,6| sed 's/[whh,]//g'`
 32   # Et lille regnestykke
 33   udtryk=`echo $pictinfo | sed 's/ /\//'`
 34   # Udregn aspekt forholdet ( et tal > 1 betyder laengden er stoerst )
 35   aspekt=`echo "scale=5;$udtryk" | bc`
 36   # Rturner vaerdier
 37   echo "$pictinfo $aspekt"
 38 }
 39 
 40 function nydimension {
 41   ## Finder ny størrelse på billede
 42   # input : $1 = X
 43   # input : $2 = Y
 44   # input : $3 = aspectforhold
 45   # output: tekst: "X Y"
 46 
 47   x=$1
 48   y=$2
 49 
 50   if [ `echo "$3 >= 1" | bc` ] ; then
 51     # Hvis aspektet er >= 1 er X stoerst
 52     if [ $1 -gt $MAXLEN ] ; then
 53     # Hvis siden er stoerre end 800 skal billedet formindskes
 54       formindsk=`echo "scale=5;$1/$MAXLEN" | bc`
 55       x=$MAXLEN
 56       y=`echo "$2/$formindsk" | bc`
 57     fi
 58   else
 59    # Y er størst
 60    if [ $2 -gt $MAXLEN ] ; then
 61    # Hvis siden er stoerre end $MAXLEN skal billedet formindskes
 62      formindsk=`echo "scale=5;$2/$MAXLEN" | bc`
 63      y=$MAXLEN
 64      x=`echo "$1/$formindsk" | bc`
 65    fi
 66  fi
 67  echo "${x}x${y}"
 68 }
 69 
 70 function billednavn {
 71   ## Laver et nyt billednavn
 72   # input : $1 loebenr
 73   # input : $2 fotografnavn
 74   # output: Tekst: Et filnavn
 75 
 76   # Lav datodelen
 77   dd=`date "+_%y_%m_%d_"`
 78   echo "${2}${dd}$1.jpg"
 79 }
 80 
 81 ###################
 82 #      MAIN       #
 83 ###################
 84 
 85 cd $PICTROOT
 86 
 87 # Start på gennemløb af træ
 88 for dir in * ; do
 89   if ! [ -e $CONVROOT/${dir}beh ] ; then
 90     # Opret katalog for behandlede billeder
 91     mkdir $CONVROOT/${dir}beh
 92   fi
 93   # Rend billederne igennem
 94   cd $dir
 95   
 96   # Billedtæller
 97   i=1;
 98   for billed in *.jpg ; do
 99     d=`dimension $PICTROOT/$dir/$billed`
100     nd=`nydimension $d`
101 
102     # Lav det nye billede - start med et ny filnavn
103     filnavn=`billednavn $i $dir`
104     echo "Vent laver $billed om til $filnavn" 
105     convert $PICTROOT/$dir/$billed -quality 75 -resize $nd $CONVROOT/${dir}beh/$filnavn
106     # Tæl billedtæller op
107     i=$[i+1]
108   done
109   cd ..
110 done

--Tomas Christian Jensen 14:00, 3 September 2009 (CEST)