{"id":66687,"date":"2023-05-02T15:10:50","date_gmt":"2023-05-02T07:10:50","guid":{"rendered":"https:\/\/version-2.com\/?p=66687"},"modified":"2024-09-13T16:31:19","modified_gmt":"2024-09-13T08:31:19","slug":"cve-2021-45456-apache-kylin-command-injection","status":"publish","type":"post","link":"https:\/\/version-2.com\/zh\/2023\/05\/cve-2021-45456-apache-kylin-command-injection\/","title":{"rendered":"CVE-2021-45456: Apache Kylin Command Injection"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-post\" data-elementor-id=\"66687\" class=\"elementor elementor-66687\">\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<span style=\"color: #000000;\"><img fetchpriority=\"high\" decoding=\"async\" class=\"alignnone size-full\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clh0yzqmh7mxb0jqg9bqh7zk7.png?tr=w-1800,c-at_max\" width=\"979\" height=\"730\" \/><\/span>\n<div class=\"news-detail-inner-content\" data-v-85c4bf60=\"\" data-v-0bbc59dc=\"\">\n<h1><span style=\"color: #000000;\">Introduction<\/span><\/h1>\n<span style=\"color: #000000;\">Command injection in #Apache #Kylin has been found and registered as #CVE-2021-45456<\/span>\n\n<span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clh0zahkp6jtb0jpeaxq6axxf.png\" \/><\/span>\n\n<span style=\"color: #000000;\">Apache Kylin is an open-source distributed analytics engine designed to provide a SQL interface and multi-dimensional analysis on Hadoop and Alluxio supporting extremely large datasets. It was originally developed by eBay, and is now a project of the Apache Software Foundation.<\/span>\n<h1><span style=\"color: #000000;\">Background Story<\/span><\/h1>\n<span style=\"color: #000000;\">The basic story behind this vulnerability is that the user can create a project, and dump diagnosis information of that project.<\/span>\n\n<span style=\"color: #000000;\">in order for the solution to dump the diagnosis information it executes a script.<\/span>\n\n<span style=\"color: #000000;\">Since the project name is controlled by the user, the user can enter the project name as a Linux command but without characters or spaces, after that<\/span>\n\n<span style=\"color: #000000;\">When the user sends the request of the diagnosis, can modify the project name (i.e. the Linux command) and add spaces and other needed characters but URL-encoded so the command will be a valid command.<\/span>\n\n<span style=\"color: #000000;\">The solution will process this request, decode the project name, and treat it as a Linux command in the execution process, therefore, it will execute the malicious payload.<\/span>\n<h1><span style=\"color: #000000;\">Build the\u00a0lab<\/span><\/h1>\n<span style=\"color: #000000;\">I&#8217;m using docker on Ubuntu server 20.04<\/span>\n<h3><span style=\"color: #000000;\">Install docker<\/span><\/h3>\n<ul>\n \t<li><span style=\"color: #000000;\"><code>apt update<\/code><\/span><\/li>\n \t<li><span style=\"color: #000000;\"><code>apt install docker docker-compose<\/code><\/span><\/li>\n<\/ul>\n<h3><span style=\"color: #000000;\">Install Apache Kylin<\/span><\/h3>\n<ul>\n \t<li><span style=\"color: #000000;\"><code>docker pull apachekylin\/apache-kylin-standalone:4.0.0<\/code><\/span>\n\n&nbsp;\n\n<span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clh0zoqmu7ncf0jqgh465fby8.png\" \/><\/span><\/li>\n<\/ul>\n<ul>\n \t<li><span style=\"color: #000000;\"><code>sudo docker run -d \\<\/code><\/span>\n\n<span style=\"color: #000000;\"><code>-m 8G \\<\/code><\/span>\n\n<span style=\"color: #000000;\"><code>-p 7070:7070 \\<\/code><\/span>\n\n<span style=\"color: #000000;\"><code>-p 8088:8088 \\<\/code><\/span>\n\n<span style=\"color: #000000;\"><code>-p 50070:50070 \\<\/code><\/span>\n\n<span style=\"color: #000000;\"><code>-p 8032:8032 \\<\/code><\/span>\n\n<span style=\"color: #000000;\"><code>-p 8042:8042 \\<\/code><\/span>\n\n<span style=\"color: #000000;\"><code>-p 2181:2181 \\<\/code><\/span>\n\n<span style=\"color: #000000;\"><code>-p 1337:1337 \\<\/code><\/span>\n\n<span style=\"color: #000000;\"><code>--name kylin-4.0.0 \\<\/code><\/span>\n\n<span style=\"color: #000000;\"><code>apachekylin\/apache-kylin-standalone:4.0.0<\/code><\/span><\/li>\n<\/ul>\n<span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clh102gio6kgm0jpee4geb6i7.png\" \/><\/span>\n\n<span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clh102op26kgw0jpe82lxfdh8.png\" \/><\/span>\n<h3><span style=\"color: #000000;\">Setup the debugger<\/span><\/h3>\n<span style=\"color: #000000;\">First, configure the kylin.sh file<\/span>\n<ul>\n \t<li><span style=\"color: #000000;\"><code>docker exec -it container_id bash<\/code><\/span><\/li>\n \t<li><span style=\"color: #000000;\">file path <code>\/home\/admin\/apache-kylin-4.0.0-bin-spark2\/bin\/kylin.sh<\/code><\/span><\/li>\n \t<li><span style=\"color: #000000;\">Under the <code>retrieveStartCommand()<\/code> function which is the start command function. line number 267<\/span><\/li>\n<\/ul>\n<span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clh109c6u6klt0jpefq2rc939.png\" \/><\/span>\n<ul>\n \t<li><span style=\"color: #000000;\">Scroll down to line number 307, the line starts with the following <code>$JAVA ${KYLIN_EXTRA_START_OPTS} ${KYLIN_TOMCAT_OPTS}<\/code><\/span><\/li>\n \t<li><span style=\"color: #000000;\">Add the following <code>-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=1337<\/code><\/span><\/li>\n<\/ul>\n<span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clh10bbyq6kn30jpe29gjeitn.png\" \/><\/span>\n<ul>\n \t<li><span style=\"color: #000000;\">Restart the container <code>docker container restart container_id<\/code><\/span><\/li>\n \t<li><span style=\"color: #000000;\">Login to Kylin, port is 7070. I&#8217;m using the docker ip, you can also use the localhost IP.<\/span><\/li>\n \t<li><span style=\"color: #000000;\">Creds <code>admin:KYLIN<\/code><\/span><\/li>\n<\/ul>\n<span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clh10j4746kt20jpeaky10i0h.png\" \/><\/span>\n\n<span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clh10jctf6kt90jpe7rs1ex48.png\" \/><\/span>\n<ul>\n \t<li><span style=\"color: #000000;\">Configure the debugger in Intellij IDEA<\/span><\/li>\n<\/ul>\n<span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clh10lbxd7o5j0jqg1ln71dxq.png\" \/><\/span>\n\n<span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clh10lkiq6kva0jpe9xhh7781.png\" \/><\/span>\n\n<span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clh10rhx87o9a0jqgho9nda6z.png\" \/><\/span>\n\n<span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clh10rri36kz40jpeahweaw4e.png\" \/><\/span>\n<h1><span style=\"color: #000000;\">Reproduce the vulnerability<\/span><\/h1>\n<span style=\"color: #000000;\">Based on the advisory, we will create a project with command injected e.g. <code>touchpwned<\/code><\/span>\n\n<span style=\"color: #000000;\">and after that, we will dump the diagnosis information for the project, but while we are doing this we will modify it using burpsuite to trigger the command injection, therefore, triggering the exploit.<\/span>\n\n<span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clh10vqca6l200jpe78ra98hb.png\" \/><\/span>\n\n<span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clh10wjqs6l2r0jpe5zrf595k.png\" \/><\/span>\n\n<span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clh10x48z6l370jpe6a02f4ub.png\" \/><\/span>\n<ul>\n \t<li><span style=\"color: #000000;\">Once you click &#8220;Diagnosis&#8221;, intercept the request<\/span><\/li>\n<\/ul>\n<span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clh113r2z7oht0jqgafqg9sj4.png\" \/><\/span>\n<ul>\n \t<li><span style=\"color: #000000;\">Change the name <strong>touchpawned<\/strong> to <code>%60touch%20pawned%60<\/code> which the URL-encoded result of the following: <\/span>\n<pre><span style=\"color: #000000;\"><code>`touch pawned`<\/code><\/span><\/pre>\n<\/li>\n<\/ul>\n<span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clh118fxk6laq0jpehcuz0h99.png\" \/><\/span>\n<ul>\n \t<li><span style=\"color: #000000;\">Now, check the container<\/span><\/li>\n<\/ul>\n<span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clh119nqp6lbg0jpecuks8y5j.png\" \/><\/span>\n\n<span style=\"color: #000000;\">We demonstrated how you can gain access to the target and leverage this to RCE in the PoC blog from here:<\/span>\n\n<span style=\"color: #000000;\"><a style=\"color: #000000;\" href=\"https:\/\/www.vicarius.io\/vsociety\/blog\/cve-2021-45456-apache-kylin-rce-poc\" target=\"_blank\" rel=\"noopener noreferrer nofollow\">https:\/\/www.vicarius.io\/vsociety\/blog\/cve-2021-45456-apache-kylin-rce-poc<\/a><\/span>\n<h1><span style=\"color: #000000;\">Static Analysis &amp; Debugging<\/span><\/h1>\n<span style=\"color: #000000;\">NOTE: to run Kylin solution you run other apache solutions along with it, and this includes spark, Kafka, hbase, hive, spring &#8230;etc. therefore the debugging won&#8217;t be as detailed as usual because it will take it us into the source code of the other solutions.<\/span>\n<h3><span style=\"color: #000000;\">Find an entry point<\/span><\/h3>\n<span style=\"color: #000000;\">Based on the advisory the vulnerability happens in <strong>dumpProjectDiagnosisInfo<\/strong> method, but I want to go through how it handles the request, how the project gets created, how the name got stored, and how the vulnerability gets triggered with the latest request we saw.<\/span>\n<ul>\n \t<li><span style=\"color: #000000;\">I searched for &#8220;projects&#8221; and found the &#8220;ProjectController.java&#8221;. This class here responsible for listing all projects, saving the project, updating the project, deleting the project, updating the project owner, and basically most of the project functions.<\/span><\/li>\n \t<li><span style=\"color: #000000;\">I set a few breakpoints as you can see and I created a new project called &#8220;test1&#8221;, you can see this in <code>projectDescData<\/code> variable the values of the project.<\/span><\/li>\n<\/ul>\n<span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clh11zzh77p6y0jqg61lwejhc.png\" \/><\/span>\n<h3><span style=\"color: #000000;\">Understand how the project gets created and saved<\/span><\/h3>\n<ul>\n \t<li><span style=\"color: #000000;\">So first time we create a project, the solution will use the <code>saveProject<\/code> method. Let&#8217;s go through this method real quick.<\/span><\/li>\n<\/ul>\n<span style=\"color: #000000;\">The method handles a POST request to create a new project instance.<\/span>\n<ul>\n \t<li><span style=\"color: #000000;\"><code>@RequestMapping(value = \"\", method = { RequestMethod.POST }, produces = { \"application\/json\" })<\/code>: This line is an annotation that maps the method to the endpoint for creating a new project instance. It specifies that the endpoint should accept a POST request with an empty URL and that it should produce a JSON response.<\/span><\/li>\n<\/ul>\n<ul>\n \t<li><span style=\"color: #000000;\"><code>@ResponseBody<\/code>: This annotation is used to indicate that the method&#8217;s return value should be written directly to the response body.<\/span><\/li>\n<\/ul>\n<ul>\n \t<li><span style=\"color: #000000;\"><code>public ProjectInstance saveProject(@RequestBody ProjectRequest projectRequest)<\/code>: This line defines the method signature, which includes a <code>ProjectRequest<\/code> object as the request body and returns a <code>ProjectInstance<\/code> object.<\/span><\/li>\n<\/ul>\n<ul>\n \t<li><span style=\"color: #000000;\"><code>if (StringUtils.isEmpty(projectDesc.getName()))<\/code>: This line checks whether the <code>name<\/code> field of the <code>ProjectInstance<\/code> object is empty.<\/span><\/li>\n<\/ul>\n<ul>\n \t<li><span style=\"color: #000000;\"><code>if (!ValidateUtil.isAlphanumericUnderscore(projectDesc.getName()))<\/code>: This line checks whether the <code>name<\/code> field of the <code>ProjectInstance<\/code> object contains only alphanumeric characters and underscores.<code>throw new BadRequestException(<\/code>: If the <code>name<\/code> field does not contain only alphanumeric characters and underscores, a <code>BadRequestException<\/code> is thrown.<\/span><\/li>\n<\/ul>\n<pre><span style=\"color: #000000;\"><code>ProjectInstance createdProj = null;\n        try {\n            createdProj = projectService.createProject(projectDesc);\n        } catch (Exception e) {\n            throw new InternalErrorException(e.getLocalizedMessage(), e);\n        }<\/code><\/span><\/pre>\n<span style=\"color: #000000;\">This snippet here creates a new ProjectInstance object named <code>createdProj<\/code> and sets it initially to null. It then tries to create a new project using a <code>projectService<\/code> object and the <code>projectDesc<\/code> parameter passed to the createProject method.<\/span>\n\n<span style=\"color: #000000;\">If the project creation is successful, the <code>createdProj<\/code> object will be assigned the newly created project instance. If an exception is thrown during the project creation process, the catch block will be executed.<\/span>\n<ul>\n \t<li><span style=\"color: #000000;\"><code>return createdProj;<\/code>: This line returns the <code>createdProj<\/code> object, which contains the newly created project instance<\/span><\/li>\n<\/ul>\n<h3><span style=\"color: #000000;\">How the diagnosis request get proceeded &amp; how the command gets executed<\/span><\/h3>\n<ul>\n \t<li><span style=\"color: #000000;\">It all starts from the <code>dumpProjectDiagnosisInfo<\/code> method, set the breakpoints.<\/span>\n\n&nbsp;\n\n<span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clh129xpr6m6f0jpe9unm01g6.png\" \/><\/span><\/li>\n<\/ul>\n<ul>\n \t<li><span style=\"color: #000000;\">Now click on &#8220;Diagnosis&#8221; in the website. you can always see variables and their values right there.<\/span>\n\n&nbsp;\n\n<span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clh12cugi6m8z0jpe5u51evav.png\" \/><\/span><\/li>\n<\/ul>\n<ul>\n \t<li><span style=\"color: #000000;\">The important line for me is the following<\/span>\n\n<span style=\"color: #000000;\"><code>String filePath = dgService.dumpProjectDiagnosisInfo(project, diagDir.getFile());<\/code><\/span><\/li>\n<\/ul>\n<ul>\n \t<li><span style=\"color: #000000;\">We have here the <code>dumpProjectDiagnosisInfo<\/code> , now follow this and you will find yourself in <code>DiagnosisService.java<\/code> file<\/span><\/li>\n<\/ul>\n<span style=\"color: #000000;\">You can see the path here which is supposed to be the path of the diagnosis data.<\/span>\n\n<span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clh12glpi7pnd0jqg3ekobwzs.png\" \/><\/span>\n<ul>\n \t<li><span style=\"color: #000000;\">Keep following with the debugger, now this is another interesting<\/span><\/li>\n<\/ul>\n<span style=\"color: #000000;\"><code>String[] args = { project, exportPath.getAbsolutePath() };<\/code><\/span>\n\n<span style=\"color: #000000;\">This is an array named <code>args<\/code> and it contains the project name along with the exportPath which is the diagnosis data path and it&#8217;s using the getAbsolutePath() method.<\/span>\n\n<span style=\"color: #000000;\">The getAbsolutePath() method is a part of the File class. This function returns the absolute pathname of the given file object.<\/span>\n\n<span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clh12huir7pol0jqga5925mfx.png\" \/><\/span>\n<ul>\n \t<li><span style=\"color: #000000;\">After that we see <code>runDiagnosisCLI(args)<\/code> takes the args array as input.<\/span><\/li>\n \t<li><span style=\"color: #000000;\">Step-in, and here is the <code>runDiagnosisCLI()<\/code> method, and we can see the args with the values right there.<\/span>\n\n&nbsp;\n\n<span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clh12ip896mfh0jpe91shbmlt.png\" \/><\/span><\/li>\n<\/ul>\n<span style=\"color: #000000;\">After that we couple of loggers. from there, we go to<\/span>\n\n<span style=\"color: #000000;\"><code>File script = new File(KylinConfig.getKylinHome() + File.separator + \"bin\", \"diag.sh\");<\/code><\/span>\n\n<span style=\"color: #000000;\">This line of the method creates a new <code>File<\/code> object representing a shell script named &#8220;diag.sh&#8221; located in the &#8220;bin&#8221; directory of the Kylin configuration directory.<\/span>\n\n<span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clh12k3l57pra0jqg3e44fbv5.png\" \/><\/span>\n\n<span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clh12kigf7prn0jqgcgc5cffd.png\" \/><\/span>\n\n<span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clh12kq927prv0jqg88ro347r.png\" \/><\/span>\n\n<span style=\"color: #000000;\">If the script does not exist, the method throws a <code>BadRequestException<\/code> with a message that indicates the file could not be found.<\/span>\n<ul>\n \t<li><span style=\"color: #000000;\">Now, we have diagCmd variable which has the script path and the args.<\/span><\/li>\n<\/ul>\n<span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clh12m3m36mio0jpeaq1ebij7.png\" \/><\/span>\n<ul>\n \t<li><span style=\"color: #000000;\">Step-in, and click <code>getCliCommandExecutor()<\/code><\/span><\/li>\n<\/ul>\n<span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clh12nakk7pu30jqgdrffdu0u.png\" \/><\/span>\n<ul>\n \t<li><span style=\"color: #000000;\">This will take you to <code>getCliCommandExecutor<\/code> and this method determines if it will get the remote access configuration of a Hadoop cluster or not to execute commands on it, i.e. remote commands. if the value retrieved is null in regards to the remote access configuration of the Hadoop cluster, and this is what happened in our case, the commands will be executed locally.<\/span><\/li>\n<\/ul>\n<span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clh12osim6mkz0jpe7sd1gyzv.png\" \/><\/span>\n<ul>\n \t<li><span style=\"color: #000000;\">You can see the value of <code>executor<\/code> returned<\/span><\/li>\n<\/ul>\n<span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clh12pi426mlo0jped0au4raf.png\" \/><\/span>\n\n<span style=\"color: #000000;\">We have here kinda two versions of the <code>execute<\/code> method in the <code>CliCommandExecutor<\/code> calls. both of the methods execute a shell command and return a <code>Pair<\/code> object containing the exit code and output of the command.<\/span>\n\n<span style=\"color: #000000;\">We can see the first <code>execute<\/code> method takes only one argument: <code>String command<\/code>. Then, it calls the second <code>execute<\/code> method with the same <code>command<\/code> argument, along with a default <code>logAppender<\/code> of <code>new SoutLogger()<\/code> and a <code>jobId<\/code> of <code>null<\/code>.<\/span>\n\n<span style=\"color: #000000;\">The second <code>execute<\/code> method takes the <code>command<\/code>, a <code>logAppender<\/code> (which is a logger instance that is used to log the output of the command), and a <code>jobId<\/code> (which is an optional identifier that can be used to track the execution of the command).<\/span>\n\n<span style=\"color: #000000;\">The method then checks if a remote host has been specified for the <code>CliCommandExecutor<\/code> instance. If not, it runs the command locally using the <code>runNativeCommand<\/code> method, passing in the <code>command<\/code>, <code>logAppender<\/code>, and <code>jobId<\/code>. This method executes the command using a <code>ProcessBuilder<\/code> and captures the output and exit code of the command.<\/span>\n\n<span style=\"color: #000000;\">If a remote host has been specified for the <code>CliCommandExecutor<\/code> instance, the <code>execute<\/code> method instead runs the command on the remote host using the <code>runRemoteCommand<\/code> method.<\/span>\n\n<span style=\"color: #000000;\">Finally, the method checks the exit code of the command. If the exit code is non-zero, the method throws an <code>IOException<\/code> with an error message containing the exit code, error message, and command itself.<\/span>\n\n<span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clh12rn4m6mni0jpe8fuab3h3.png\" \/><\/span>\n\n<span style=\"color: #000000;\">Since we know that the command execution will happen locally, I added new breakpoints<\/span>\n\n<span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clh12sapp6mnv0jpe2pvvextd.png\" \/><\/span>\n\n<span style=\"color: #000000;\">Step-in to follow <code>runNativeCommand<\/code> method since it&#8217;s the method that will execute the command.<\/span>\n\n<span style=\"color: #000000;\">Obviously, the code defines a private method <code>runNativeCommand<\/code> which is called by the <code>execute<\/code> method in the same class, and it executes a shell command using <code>ProcessBuilder<\/code> and returns a <code>Pair<\/code> object containing the exit code and output of the command.<\/span>\n\n<span style=\"color: #000000;\">The method takes three arguments: <code>command<\/code> (which is the shell command to be executed), <code>logAppender<\/code> (which is a logger instance that is used to log the output of the command), and <code>jobId<\/code> (which is an optional identifier that can be used to track the execution of the command).<\/span>\n\n<span style=\"color: #000000;\">The method first constructs an array <code>cmd<\/code> of strings, which contains the command and its arguments. The <code>cmd<\/code> array is constructed differently depending on the operating system: for Windows, the command is executed using <code>cmd.exe \/C<\/code>, while for other operating systems (such as Linux or macOS), the command is executed using <code>\/bin\/bash -c<\/code>.<\/span>\n\n<span style=\"color: #000000;\">Then, the method constructs a <code>ProcessBuilder<\/code> instance using the <code>cmd<\/code> array and sets the <code>redirectErrorStream<\/code> property to true, which means that any error messages produced by the command will be redirected to the same output stream as the command&#8217;s standard output.<\/span>\n\n<span style=\"color: #000000;\">The method then starts the process using <code>ProcessBuilder.start()<\/code> and registers it with a <code>JobProcessContext<\/code> if a <code>jobId<\/code> is provided.<\/span>\n\n<span style=\"color: #000000;\">The method then reads the command&#8217;s standard output line by line using a <code>BufferedReader<\/code>, and appends each line to a <code>StringBuilder<\/code>. For each line, if a <code>logAppender<\/code> is provided, the line is logged using the <code>Logger.log()<\/code> method.<\/span>\n\n<span style=\"color: #000000;\">If the method is interrupted by another thread (as determined by <code>Thread.interrupted()<\/code>), it destroys the process and returns a <code>Pair<\/code> object with an exit code of 1 and a message of &#8220;Killed&#8221;.<\/span>\n\n<span style=\"color: #000000;\">If the command execution completes successfully, the method waits for the process to exit using <code>Process.waitFor()<\/code> and returns a <code>Pair<\/code> object with the exit code and output of the command.<\/span>\n\n<span style=\"color: #000000;\">Finally, the method checks if the <code>jobId<\/code> is not null removes the process from the <code>JobProcessContext<\/code> .<\/span>\n\n<span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clh12ujvj7pzu0jqg3fdqe9tt.png\" \/><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clh12urj56mpn0jpeai4ahdco.png\" \/><\/span>\n\n<span style=\"color: #000000;\">You can see from here how the variables get set along the execution of the software.<\/span>\n\n<span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clh12vrqj7q100jqgfzlg2w9z.png\" \/><\/span>\n\n<span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clh12vz0l6mqy0jpe762q6kuu.png\" \/><\/span>\n\n<span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clh12w6af6mr20jpe16bnhtrz.png\" \/><\/span>\n\n<span style=\"color: #000000;\">Those are all the variables after the <code>runNativeCommand<\/code> is done.<\/span>\n\n<span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clh12wwd67q1z0jqgcqgkf68l.png\" \/><\/span>\n\n<span style=\"color: #000000;\">From here it will return to <code>r = runNativeCommand(command, logAppender, jobId);<\/code> and now it&#8217;s a matter of sending the command output back in the response.<\/span>\n\n<span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clh12xrih7q2p0jqg44yd5112.png\" \/><\/span>\n\n<span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clh12xxzr7q2t0jqgfmg6apnz.png\" \/><\/span>\n<h2><span style=\"color: #000000;\">How the execution looks like with an injected malicious payload<\/span><\/h2>\n<span style=\"color: #000000;\">Since we understood in-depth how everything gets processed in the previous section, now I will just show screenshots of how it looks like with an injected malicious payload.<\/span>\n\n<span style=\"color: #000000;\">Follow the same steps in the &#8220;Reproduce the vulnerability&#8221; section, but instead of sending the request through burpsuite. Send the request from the browser, so you can follow it in the debugger:<\/span>\n\n<span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clh12z7au6mt90jpeatsc688p.png\" \/><\/span>\n\n<span style=\"color: #000000;\">The basic idea here is that you send the request with the project name edited and encoded.<\/span>\n\n<span style=\"color: #000000;\">The server behind the solution decodes the payload, so now it&#8217;s just a normal Linux command.<\/span>\n\n<span style=\"color: #000000;\">So, the basic structure of the command as we saw before is &#8220;script (dig.sh)&#8221; + &#8220;project name&#8221; + &#8220;folder&#8221;, and there&#8217;s where the injection happens in the project name, so the normal project name is now replaced with the payload. and this is what will be executed.<\/span>\n\n<span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clh130mri6muq0jpe3r6h7gyp.png\" \/><\/span>\n<h3><span style=\"color: #000000;\">The root cause<\/span><\/h3>\n<span style=\"color: #000000;\">I understood the root cause after the patch diffing.<\/span>\n\n<span style=\"color: #000000;\">as it&#8217;s explained in the patch diffing, they replaced &#8220;project&#8221; with &#8220;projectName&#8221; and the reason is when you follow the debugger<\/span>\n\n<span style=\"color: #000000;\">you will notice that &#8220;project&#8221; it&#8217;s just the name of the project name as it&#8217;s submitted (which is controlled by the user) after decoding. so when the attacker submits the malicious payload, the solution decodes it and passes it as it is a payload.<\/span>\n\n<span style=\"color: #000000;\">The projectName it&#8217;s the real name with no characters or spaces.<\/span>\n\n<span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clh134lhc6my40jpe5da26sqe.png\" \/><\/span>\n\n<span style=\"color: #000000;\">Once you follow<\/span>\n<pre><span style=\"color: #000000;\"><code>ProjectManager.getInstance(KylinConfig.getInstanceFromEnv())<\/code><\/span><\/pre>\n<span style=\"color: #000000;\">You will notice the projectName variable value<\/span>\n\n<span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clh136aqr7q9w0jqg7rl04kp0.png\" \/><\/span>\n\n<span style=\"color: #000000;\">This is how it looks like after that<\/span>\n\n<span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clh136xwe7qan0jqg3ss4c4rv.png\" \/><\/span>\n<h1><span style=\"color: #000000;\">Patch Diffing<\/span><\/h1>\n<span style=\"color: #000000;\">The fix link from here:<\/span>\n\n<span style=\"color: #000000;\"><a style=\"color: #000000;\" href=\"https:\/\/github.com\/apache\/kylin\/commit\/f4daf14dde99b934c92ce2c832509f24342bc845#diff-5ca0e5634941e5810bc535c8084b3f11f9dce8cbb513500ec22db6a3a69ec930L97\" target=\"_blank\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/apache\/kylin\/commit\/f4daf14dde99b934c92ce2c832509f24342bc845#diff-5ca0e5634941e5810bc535c8084b3f11f9dce8cbb513500ec22db6a3a69ec930L97<\/a><\/span>\n\n<span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clh137y146n150jpec7l458lo.png\" \/><\/span>\n\n<span style=\"color: #000000;\">As we can see the project variable was replaced with the projectName variable, and based on what we explained in the root cause of the vulnerable we understand that by replacing the project with projectName we eliminate the danger of the malicious payload injection.<\/span>\n<h1><span style=\"color: #000000;\">Mitigation<\/span><\/h1>\n<span style=\"color: #000000;\">Update Apache to the latest version.<\/span>\n<h1><span style=\"color: #000000;\">Final Thoughts<\/span><\/h1>\n<span style=\"color: #000000;\">This software was a real joy, the dependency between multiple solutions makes it a little bit harder to debug, but I tried my best to make it focus on Apache Kylin only.<\/span>\n\n<span style=\"color: #000000;\">How the payload gets structured in order to be injected it&#8217;s really interesting and fun.<\/span>\n<h1><span style=\"color: #000000;\">Resources:<\/span><\/h1>\n<ul>\n \t<li><span style=\"color: #000000;\"><a style=\"color: #000000;\" href=\"https:\/\/securitylab.github.com\/advisories\/GHSL-2021-1048_GHSL-2021-1051_Apache_Kylin\/\" target=\"_blank\" rel=\"noopener noreferrer nofollow\">https:\/\/securitylab.github.com\/advisories\/GHSL-2021-1048_GHSL-2021-1051_Apache_Kylin\/<\/a><\/span><\/li>\n \t<li><span style=\"color: #000000;\"><a style=\"color: #000000;\" href=\"https:\/\/github.com\/apache\/kylin\/commit\/f4daf14dde99b934c92ce2c832509f24342bc845#diff-5ca0e5634941e5810bc535c8084b3f11f9dce8cbb513500ec22db6a3a69ec930L97\" target=\"_blank\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/apache\/kylin\/commit\/f4daf14dde99b934c92ce2c832509f24342bc845#diff-5ca0e5634941e5810bc535c8084b3f11f9dce8cbb513500ec22db6a3a69ec930L97<\/a><\/span><\/li>\n \t<li><span style=\"color: #000000;\"><a style=\"color: #000000;\" href=\"https:\/\/kylin.apache.org\/docs\/install\/index.html\" target=\"_blank\" rel=\"noopener noreferrer nofollow\">https:\/\/kylin.apache.org\/docs\/install\/index.html<\/a><\/span><\/li>\n \t<li><span style=\"color: #000000;\"><a style=\"color: #000000;\" href=\"https:\/\/github.com\/apache\/kylin\" target=\"_blank\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/apache\/kylin<\/a><\/span><\/li>\n<\/ul>\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 class=\"wp-block-paragraph\"><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 Command injection in #Apache #Kylin has be [&hellip;]<\/p>\n","protected":false},"author":148637484,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_jetpack_feature_clip_id":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[476,1075,61],"tags":[477,1076],"class_list":["post-66687","post","type-post","status-publish","format-standard","hentry","category-vrx","category-year2023","category-press-release","tag-vrx","tag-1076"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.6 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>CVE-2021-45456: Apache Kylin 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-2022-45875-apache-dolphinscheduler-vulnerable-to-improper-input-validation-leads-to-rce\" \/>\n<meta property=\"og:locale\" content=\"zh_HK\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"CVE-2021-45456: Apache Kylin Command Injection - Version 2\" \/>\n<meta property=\"og:description\" content=\"Introduction Command injection in #Apache #Kylin has be [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.vicarius.io\/blog\/cve-2022-45875-apache-dolphinscheduler-vulnerable-to-improper-input-validation-leads-to-rce\" \/>\n<meta property=\"og:site_name\" content=\"Version 2\" \/>\n<meta property=\"article:published_time\" content=\"2023-05-02T07:10:50+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-09-13T08:31:19+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clh0yzqmh7mxb0jqg9bqh7zk7.png?tr=w-1800,c-at_max\" \/>\n<meta name=\"author\" content=\"versionpan\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"\u4f5c\u8005\" \/>\n\t<meta name=\"twitter:data1\" content=\"versionpan\" \/>\n\t<meta name=\"twitter:label2\" content=\"\u9810\u8a08\u95b1\u8b80\u6642\u9593\" \/>\n\t<meta name=\"twitter:data2\" content=\"19 \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-2022-45875-apache-dolphinscheduler-vulnerable-to-improper-input-validation-leads-to-rce#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/version-2.com\\\/2023\\\/05\\\/cve-2021-45456-apache-kylin-command-injection\\\/\"},\"author\":{\"name\":\"versionpan\",\"@id\":\"https:\\\/\\\/version-2.com\\\/zh\\\/#\\\/schema\\\/person\\\/103ffe36f7fd34a1cc126a30431b94d8\"},\"headline\":\"CVE-2021-45456: Apache Kylin Command Injection\",\"datePublished\":\"2023-05-02T07:10:50+00:00\",\"dateModified\":\"2024-09-13T08:31:19+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/version-2.com\\\/2023\\\/05\\\/cve-2021-45456-apache-kylin-command-injection\\\/\"},\"wordCount\":2107,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/version-2.com\\\/zh\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.vicarius.io\\\/blog\\\/cve-2022-45875-apache-dolphinscheduler-vulnerable-to-improper-input-validation-leads-to-rce#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/ik.imagekit.io\\\/14sfaswy6hrz\\\/blog-posts\\\/images\\\/clh0yzqmh7mxb0jqg9bqh7zk7.png?tr=w-1800,c-at_max\",\"keywords\":[\"vRx\",\"2023\"],\"articleSection\":[\"vRx\",\"2023\",\"Press Release\"],\"inLanguage\":\"zh-HK\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.vicarius.io\\\/blog\\\/cve-2022-45875-apache-dolphinscheduler-vulnerable-to-improper-input-validation-leads-to-rce#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/version-2.com\\\/2023\\\/05\\\/cve-2021-45456-apache-kylin-command-injection\\\/\",\"url\":\"https:\\\/\\\/www.vicarius.io\\\/blog\\\/cve-2022-45875-apache-dolphinscheduler-vulnerable-to-improper-input-validation-leads-to-rce\",\"name\":\"CVE-2021-45456: Apache Kylin Command Injection - Version 2\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/version-2.com\\\/zh\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.vicarius.io\\\/blog\\\/cve-2022-45875-apache-dolphinscheduler-vulnerable-to-improper-input-validation-leads-to-rce#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.vicarius.io\\\/blog\\\/cve-2022-45875-apache-dolphinscheduler-vulnerable-to-improper-input-validation-leads-to-rce#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/ik.imagekit.io\\\/14sfaswy6hrz\\\/blog-posts\\\/images\\\/clh0yzqmh7mxb0jqg9bqh7zk7.png?tr=w-1800,c-at_max\",\"datePublished\":\"2023-05-02T07:10:50+00:00\",\"dateModified\":\"2024-09-13T08:31:19+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.vicarius.io\\\/blog\\\/cve-2022-45875-apache-dolphinscheduler-vulnerable-to-improper-input-validation-leads-to-rce#breadcrumb\"},\"inLanguage\":\"zh-HK\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.vicarius.io\\\/blog\\\/cve-2022-45875-apache-dolphinscheduler-vulnerable-to-improper-input-validation-leads-to-rce\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"zh-HK\",\"@id\":\"https:\\\/\\\/www.vicarius.io\\\/blog\\\/cve-2022-45875-apache-dolphinscheduler-vulnerable-to-improper-input-validation-leads-to-rce#primaryimage\",\"url\":\"https:\\\/\\\/ik.imagekit.io\\\/14sfaswy6hrz\\\/blog-posts\\\/images\\\/clh0yzqmh7mxb0jqg9bqh7zk7.png?tr=w-1800,c-at_max\",\"contentUrl\":\"https:\\\/\\\/ik.imagekit.io\\\/14sfaswy6hrz\\\/blog-posts\\\/images\\\/clh0yzqmh7mxb0jqg9bqh7zk7.png?tr=w-1800,c-at_max\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.vicarius.io\\\/blog\\\/cve-2022-45875-apache-dolphinscheduler-vulnerable-to-improper-input-validation-leads-to-rce#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"\u9996\u9801\",\"item\":\"https:\\\/\\\/version-2.com\\\/zh\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"CVE-2021-45456: Apache Kylin 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\\\/103ffe36f7fd34a1cc126a30431b94d8\",\"name\":\"versionpan\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"zh-HK\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/72541e15024f6716236decb252e7488d4a7359d4df6f8506b01f447174f92c7c?s=96&d=identicon&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/72541e15024f6716236decb252e7488d4a7359d4df6f8506b01f447174f92c7c?s=96&d=identicon&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/72541e15024f6716236decb252e7488d4a7359d4df6f8506b01f447174f92c7c?s=96&d=identicon&r=g\",\"caption\":\"versionpan\"},\"url\":\"https:\\\/\\\/version-2.com\\\/zh\\\/author\\\/versionpan\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"CVE-2021-45456: Apache Kylin 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-2022-45875-apache-dolphinscheduler-vulnerable-to-improper-input-validation-leads-to-rce","og_locale":"zh_HK","og_type":"article","og_title":"CVE-2021-45456: Apache Kylin Command Injection - Version 2","og_description":"Introduction Command injection in #Apache #Kylin has be [&hellip;]","og_url":"https:\/\/www.vicarius.io\/blog\/cve-2022-45875-apache-dolphinscheduler-vulnerable-to-improper-input-validation-leads-to-rce","og_site_name":"Version 2","article_published_time":"2023-05-02T07:10:50+00:00","article_modified_time":"2024-09-13T08:31:19+00:00","og_image":[{"url":"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clh0yzqmh7mxb0jqg9bqh7zk7.png?tr=w-1800,c-at_max","type":"","width":"","height":""}],"author":"versionpan","twitter_card":"summary_large_image","twitter_misc":{"\u4f5c\u8005":"versionpan","\u9810\u8a08\u95b1\u8b80\u6642\u9593":"19 \u5206\u9418"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.vicarius.io\/blog\/cve-2022-45875-apache-dolphinscheduler-vulnerable-to-improper-input-validation-leads-to-rce#article","isPartOf":{"@id":"https:\/\/version-2.com\/2023\/05\/cve-2021-45456-apache-kylin-command-injection\/"},"author":{"name":"versionpan","@id":"https:\/\/version-2.com\/zh\/#\/schema\/person\/103ffe36f7fd34a1cc126a30431b94d8"},"headline":"CVE-2021-45456: Apache Kylin Command Injection","datePublished":"2023-05-02T07:10:50+00:00","dateModified":"2024-09-13T08:31:19+00:00","mainEntityOfPage":{"@id":"https:\/\/version-2.com\/2023\/05\/cve-2021-45456-apache-kylin-command-injection\/"},"wordCount":2107,"commentCount":0,"publisher":{"@id":"https:\/\/version-2.com\/zh\/#organization"},"image":{"@id":"https:\/\/www.vicarius.io\/blog\/cve-2022-45875-apache-dolphinscheduler-vulnerable-to-improper-input-validation-leads-to-rce#primaryimage"},"thumbnailUrl":"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clh0yzqmh7mxb0jqg9bqh7zk7.png?tr=w-1800,c-at_max","keywords":["vRx","2023"],"articleSection":["vRx","2023","Press Release"],"inLanguage":"zh-HK","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.vicarius.io\/blog\/cve-2022-45875-apache-dolphinscheduler-vulnerable-to-improper-input-validation-leads-to-rce#respond"]}]},{"@type":"WebPage","@id":"https:\/\/version-2.com\/2023\/05\/cve-2021-45456-apache-kylin-command-injection\/","url":"https:\/\/www.vicarius.io\/blog\/cve-2022-45875-apache-dolphinscheduler-vulnerable-to-improper-input-validation-leads-to-rce","name":"CVE-2021-45456: Apache Kylin Command Injection - Version 2","isPartOf":{"@id":"https:\/\/version-2.com\/zh\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.vicarius.io\/blog\/cve-2022-45875-apache-dolphinscheduler-vulnerable-to-improper-input-validation-leads-to-rce#primaryimage"},"image":{"@id":"https:\/\/www.vicarius.io\/blog\/cve-2022-45875-apache-dolphinscheduler-vulnerable-to-improper-input-validation-leads-to-rce#primaryimage"},"thumbnailUrl":"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clh0yzqmh7mxb0jqg9bqh7zk7.png?tr=w-1800,c-at_max","datePublished":"2023-05-02T07:10:50+00:00","dateModified":"2024-09-13T08:31:19+00:00","breadcrumb":{"@id":"https:\/\/www.vicarius.io\/blog\/cve-2022-45875-apache-dolphinscheduler-vulnerable-to-improper-input-validation-leads-to-rce#breadcrumb"},"inLanguage":"zh-HK","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.vicarius.io\/blog\/cve-2022-45875-apache-dolphinscheduler-vulnerable-to-improper-input-validation-leads-to-rce"]}]},{"@type":"ImageObject","inLanguage":"zh-HK","@id":"https:\/\/www.vicarius.io\/blog\/cve-2022-45875-apache-dolphinscheduler-vulnerable-to-improper-input-validation-leads-to-rce#primaryimage","url":"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clh0yzqmh7mxb0jqg9bqh7zk7.png?tr=w-1800,c-at_max","contentUrl":"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clh0yzqmh7mxb0jqg9bqh7zk7.png?tr=w-1800,c-at_max"},{"@type":"BreadcrumbList","@id":"https:\/\/www.vicarius.io\/blog\/cve-2022-45875-apache-dolphinscheduler-vulnerable-to-improper-input-validation-leads-to-rce#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"\u9996\u9801","item":"https:\/\/version-2.com\/zh\/"},{"@type":"ListItem","position":2,"name":"CVE-2021-45456: Apache Kylin 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\/103ffe36f7fd34a1cc126a30431b94d8","name":"versionpan","image":{"@type":"ImageObject","inLanguage":"zh-HK","@id":"https:\/\/secure.gravatar.com\/avatar\/72541e15024f6716236decb252e7488d4a7359d4df6f8506b01f447174f92c7c?s=96&d=identicon&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/72541e15024f6716236decb252e7488d4a7359d4df6f8506b01f447174f92c7c?s=96&d=identicon&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/72541e15024f6716236decb252e7488d4a7359d4df6f8506b01f447174f92c7c?s=96&d=identicon&r=g","caption":"versionpan"},"url":"https:\/\/version-2.com\/zh\/author\/versionpan\/"}]}},"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/pbQRKm-hlB","post_mailing_queue_ids":[],"_links":{"self":[{"href":"https:\/\/version-2.com\/zh\/wp-json\/wp\/v2\/posts\/66687","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\/148637484"}],"replies":[{"embeddable":true,"href":"https:\/\/version-2.com\/zh\/wp-json\/wp\/v2\/comments?post=66687"}],"version-history":[{"count":6,"href":"https:\/\/version-2.com\/zh\/wp-json\/wp\/v2\/posts\/66687\/revisions"}],"predecessor-version":[{"id":69380,"href":"https:\/\/version-2.com\/zh\/wp-json\/wp\/v2\/posts\/66687\/revisions\/69380"}],"wp:attachment":[{"href":"https:\/\/version-2.com\/zh\/wp-json\/wp\/v2\/media?parent=66687"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/version-2.com\/zh\/wp-json\/wp\/v2\/categories?post=66687"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/version-2.com\/zh\/wp-json\/wp\/v2\/tags?post=66687"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}