NOTA: Este é principalmente um programa (shell script) que eu criei e sei que este fórum é mais um site de perguntas e respostas do que um site de introdução de programas. Mas eu não tenho nenhuma conta no GitHub (ou similar), nem tive tempo para pesquisar sobre o método de publicação de um programa de código aberto para a comunidade. Portanto, desde que exista o risco de um programa útil e útil passar despercebido (mesmo por meses) para aqueles que possam apreciá-lo, e seria triste não compartilhar um programa já criado, vou publicá-lo aqui para agora. Sem problemas para mim, se os administradores decidirem remover este tópico, eu entenderei. Espero ter redigido o assunto de uma
maneira que responda perguntas e respostas, a fim de torná-lo útil para este fórum. Se houver o suficienteusuários interessados , farei o possível para dedicar algum tempo para continuar o projeto (depois de todas as minhas pesquisas, não encontrei nada mais próximo disso na Internet, mas, bem ... não sei se meu script é valioso ou foi uma perda de tempo).
Programei um script de shell simples do Linux que funciona (até agora) no CygWin e ajuda (espero) a reduzir o SUDO para o intervalo de ataque de tempo do CygWin. O programa é nomeado TOUACExt (acrônimo de " TimeOut e extensão UAC ") e atua como um wrapper para SUDO para CygWin (necessário instalado) e é realmente composto por um conjunto de quatro .sh
programas.
Características :
- Uso confortável : simulando o sudo original do comportamento do Linux, o prompt de solicitação de confirmação do UAC é exibido apenas uma vez (vários
sudo
comandos consecutivos geram apenas uma solicitação do UAC). Enquanto o sudoserver.py continuar em execução (padrão de 15 minutos), não haverá mais solicitações de UAC .
- Usuários privilegiados (Admin) recebem apenas uma solicitação de confirmação do UAC ( Sim / Não ) na tela.
- Usuários não privilegiados (não administradores) recebem uma tela de entrada de conta / senha de administrador .
- O sudoserver.py continua em execução e fecha automaticamente após um tempo predefinido (15 minutos) a partir da última execução do comando sudo.
- O sudoserver.py não fecha (continua em execução e verifica novamente em 5 minutos) no caso de qualquer instância de sudo em execução.
- Funciona remotamente (testado via SSH):
- Usuários não privilegiados não podem iniciar o sudoserver.py remotamente.
- Cria um log (ainda que simples e pouco legível) em
/var/log/SUDOForCygWin/
.
Requisitos (no CygWin):
- SUDO para CygWin .
- pgrep (no
procps
pacote).
- rebanho (na
util-linux
embalagem).
- nohup (acho que instalado por padrão no CygWin, mas não tenho certeza).
Assumindo : - Os dois programas do projeto SUDO for CygWin no caminho sugerido pelo autor:
/usr/local/bin/sudoserver.py
/usr/local/bin/sudo
O TOUACExt foi testado em Windows 7 SP1 e Windows XP SP3, mas não sei se faz sentido usá-lo neste último.
Instruções de instalação :
Coloque esse script (nome sugerido:) SUDOServer.cmd
e crie um atalho (você pode personalizar seu ícone, se desejar) com o nome SUDOServer.lnk
(você deve ativar esse atalho Advanced Options --> Execute as Administrator
) em qualquer lugar do caminho do Windows , para que sudoserver.py
possa ser solicitado diretamente no Windows:
c:\CygWin\bin\python2.7.exe /usr/local/bin/sudoserver.py
Coloque os quatro scripts .sh do TOUACExt no caminho, por exemplo:
/usr/local/bin/SUDO.sh
/usr/local/bin/SUDOServer.sh
/usr/local/bin/SUDOServerWatchDog.sh
/usr/local/bin/SUDOServerWatchDogScheduler.sh
Renomeie o script Python original de sudo
para sudo.py
:
mv /usr/local/bin/sudo /usr/local/bin/sudo.py
AVISO: O script Python "sudo" original não deve permanecer em nenhum lugar do caminho ou pode ser executado.
Crie este alias (por exemplo, manualmente ou editando o seu ~/.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
Teste o programa a partir de um 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: Esses scripts estão na versão pré-beta , portanto ainda estão com erros e o código não está muito limpo. Enfim, nos meus testes com três computadores com Windows 7 diferentes, eles parecem estar funcionando (principalmente) OK.
Breve explicação do programa:
- Devido ao alias, ao executar um comando sudo, o script SUDO.sh é chamado.
- SUDO.sh chama SUDOServer.sh , abrindo (via
SUDOServer.lnk
) "sudoserver.py" se necessário.
- O comando sudo original invocado pelo usuário é executado.
- Em seguida, SUDO.sh chama SUDOServerWatchDogScheduler.sh , que agenda SUDOServerWatchDog.sh para execução após o tempo determinado (padrão de 15 minutos) para fechar
sudoserver.py
.
- Após o tempo predefinido, SUDOServerWatchDog.sh fecha o sudoserver.py . Se houver alguma instância do sudo em execução , ele se programa para nova execução após 5 minutos.
Para fazer :
- Auto-instalador que cria todos os arquivos .sh, .cmd e .lnk automaticamente.
- Estabeleça um arquivo de bloqueio para outro (está em $ TMP / lockfile.lck).
- Adicione um script de configuração ou arquivo .config (para padrões em tempos limite, localizações de arquivos ... etc).
- Adicionar comportamento da conta do sistema (obrigado, @ Wyatt8740).
- ¿Troque "rebanho" (modo SUDO de travamento interno) por "fusor", onde apropriado?
- Sugestões aceitas.
Erros relatados :
- O shell bash permanece aberto mesmo após a entrada,
exit
se sudoserver.py
estiver em execução até fechar. Soluções provisórias são bem-vindas.
Espero que alguém use as longas horas de programação que dediquei ao TOUACExt.
Aprimoramentos e correções aceitos. Também são aceitas
sugestões sobre onde devo publicar o código para deixar de incomodar este fórum ;-).
Desculpe pelo longo post. Não tenho muito tempo livre, e esse projeto estava prestes a desaparecer no meu armário (talvez por anos, quem sabe?).