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

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

能够使用sudo命令CygWin 很有用,而且速度更快比打开高架外壳:

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.

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

CygWin 的 SUDO项目有以下行为:危险的:它的作用是服务器/客户端架构,实际上,客户端(sudo)向内部(不在本地计算机外部监听)端口 7070TCP 的服务器(sudoserver.py)发送命令请求,无需检查用户或权限,因此任何人(甚至是非特权用户)都可以登录到计算机可以处决管理员(CygWin 或 Windows)shell 命令或脚本(CygWin 或 Windows 也是如此)。
问题变差如果你遵循作者建议的方法:将“sudoserver.py”注册为服务,那么它将一直运行。

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

一点点恼人的。我正在使用.cmd已分配的文件来解决这个问题热键运行“sudoserver.py”,我在完成管理工作后(手动)关闭它,但是距离经典的“sudo”还很远Linux 上的可用性。

最好且实用的方法是:

  1. **自动打开“sudoserver.py”请求 UAC 提升提示(或用户/密码)。
  2. 关闭它过一会儿,这样在sudo连续执行多个命令的情况下,UAC 请求就不会继续造成干扰。

有什么办法自动化,至少部分如此?

答案1

注意:这主要是一个程序(shell 脚本)是我做的,我知道这个论坛更像是一个问答网站,而不是一个程序介绍网站。但我没有任何 GitHub(或类似)帐户,也没有时间研究向社区发布开源程序的方法。所以,只要一个可以工作和有用的程序有可能被那些可能喜欢它的人忽视(甚至几个月),如果不分享一个已经制作好的程序会很可惜,我就会在这里发布目前来说。如果管理员决定删除此帖子,我没问题,我会理解。我希望用一种 问答足以使它对这个论坛有用。如果有足够的感兴趣的用户我会尽力抽出一些时间来继续项目(经过我所有的研究,我没有在互联网上找到最接近这个的东西,但是,嗯......我不知道我的脚本是否有价值或者它是否浪费了时间)。

我已经编写了一个简单的 Linux shell 脚本它在 CygWin 上运行(到目前为止),并有助于(我希望)减少 CygWin 的 SUDO 时间攻击间隔。该程序名为TOUACExt(缩写“超时和 UAC 扩展“)并充当CygWin 的 SUDO 包装器(需要安装),实际上是由一组四个.sh程序组成。

TOUACExt 执行示例

特征

  • 使用舒适:通过模拟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

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

安装说明

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

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

  • 将四个.shTOUACExt 脚本在路径上,例如:

    /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 教程

#!/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.

代碼SUDO服务器

#!/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). 

代碼SUDO服务器WatchDog.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 

代碼SUDO服务器WatchDogScheduler.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 

从 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

注2:这些脚本位于预测试版发布,所以它们仍然有缺陷,代码也不是很干净。无论如何,在我使用三台不同的 Windows 7 计算机进行的测试中,它们似乎(大部分)运行正常。

简短的解释该计划:

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

去做

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

已举报漏洞

  • exit即使在输入if is running后,bash shell 仍保持打开状态,sudoserver.py直到其关闭。欢迎使用临时解决方法。

我希望有人会用我为 TOUACExt 编程付出了很长时间。
增强和修正接受。
关于的建议我应该去哪里出版停止唠叨这个论坛的代码也被接受了;-)。

抱歉发了这么长的帖子。我没有太多的空闲时间,而且这个项目几乎要消失在我的衣柜里了(也许要好几年了,谁知道呢?)。

答案2

简单的 sudo.bat (使用 nircmd)

Nircmd 可以在这里下载:
http://www.nirsoft.net/utils/nircmd.html

我下载了 nircmd 并将其重命名nircmdc.exenircmd.exe,替换了原来的nircmd.exe。然后我将其移动到C:\windows\system32

我还制作了以下批处理文件以允许将参数传递给脚本。

应该说,我已经在我的计算机上禁用了 UAC,所以我不再需要这个脚本,但它在 Windows 8 中确实可以工作。它在 cygwin 中也能很好地工作。

@echo off
if "%*" == "" goto error
nircmd elevate %*
goto thisiseof
:error
echo No arguments were given. Exiting.
:thisiseof

答案3

由于对现有解决方案不满意,我采用了nu774 的脚本增加安全性并使其更易于设置和使用。该项目现已可用在 Github 上

要使用它,只需下载cygwin-sudo.py并通过 运行它python3 cygwin-sudo.py **yourcommand**

为了方便起见,您可以设置一个别名:

alias sudo="python3 /path-to-cygwin-sudo/cygwin-sudo.py"

相关内容