Buscar ficheros de riesgo(setuid, setgid o wx en group/public) para usuarios que no sean root en el sistema

#!/usr/bin/env bash

#
# Copyright (c) 2010 Jorge Alonso Toro
# All rights reserved.

# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in the
#    documentation and/or other materials provided with the distribution.
# 3. The name of the author may not be used to endorse or promote products
#    derived from this software without specific prior written permission.

# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
declare -r FINDUID_VERSION=0.1

# Descripcion:
# 'setuid' busca los ficheros que tengan activado el bit SUID/SGID o w/x en grup/public
# y que pertenezcan a los usuarios indicados o del sistema, dejando un log de eventos
# indicando: nombre_user, directorio, fichero y permisos. Ademas se cambiara el nombre
# del fichero a nombre_fichero.riesgo y se enviara un mail informando a cada usuario
# dueño.
#
# sintaxis: setuid [opciones]
# opciones:
# -f file                          archivo de logs. si no existe se guardara en /root/riesgo.txt             
#
# -u user1[:user2 ...:userN]       lista de usuarios separados por ':'.Si no se invoca esta opcion
#                                  se aplicara setuid a todos los usuarios del sistema.
#

# directorio publico
declare -r FDIR=grup/públic/
# fichero log
FLOG=/root/riesgo.txt
#FLOG="riesgo.txt"
rm -rf $FLOG
# usuarios del sistema
declare -a A
# fichero email, guarda los
# usuarios que se les envia correo
FMAIL=/tmp/email.txt
rm -rf $FMAIL
# hostname
HOSTN=$(hostname)

# ARG
arg1=$1
arg2=$2
arg3=$3
arg4=$4

smg_syntax() {
# mensaje de sintaxis:
#
    echo """
  Descripcion:
    'setuid' busca los ficheros que tengan activado el bit SUID/SGID o w/x en grup/public
    y que pertenezcan a los usuarios indicados o del sistema, dejando un log de eventos
    indicando: nombre_user, directorio, fichero y permisos. Ademas se cambiara el nombre
    del fichero a nombre_fichero.riesgo y se enviara un mail informando a cada usuario
    dueño.

    sintaxis: setuid [-u user1[:user2..:N]] [-f nombre_fichero_log]
    opciones:
    -f file                          archivo de logs. si no existe se guardara en /root/riesgo.txt             

    -u user1:[user2:...:userN:]      lista de usuarios separados por ':'.Si no se invoca esta opcion
                                     se aplicara setuid a todos los usuarios del sistema.
    """
    exit 0

}

usuarios(){
# busca los usuarios del sistema
#
    con_user=0

# buscamos todos los user del sistema, menos a root.
for u in $(cat /etc/passwd | egrep 'bash$' | awk -F: '{print $1}' | sed '/root/d'); do
        A[$con_user]=$u
        ((con_user++))
    done
    ((c--))
#    echo "USUARIOS DEL SISTEMA: " $con_user
#    for i in ${A[*]}; do
#        echo $i
#    done

    return
}

syntax_user(){
# verificamos la sintaxis para el parametro -u
#
    local n=1
    local CENTINELA=0
    `echo $@ | grep -q '\-u'` # busca que exista -u
    local c=$?
#  echo syntax
#  echo $@
#  echo c = $c

  # recorre hasta encontrar la lista de usuarios.
    for i in $@; do
        ( echo $i | grep -q ':') && CENTINELA=$n && INPUT_USER=$i
        let n=n+1
    done

    if [ "$CENTINELA" = "0" ] && [  "$c" = "0" ]; then
        echo -e "Error de sintaxis hay que ingresar una lista de usuarios seguido de la opcion -u ....\n"
        smg_syntax
    fi
  [ "$CENTINELA" = "0" ] && return 0
    n=$CENTINELA
  if ((n > 1))
    then
     ((n--))
    else
        echo -e "Error de sintaxis debe preceder la opcion -u al usar una lista de usuarios...\n"
        smg_syntax
    fi
    echo $n
    u=`echo $@ | tr -s ' ' | cut -d' ' -f$n`
    if [ "-u" = "$u" ]; then
        echo "si"
      echo lista de usuarios ${CENTINELA}
    else
      echo -e "Error en la sintaxis.....\n"
        smg_syntax
    fi

  return $CENTINELA
}

syntax_file_log(){
# verifica la sintaxis del parametro -f
#
    local centinela=0

    # si existe un -f revisa la sintaxis
    # si no retorna cero.
    ( echo $* | grep -q "\-f" ) || return $centinela 

    for i in $@ ; do
        [ "$i" = "-f" ] && centinela=1
        [ "$centinela" = "1" ] && centinela=2 && continue 1
        [ "$centinela" = "2" ] && FILE_OUT=$i
    done
    if [ -z "$FILE_OUT" ]; then
        echo "Error, nombre de fichero log no valido o no existe ...."
        smg_syntax
    else
        FLOG=$FILE_OUT
    fi

    return $centinela
}

there_user(){
# determina que usuarios son verdaderos
#    usuarios
#    declare -a
    local y=0
    local i=0

#    echo INPUT_USER=$INPUT_USER
    for u in `echo $INPUT_USER | sed 's/:/\n/g'` ; do
        I[$y]=$u
        ((y++)) # usuarios ingresados
    done

#    for t in ${I[*]} ; do
#        echo usuarios ingresados: $t
#    done

    for c in ${A[*]}; do
        for a in ${I[*]}; do
            echo $c == $a
            [ "$c" = "$a" ] && UI[$i]=$a && ((i++))
        done
    done

# DEBUG:
     for x in ${UI[*]} ; do
         echo usuario para la busqueda: $x
    done

    #[ "$i" = "0" ] # no hubo coincidencias de usuarios.
    case $i in
        0) # se usan los usuarios del sistema A[]
            return $i
                ;;
        *) # se usan los usuarios ingresados UI[]
            return $i
            ;;
    esac

}

fsuid(){
# busca los ficheros con bit suid/sgid y w/x
#

    echo -e "\n"BUSCADO ... SUID/SGID para user: $1 "\n" >> $FLOG
    find $FDIR -user $1 \( -perm -04000 -o -perm -02000 \) -exec ls -l {} \; >> $FLOG && echo "$1"  >> $FMAIL
    echo -e "\n"BUSCADO ... WRITE/EXECUTE para user: $1 "\n" >> $FLOG
    find $FDIR -user $1 \( -perm -0200 -o -perm -0100 \) -exec ls -l {} \; >> $FLOG  && echo "$1" >> $FMAIL
    echo ------------------------------------------------------------------------------------------- >> $FLOG
# Renombra:
    echo -e "\n"BUSCADO ... SUID/SGID para user: $1 "\n"
    find $FDIR -user $1 \( -perm -04000 -o -perm -02000 \) -exec mv {} {}.riesgo \; 2> /dev/null
    echo -e "\n"BUSCADO ... WRITE/EXECUTE para user: $1 "\n"
    find $FDIR -user $1 \( -perm -0200 -o -perm -0100 \) -exec mv {} {}.riesgo \; 2> /dev/null

  return
}

email(){

    if [ -z $FLOG ]; then
        echo "No se pudo enviar el email ...."
        exit 1
    else
        echo -e "\n"Enviando emails ....
        for i in $(cat $FMAIL)
        do
            mail -s "ficheros de riesgo" $i@$HOSTN < $FLOG
        done
    fi

}

#-------------- MAIN PRUEBAS -------------------

[ $# -gt 4 ] && smg_syntax
usuarios
syntax_user $@
# RSU capturamos el dato retornado de syntax_user
# si RSU es 0, no se ingresaron usuarios con -u
RSU=$?
syntax_file_log $@

#-------------- MAIN -------------------
#
there_user
# RTU captura el dato retornado por there_user
# si RTU es 0, no existen los usuarios ingresados
RTU=$?

((v=RTU + RSU))
case $v in
    0)
        # Cuando no se ingresan usuarios al sistema
        for i in ${A[*]}; do
            fsuid $i
        done
        email
        ;;
    *)
        # cuando no coinciden los usuarios ingresados con los del sistema
        if [ "$RTU" = "0" ]; then
            for i in ${A[*]}; do
                fsuid $i
            done
            email
        else
        # cuando ingresamos usuarios y coinciden
            for i in ${UI[*]}; do
                fsuid $i
            done
            email
        fi
        ;;

esac

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s