CVE-2022-30950
Description
Jenkins WMI Windows Agents Plugin 1.8 and earlier includes a buffer overflow in the Windows Remote Command library, allowing named-pipe access to execute commands on the Windows agent.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Jenkins WMI Windows Agents Plugin 1.8 and earlier includes a buffer overflow in the Windows Remote Command library, allowing named-pipe access to execute commands on the Windows agent.
Vulnerability
Jenkins WMI Windows Agents Plugin 1.8 and earlier includes the Windows Remote Command library, which contains a buffer overflow vulnerability. This flaw allows users who can connect to a named pipe on the Windows agent machine to trigger the overflow [1][2]. The plugin is used to manage Windows agents via WMI, and the vulnerable library is responsible for remote command execution over the named pipe. Versions up to and including 1.8 are affected.
Exploitation
An attacker must have the ability to connect to the named pipe used by the Windows Remote Command service on the Windows agent. This typically requires network access to the agent and the ability to authenticate to the Jenkins controller or local system privileges to access the named pipe. No additional authentication beyond the named-pipe connection is needed; the attack exploits the buffer overflow to inject and execute arbitrary commands [1][2].
Impact
Successful exploitation of the buffer overflow enables the attacker to execute arbitrary commands on the Windows agent machine. This can lead to full compromise of the agent, including installation of malware, data exfiltration, or lateral movement within the network. The attacker may gain SYSTEM-level privileges, as the vulnerable service runs with high integrity [1][2].
Mitigation
The Jenkins WMI Windows Agents Plugin has been fixed in version 1.8.1, released on 2022-05-17 [2]. Users should upgrade to version 1.8.1 or later immediately. No workaround is available; discontinuing use of the plugin is the only alternative if upgrading is not possible. The vulnerability is not currently listed on CISA's Known Exploited Vulnerabilities (KEV) catalog [1][2].
AI Insight generated on May 21, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
org.jenkins-ci.plugins:windows-slavesMaven | < 1.8.1 | 1.8.1 |
Affected products
2- Jenkins project/Jenkins WMI Windows Agents Pluginv5Range: unspecified
Patches
14638cf0e56ca[SECURITY-2604]
6 files changed · +6 −286
docs/troubleshooting.adoc+0 −30 modified@@ -169,36 +169,6 @@ NAT is not security damn it! == Windows registry related issues -=== Remote Communication Service - -The Remote Communication Service "RemComSvc" must be running in order to launch commands remotely. -If not started, Jenkins will try to (remotely) start this service, assuming it is well configured. -If not, you may get an error like : - -``` -.... -Checking if Java exists -ERROR: Failed to prepare Java -java.lang.reflect.UndeclaredThrowableException -.... -``` - -In some cases (especially Windows 2008 R2) this can be caused by the lack of the Visual C++ runtime libraries needed by the service. -If this is the case you will see an error in the windows event log similar to: - -``` -.... -Activation context generation failed for "C:\Windows\RemComSvc.exe". -Dependent Assembly Microsoft.VC90.CRT,processorArchitecture="x86",publicKeyToken="1fc8b3b9a1e18e3b",type="win32",version="9.0.21022.8" could not be found. -Please use sxstrace.exe for detailed diagnosis. -.... -``` - -To solve this issue install the http://www.microsoft.com/download/en/details.aspx?id=5582[Visual C++ 2008 x86] libraries. - -The Remote Communication Service source code is a -https://github.com/jenkinsci/lib-windows-remote-command[part of Jenkins]. - === Remote Registry Service The Remote Registry service must be running in order to install the Jenkins service, but it may be stopped on your computer.
pom.xml+2 −6 modified@@ -60,19 +60,15 @@ <dependencies> <dependency> <groupId>org.jenkins-ci</groupId> - <artifactId>windows-remote-command</artifactId> - <version>1.4</version> + <artifactId>jinterop-wmi</artifactId> + <version>1.1</version> <exclusions> <exclusion> <groupId>org.jvnet</groupId> <artifactId>tiger-types</artifactId> </exclusion> </exclusions> </dependency> - <dependency> - <groupId>org.jenkins-ci.plugins</groupId> - <artifactId>jdk-tool</artifactId> - </dependency> <dependency> <groupId>io.jenkins</groupId> <artifactId>configuration-as-code</artifactId>
README.adoc+4 −8 modified@@ -18,7 +18,10 @@ image:docs/images/configuration.png[] This section goes into the details of how the managed Windows agent launcher actually works. -This launcher uses several protocols that has been around for a quite some time. +Jenkins uses multiple protocols to install the actual agent as a Windows service and then start it. These protocols have been around for a quite some time. + +IMPORTANT: The installation process assumes that the JRE is installed and accessible on the agent. Please see link:docs/troubleshooting.adoc[Troubleshooting WMI Windows Agents] if you need further help. + * It first uses http://en.wikipedia.org/wiki/Server_Message_Block[CIFS] (also known as "Windows file share protocol") to push files into the agent. @@ -29,13 +32,6 @@ http://en.wikipedia.org/wiki/Distributed_Component_Object_Model[DCOM] to talk to http://en.wikipedia.org/wiki/Windows_Management_Instrumentation[WMI] to install and start a service remotely. -* Jenkins uses two services, one is called -https://github.com/jenkinsci/lib-windows-remote-command[Remote Communication Service] and this provides a general-purpose remote command execution capability. -Jenkins uses this to check if Java is available and if not install it. -A failure to do this is not fatal problem, as Jenkins will proceed by assuming that Java is available in a reasonable place. -This service is destroyed after it is used so as not to cause any harm to the security. -The communication between Jenkins controller and this service happens over a named pipe, which itself is protected by access control. -* Jenkins then installs the actual agent as a Windows service, by using the WMI over DCOM, then it starts this service. == Troubleshooting
src/main/java/hudson/os/windows/ManagedWindowsServiceLauncher.java+0 −37 modified@@ -37,9 +37,6 @@ import hudson.remoting.Channel.Listener; import hudson.remoting.SocketChannelStream; import hudson.slaves.*; -import hudson.tools.JDKInstaller; -import hudson.tools.JDKInstaller.CPU; -import hudson.tools.JDKInstaller.Platform; import hudson.util.DescribableList; import hudson.util.Secret; import hudson.util.jna.DotNet; @@ -48,7 +45,6 @@ import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.Socket; -import java.net.URL; import java.net.UnknownHostException; import java.util.Date; import java.util.logging.Level; @@ -67,7 +63,6 @@ import org.jinterop.dcom.common.JIDefaultAuthInfoImpl; import org.jinterop.dcom.common.JIException; import org.jinterop.dcom.core.JISession; -import org.jvnet.hudson.remcom.WindowsRemoteProcessLauncher; import org.jvnet.hudson.wmi.SWbemServices; import org.jvnet.hudson.wmi.WMI; import org.jvnet.hudson.wmi.Win32Service; @@ -221,38 +216,6 @@ public void launch(final SlaveComputer computer, final TaskListener listener) th String java = resolveJava(computer); - try {// does Java exist? - logger.println("Checking if Java exists"); - WindowsRemoteProcessLauncher wrpl = new WindowsRemoteProcessLauncher(name, auth); - Process proc = wrpl.launch("\"" + java + "\" -version", "c:\\"); - proc.getOutputStream().close(); - StringWriter console = new StringWriter(); - IOUtils.copy(proc.getInputStream(), console); - proc.getInputStream().close(); - int exitCode = proc.waitFor(); - if (exitCode == 1) {// we'll get this error code if Java is not found - logger.println("No Java found. Downloading JDK"); - JDKInstaller jdki = new JDKInstaller("jdk-6u16-oth-JPR@CDS-CDS_Developer", true); - URL jdk = jdki.locate(listener, Platform.WINDOWS, CPU.i386); - - listener.getLogger().println("Installing JDK"); - copyStreamAndClose(jdk.openStream(), new SmbFile(remoteRoot, "jdk.exe").getOutputStream()); - - String javaDir = path + "\\jdk"; // this is where we install Java to - - WindowsRemoteFileSystem fs = new WindowsRemoteFileSystem(name, createSmbAuth()); - fs.mkdirs(javaDir); - - jdki.install(new WindowsRemoteLauncher(listener, wrpl), Platform.WINDOWS, - fs, listener, javaDir, path + "\\jdk.exe"); - } else { - checkJavaVersion(logger, java, new BufferedReader(new StringReader(console.toString()))); - } - } catch (Exception e) { - e.printStackTrace(listener.error("Failed to prepare Java")); - return; - } - // this just doesn't work --- trying to obtain the type or check the existence of smb://server/C$/ results in "access denied" // {// check if the administrative share exists // String fullpath = remoteRoot.getPath();
src/main/java/hudson/os/windows/WindowsRemoteFileSystem.java+0 −65 removed@@ -1,65 +0,0 @@ -package hudson.os.windows; - -import hudson.tools.JDKInstaller.FileSystem; -import jcifs.smb.NtlmPasswordAuthentication; -import jcifs.smb.SmbFile; - -import java.io.IOException; -import java.io.InputStream; -import java.net.MalformedURLException; -import java.util.List; - -import static java.util.Arrays.asList; - -/** - * {@link FileSystem} implementation for remote Windows system. - * - * @author Kohsuke Kawaguchi - */ -public class WindowsRemoteFileSystem implements FileSystem { - private final String hostName; - private final NtlmPasswordAuthentication auth; - - public WindowsRemoteFileSystem(String hostName, NtlmPasswordAuthentication auth) { - this.hostName = hostName; - this.auth = auth; - } - - private SmbFile $(String path) throws MalformedURLException { - return new SmbFile("smb://" + hostName + "/" + path.replace('\\', '/').replace(':', '$') + "/", auth); - } - - @Override - public void delete(String file) throws IOException, InterruptedException { - $(file).delete(); - } - - @Override - public void chmod(String file, int mode) throws IOException, InterruptedException { - // no-op on Windows - } - - @Override - public InputStream read(String file) throws IOException { - return $(file).getInputStream(); - } - - @Override - public List<String> listSubDirectories(String dir) throws IOException, InterruptedException { - return asList($(dir).list()); - } - - @Override - public void pullUp(String from, String to) throws IOException, InterruptedException { - SmbFile src = $(from); - SmbFile dst = $(to); - for (SmbFile e : src.listFiles()) { - e.renameTo(new SmbFile(dst, e.getName())); - } - src.delete(); - } - - public void mkdirs(String path) throws IOException { - $(path).mkdirs(); - } -}
src/main/java/hudson/os/windows/WindowsRemoteLauncher.java+0 −140 removed@@ -1,140 +0,0 @@ -package hudson.os.windows; - -import hudson.FilePath; -import hudson.Launcher; -import hudson.Proc; -import hudson.Util; -import hudson.model.Computer; -import hudson.model.TaskListener; -import hudson.remoting.Channel; -import hudson.remoting.ChannelBuilder; -import hudson.util.StreamCopyThread; -import org.jinterop.dcom.common.JIException; -import org.jvnet.hudson.remcom.WindowsRemoteProcessLauncher; - -import java.io.BufferedOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.Map; - -import static java.util.Arrays.asList; - -/** - * Pseudo-{@link Launcher} implementation that uses {@link WindowsRemoteProcessLauncher} - * - * @author Kohsuke Kawaguchi - */ -public class WindowsRemoteLauncher extends Launcher { - private final WindowsRemoteProcessLauncher launcher; - - public WindowsRemoteLauncher(TaskListener listener, WindowsRemoteProcessLauncher launcher) { - super(listener, null); - this.launcher = launcher; - } - - private String buildCommandLine(ProcStarter ps) { - StringBuilder b = new StringBuilder(); - for (String cmd : ps.cmds()) { - if (b.length() > 0) b.append(' '); - if (cmd.indexOf(' ') >= 0) - b.append('"').append(cmd).append('"'); - else - b.append(cmd); - } - return b.toString(); - } - - @Override - public Proc launch(ProcStarter ps) throws IOException { - FilePath pwd = ps.pwd(); - if (pwd == null) { - throw new IOException("Cannot access the process location."); - } - maskedPrintCommandLine(ps.cmds(), ps.masks(), pwd); - - // TODO: environment variable handling - - String name = ps.cmds().toString(); - - final Process proc; - try { - proc = launcher.launch(buildCommandLine(ps), pwd.getRemote()); - } catch (JIException | InterruptedException e) { - throw new IOException(e); - } - final Thread t1 = new StreamCopyThread("stdout copier: " + name, proc.getInputStream(), ps.stdout(), false); - t1.start(); - final Thread t2 = new StreamCopyThread("stdin copier: " + name, ps.stdin(), proc.getOutputStream(), true); - t2.start(); - - return new Proc() { - - @Override - public boolean isAlive() throws IOException, InterruptedException { - try { - proc.exitValue(); - return false; - } catch (IllegalThreadStateException e) { - return true; - } - } - - @Override - public void kill() throws IOException, InterruptedException { - t1.interrupt(); - t2.interrupt(); - proc.destroy(); - } - - @Override - public int join() throws IOException, InterruptedException { - try { - t1.join(); - t2.join(); - return proc.waitFor(); - } finally { - proc.destroy(); - } - } - - @Override - public InputStream getStdout() { - throw new UnsupportedOperationException(); - } - - @Override - public InputStream getStderr() { - throw new UnsupportedOperationException(); - } - - @Override - public OutputStream getStdin() { - throw new UnsupportedOperationException(); - } - }; - } - - @Override - public Channel launchChannel(String[] cmd, OutputStream out, FilePath _workDir, Map<String, String> envVars) throws IOException, InterruptedException { - if (_workDir == null) { - throw new IOException("Cannot access local process workdir."); - } - printCommandLine(cmd, _workDir); - - try { - Process proc = launcher.launch(Util.join(asList(cmd), " "), _workDir.getRemote()); - - return new ChannelBuilder("channel over named pipe to " + launcher.getHostName(), Computer.threadPoolForRemoting) - .withMode(Channel.Mode.BINARY) - .build(proc.getInputStream(), new BufferedOutputStream(proc.getOutputStream())); - } catch (JIException e) { - throw new IOException(e); - } - } - - @Override - public void kill(Map<String, String> modelEnvVars) throws IOException, InterruptedException { - // no way to do this - } -}
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
5- github.com/advisories/GHSA-xhw3-wmx2-76wfghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2022-30950ghsaADVISORY
- www.openwall.com/lists/oss-security/2022/05/17/8ghsamailing-listx_refsource_MLISTWEB
- github.com/jenkinsci/windows-slaves-plugin/commit/4638cf0e56caf839eadfdf0fab545abd2a9ac65eghsaWEB
- www.jenkins.io/security/advisory/2022-05-17/ghsax_refsource_CONFIRMWEB
News mentions
1- Jenkins Security Advisory 2022-05-17Jenkins Security Advisories · May 17, 2022