NOTA: Este es principalmente un programa (script de shell) que hice, y sé que este foro es más un sitio de preguntas y respuestas que uno de introducción de programas. Pero no tengo ninguna cuenta de GitHub (o similar), ni he tenido tiempo para investigar sobre el método de publicación de un programa Open Source en la comunidad. Por lo tanto, mientras exista el riesgo de que un programa funcional y útil pase desapercibido (incluso durante meses) para aquellos que puedan disfrutarlo, y sería triste no compartir un programa ya realizado, lo publicaré aquí para ahora. No hay problemas para mí si los administradores deciden eliminar este hilo, lo entenderé. Espero haber redactado el asunto lo
suficiente como para responder preguntas lo suficiente como para que sea útil para este foro. Si hay suficientesusuarios interesados , haré todo lo posible para dedicar algo de tiempo a continuar el proyecto (después de todas mis investigaciones, no he encontrado nada más cercano a esto en Internet, pero, bueno ... no sé si mi script es valioso o no ha sido una pérdida de tiempo).
He programado un simple script de shell de Linux que funciona (hasta ahora) en CygWin y ayuda (espero) a reducir el SUDO para el intervalo de tiempo de ataque de CygWin. El programa se llama TOUACExt (acrónimo de " TimeOut and UAC Extension ") y actúa como un contenedor para SUDO para CygWin (requerido instalado), y está realmente compuesto por un conjunto de cuatro .sh
programas.
Caracteristicas :
- Uso cómodo : al simular el sudo original del comportamiento de Linux, el mensaje de solicitud de confirmación de UAC solo aparece una vez (varios
sudo
comandos consecutivos solo generarán una solicitud de UAC). Mientras sudoserver.py siga ejecutándose (15 minutos por defecto), no habrá más solicitudes de UAC .
- Los usuarios privilegiados (administradores) solo reciben la solicitud de confirmación de UAC ( Sí / No ) en la pantalla.
- Los usuarios no privilegiados (no administradores) obtienen una pantalla de ingreso de cuenta / contraseña de administrador .
- sudoserver.py sigue ejecutándose, luego se cierra automáticamente después de un tiempo predefinido (15 minutos) desde la última ejecución del comando sudo.
- sudoserver.py no se cierra (sigue ejecutándose y volverá a comprobarlo en 5 minutos) en caso de que se ejecute sudo .
- Funciona de forma remota (probado a través de SSH):
- Los usuarios sin privilegios no pueden iniciar sudoserver.py de forma remota.
- Crea un registro (aunque simple y no muy legible) en
/var/log/SUDOForCygWin/
.
Requisitos (en CygWin):
- SUDO para CygWin .
- pgrep (en el
procps
paquete).
- flock (en
util-linux
paquete).
- nohup (creo que está instalado por defecto en CygWin, pero no estoy seguro).
Suponiendo : - Los dos programas del proyecto SUDO para CygWin en el camino sugerido por el autor:
/usr/local/bin/sudoserver.py
/usr/local/bin/sudo
TOUACExt ha sido probado trabajando en Windows 7 SP1 y Windows XP SP3, pero no sé si tiene sentido usarlo en este último.
Instrucciones de instalación :
Ponga este script (nombre sugerido:) SUDOServer.cmd
y cree un acceso directo (puede personalizar su icono si lo desea) con el nombre SUDOServer.lnk
(debe habilitarlo en este acceso directo Advanced Options --> Execute as Administrator
) en cualquier lugar de su ruta de Windows , por lo que sudoserver.py
puede solicitarlo directamente desde Windows:
c:\CygWin\bin\python2.7.exe /usr/local/bin/sudoserver.py
Coloque los cuatro scripts .sh de TOUACExt en la ruta, por ejemplo:
/usr/local/bin/SUDO.sh
/usr/local/bin/SUDOServer.sh
/usr/local/bin/SUDOServerWatchDog.sh
/usr/local/bin/SUDOServerWatchDogScheduler.sh
Cambie el nombre del script de Python original de sudo
a sudo.py
:
mv /usr/local/bin/sudo /usr/local/bin/sudo.py
ADVERTENCIA: El script Python original "sudo" no debe permanecer en ninguna parte de su ruta, o podría ejecutarse en su lugar.
Cree este alias (por ejemplo, manualmente o editando su ~/.bashrc
):
alias sudo='SUDO.sh'
Código para SUDO.sh :
#!/bin/bash
# ********** SUDO.sh v0.04a **********
# Variables:
# LockFile (will use a temporal one for now):
#lockfile=sudoserver-running.lck
LockFile=lockfile.lck
# Creating LogFile (if it does not exist):
mkdir /var/log/SUDOForCygWin 2>/dev/null
chmod 777 /var/log/SUDOForCygWin 2>/dev/null
LogFile=/var/log/SUDOForCygWin/$(date +%Y%m%d).log
exec 5>>$LogFile # Redirector 5 will be the log file.
chmod 777 $LogFile >&5 2>&5 # Writable to anyone (for now).
# Start of the program
echo "========== Starting SUDO Server for CygWin ==========" >&5
echo $(date) >&5
# does the lock file exists as locked?
if [ $(flock -n $TMP/$LockFile echo>/dev/null;echo $?) -eq 0 ]
then
# The lock file is not locked.
echo "LockFile not locked. Testing sudo access..." >&5
if [ $(sudo.py vartemp=0>/dev/null 2>/dev/null;printf $?) -eq 0 ]
then
# Wooops. sudoserver.py is running without the lockfile. Better to correct this.
echo "LockFile not locked, but sudoserver.py seems to be running." >&5
printf "Killing sudoserver.py...\n" >&5
sudo.py kill $(sudo.py pgrep.exe -f -l sudoserver.p[y] | grep "pgrep" -v | awk '{print $1}') >&5 2>&5
fi
# Starting SUDOServer.sh
printf "Requesting SUDOServer start...\n" >&5
nohup SUDOServer.sh >&5 2>&1&
# Wait some time delay for UAC Prompt to start
sleep 2
timeout=$((SECONDS+10))
# Has sudoserver.py already started?
while [ $(flock -w 1 $TMP/$LockFile echo>/dev/null;printf $?) -eq 0 ] || [ $(tasklist | grep "consent.exe" -i>/dev/null;printf $?) -eq 0 ]
do
# No. We have to wait.
# Waiting for SUDOServer.py to be running.
printf "."
if [ $SECONDS -ge $timeout ]
then
# sudoserver.py not responding. Aborting with errorlevel=3.
printf "sudoserver.py not responding. Aborting.\n"
exit 3
fi
done
# Yes. sudoserver.py is up and running.
fi
printf "\n"
# Schedule (add) SUDOServer Watch Dog to Task Scheduler:
SUDOServerWatchDogScheduler.sh
# Invoke requested sudo command
sudo.py $@
#printf "ErrorLevel was: "$?
# ErrorLevel Codes:
# 3 --> timeout waiting for sudoserver.py to respond.
Código para SUDOServer.sh :
#!/bin/bash
# ********** SUDOServer.sh v0.04a **********
# Variables:
# LockFile (a temporal one for now):
#lockfile=sudoserver-running.lck
LockFile=lockfile.lck
# Check for other instances of sudoserver.py running
if [ $(flock -n $TMP/$LockFile echo>/dev/null;printf $?) -eq 0 ]
then
printf "Creating lockfile: "$TMP/$LockFile"\n"
flock $TMP/$LockFile -c 'cmd /c SUDOServer'
# The file has been unlocked. Send error level=2.
exit 2
else
printf "The lockfile: "$TMP/$LockFile" is locked by another process.\n"
printf "Exiting SUDOServer.sh"
fi
printf "SUDOServer.sh execution finished. Exiting."
# Exiting with no problems.
exit 0
# ErrorLevel Codes:
# 2 --> SUDOServer.lnk (maybe denial of UAC).
Código para SUDOServerWatchDog.sh :
#!/bin/bash
# ********** SUDOServerWatchDog.sh v0.04a **********
# Variables:
# LockFile (a temporal one for now):
#lockfile=sudoserver-running.lck
LockFile=lockfile.lck
# Redirecting to LogFile:
LogFile=/var/log/SUDOForCygWin/$(date +%Y%m%d).log
exec 5>>$LogFile
if [ $(stat $LogFile -c %a) -ne 777 ]
then
echo "Logfile "$LogFile" has incorrect permissions." >&5
echo "Attemping to change permissions of "$LogFile >&5
chmod 777 $LogFile >&5 2>&5
fi
# Remove Task Scheduler entry, if exists.
if [ $(schtasks.exe /query | grep "SUDOServerWatchDog" -i>/dev/null 2>&5;printf $?) -eq 0 ]
then
sudo.py schtasks.exe /delete /tn "SUDOServerWatchDog" /f >&5 2>&5
fi
# Is sudoserver.py running?
if [ $(flock -n $TMP/$LockFile echo>/dev/null;printf $?) -eq 1 ] || [ $(sudo.py vartemp=0>/dev/null 2>/dev/null;printf $?) -eq 0 ]
then
# Yes. sudoserver.py is running. So...
printf "sudoserver.py detected running...\n" >&5
# Is any instance of sudo running right now?
if [ $(sudo.py pgrep -f -l "/usr/local/bin/sudo.py " | grep -v grep>/dev/null 2>&5;printf $?) -eq 0 ]
then
# Yes. sudo is running right now. So...
printf "There are instances of sudo running.\n" >&5
sudo.py schtasks /create /tn "SUDOServerWatchDog" /tr "SUDOServerWatchDog" /sc minute /mo 5 /sd 10/10/2010 /ru "SYSTEM" >&5 2>&5
printf "Will check again in 5 minutes. Adding Task.\n" >&5
else
# No. sudo is not running right now. So...
# Kill sudoserver.py.
printf "Closing sudoserver.py\n" >&5
sudo.py kill $(sudo.py pgrep.exe -f -l sudoserver.p[y] | grep "pgrep" -v | awk '{print $1}')
fi
else
printf "sudoserver.py not running. Nothing to be done.\n" >&5
fi
Código para SUDOServerWatchDogScheduler.sh :
#!/bin/bash
# ********** SUDOWatchDogScheduler.sh v0.04a **********
# Check if WatchDog is already scheduled
if [ $(schtasks.exe /query | grep "SUDOServerWatchDog">/dev/null 2>&5;printf $?) -eq 0 ]
then
# Yes. Remove it in order to create a new one.
echo "Task SUDOServerWatchDog already existing." >&5
echo "Removing task SUDOServerWatchDog..." >&5
sudo.py schtasks.exe /delete /tn "SUDOServerWatchDog" /f >&5 2>&5
if [ $? -eq 0 ]
then
# Task correctly deleted.
echo "Task correctly removed." >&5
else
# Something failed in task creation. Report.
echo "ERROR on deleting the SUDOServerWatchDog programmed task." >&5
fi
fi
# Schedule new task for deletion.
echo "Adding new SUDOServerWatchDog task to trigger in 15 minutes." >&5
sudo.py schtasks /create /tn "SUDOServerWatchDog" /tr "SUDOServerWatchDog" /sc minute /mo 15 /sd 10/10/2010 /ru "SYSTEM" >&5 2>&5
if [ $? -eq 0 ]
then
# Task correctly scheduled.
echo "Task SUDOServerWatchDog correctly scheduled." >&5
else
# Something failed in task scheduling. Report.
echo "ERROR on scheduling programmed task SUDOServerWatchDog." >&5
fi
Pruebe el programa desde un shell CygWin Bash:
Luis@Kenobi ~
$ sudo ls -la
<UAC ELEVATION PROMPT APPEARS>
total 49
drwxr-xr-x+ 1 Luis None 0 abr 7 02:23 .
drwxrwxrwt+ 1 Luis- None 0 abr 4 03:27 ..
-rw------- 1 Luis None 13798 abr 14 00:31 .bash_history
-rwxr-xr-x 1 Luis None 1494 mar 3 11:36 .bash_profile
-rwxr-xr-x 1 Luis None 6260 abr 6 05:19 .bashrc
-rwxr-xr-x 1 Luis None 1919 mar 3 11:36 .inputrc
-rw------- 1 Luis None 35 abr 2 01:43 .lesshst
-rwxr-xr-x 1 Luis None 1236 mar 3 11:36 .profile
drwx------+ 1 Luis None 0 mar 8 01:49 .ssh
-rw-r--r-- 1 Luis None 7 mar 4 18:01 d:ppp.txt
-rw-r--r-- 1 Luis None 37 abr 7 02:23 my.log
NOTA2: estos scripts están en versión pre-beta , por lo que todavía tienen errores y el código no está muy limpio. De todos modos, en mis pruebas con tres computadoras con Windows 7 diferentes, parecen estar funcionando (en su mayoría) bien.
Breve explicación del programa:
- Debido al alias, al ejecutar un comando sudo se invoca el script SUDO.sh.
- SUDO.sh llama a SUDOServer.sh , abriendo (mediante
SUDOServer.lnk
) "sudoserver.py" si es necesario.
- Se ejecuta el comando sudo original invocado por el usuario.
- Luego, SUDO.sh llama a SUDOServerWatchDogScheduler.sh , que programa SUDOServerWatchDog.sh para que se ejecute después del tiempo dado (15 minutos predeterminado) para cerrar
sudoserver.py
.
- Después del tiempo predefinido, SUDOServerWatchDog.sh cierra sudoserver.py . Si hay alguna instancia de sudo en ejecución , se programa para una nueva ejecución después de 5 minutos.
Para hacer :
- Auto instalador que crea todos los archivos .sh, .cmd y .lnk automáticamente.
- Establezca el archivo de bloqueo a otro (está en $ TMP / lockfile.lck).
- Agregue una secuencia de comandos de configuración o un archivo .config (para valores predeterminados en tiempos de espera, ubicaciones de archivos ... etc.).
- Agregar el comportamiento de la cuenta del sistema (gracias, @ Wyatt8740).
- ¿Cambiar "flock" (modo SUDO de bloqueo interno) con "fusor" cuando corresponda?
- Sugerencias aceptadas.
Reportadas Errores :
- El shell bash se mantiene abierto incluso después de ingresar
exit
si se sudoserver.py
está ejecutando hasta que se cierra. Las soluciones provisionales son bienvenidas.
Espero que alguien use las largas horas de programación que he dedicado a TOUACExt.
Mejoras y correcciones aceptadas. También se aceptaron
sugerencias sobre dónde debo publicar el código para dejar de molestar a este foro ;-).
Perdón por la larga publicación. No tengo mucho tiempo libre, y este proyecto estuvo a punto de desaparecer en mi armario (tal vez durante años, ¿quién sabe?).