CygWin 使用(自动化)SUDO 的实用(更接近经典的 Linux 之一)方法

Sop*_*rez 11 windows sudo cygwin bash command-line

能够sudoCygWin 中使用命令很有用,而且比打开提升的 shell更快

Luis@Kenobi /cygdrive/c/Users/Luis
$ net user /add TestUser
System error 5.
Access denied.

Luis@Kenobi /cygdrive/c/Users/Luis
$ sudo net user /add TestUser
Command completed successfully.
Run Code Online (Sandbox Code Playgroud)

如上所示,您也可以像 Linux 一样运行 Windows 命令/脚本。对我来说是整洁的;在远程(SSH) 控制台上工作,并允许组合 Windows/Linux命令。因此,能够执行管理任务几乎是必须的。

但该 CygWin项目SUDO有一种可能很危险的行为:它作为服务器/客户端架构工作,实际上,客户端 (sudo) 在内部向服务器 (sudoserver.py) 发送命令请求(不在外部侦听)本地计算机)端口 7070TCP,没有用户或权限检查,因此登录到计算机的任何人(甚至是非特权用户)都可以执行管理员(CygWin 或 Windows)shell 命令或脚本(CygWin 或 Windows)。如果您保留作者建议的方法,则
问题会变得更糟:将“sudoserver.py”注册为服务,因此它将永久运行。

因此,为了使事情更安全(并非完全),我这样做:
1.- 在管理外壳上执行“sudoserver.py”。
2.- 在另一个 CygWin shell 上执行我的“sudo”命令。
3.- 关闭(Ctrl+C)“sudoserver.py”和管理外壳。

有点讨厌。我正在使用一个.cmd带有运行“sudoserver.py”的指定热键的文件来解决它,并且我在我的管理工作之后(手动)关闭它,但仍然远离Linux 上经典的“sudo”可用性。

伟大而实用的方法是一些方法:

  1. **自动打开“sudoserver.py”请求 UAC 提升提示(或用户/密码)。
  2. 一段时间后关闭它,因此在sudo连续执行多个命令的情况下,UAC 请求不会继续受到干扰。

有没有办法自动化这个,至少是部分自动化

Sop*_*rez 10

注意:这主要是一个感兴趣的用户,我会尽我所能花一些时间我制作的程序(shell 脚本),我知道这个论坛更像是一个问答网站,而不是一个程序介绍网站。但是我没有任何 GitHub(或类似)帐户,也没有时间研究向社区发布开源程序的方法。所以,只要有一个风险,即一个工作和有用的程序一直被忽视(甚至几个月)那些谁可以享受它,那将是可悲的不是共享一个已经作出计划,我将在这里发布的现在。如果管理员决定删除此线程,对我来说没有问题,我会理解。我希望以问答的方式表达这个问题, 足以使它对这个论坛有用。如果有足够的继续这个项目(经过我所有的研究,我在互联网上没有找到最接近这个的东西,但是,好吧......我不知道我的脚本是否有价值或这是浪费时间)。

我已经编写了一个简单的 Linux shell 脚本,它可以在 CygWin 上运行(直到现在)并且有助于(我希望)减少 CygWin 时间攻击间隔的 SUDO。该程序名为TOUACExt(“ TimeOut and UAC Extension ”的首字母缩写),作为CygWin SUDO包装器(需要安装),实际上由一组四个.sh程序组成。

TOUACEExt 执行示例

特征

  • 使用方便:通过模拟Linux中原有的sudo行为,UAC确认请求提示只出现一次(多个连续sudo命令只会产生一个UAC请求)。只要 sudoserver.py 继续运行(默认 15 分钟),就不会再有 UAC请求。
  • 特权(管理员)用户只能在屏幕上收到 UAC 确认请求(是/否)。
  • 非特权(非管理员)用户获得管理员帐户/密码输入屏幕。
  • sudoserver.py 继续运行,然后在上次 sudo 命令执行后的预定义时间(15 分钟)后自动关闭
  • sudoserver.py 不会关闭(继续运行并在 5 分钟后再次检查)以防万一 任何 sudo 实例运行。
  • 远程工作(通过 SSH 测试):
    • 非特权用户无法远程启动 sudoserver.py。
  • 创建(但简单的,不是很可读)日志/var/log/SUDOForCygWin/

要求(在 CygWin 中):

  • CygWin 的 SUDO
  • pgrep(在 procps包中)。
  • 羊群(在 util-linux包)。
  • nohup(我认为默认安装在 CygWin 上,但不确定)。

假设: - 作者建议的路径上的 SUDO for CygWin 项目的两个程序:

/usr/local/bin/sudoserver.py
/usr/local/bin/sudo
Run Code Online (Sandbox Code Playgroud)

TOUACext 已经 在 Windows 7 SP1 和 Windows XP SP3 上测试,但我不知道在最后一个上使用它是否有意义。

安装说明

  • 将此脚本(建议名称:)SUDOServer.cmd并创建一个快捷方式(如果需要,您可以个性化其图标)将其命名SUDOServer.lnk(您必须在此快捷方式启用Advanced Options --> Execute as Administrator在您的 Windows 路径的任何位置,因此sudoserver.py可以直接从 Windows 请求:

    c:\CygWin\bin\python2.7.exe /usr/local/bin/sudoserver.py

  • TOUACExt的四个.sh脚本放在路径上,例如:

    /usr/local/bin/SUDO.sh /usr/local/bin/SUDOServer.sh /usr/local/bin/SUDOServerWatchDog.sh /usr/local/bin/SUDOServerWatchDogScheduler.sh

  • 将原始Python 脚本重命名sudosudo.py

    mv /usr/local/bin/sudo /usr/local/bin/sudo.py
    警告:原始的“sudo”Python 脚本不得保留在您路径中的任何位置,否则可能会被执行。

  • 创建此别名(例如,手动或通过编辑您的~/.bashrc):

    alias sudo='SUDO.sh'

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.
Run Code Online (Sandbox Code Playgroud)

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). 
Run Code Online (Sandbox Code Playgroud)

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 
Run Code Online (Sandbox Code Playgroud)

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 
Run Code Online (Sandbox Code Playgroud)

从 CygWin Bash shell 测试程序:

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
Run Code Online (Sandbox Code Playgroud)

注意 2:这些脚本处于预测试阶段版本,因此它们仍然存在错误并且代码不是很干净。无论如何,在我对三台不同的 Windows 7 计算机的测试中,它们似乎工作(大部分)正常。

程序简要说明

  1. 由于别名,执行 sudo 命令时SUDO.sh 脚本会调用。
  2. SUDO.sh调用 SUDOServer.sh,打开(通过SUDOServer.lnk如果需要)“sudoserver.py”。
  3. 执行用户调用的原始 sudo 命令
  4. 然后 SUDO.sh调用 SUDOServerWatchDogScheduler.sh,它安排 SUDOServerWatchDog.sh 在给定时间(默认为 15 分钟)后执行 close sudoserver.py
  5. 在预定义的时间之后, SUDOServerWatchDog.sh关闭 sudoserver.py。如果有任何sudo running 实例,它会在 5 分钟后自行编程以进行新的执行。

要做

  • 自动创建所有 .sh、.cmd 和 .lnk 文件的自安装程序
  • 建立其他的锁定文件(它在 $TMP/lockfile.lck)。
  • 添加配置脚本或 .config 文件(用于超时、文件位置等的默认值)。
  • 添加系统帐户行为(感谢@Wyatt8740)。
  • ¿在适当的地方使用“fuser”更改“flock”(内部锁定 SUDO 模式)?
  • 接受建议

报告的错误

  • 即使输入exitifsudoserver.py正在运行,bash shell 也会保持打开状态,直到它关闭。欢迎临时解决方法。

我希望有人会使用我专门为 TOUACEExt 编写的长时间编程。接受
增强和更正
关于我应该去哪里发布代码以停止唠叨这个论坛的建议也被接受;-)。

抱歉,帖子太长了。我没有太多空闲时间,这个项目即将消失在我的衣橱里(也许多年,谁知道?)。

  • 如果您想要对代码的反馈,请将其发布在 codereview.stackexchange.com 上。(这里有使用说明和示例很好) (2认同)