<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE article PUBLIC "-//NLM//DTD JATS (Z39.96) Journal Publishing DTD v1.1 20151215//EN" "http://jats.nlm.nih.gov/publishing/1.1/JATS-journalpublishing1.dtd">
<article xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:mml="http://www.w3.org/1998/Math/MathML" xml:lang="en" article-type="research-article" dtd-version="1.1">
<front>
<journal-meta>
<journal-id journal-id-type="pmc">CMC</journal-id>
<journal-id journal-id-type="nlm-ta">CMC</journal-id>
<journal-id journal-id-type="publisher-id">CMC</journal-id>
<journal-title-group>
<journal-title>Computers, Materials &#x0026; Continua</journal-title>
</journal-title-group>
<issn pub-type="epub">1546-2226</issn>
<issn pub-type="ppub">1546-2218</issn>
<publisher>
<publisher-name>Tech Science Press</publisher-name>
<publisher-loc>USA</publisher-loc>
</publisher>
</journal-meta>
<article-meta>
<article-id pub-id-type="publisher-id">34505</article-id>
<article-id pub-id-type="doi">10.32604/cmc.2023.034505</article-id>
<article-categories>
<subj-group subj-group-type="heading">
<subject>Article</subject>
</subj-group>
</article-categories>
<title-group>
<article-title>JShellDetector: A Java Fileless Webshell Detector Based on Program Analysis</article-title>
<alt-title alt-title-type="left-running-head">JShellDetector: A Java Fileless Webshell Detector Based on Program Analysis</alt-title>
<alt-title alt-title-type="right-running-head">JShellDetector: A Java Fileless Webshell Detector Based on Program Analysis</alt-title>
</title-group>
<contrib-group>
<contrib id="author-1" contrib-type="author">
<name name-style="western"><surname>Song</surname><given-names>Xuyan</given-names></name></contrib>
<contrib id="author-2" contrib-type="author">
<name name-style="western"><surname>Qin</surname><given-names>Yiting</given-names></name></contrib>
<contrib id="author-3" contrib-type="author">
<name name-style="western"><surname>Liu</surname><given-names>Xinyao</given-names></name></contrib>
<contrib id="author-4" contrib-type="author" corresp="yes">
<name name-style="western"><surname>Cui</surname><given-names>Baojiang</given-names></name><email>cuibj@bupt.edu.cn</email></contrib>
<contrib id="author-5" contrib-type="author">
<name name-style="western"><surname>Fu</surname><given-names>Junsong</given-names></name></contrib>
<aff id="aff-1"><institution>School of Cyber Security, Beijing University of Posts and Telecommunications</institution>, <addr-line>Beijing, 100876</addr-line>, <country>China</country></aff>
</contrib-group>
<author-notes>
<corresp id="cor1"><label>&#x002A;</label>Corresponding Author: Baojiang Cui. Email: <email>cuibj@bupt.edu.cn</email></corresp>
</author-notes>
<pub-date date-type="collection" publication-format="electronic"><year>2023</year></pub-date>
<pub-date date-type="pub" publication-format="electronic"><day>24</day><month>1</month><year>2023</year></pub-date>
<volume>75</volume>
<issue>1</issue>
<fpage>2061</fpage>
<lpage>2078</lpage>
<history>
<date date-type="received"><day>19</day><month>7</month><year>2022</year></date>
<date date-type="accepted"><day>22</day><month>9</month><year>2022</year></date>
</history>
<permissions>
<copyright-statement>&#x00A9; 2023 Song et al.</copyright-statement>
<copyright-year>2023</copyright-year>
<copyright-holder>Song et al.</copyright-holder>
<license xlink:href="https://creativecommons.org/licenses/by/4.0/">
<license-p>This work is licensed under a <ext-link ext-link-type="uri" xlink:type="simple" xlink:href="https://creativecommons.org/licenses/by/4.0/">Creative Commons Attribution 4.0 International License</ext-link>, which permits unrestricted use, distribution, and reproduction in any medium, provided the original work is properly cited.</license-p>
</license>
</permissions>
<self-uri content-type="pdf" xlink:href="TSP_CMC_34505.pdf"></self-uri>
<abstract><p>Fileless webshell attacks against Java web applications have become more frequent in recent years as Java has gained market share. Webshell is a malicious script that can remotely execute commands and invade servers. It is widely used in attacks against web applications. In contrast to traditional file-based webshells, fileless webshells leave no traces on the hard drive, which means they are invisible to most antivirus software. To make matters worse, although there are some studies on fileless webshells, almost all of them are aimed at web applications developed in the PHP language. The complex mechanism of Java makes researchers face more challenges. To mitigate this attack, this paper proposes JShellDetector, a fileless webshell detector for Java web applications based on program analysis. JShellDetector uses method probes to capture dynamic characteristics of web applications in the Java Virtual Machine (JVM). When a suspicious class tries to call a specific sensitive method, JShellDetector catches it and converts it from the JVM to a bytecode file. Then, JShellDetector builds a Jimple-based control flow graph and processes it using taint analysis techniques. A suspicious class is considered malicious if there is a valid path from <italic>sources</italic> to <italic>sinks</italic>. To demonstrate the effectiveness of the proposed approach, we manually collect 35 test cases (all open source on GitHub) and test JShellDetector and only two other Java fileless webshell detection tools. The experimental results show that the detection rate of JShellDetector reaches 77.1&#x0025;, which is about 11&#x0025; higher than the other two tools.</p>
</abstract>
<kwd-group kwd-group-type="author">
<kwd>Web security</kwd>
<kwd>fileless webshell</kwd>
<kwd>Java web application</kwd>
<kwd>malware</kwd>
</kwd-group>
</article-meta>
</front>
<body>
<sec id="s1"><label>1</label><title>Introduction</title>
<p>In the past few years, injection vulnerabilities have been in the Open Web Application Security Project (OWASP) Top 10 [<xref ref-type="bibr" rid="ref-1">1</xref>], which makes web servers the largest victim of network attacks. Attackers use injection vulnerabilities to upload malicious programs and scripts to web servers or inject existing files to damage websites [<xref ref-type="bibr" rid="ref-2">2</xref>]. A webshell is a typical malicious script that exploits an injection vulnerability to launch a persistent attack. Webshell is a shell-like interface that can remotely execute commands and hack servers. Once the server is implanted with a webshell, an attacker can legitimately connect to the server by loading the webshell page in the browser. Through the webshell page, attackers can steal information, tamper with databases, upload more dangerous malware and escalate their privileges [<xref ref-type="bibr" rid="ref-3">3</xref>]. The problem is exacerbated when attackers use the compromised server as a springboard to break into internal network systems.</p>
<p>A fileless webshell is a special kind of webshell that is sometimes referred to as fileless malware or fileless attack. Compared to a traditional webshell, it only runs in memory (system memory or virtual machine memory), does not rely on files, or deletes its fingerprints after running, which means it is an invisible attack. This feature makes both detection and removal a challenge. According to the 2020 fourth quarter security report released by the network security research company WatchGuard [<xref ref-type="bibr" rid="ref-4">4</xref>], the infection rate of fileless malware increased by 888&#x0025; in 2020 compared with 2019. In the same year, cybersecurity research company Red Canary published a threat detection report [<xref ref-type="bibr" rid="ref-5">5</xref>], detailing that 48.7&#x0025; of organizations were affected by malicious fileless webshells.</p>
<p>Because the fileless webshell deletes itself and stays hidden in memory, it has high concealment and is extremely difficult to detect. Therefore, how to quickly and accurately detect whether a fileless webshell is implanted in a server is crucial to the security of systems. In recent years, there have been many studies in this field. Webshell detection is usually divided into static detection and dynamic detection. Static detection does not require the execution of webshell but models malicious behavior through statistical features. For example, Kang&#x00A0;et&#x00A0;al.&#x00A0;[<xref ref-type="bibr" rid="ref-6">6</xref>] used statistical features such as information entropy and coincidence index of PHP source files to extract opcode sequences of PHP source files, and integrated statistical features with opcode sequences to improve the detection efficiency of webshell. Yang&#x00A0;et&#x00A0;al.&#x00A0;[<xref ref-type="bibr" rid="ref-7">7</xref>] realize the detection of webshell attack traffic in network traffic using the method of supervised machine learning model. Compared with static detection, dynamic detection takes more time and may produce a large number of false positives [<xref ref-type="bibr" rid="ref-8">8</xref>]. Therefore, the mainstream method for webshell is static detection.</p>
<p>Through literature research, we found that the existing research on webshell detection has two characteristics. On the one hand, most of the research is for traditional file-based webshells, and research on fileless attacks focuses on the Windows operating system rather than web servers. On the other hand, PHP webshell detection has attracted the attention of most researchers. Java as one of the most widely used program languages in the world [<xref ref-type="bibr" rid="ref-9">9</xref>], has not received corresponding attention. To the best of our knowledge, there is currently no literature for fileless webshell detection in Java web applications. We consider that this dilemma stems from three challenges: 1) Lack of samples of Java fileless webshells. There is no publicly available dataset on the internet, sporadic webshells samples exist in blogs. 2) A variety of Java web frameworks. Most Java web applications are built with open source frameworks that encapsulate many low-level operations. These complex features provide convenience to attackers to implant fileless webshell while increasing the difficulty of detection. 3) Java Virtual Machine (JVM). The JVM is an independent ecosystem, which makes the fileless malware detection method for PHP applications or the Windows operating system unable to be directly migrated to Java web applications.</p>
<p>In this paper, we overcome the above 3 challenges and propose JShellDetector, a detector for Java fileless webshells based on JVM monitoring and taint analysis. Overall, the main contributions of this paper are as follows:
<list list-type="simple">
<list-item><label>1)</label><p>This paper studies the principle of Java fileless webshell in detail, and constructs a webshell test case dataset based on different Java web components and Spring framework components. All test cases are publicly accessible.</p></list-item>
<list-item><label>2)</label><p>We propose JShellDetector, a Java fileless webshell detector based on Java Virtual Machine monitoring and taint analysis. The method probe proposed in this paper can be triggered when a suspicious class calls a sensitive method and converts the class into a bytecode file. Then taint analysis is used to determine whether the suspicious class is a webshell.</p></list-item>
<list-item><label>3)</label><p>We evaluate the performance of our tools in detail and compare them with the only two Java fileless webshell detection tools. The experimental results show that JShellDetector can find more webshell test cases. The detection rate of our tool is 77.1&#x0025;, which is about 11&#x0025; higher than the other two tools.</p></list-item>
</list></p>
<p>The remainder of this paper is organized as follows. In Section 2, we introduce the related work about fileless webshell detection. Two mainstream approaches are discussed in detail. Section&#x00A0;3 introduces the background knowledge of Java fileless webshell, including the composition of Java web and the classification of Java fileless webshell. In Section 4, the composition and principles of JShellDetector are introduced in detail. To evaluate JShellDetector, we make comprehensive experiments in Section 5. We propose 3 standard research questions and demonstrate the effectiveness of our tool by answering them. Section 6 summarizes the work in this paper and introduces future work.</p>
</sec>
<sec id="s2"><label>2</label><title>Related Work</title>
<p>Webshell detection is usually divided into static detection and dynamic detection. In this section, the classification models and advantages and disadvantages of these two detection approaches are introduced respectively.</p>
<sec id="s2_1"><label>2.1</label><title>Static Webshell Detection</title>
<p>Static detection finds webshells by matching statistical features and code features. The advantage of this approach is that it is easy to deploy, with a simple script. At the same time, static detection has a high detection rate for known webshell features. But this method can only find known webshells and requires manual exclusion of weak signature files. This process requires a lot of manual work.</p>
<p>Zhu&#x00A0;et&#x00A0;al.&#x00A0;[<xref ref-type="bibr" rid="ref-10">10</xref>] proposed a webshell detection system based on the support vector machine (SVM) classifier. This classifier is trained and tested on mixed source code features, i.e., lexical, syntactic and statistical. A total of 20 features were first measured and normalized, then filtered using the Fisher score to designate the most important features. Finally, 16 features were selected to build the SVM model.</p>
<p>Kurniawan&#x00A0;et&#x00A0;al.&#x00A0;[<xref ref-type="bibr" rid="ref-11">11</xref>] used static statistical features based on source code. They define 50 sensitive functions and count the number of calls to these functions in each file. The obtained counts are used to construct feature vectors, which are used to provide different classifiers. Experiments show that SVM performs better than other classifiers such as Decision Tree and Naive Bayes. However, the dataset used in the experiments is not limited to 100 files, so more data is needed to validate the model.</p>
<p>Huang&#x00A0;et&#x00A0;al.&#x00A0;[<xref ref-type="bibr" rid="ref-12">12</xref>] used 2 statistical features, 21 high-risk functions, and term frequency-inverse document frequency (TF-IDF) vectorization of PHP opcode sequences. They found that the random forest (RF) classifier outperformed the SVM and k-nearest neighbors (KNN) algorithms. The advantage of this approach is that it combines two opcode sequences, one for the execution path and one for the code itself. Experimental results show that the proposed model shows improved performance.</p>
<p>Tian&#x00A0;et&#x00A0;al.&#x00A0;[<xref ref-type="bibr" rid="ref-13">13</xref>] proposed a word2vec-based feature extraction method. First, they use the word2vec tool to convert each word of the Hypertext Transfer Protocol (HTTP) request into a vector. Then the scheme converts the vector to a fixed-size matrix. Finally, detection methods based on convolutional neural network (CNN) models are used for classification.</p>
</sec>
<sec id="s2_2"><label>2.2</label><title>Dynamic Webshell Detection</title>
<p>Dynamic detection determines the threat level of the behavior through the system commands invoked by the webshell runtime. Therefore, it is necessary to collect the runtime characteristics of known webshells. The effectiveness of dynamic detection depends on the number of valid features collected. If there are not enough features, it will lead to a lot of false negatives.</p>
<p>Wang&#x00A0;et&#x00A0;al.&#x00A0;[<xref ref-type="bibr" rid="ref-14">14</xref>] proposed a webshell detection method based on Multi-Layer Perceptron (MLP) neural network. It is preferred to compile the webshell sample to obtain the bytecode, then use the TF-IDF tool to perform feature vectorization of the bytecode sequence according to bi-gram, and finally use the multi-layer perceptron to train and predict the model.</p>
<p>For PHP webshell, Cui&#x00A0;et&#x00A0;al.&#x00A0;[<xref ref-type="bibr" rid="ref-15">15</xref>] extracted static features from PHP source files, and used TF-IDF vector and hash vector to extract dynamic features for opcode opcodes, and used static features and dynamic features together as webshell features. The classification is then performed using a combination of the random forest classification algorithm and the Gradient-Boosted Decision Trees (GBDT) classifier algorithm.</p>
<p>Fang&#x00A0;et&#x00A0;al.&#x00A0;[<xref ref-type="bibr" rid="ref-16">16</xref>] first obtained the opcode sequences of PHP files. Then use the FastText algorithm to train the opcode sequence model and predict the corresponding eigenvalues, and combine the predicted eigenvalues and static features into the features of the sample. Finally, the random forest classification algorithm is used for model training and prediction.</p>
<p>Yang&#x00A0;et&#x00A0;al.&#x00A0;[<xref ref-type="bibr" rid="ref-7">7</xref>] proposed an attack detection technique based on the SVM algorithm. This technology realizes the detection of webshell attack traffic in HTTP traffic by supervising the machine learning model. This technique achieves high precision and recall. After detecting abnormal traffic, the system can locate the webshell based on the traffic information. And remove the backdoor in time to ensure the security and stability of the Web server. So it can also help monitor trends in intrusions and network security.</p>
</sec>
</sec>
<sec id="s3"><label>3</label><title>Background</title>
<p>In this section, we present background knowledge related to the Java fileless webshell. We first introduce Java web components, which provide the underlying functionality of web service. Most Java web frameworks are built on these components. Attackers construct fileless webshells by maliciously exploiting certain features of these components. We then categorized Java fileless webshells based on the components used by the attackers.</p>
<sec id="s3_1"><label>3.1</label><title>Java Web Composition</title>
<p>The web server runs a lot of middleware, such as Tomcat [<xref ref-type="bibr" rid="ref-17">17</xref>], Weblogic [<xref ref-type="bibr" rid="ref-18">18</xref>], etc. These middlewares are composed of multiple Java web components, including Servlet, Filter, and Listener. When developers use these components, they need to define subclasses and override some methods. A Servlet is a program that runs on a web server or application server as an intermediary layer between requests from HTTP clients and a database or application on the HTTP server. It is responsible for processing the user&#x2019;s request, and according to the request generates the corresponding return information and provides it to the user. Usually, functions are implemented in the <italic>service()</italic> method of the Servlet. The Filter is a supplement to Servlet, used to inspect or modify request headers and data. When a request needs to read, write or execute data in memory, it needs to be judged and filtered by a Filter. Filter decides whether these requests have permission to perform these operations. In program development, the filtering logic is implemented in the <italic>doFilter()</italic> method. Listeners track specific events in a web application. This feature allows for more efficient resource management and automated processing based on event status. Through the Listener, developers can automatically perform some actions, such as monitoring the number of online users, counting website visits, and monitoring website visits. The most commonly used Listener subclass is ServletRequestListener, which has two methods, <italic>requestInitialized()</italic> and <italic>requestDestroyed()</italic>. The <italic>requestInitialized()</italic> implements the function of monitoring client requests. The <italic>requestDestroyed()</italic> is used to destroy resources (such as ServletRequest objects) at the end of the request.</p>
<p>Developers generally use the above components together. As shown in <xref ref-type="fig" rid="fig-1">Fig. 1</xref>, a request goes through Listener, Filter and Servlet in turn. The Servlet finally processes the client&#x2019;s request and generates a response. The response goes through the above three components in reverse order and is returned to the client. We take the user visiting the <ext-link ext-link-type="uri" xlink:href="https://www.example.com">www.example.com</ext-link> website as an example to introduce the 6 steps in <xref ref-type="fig" rid="fig-1">Fig. 1</xref>.
<list list-type="simple">
<list-item><label>1)</label><p>The user enters <ext-link ext-link-type="uri" xlink:href="https://www.example.com">www.example.com</ext-link> in the browser. The web server receives the browser&#x2019;s request and tries to forward it to the corresponding Servlet.</p></list-item>
<list-item><label>2)</label><p>The request is monitored by the Listener. ServletRequestListener calls the <italic>requestInitialized()</italic> method, which performs developer-defined functions, such as counting website visits. Then forward the request to Filter.</p></list-item>
<list-item><label>3)</label><p>The Filter calls the <italic>doFilter()</italic> method to execute the filtering logic. A typical <italic>doFilter()</italic> method body is usually divided into two parts, the first half checks the request and the second half checks the response. At this point, <italic>doFilter()</italic> executes the first half and then sends the request to the servlet.</p></list-item>
<list-item><label>4)</label><p>The servlet calls the <italic>service()</italic> method, generates the code of the <ext-link ext-link-type="uri" xlink:href="https://www.example.com">www.example.com</ext-link> web page and encapsulates it in the response. Then forward to Filter.</p></list-item>
<list-item><label>5)</label><p>Filter executes the second half of <italic>doFilter()</italic> to check whether the response conforms to the rules defined by the developer. Then forward to the Listener.</p></list-item>
<list-item><label>6)</label><p>ServletRequestListener executes the <italic>requestDestroyed()</italic> method to destroy resources. The response is then returned to the browser.</p></list-item>
</list></p>
<fig id="fig-1"><label>Figure 1</label><caption><title>The relationship between Listener, Filter, and Servlet</title></caption><graphic mimetype="image" mime-subtype="tif" xlink:href="CMC_34505-fig-1.tif"/></fig>
<p>Fileless webshell attacks take advantage of these components. By dynamically registering a new Filter (or other components) or injecting malicious instructions into an existing Filter (or other components), the attacker makes the Filter allow him to access the data in the memory of the web server. As long as there is a Filter available, an attacker can conduct remote attacks, whether it is command injection or data access. In addition, since the web server is connected to the database and the authentication system in the network, after the intrusion, the attacker can more easily carry out lateral penetration and obtain the permissions of multiple hosts.</p>
</sec>
<sec id="s3_2"><label>3.2</label><title>Java Fileless Webshell</title>
<p>Java fileless webshells rely on specific Java web components to perform malicious behavior. According to the different components utilized, Java fileless webshells can be divided into 3 categories, namely Java Web Component-based webshells, Spring framework-based webshells, and Java Instrumentation-based webshells.</p>
<sec id="s3_2_1"><label>3.2.1</label><title>Webshells Based on Java Web Component</title>
<p>Java web contains three basic components: Servlet, Filter, and Listener. Java Servlet 3.0 Specification [<xref ref-type="bibr" rid="ref-19">19</xref>] allows these components to be dynamically registered through the ServlFetContext when the web container is initialized. Specifically, an attacker can trace and analyze the method chaining when these components are dynamically registered, and register the components containing malicious code into the web server (e.g., Tomcat) container through the Java reflection mechanism. When the request path contains specific parameters, the malicious component is triggered.</p>
</sec>
<sec id="s3_2_2"><label>3.2.2</label><title>Webshells Based on Spring Framework</title>
<p>The principle of the fileless webshell based on the Spring framework is similar to that of the fileless webshell based on the Java web component. The main difference is that the components that implement the malicious code are replaced by the Spring framework Controller and Interceptor. Taking the Controller-based fileless webshell as an example, the dynamic registration process essentially registers two functions, one is the Controller component itself containing malicious logic, and the other is RequestMapping for address mapping.</p>
</sec>
<sec id="s3_2_3"><label>3.2.3</label><title>Webshells Based on Java Instrumentation</title>
<p>The Java instrument mechanism provides the ability to add bytecode to compiled Java classes. The instrumentation mechanism supports application-independent agents to monitor and assist applications running on the JVM. Such monitoring and assistance include, but are not limited to, obtaining JVM runtime status, replacing and modifying class definitions, etc. So specially crafted agents can intercept requests and responses. Through this mechanism, the attacker injects a specially constructed agent into the Java runtime environment to take over network requests and responses to handle their backdoor requests.</p>
</sec>
</sec>
</sec>
<sec id="s4"><label>4</label><title>Approach</title>
<sec id="s4_1"><label>4.1</label><title>Overview</title>
<p>In a Java program, a class cannot be used until it has been loaded by the JVM. Therefore, all the features of the Java fileless webshell are in JVM memory, in the form of loaded classes. An intuitive idea is to obtain the bytecode files of all classes loaded in the JVM. When the bytecode file is obtained, the detection of the fileless webshell can be converted into the detection of the traditional file-based webshell.</p>
<p>However, extracting all loaded bytecode files out of the JVM is inefficient and performance-consuming. Therefore, the scope of detection needs to be narrowed, that is, only the bytecode files of suspicious classes are extracted and detected. To achieve this, we implement JShellDetector. As shown in <xref ref-type="fig" rid="fig-2">Fig. 2</xref>, the process of JShellDetector detecting Java fileless webshell is divided into two steps. The first step is to filter suspicious classes. In a fileless webshell attack, an attacker exploited a vulnerability in the local server to inject a webshell on a remote server into the JVM. We manually selected some sensitive methods in the JVM and used method probes proposed in this paper to monitor them. When the method probe initializes, the user needs to provide the process id of the protected application. When the webshell tries to call a sensitive method, the method probe activates and marks it as a suspicious class. The bytecode stream of this class will be converted into a bytecode file. The second step is to detect the webshell. A suspicious class is in turn transformed into an intermediate representation of Jimple and a control flow graph. Then taint analysis is used to determine whether the suspicious class is malicious. If there is a path from <italic>sources</italic> to <italic>sinks</italic> on the control flow graph, the suspicious class is considered a webshell. Otherwise, it is considered a benign class.</p>
<fig id="fig-2"><label>Figure 2</label><caption><title>Overview of JShellDetector</title></caption><graphic mimetype="image" mime-subtype="tif" xlink:href="CMC_34505-fig-2.tif"/></fig>
</sec>
<sec id="s4_2"><label>4.2</label><title>Suspicious Class Filter</title>
<p>The mainstream method for filtering suspicious classes is the blacklist, which is widely used by anti-virus software. Security researchers use strings that contain webshell characteristics as keywords and filter suspicious classes by string matching. However, attackers gradually bypass these keywords by changing the way of constructing webshells, which causes the anti-virus software to fail for the new webshells. In order to maintain the effectiveness of the blacklist, security researchers must constantly update the blacklist. To avoid the drawback of blacklist-based approaches, we propose to filter suspicious classes by monitoring low-level sensitive methods. Because, regardless of how the webshell hides its behavior, some operations must be performed, such as dynamically registering servlets. If we can monitor the status of these operations, we can sense this process when an attacker implants a webshell. To achieve this goal, we propose method probes to monitor these sensitive methods and filter suspicious classes in JVM memory. In this paper, sensitive methods are those that are called when a component is dynamically registered. For example, the fileless webshell based on the Spring Controller component calls <italic>registerMapping()</italic> to dynamically register, and the Servlet component-based calls <italic>addServletMapping()</italic> to dynamically register.</p>
<sec id="s4_2_1"><label>4.2.1</label><title>Sensitive Method Selection</title>
<p>The selection of sensitive methods needs to meet some conditions. Too many sensitive methods will consume system resources and reduce the access speed of web applications. At the same time, it will lead to more false positives. On the contrary, if the selected sensitive method is insufficient, it will lead to false negatives. So we propose two conditions for selecting sensitive methods: 1) the sensitive method should come from the web framework rather than the method defined by the web application developer; 2) the sensitive method should be as close as possible to the method defined by the developer. For example, if there is a method call sequence <inline-formula id="ieqn-1"><mml:math id="mml-ieqn-1"><mml:mrow><mml:mo>(</mml:mo><mml:msub><mml:mi>m</mml:mi><mml:mrow><mml:mn>1</mml:mn></mml:mrow></mml:msub><mml:mo>,</mml:mo><mml:msub><mml:mi>m</mml:mi><mml:mrow><mml:mn>2</mml:mn></mml:mrow></mml:msub><mml:mo>,</mml:mo><mml:msub><mml:mi>m</mml:mi><mml:mrow><mml:mn>3</mml:mn></mml:mrow></mml:msub><mml:mo>)</mml:mo></mml:mrow></mml:math></inline-formula>, where <inline-formula id="ieqn-2"><mml:math id="mml-ieqn-2"><mml:msub><mml:mi>m</mml:mi><mml:mrow><mml:mn>1</mml:mn></mml:mrow></mml:msub></mml:math></inline-formula> is a method defined by the developer, and <inline-formula id="ieqn-3"><mml:math id="mml-ieqn-3"><mml:msub><mml:mi>m</mml:mi><mml:mrow><mml:mn>2</mml:mn></mml:mrow></mml:msub></mml:math></inline-formula> and <inline-formula id="ieqn-4"><mml:math id="mml-ieqn-4"><mml:msub><mml:mi>m</mml:mi><mml:mrow><mml:mn>3</mml:mn></mml:mrow></mml:msub></mml:math></inline-formula> are methods provided by the framework, <inline-formula id="ieqn-5"><mml:math id="mml-ieqn-5"><mml:msub><mml:mi>m</mml:mi><mml:mrow><mml:mn>2</mml:mn></mml:mrow></mml:msub></mml:math></inline-formula> should be selected as a sensitive method. Combining the above selection conditions and manual analysis of Java fileless webshell samples, we selected six sensitive methods for JShellDetector monitoring. The selected sensitive method information is shown in <xref ref-type="table" rid="table-1">Table 1</xref>.</p>
<table-wrap id="table-1"><label>Table 1</label><caption><title>Sensitive methods for JShellDetector</title></caption>
<table frame="hsides">
<colgroup>
<col align="left"/>
<col align="left"/>
<col align="left"/>
<col align="left"/>
</colgroup>
<thead>
<tr>
<th align="left">No</th>
<th align="left">Class</th>
<th align="left">Method</th>
<th align="left">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left">1</td>
<td align="left">AbstractHandler MethodMapping</td>
<td align="left"><italic>registerMapping</italic></td>
<td align="left">Register the given mapping.</td>
</tr>
<tr>
<td align="left">2</td>
<td align="left">AbstractUrlHandler Mapping</td>
<td align="left"><italic>registerHandler</italic></td>
<td align="left">Register the specified handler for the given URL paths.</td>
</tr>
<tr>
<td align="left">3</td>
<td align="left">Field</td>
<td align="left"><italic>get</italic></td>
<td align="left">Returns the value of the field represented by this Field, on the specified object.</td>
</tr>
<tr>
<td align="left">4</td>
<td align="left">FilterDef</td>
<td align="left"><italic>setFilterName</italic></td>
<td align="left">Set the name of a filter.</td>
</tr>
<tr>
<td align="left">5</td>
<td align="left">StandardContext</td>
<td align="left"><italic>addApplicationEvent Listener</italic></td>
<td align="left">Add a listener to the end of the list of initialized application event listeners.</td>
</tr>
<tr>
<td align="left">6</td>
<td align="left">StandardContext</td>
<td align="left"><italic>addServletMapping Decoded</italic></td>
<td align="left">Add a new servlet mapping, replacing any existing mapping for the specified pattern.</td>
</tr>
</tbody>
</table>
</table-wrap>
</sec>
<sec id="s4_2_2"><label>4.2.2</label><title>Method Probe</title>
<p>A method probe is a piece of code that is injected at a specific point in a program. It will automatically execute when a sensitive method is called. We use javassist [<xref ref-type="bibr" rid="ref-20">20</xref>] to implement the method probe and implant it into the target application. Javassist is a class library for dynamically editing Java bytecode. It can define a new class when the java program is running and load it into the JVM, and it can also modify a class file when the JVM is loaded [<xref ref-type="bibr" rid="ref-21">21</xref>]. Javassist enables us to edit class files without understanding bytecode-related specifications. When JShellDetector starts, the user needs to provide the process id of the protected web application. JShellDetector traverses all the classes in the JVM. If the class name is the same as the class name in <xref ref-type="table" rid="table-1">Table 1</xref>, it uses the <italic>insertAfter()</italic> interface provided by javassist to insert a method probe after the sensitive method. When the method probe is triggered, it will look for the call point of the sensitive method from the stack trace [<xref ref-type="bibr" rid="ref-22">22</xref>], which is a snapshot of a moment in time. Stack trace stores the information of the call stack. Each time a method is called, a method stack will be generated, and it will save the call site information. For example, method A calls method B, and the context of A is stored on the stack when the call occurs. By traversing the stack trace, the method probe obtains the call site of the sensitive method.</p>

<p>Another function of the method probe is to convert suspicious classes in the JVM into bytecode files. We implement this function through Oracle&#x2019;s <italic>ClassFileTransformer</italic> and <italic>VirtualMachine.attach()</italic>. The <italic>VirtualMachine.attach()</italic> method allows us to attach to the JVM running another application by its process id. We use the interface provided by the JVM to process the target value. Then, we create an agent, which inherits from <italic>ClassFileTransformer</italic>. <italic>ClassFileTransformer</italic> provides the ability to convert individual classes to files from the attacher [<xref ref-type="bibr" rid="ref-23">23</xref>]. Method probes convert classes loaded into memory into <italic>&#x003C;classname&#x003E;</italic> <italic>.class</italic> files.</p>
</sec>
</sec>
<sec id="s4_3"><label>4.3</label><title>Webshell Detection</title>
<p>We implement a taint analysis on control flow graphs (CFGs) aimed at determining whether a suspicious class&#x2019;s behavior is malicious [<xref ref-type="bibr" rid="ref-24">24</xref>]. Taint analysis is a technique for tracking and analyzing the flow of taint information through a program. In taint analysis, data of interest (usually from external input to a program) is labeled as tainted data (other data called untainted data). Sources of tainted data are called <italic>sources</italic>. In practice, tainted data usually come from the return values of some methods. By tracking the flow of information related to tainted data, we can know whether they can flow to locations of the program (called <italic>sinks</italic>) and then detect program vulnerabilities [<xref ref-type="bibr" rid="ref-25">25</xref>&#x2013;<xref ref-type="bibr" rid="ref-27">27</xref>]. <italic>Sinks</italic> are usually some security-sensitive methods.</p>
<p>In this paper, if the suspicious class allows external unauthenticated data to enter some key points of the program, this class will be considered a webshell. That means an attacker can pass instructions to some security-sensitive methods. The <italic>source</italic> we choose is <italic>request.getParameter()</italic>, which can get the input value of the web page. The <italic>sinks</italic> we choose are <italic>Runtime.exec()</italic> and <italic>ProcessBuilder()</italic>. <italic>Runtime.exec()</italic> executes arguments as commands. <italic>ProcessBuilder()</italic> creates and modifies operating system processes.</p>
<sec id="s4_3_1"><label>4.3.1</label><title>Intermediate Representation</title>
<p>In Section 4.2, we convert the suspicious classes in the JVM into bytecode files. However, Java bytecode contains more than 200 instructions. Direct analysis of bytecode files requires processing all these instructions, making taint analysis difficult. Therefore, we convert the bytecode into an intermediate representation that is easy to analyze. Soot [<xref ref-type="bibr" rid="ref-28">28</xref>] is a state-of-the-art Java bytecode manipulation and optimization framework, providing a set of intermediate representations that can be analyzed and transformed, including Jimple, Grimple, Baf, and Shimple. They represent different levels of abstraction and purpose of use, respectively. We choose Jimple as the intermediate representation for taint analysis. Jimple is a typed three-address intermediate representation [<xref ref-type="bibr" rid="ref-29">29</xref>]. We use Jimple as our intermediate representation because of its three features: 1) Jimple retains some Java data types. 2) Each statement of Jimple includes up to three variable operations, which splits Java&#x2019;s advanced features (e.g., reflection or annotation) into small units. 3) Jimple remains statement characteristics. Compared with bytecode files, each statement of Jimple can encapsulate multiple instructions. These features allow JShellDetector to maintain high accuracy while reducing the complexity of taint analysis.</p>
</sec>
<sec id="s4_3_2"><label>4.3.2</label><title>Jimple-Based Control Flow Graph</title>
<p>CFG is a method of modeling code execution flow, which can display all program execution paths within the method in a graph structure. A CFG is a directed graph, <inline-formula id="ieqn-6"><mml:math id="mml-ieqn-6"><mml:mi>G</mml:mi><mml:mo>=</mml:mo><mml:mrow><mml:mo>(</mml:mo><mml:mi>N</mml:mi><mml:mo>,</mml:mo><mml:mi>E</mml:mi><mml:mo>)</mml:mo></mml:mrow></mml:math></inline-formula>. Each node <inline-formula id="ieqn-7"><mml:math id="mml-ieqn-7"><mml:mi>n</mml:mi><mml:mo>&#x2208;</mml:mo><mml:mi>N</mml:mi></mml:math></inline-formula> corresponds to a basic block. Each edge <inline-formula id="ieqn-8"><mml:math id="mml-ieqn-8"><mml:mi>e</mml:mi><mml:mo>=</mml:mo><mml:mrow><mml:mo>(</mml:mo><mml:msub><mml:mi>n</mml:mi><mml:mrow><mml:mi>i</mml:mi></mml:mrow></mml:msub><mml:mo>,</mml:mo><mml:msub><mml:mi>n</mml:mi><mml:mrow><mml:mi>j</mml:mi></mml:mrow></mml:msub><mml:mo>)</mml:mo></mml:mrow><mml:mo>&#x2208;</mml:mo><mml:mi>E</mml:mi></mml:math></inline-formula> corresponds to a possible transfer of control from the block <inline-formula id="ieqn-9"><mml:math id="mml-ieqn-9"><mml:msub><mml:mi>n</mml:mi><mml:mrow><mml:mi>i</mml:mi></mml:mrow></mml:msub></mml:math></inline-formula> to block <inline-formula id="ieqn-10"><mml:math id="mml-ieqn-10"><mml:msub><mml:mi>n</mml:mi><mml:mrow><mml:mi>j</mml:mi></mml:mrow></mml:msub></mml:math></inline-formula> [<xref ref-type="bibr" rid="ref-30">30</xref>]. JShellDetector uses Jimple as the analysis target. Therefore, it builds a CFG with Jimple units (a soot data structure) as the basic block. Each unit contains statement details.</p>
<p>To illustrate the process of generating CFG through Jimple, we choose a toy example, FizzBuzz. As shown in <xref ref-type="fig" rid="fig-3">Fig. 3a</xref>, FizzBuzz prints every number from 1 to n. But if the number is divisible by 3, 5, and 15, this program outputs Fuzz, Buzz, and FizzBuzz, respectively. <xref ref-type="fig" rid="fig-3">Fig. 3b</xref> shows the Jimple code transformed by FizzBuzz, and each line represents a unit. We can get a lot of intuitive information from Jimple. For example, <italic>this</italic> is represented as <italic>r0</italic> which is a <italic>Local</italic> Object. Or the argument of the function is explicitly defined in <italic>i0</italic> and its type is <italic>int</italic>. In <xref ref-type="fig" rid="fig-3">Fig. 3c</xref>, each circle represents a Jimple unit, and the number is the Jimple code line number. There are 4 possible paths from the beginning to the end of the method, which include 3 branching statements (blue circle). These path representations are divisible by 3, 5, 15, or none of them.</p>
<fig id="fig-3"><label>Figure 3</label><caption><title>Source code of FizzBuzz conversion to Jimple-based CFG. (a) for FizzBuzz source code, (b) for FizzBuzz&#x2019;s Jimple representation (c) for FizzBuzz&#x2019;s Jimple-based CFG</title></caption><graphic mimetype="image" mime-subtype="tif" xlink:href="CMC_34505-fig-3.tif"/></fig>
</sec>
<sec id="s4_3_3"><label>4.3.3</label><title>Taint Propagation</title>
<p>During the taint propagation process, taint data needs to be recorded according to the propagation rules. The taint propagation rule refers to how taints flow between data [<xref ref-type="bibr" rid="ref-24">24</xref>]. Too strict propagation rules lead to under-taint, and too loose propagation rules increase system overhead and lead to over-taint. <xref ref-type="table" rid="table-2">Table 2</xref> shows the taint propagation rules we use. <inline-formula id="ieqn-11"><mml:math id="mml-ieqn-11"><mml:mi>&#x03B7;</mml:mi><mml:mrow><mml:mo>(</mml:mo><mml:mi>v</mml:mi><mml:mi>a</mml:mi><mml:mi>l</mml:mi><mml:mo>)</mml:mo></mml:mrow></mml:math></inline-formula> represents the state of the variable <inline-formula id="ieqn-12"><mml:math id="mml-ieqn-12"><mml:mi>v</mml:mi><mml:mi>a</mml:mi><mml:mi>l</mml:mi></mml:math></inline-formula> in the taint analysis. <inline-formula id="ieqn-13"><mml:math id="mml-ieqn-13"><mml:mi>&#x03C4;</mml:mi><mml:mo>&#x2208;</mml:mo><mml:mrow><mml:mo>[</mml:mo><mml:mi>t</mml:mi><mml:mo>,</mml:mo><mml:mi>u</mml:mi><mml:mo>]</mml:mo></mml:mrow></mml:math></inline-formula> is the value of <inline-formula id="ieqn-14"><mml:math id="mml-ieqn-14"><mml:mi>&#x03B7;</mml:mi><mml:mrow><mml:mo>(</mml:mo><mml:mi>v</mml:mi><mml:mi>a</mml:mi><mml:mi>l</mml:mi><mml:mo>)</mml:mo></mml:mrow></mml:math></inline-formula>, where <italic>t</italic> indicates the variable is tainted, and <italic>u</italic> indicates that the variable is untainted. We use the binary operator <inline-formula id="ieqn-15"><mml:math id="mml-ieqn-15"><mml:mo>&#x2217;</mml:mo></mml:math></inline-formula> to calculate the taint state, and the calculation rule is as follows:
<disp-formula id="eqn-1"><label>(1)</label><mml:math id="mml-eqn-1" display="block"><mml:msub><mml:mi>&#x03C4;</mml:mi><mml:mrow><mml:mn>1</mml:mn></mml:mrow></mml:msub><mml:mo>&#x2217;</mml:mo><mml:msub><mml:mi>&#x03C4;</mml:mi><mml:mrow><mml:mn>2</mml:mn></mml:mrow></mml:msub><mml:mo>=</mml:mo><mml:mrow><mml:mo>{</mml:mo><mml:mtable columnalign="left left" rowspacing=".2em" columnspacing="1em" displaystyle="false"><mml:mtr><mml:mtd><mml:mi>t</mml:mi><mml:mo>,</mml:mo><mml:mi>i</mml:mi><mml:mi>f</mml:mi><mml:msub><mml:mi>&#x03C4;</mml:mi><mml:mrow><mml:mn>1</mml:mn></mml:mrow></mml:msub><mml:mo>=</mml:mo><mml:mi>t</mml:mi><mml:mi>o</mml:mi><mml:mi>r</mml:mi><mml:msub><mml:mi>&#x03C4;</mml:mi><mml:mrow><mml:mn>2</mml:mn></mml:mrow></mml:msub><mml:mo>=</mml:mo><mml:mi>t</mml:mi></mml:mtd></mml:mtr><mml:mtr><mml:mtd><mml:mi>u</mml:mi><mml:mo>,</mml:mo><mml:mi>i</mml:mi><mml:mi>f</mml:mi><mml:msub><mml:mi>&#x03C4;</mml:mi><mml:mrow><mml:mn>1</mml:mn></mml:mrow></mml:msub><mml:mo>=</mml:mo><mml:mi>u</mml:mi><mml:mi>a</mml:mi><mml:mi>n</mml:mi><mml:mi>d</mml:mi><mml:msub><mml:mi>&#x03C4;</mml:mi><mml:mrow><mml:mn>2</mml:mn></mml:mrow></mml:msub><mml:mo>=</mml:mo><mml:mi>u</mml:mi></mml:mtd></mml:mtr></mml:mtable><mml:mo fence="true" stretchy="true" symmetric="true"></mml:mo></mml:mrow></mml:math></disp-formula></p>
<table-wrap id="table-2"><label>Table 2</label><caption><title>Taint propagation rules</title></caption>
<table frame="hsides">
<colgroup>
<col align="left"/>
<col align="left"/>
<col align="left"/>
<col align="left"/>
</colgroup>
<thead>
<tr>
<th align="left">No</th>
<th align="left">Statement</th>
<th align="left">Condition</th>
<th align="left">Result</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left">1</td>
<td align="left"><inline-formula id="ieqn-16"><mml:math id="mml-ieqn-16"><mml:mi>v</mml:mi><mml:mi>a</mml:mi><mml:mi>l</mml:mi><mml:mo>=</mml:mo><mml:mi>n</mml:mi><mml:mi>e</mml:mi><mml:mi>w</mml:mi><mml:mi>T</mml:mi><mml:mo stretchy="false">(</mml:mo><mml:mo stretchy="false">)</mml:mo></mml:math></inline-formula></td>
<td align="left">/</td>
<td align="left"><inline-formula id="ieqn-17"><mml:math id="mml-ieqn-17"><mml:mi>&#x03B7;</mml:mi><mml:mrow><mml:mo>(</mml:mo><mml:mi>v</mml:mi><mml:mi>a</mml:mi><mml:mi>l</mml:mi><mml:mo>)</mml:mo></mml:mrow><mml:mo>=</mml:mo><mml:mi>u</mml:mi></mml:math></inline-formula></td>
</tr>
<tr>
<td align="left">2</td>
<td align="left"><inline-formula id="ieqn-18"><mml:math id="mml-ieqn-18"><mml:mi>v</mml:mi><mml:mi>a</mml:mi><mml:mi>l</mml:mi><mml:mo>=</mml:mo><mml:mrow><mml:mtext mathvariant="italic">arrray</mml:mtext></mml:mrow><mml:mrow><mml:mo>[</mml:mo><mml:mi>i</mml:mi><mml:mo>]</mml:mo></mml:mrow></mml:math></inline-formula></td>
<td align="left"><inline-formula id="ieqn-19"><mml:math id="mml-ieqn-19"><mml:mi>&#x03B7;</mml:mi><mml:mrow><mml:mo>(</mml:mo><mml:mrow><mml:mtext mathvariant="italic">array</mml:mtext></mml:mrow><mml:mrow><mml:mo>[</mml:mo><mml:mi>i</mml:mi><mml:mo>]</mml:mo></mml:mrow><mml:mo>)</mml:mo></mml:mrow><mml:mo>=</mml:mo><mml:msub><mml:mi>&#x03C4;</mml:mi><mml:mrow><mml:mi>i</mml:mi></mml:mrow></mml:msub></mml:math></inline-formula></td>
<td align="left"><inline-formula id="ieqn-20"><mml:math id="mml-ieqn-20"><mml:mi>&#x03B7;</mml:mi><mml:mrow><mml:mo>(</mml:mo><mml:mi>v</mml:mi><mml:mi>a</mml:mi><mml:mi>l</mml:mi><mml:mo>)</mml:mo></mml:mrow><mml:mo>=</mml:mo><mml:msub><mml:mi>&#x03C4;</mml:mi><mml:mrow><mml:mn>1</mml:mn></mml:mrow></mml:msub><mml:mo>&#x2217;</mml:mo><mml:msub><mml:mi>&#x03C4;</mml:mi><mml:mrow><mml:mn>2</mml:mn></mml:mrow></mml:msub><mml:mo>&#x2026;</mml:mo><mml:mo>&#x2217;</mml:mo><mml:msub><mml:mi>&#x03C4;</mml:mi><mml:mrow><mml:mi>n</mml:mi></mml:mrow></mml:msub></mml:math></inline-formula></td>
</tr>
<tr>
<td align="left">3</td>
<td align="left"><inline-formula id="ieqn-21"><mml:math id="mml-ieqn-21"><mml:mi>v</mml:mi><mml:mi>a</mml:mi><mml:mi>l</mml:mi><mml:mo>=</mml:mo><mml:mi>e</mml:mi><mml:mi>x</mml:mi><mml:mi>p</mml:mi><mml:msub><mml:mi>r</mml:mi><mml:mrow><mml:mn>1</mml:mn></mml:mrow></mml:msub><mml:mi>o</mml:mi><mml:mi>p</mml:mi><mml:mi>e</mml:mi><mml:mi>x</mml:mi><mml:mi>p</mml:mi><mml:msub><mml:mi>r</mml:mi><mml:mrow><mml:mn>2</mml:mn></mml:mrow></mml:msub></mml:math></inline-formula></td>
<td align="left"><inline-formula id="ieqn-22"><mml:math id="mml-ieqn-22"><mml:mi>&#x03B7;</mml:mi><mml:mrow><mml:mo>(</mml:mo><mml:mi>e</mml:mi><mml:mi>x</mml:mi><mml:mi>p</mml:mi><mml:msub><mml:mi>r</mml:mi><mml:mrow><mml:mn>1</mml:mn></mml:mrow></mml:msub><mml:mo>)</mml:mo></mml:mrow><mml:mo>=</mml:mo><mml:msub><mml:mi>&#x03C4;</mml:mi><mml:mrow><mml:mn>1</mml:mn></mml:mrow></mml:msub><mml:mo>,</mml:mo></mml:math></inline-formula></td>
<td align="left"><inline-formula id="ieqn-23"><mml:math id="mml-ieqn-23"><mml:mi>&#x03B7;</mml:mi><mml:mrow><mml:mo>(</mml:mo><mml:mi>v</mml:mi><mml:mi>a</mml:mi><mml:mi>l</mml:mi><mml:mo>)</mml:mo></mml:mrow><mml:mo>=</mml:mo><mml:msub><mml:mi>&#x03C4;</mml:mi><mml:mrow><mml:mn>1</mml:mn></mml:mrow></mml:msub><mml:mo>&#x2217;</mml:mo><mml:msub><mml:mi>&#x03C4;</mml:mi><mml:mrow><mml:mn>2</mml:mn></mml:mrow></mml:msub></mml:math></inline-formula></td>
</tr>
<tr>
<td></td>
<td></td>
<td><inline-formula id="ieqn-24"><mml:math id="mml-ieqn-24"><mml:mi>&#x03B7;</mml:mi><mml:mrow><mml:mo>(</mml:mo><mml:mi>e</mml:mi><mml:mi>x</mml:mi><mml:mi>p</mml:mi><mml:msub><mml:mi>r</mml:mi><mml:mrow><mml:mn>2</mml:mn></mml:mrow></mml:msub><mml:mo>)</mml:mo></mml:mrow><mml:mo>=</mml:mo><mml:msub><mml:mi>&#x03C4;</mml:mi><mml:mrow><mml:mn>2</mml:mn></mml:mrow></mml:msub></mml:math></inline-formula></td>
<td></td>
</tr>
<tr>
<td align="left">4</td>
<td align="left"><inline-formula id="ieqn-25"><mml:math id="mml-ieqn-25"><mml:mi>v</mml:mi><mml:mi>a</mml:mi><mml:mi>l</mml:mi><mml:mo>=</mml:mo><mml:mi>o</mml:mi><mml:mi>b</mml:mi><mml:mi>j</mml:mi><mml:mspace width="thinmathspace" /><mml:mo>.</mml:mo><mml:mspace width="thinmathspace" /><mml:mi>x</mml:mi></mml:math></inline-formula></td>
<td align="left"><inline-formula id="ieqn-26"><mml:math id="mml-ieqn-26"><mml:mi>&#x03B7;</mml:mi><mml:mrow><mml:mo>(</mml:mo><mml:mi>o</mml:mi><mml:mi>b</mml:mi><mml:mi>j</mml:mi><mml:mo>)</mml:mo></mml:mrow><mml:mo>=</mml:mo><mml:msub><mml:mi>&#x03C4;</mml:mi><mml:mrow><mml:mn>1</mml:mn></mml:mrow></mml:msub></mml:math></inline-formula></td>
<td align="left"><inline-formula id="ieqn-27"><mml:math id="mml-ieqn-27"><mml:mi>&#x03B7;</mml:mi><mml:mrow><mml:mo>(</mml:mo><mml:mi>v</mml:mi><mml:mi>a</mml:mi><mml:mi>l</mml:mi><mml:mo>)</mml:mo></mml:mrow><mml:mo>=</mml:mo><mml:msub><mml:mi>&#x03C4;</mml:mi><mml:mrow><mml:mn>1</mml:mn></mml:mrow></mml:msub><mml:mo>&#x2217;</mml:mo><mml:msub><mml:mi>&#x03C4;</mml:mi><mml:mrow><mml:mn>2</mml:mn></mml:mrow></mml:msub></mml:math></inline-formula></td>
</tr>
<tr>
<td></td>
<td></td>
<td><inline-formula id="ieqn-28"><mml:math id="mml-ieqn-28"><mml:mi>&#x03B7;</mml:mi><mml:mrow><mml:mo>(</mml:mo><mml:mi>x</mml:mi><mml:mo>)</mml:mo></mml:mrow><mml:mo>=</mml:mo><mml:msub><mml:mi>&#x03C4;</mml:mi><mml:mrow><mml:mn>2</mml:mn></mml:mrow></mml:msub></mml:math></inline-formula></td>
<td></td>
</tr>
<tr>
<td align="left">5</td>
<td align="left"><inline-formula id="ieqn-29"><mml:math id="mml-ieqn-29"><mml:mi>v</mml:mi><mml:mi>a</mml:mi><mml:mi>l</mml:mi><mml:mo>=</mml:mo><mml:mi>o</mml:mi><mml:mi>b</mml:mi><mml:mi>j</mml:mi><mml:mspace width="thinmathspace" /><mml:mo>.</mml:mo><mml:mspace width="thinmathspace" /><mml:mi>f</mml:mi><mml:mo stretchy="false">(</mml:mo><mml:mo stretchy="false">)</mml:mo></mml:math></inline-formula></td>
<td align="left"><inline-formula id="ieqn-30"><mml:math id="mml-ieqn-30"><mml:mi>&#x03B7;</mml:mi><mml:mrow><mml:mo>(</mml:mo><mml:mi>o</mml:mi><mml:mi>b</mml:mi><mml:mi>j</mml:mi><mml:mo>)</mml:mo></mml:mrow><mml:mo>=</mml:mo><mml:mi>&#x03C4;</mml:mi></mml:math></inline-formula></td>
<td align="left"><inline-formula id="ieqn-31"><mml:math id="mml-ieqn-31"><mml:mi>&#x03B7;</mml:mi><mml:mrow><mml:mo>(</mml:mo><mml:mi>v</mml:mi><mml:mi>a</mml:mi><mml:mi>l</mml:mi><mml:mo>)</mml:mo></mml:mrow><mml:mo>=</mml:mo><mml:mi>&#x03C4;</mml:mi></mml:math></inline-formula></td>
</tr>
<tr>
<td align="left">6</td>
<td align="left"><inline-formula id="ieqn-32"><mml:math id="mml-ieqn-32"><mml:mi>v</mml:mi><mml:mi>a</mml:mi><mml:mi>l</mml:mi><mml:mo>=</mml:mo><mml:mi>o</mml:mi><mml:mi>b</mml:mi><mml:mi>j</mml:mi><mml:mtext>&#xA0;</mml:mtext><mml:mo>.</mml:mo><mml:mtext>&#xA0;</mml:mtext><mml:mi>f</mml:mi><mml:mrow><mml:mo>(</mml:mo><mml:msub><mml:mi>a</mml:mi><mml:mrow><mml:mn>1</mml:mn></mml:mrow></mml:msub><mml:mo>,</mml:mo><mml:mo>&#x2026;</mml:mo><mml:mo>,</mml:mo><mml:msub><mml:mi>a</mml:mi><mml:mrow><mml:mi>n</mml:mi></mml:mrow></mml:msub><mml:mo>)</mml:mo></mml:mrow></mml:math></inline-formula></td>
<td align="left"><inline-formula id="ieqn-33"><mml:math id="mml-ieqn-33"><mml:mi>&#x03B7;</mml:mi><mml:mrow><mml:mo>(</mml:mo><mml:msub><mml:mi>a</mml:mi><mml:mrow><mml:mi>i</mml:mi></mml:mrow></mml:msub><mml:mo>)</mml:mo></mml:mrow><mml:mo>=</mml:mo><mml:msub><mml:mi>&#x03C4;</mml:mi><mml:mrow><mml:mrow><mml:mtext>i</mml:mtext></mml:mrow></mml:mrow></mml:msub></mml:math></inline-formula></td>
<td align="left"><inline-formula id="ieqn-34"><mml:math id="mml-ieqn-34"><mml:mi>&#x03B7;</mml:mi><mml:mrow><mml:mo>(</mml:mo><mml:mi>v</mml:mi><mml:mi>a</mml:mi><mml:mi>l</mml:mi><mml:mo>)</mml:mo></mml:mrow><mml:mo>=</mml:mo><mml:msub><mml:mi>&#x03C4;</mml:mi><mml:mrow><mml:mn>1</mml:mn></mml:mrow></mml:msub><mml:mo>&#x2217;</mml:mo><mml:msub><mml:mi>&#x03C4;</mml:mi><mml:mrow><mml:mn>2</mml:mn></mml:mrow></mml:msub><mml:mo>&#x2026;</mml:mo><mml:mo>&#x2217;</mml:mo><mml:msub><mml:mi>&#x03C4;</mml:mi><mml:mrow><mml:mi>n</mml:mi></mml:mrow></mml:msub></mml:math></inline-formula></td>
</tr>
</tbody>
</table>
</table-wrap>
<p>The taint propagation rules have a great influence on the accuracy of taint analysis. Therefore, we mainly focus on the rules of variable assignment and function calls. Other operations are generally included in these two operations. For example, for the statement <inline-formula id="ieqn-35"><mml:math id="mml-ieqn-35"><mml:mi>v</mml:mi><mml:mi>a</mml:mi><mml:mi>l</mml:mi><mml:mo>=</mml:mo><mml:mrow><mml:mtext mathvariant="italic">arrray</mml:mtext></mml:mrow><mml:mrow><mml:mo>[</mml:mo><mml:mi>i</mml:mi><mml:mo>]</mml:mo></mml:mrow></mml:math></inline-formula>, we need to calculate the taint state of each element of the array, and finally use the calculation result as the taint state of <inline-formula id="ieqn-36"><mml:math id="mml-ieqn-36"><mml:mi>v</mml:mi><mml:mi>a</mml:mi><mml:mi>l</mml:mi></mml:math></inline-formula>.</p>
</sec>
</sec>
</sec>
<sec id="s5"><label>5</label><title>Evaluation</title>
<p>In this section, we evaluate the effectiveness of JShellDetector and compare it with only two tools. We propose the following standard research questions. These questions can help us to comprehensively evaluate the performance of JShellDetector in the detection of Java fileless webshell.
<list list-type="bullet">
<list-item><p><bold>RQ1. Effectiveness:</bold> Is JShellDetector able to detect Java fileless webshells? What is the reason for the false negative?</p></list-item>
<list-item><p><bold>RQ2. Comparison with other tools:</bold> Does JShellDetector perform better than other tools? What is the reason?</p></list-item>
<list-item><p><bold>RQ3. Resource Consuming:</bold> Is JShellDetector consuming excessive system resources?</p></list-item>
</list></p>
<sec id="s5_1"><label>5.1</label><title>Experimental Setup</title>
<p>JShellDetector is implemented on JDK 8 (build 1.8_301) of Oracle. To simulate a real Java fileless webshell attack, we need some open-source tools to help us. First, we used an open source network range, SecExample [<xref ref-type="bibr" rid="ref-31">31</xref>], as the attacked web application. A cyber range is a controlled, interactive technological environment where cybersecurity professionals can learn how to detect and mitigate cyberattacks using the same kind of equipment used at work [<xref ref-type="bibr" rid="ref-32">32</xref>]. SecExample provides a simulation environment for CVE-2017-18349 [<xref ref-type="bibr" rid="ref-33">33</xref>]. This is a deserialization vulnerability in the open source software fastjson-1.2.24. The marshalsec [<xref ref-type="bibr" rid="ref-34">34</xref>] is used to provide Java Remote Method Invocation (RMI) services. This service allows the JVM of one server in the same network to access Java classes on another server.</p>
<p>The experiments were performed on two AMD Ryzen 7 4800H CPU@2.9&#x2005;GHz and 16 GB of RAM on Linux Ubuntu 20.04TSL. One acts as a protected server and the other acts as a malicious server controlled by the attacker. They need to be in the same network. As shown in <xref ref-type="fig" rid="fig-4">Fig. 4</xref>, SecExample and JShellDetector are deployed on the protected server. Marshalsec is deployed on the malicious server and all test cases are stored. In experiments, we first exploit the CVE-2017-18349 vulnerability to gain permission to execute commands on the protected server (details can be obtained from [<xref ref-type="bibr" rid="ref-33">33</xref>]). We then use the protected server to request the webshell test case from the malicious server&#x2019;s RMI service. Finally, the RMI server returns the webshell test cases on the malicious server to the protected server over the network. At this point, one round of testing is completed. All test cases are tested in the same way.</p>
<fig id="fig-4"><label>Figure 4</label><caption><title>Overview of the experimental environment</title></caption><graphic mimetype="image" mime-subtype="tif" xlink:href="CMC_34505-fig-4.tif"/></fig>
</sec>
<sec id="s5_2"><label>5.2</label><title>Dataset</title>
<p>Since the research on Java fileless webshell is in its infancy and lacks public datasets, we collect test cases provided by security researchers from the Internet to complete this experiment. We made the dataset public on GitHub.</p>
<p>As shown in <xref ref-type="table" rid="table-3">Table 3</xref>, we collect a total of 35 test cases. According to the web component used by webshell, these test cases are divided into Java web component-based and Spring framework-based. Test cases based on Java web components are further divided into Filter-based, Listener-based and Servlet-based. Test cases based on the Spring framework are further divided into Controller-based and Interceptor-based. For many of these test cases, the attack logic of some of the test cases is the same, only the components used are different. As for Java Instrument-based fileless webshell, we did not collect suitable test cases.</p>
<table-wrap id="table-3"><label>Table 3</label><caption><title>Test case dataset</title></caption>
<table frame="hsides">
<colgroup>
<col align="left"/>
<col align="left"/>
<col align="left"/>
</colgroup>
<thead>
<tr>
<th align="left">Type</th>
<th align="left">Category</th>
<th align="left">Count</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left" rowspan="3">Java web component</td>
<td align="left">Filter</td>
<td align="left">11</td>
</tr>
<tr>
<td align="left">Listener</td>
<td align="left">7</td>
</tr>
<tr>
<td align="left">Servlet</td>
<td align="left">9</td>
</tr>
<tr>
<td align="left" rowspan="2">Spring framework</td>
<td align="left">Controller</td>
<td align="left">5</td>
</tr>
<tr>
<td align="left">Interceptor</td>
<td align="left">3</td>
</tr>
</tbody>
</table>
</table-wrap>
</sec>
<sec id="s5_3"><label>5.3</label><title>Results and Analysis</title>
<sec id="s5_3_1"><label>5.3.1</label><title>Answering RQ1: Effectiveness</title>
<p>To systematically evaluate the effect of JShellDetector, we recorded the results of each step (suspicious class filter and webshell detection). The suspicious class filter step is used to determine whether the method probe accurately captured the call of the webshell to the sensitive method. The webshell detection step means that after the suspicious class is converted into a bytecode file, the taint analysis accurately determines whether it is a webshell.</p>
<p><xref ref-type="table" rid="table-4">Table 4</xref> gives the results of each test case. The experimental results show that in the suspicious class filter step, all 35 test cases were successfully captured by JShellDetector, and the detection rate is 100&#x0025;. As for the webshell detection step, 27 test cases were detected and the detection rate was 77.1&#x0025;. We analyze the causes of each failure in detail. There are two reasons for the failure of JShellDetector, namely string encryption and taint analysis failure. <xref ref-type="table" rid="table-5">Table 5</xref> displays the failed test case corresponding to each reason.</p>
<table-wrap id="table-4"><label>Table 4</label><caption><title>Experiment results of each test case</title></caption>
<table frame="hsides">
<colgroup>
<col align="left"/>
<col align="left"/>
<col align="left"/>
<col align="left"/>
<col align="left"/>
<col align="left"/>
<col align="left"/>
<col align="left"/>
</colgroup>
<thead>
<tr>
<th align="left" rowspan="2">Type</th>
<th align="left" rowspan="2">Category</th>
<th align="left" rowspan="2">No</th>
<th align="left" rowspan="2">Name</th>
<th align="center" colspan="2">JShellDetector</th>
<th align="left" rowspan="2">Copagent</th>
<th align="left" rowspan="2">Memory Shell</th>
</tr>
<tr>
<th align="left">Suspicious class filter</th>
<th align="left">Webshell detection</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left">Java web component</td>
<td align="left" rowspan="11">Filter</td>
<td align="left">1</td>
<td align="left">addFilter</td>
<td align="left">&#x221A;</td>
<td align="left">&#x221A;</td>
<td align="left">&#x221A;</td>
<td align="left">&#x221A;</td>
</tr>
<tr>
<td/>
<td align="left">2</td>
<td align="left">addfilter</td>
<td align="left">&#x221A;</td>
<td align="left">&#x221A;</td>
<td align="left">&#x221A;</td>
<td align="left">&#x221A;</td>
</tr>
<tr><td/>
<td align="left">3</td>
<td align="left">filterMem</td>
<td align="left">&#x221A;</td>
<td align="left">&#x00D7;</td>
<td align="left">&#x221A;</td>
<td align="left">&#x221A;</td>
</tr>
<tr><td/>
<td align="left">4</td>
<td align="left">memfilter</td>
<td align="left">&#x221A;</td>
<td align="left">&#x221A;</td>
<td align="left">&#x221A;</td>
<td align="left">&#x221A;</td>
</tr>
<tr><td/>
<td align="left">5</td>
<td align="left">AddFilter</td>
<td align="left">&#x221A;</td>
<td align="left">&#x221A;</td>
<td align="left">&#x221A;</td>
<td align="left">&#x221A;</td>
</tr>
<tr><td/>
<td align="left">6</td>
<td align="left">FilterShell</td>
<td align="left">&#x221A;</td>
<td align="left">&#x00D7;</td>
<td align="left">&#x00D7;</td>
<td align="left">&#x00D7;</td>
</tr>
<tr><td/>
<td align="left">7</td>
<td align="left">Frain</td>
<td align="left">&#x221A;</td>
<td align="left">&#x221A;</td>
<td align="left">&#x221A;</td>
<td align="left">&#x221A;</td>
</tr>
<tr><td/>
<td align="left">8</td>
<td align="left">AddTomcatFilter</td>
<td align="left">&#x221A;</td>
<td align="left">&#x00D7;</td>
<td align="left">&#x00D7;</td>
<td align="left">&#x00D7;</td>
</tr>
<tr><td/>
<td align="left">9</td>
<td align="left">FilterBasedBasic</td>
<td align="left">&#x221A;</td>
<td align="left">&#x221A;</td>
<td align="left">&#x221A;</td>
<td align="left">&#x221A;</td>
</tr>
<tr><td/>
<td align="left">10</td>
<td align="left">FilterBasedWithout Request</td>
<td align="left">&#x221A;</td>
<td align="left">&#x221A;</td>
<td align="left">&#x221A;</td>
<td align="left">&#x221A;</td>
</tr>
<tr><td/>
<td align="left">11</td>
<td align="left">FilterBasedWithout RequestVariant</td>
<td align="left">&#x221A;</td>
<td align="left">&#x221A;</td>
<td align="left">&#x00D7;</td>
<td align="left">&#x00D7;</td>
</tr>
<tr><td/>
<td align="left" rowspan="7">Listener</td>
<td align="left">12</td>
<td align="left">AddListener</td>
<td align="left">&#x221A;</td>
<td align="left">&#x221A;</td>
<td align="left">&#x221A;</td>
<td align="left">&#x221A;</td>
</tr>
<tr><td/>
<td align="left">13</td>
<td align="left">addlistener</td>
<td align="left">&#x221A;</td>
<td align="left">&#x221A;</td>
<td align="left">&#x221A;</td>
<td align="left">&#x221A;</td>
</tr>
<tr><td/>
<td align="left">14</td>
<td align="left">listener</td>
<td align="left">&#x221A;</td>
<td align="left">&#x221A;</td>
<td align="left">&#x221A;</td>
<td align="left">&#x221A;</td>
</tr>
<tr><td/>
<td align="left">15</td>
<td align="left">memlistener</td>
<td align="left">&#x221A;</td>
<td align="left">&#x221A;</td>
<td align="left">&#x221A;</td>
<td align="left">&#x221A;</td>
</tr>
<tr><td/>
<td align="left">16</td>
<td align="left">AddListener</td>
<td align="left">&#x221A;</td>
<td align="left">&#x221A;</td>
<td align="left">&#x221A;</td>
<td align="left">&#x221A;</td>
</tr>
<tr><td/>
<td align="left">17</td>
<td align="left">LRain</td>
<td align="left">&#x221A;</td>
<td align="left">&#x221A;</td>
<td align="left">&#x221A;</td>
<td align="left">&#x221A;</td>
</tr>
<tr><td/>
<td align="left">18</td>
<td align="left">AddTomcatListener</td>
<td align="left">&#x221A;</td>
<td align="left">&#x00D7;</td>
<td align="left">&#x00D7;</td>
<td align="left">&#x00D7;</td>
</tr>
<tr><td/>
<td align="left" rowspan="9">Servlet</td>
<td align="left">19</td>
<td align="left">AddServlet</td>
<td align="left">&#x221A;</td>
<td align="left">&#x221A;</td>
<td align="left">&#x221A;</td>
<td align="left">&#x221A;</td>
</tr>
<tr><td/>
<td align="left">20</td>
<td align="left">addservlet</td>
<td align="left">&#x221A;</td>
<td align="left">&#x221A;</td>
<td align="left">&#x221A;</td>
<td align="left">&#x221A;</td>
</tr>
<tr><td/>
<td align="left">21</td>
<td align="left">memservlet</td>
<td align="left">&#x221A;</td>
<td align="left">&#x221A;</td>
<td align="left">&#x221A;</td>
<td align="left">&#x221A;</td>
</tr>
<tr><td/>
<td align="left">22</td>
<td align="left">AddServlet</td>
<td align="left">&#x221A;</td>
<td align="left">&#x221A;</td>
<td align="left">&#x221A;</td>
<td align="left">&#x221A;</td>
</tr>
<tr><td/>
<td align="left">23</td>
<td align="left">Srain</td>
<td align="left">&#x221A;</td>
<td align="left">&#x221A;</td>
<td align="left">&#x221A;</td>
<td align="left">&#x221A;</td>
</tr>
<tr><td/>
<td align="left">24</td>
<td align="left">AddTomcatServlet</td>
<td align="left">&#x221A;</td>
<td align="left">&#x00D7;</td>
<td align="left">&#x00D7;</td>
<td align="left">&#x00D7;</td>
</tr>
<tr><td/>
<td align="left">25</td>
<td align="left">ServletBasedBasic</td>
<td align="left">&#x221A;</td>
<td align="left">&#x221A;</td>
<td align="left">&#x221A;</td>
<td align="left">&#x221A;</td>
</tr>
<tr><td/>
<td align="left">26</td>
<td align="left">ServletBasedWithout Request</td>
<td align="left">&#x221A;</td>
<td align="left">&#x221A;</td>
<td align="left">&#x221A;</td>
<td align="left">&#x221A;</td>
</tr>
<tr><td/>
<td align="left">27</td>
<td align="left">ServletBasedWithout RequestVariant</td>
<td align="left">&#x221A;</td>
<td align="left">&#x221A;</td>
<td align="left">&#x00D7;</td>
<td align="left">&#x00D7;</td>
</tr>
<tr>
<td align="left">Spring framework</td>
<td align="left">Controller</td>
<td align="left">28</td>
<td align="left">Evil</td>
<td align="left">&#x221A;</td>
<td align="left">&#x221A;</td>
<td align="left">&#x00D7;</td>
<td align="left">&#x00D7;</td>
</tr>
<tr>
<td/>
<td/>
<td align="left">29</td>
<td align="left">InjectToController</td>
<td align="left">&#x221A;</td>
<td align="left">&#x221A;</td>
<td align="left">&#x00D7;</td>
<td align="left">&#x00D7;</td>
</tr>
<tr>
<td/>
<td/>
<td align="left">30</td>
<td align="left">InvisibleShell</td>
<td align="left">&#x221A;</td>
<td align="left">&#x221A;</td>
<td align="left">&#x00D7;</td>
<td align="left">&#x00D7;</td>
</tr>
<tr>
<td/>
<td/>
<td align="left">31</td>
<td align="left">ReController</td>
<td align="left">&#x221A;</td>
<td align="left">&#x00D7;</td>
<td align="left">&#x00D7;</td>
<td align="left">&#x00D7;</td>
</tr>
<tr>
<td/>
<td/>
<td align="left">32</td>
<td align="left">ControllerBased</td>
<td align="left">&#x221A;</td>
<td align="left">&#x221A;</td>
<td align="left">&#x221A;</td>
<td align="left">&#x221A;</td>
</tr>
<tr>
<td/>
<td align="left">Interceptor</td>
<td align="left">33</td>
<td align="left">AddController</td>
<td align="left">&#x221A;</td>
<td align="left">&#x00D7;</td>
<td align="left">&#x00D7;</td>
<td align="left">&#x00D7;</td>
</tr>
<tr>
<td/>
<td/>
<td align="left">34</td>
<td align="left">TestInterceptor</td>
<td align="left">&#x221A;</td>
<td align="left">&#x221A;</td>
<td align="left">&#x00D7;</td>
<td align="left">&#x221A;</td>
</tr>
<tr>
<td/>
<td/>
<td align="left">35</td>
<td align="left">AddInterceptor</td>
<td align="left">&#x221A;</td>
<td align="left">&#x00D7;</td>
<td align="left">&#x00D7;</td>
<td align="left">&#x00D7;</td>
</tr>
</tbody>
</table>
</table-wrap><table-wrap id="table-5"><label>Table 5</label><caption><title>Test case for JShellDetector detection failure</title></caption>
<table frame="hsides">
<colgroup>
<col align="left"/>
<col align="left"/>
</colgroup>
<thead>
<tr>
<th align="left">Failure reason</th>
<th align="left">Test case number</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left">String encryption</td>
<td align="left">9, 19, 24, 34, 36, 38</td>
</tr>
<tr>
<td align="left">Taint analysis failure</td>
<td align="left">3, 7</td>
</tr>
</tbody>
</table>
</table-wrap>
<p>String encryption is a common approach used by attackers to hide malicious behavior, which is a big challenge for webshell detection. In the dataset we collected, 17.1&#x0025; of the test cases are encrypted. This technique erases the semantic information of the webshell and makes the code of the attack vector no longer satisfy the Java syntax rules. This means that JShellDetector cannot convert the encrypted webshell to an intermediate representation, which in turn causes taint analysis to fail. As for webshell detection in other languages, existing studies mostly use statistical feature analysis [<xref ref-type="bibr" rid="ref-35">35</xref>] or learning-based methods [<xref ref-type="bibr" rid="ref-36">36</xref>] to solve this problem. However, the Java fileless webshell currently lacks sufficient samples for these methods.</p>
<p>For test cases 3 and 7, the attacker implements malicious logic by manipulating the bytecode. In the real world, ClassWriter object is widely used to manipulate bytecode. <xref ref-type="fig" rid="fig-5">Fig. 5</xref> shows an example of using ClassWriter. In <xref ref-type="fig" rid="fig-5">Fig. 5a</xref> we use the <italic>visit()</italic> method to define a class named TreeNode, and then add two member variables (i.e., left and right) and a public method (i.e., <italic>print()</italic>) to it. <xref ref-type="fig" rid="fig-5">Fig. 5b</xref> is the code generated by the instruction in <xref ref-type="fig" rid="fig-5">Fig. 5a</xref>. In some test cases, the attacker generates the real attack vector using a manner similar to <xref ref-type="fig" rid="fig-5">Fig. 5</xref>. However, the target of JShellDetector analysis is that the instruction is based on the ClassWriter rather than the real attack vector generated at runtime, which leads to false negatives. Fortunately, the number of such test cases is not large, accounting for only 5.7&#x0025;.</p>
<fig id="fig-5"><label>Figure 5</label><caption><title>An example of using ClassWriter to generate Java code. (a) is the instruction based on ClassWriter (b) is the generated code</title></caption><graphic mimetype="image" mime-subtype="tif" xlink:href="CMC_34505-fig-5.tif"/></fig>
<p>In general, JShellDetector can effectively capture the sensitive behavior of attackers injecting fileless webshells, and most malicious behaviors of webshells can be detected through taint analysis.</p>
</sec>
<sec id="s5_3_2"><label>5.3.2</label><title>Answering RQ2: Comparison with Other Tools</title>
<p>To our knowledge, only two open source tools, i.e., Copagent [<xref ref-type="bibr" rid="ref-37">37</xref>] and MemoryShell [<xref ref-type="bibr" rid="ref-38">38</xref>], claim to automate the detection of Java fileless webshells. The Copagent extracts all classes in the JVM, and filters suspicious classes by package name, class name, interface name, and annotation. Then Copagent judges whether the behavior of the suspicious class matches the features of the Java fileless webshell. The author of Copagent proposed three features, namely, loading or modifying Java classes, no corresponding bytecode file in the web server, and no registration in the configuration file. The Copagent outputs the risk level of each suspicious class according to the feature matching result, which is processed manually. MemoryShell is optimized in Copagent. On the one hand, his author adds protection against fileless webshell attacks, and on the other hand, optimizes method call analysis.</p>
<p>As shown in <xref ref-type="table" rid="table-6">Table 6</xref>, the performance of MemoryShell and Copagent is similar. MemoryShell captured 23 fileless webshell attacks, which accounted for 65.7&#x0025; of the total test cases. Copagent detected 22 fileless webshells, accounting for 62.9&#x0025; of the total test cases. The performance of both tools is lower than the 77.1&#x0025; detection rate of JShellDetector, which demonstrates again the effectiveness of our proposed tool. Further analysis, we found that the 23 samples detected by MemoryShell included 21 test cases based on the Java web component and only 2 test cases based on the Spring framework, accounting for 77.8&#x0025; and 25&#x0025; of the dataset, respectively. This means that MemoryShell performs poorly on Spring framework-based webshells. Similarly, Copagent only captures 1 webshell based on the Spring framework, and the performance is equally bad. For JShellDetector, the detection rates are 81.5&#x0025; and 62.5&#x0025; on Java web component-based test cases and Spring framework-based test cases, respectively. Overall, JShellDetector outperforms MemoryShell and Copagent both on each type and overall.</p>
<table-wrap id="table-6"><label>Table 6</label><caption><title>Detection rate on different types of test cases</title></caption>
<table frame="hsides">
<colgroup>
<col align="left"/>
<col align="left"/>
<col align="left"/>
<col align="left"/>
</colgroup>
<thead>
<tr>
<th align="left">Type</th>
<th align="left">JShellDetector</th>
<th align="left">Copagent</th>
<th align="left">MemoryShell</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left">Java web component</td>
<td align="left">81.5&#x0025;</td>
<td align="left">77.8&#x0025;</td>
<td align="left">77.8&#x0025;</td>
</tr>
<tr>
<td align="left">Spring framework</td>
<td align="left">62.5&#x0025;</td>
<td align="left">12.5&#x0025;</td>
<td align="left">25&#x0025;</td>
</tr>
<tr>
<td align="left">Overall detection rate</td>
<td align="left">77.1&#x0025;</td>
<td align="left">62.9&#x0025;</td>
<td align="left">65.7&#x0025;</td>
</tr>
</tbody>
</table>
</table-wrap>
<p>To figure out the reasons for this, we analyzed the differences between the three tools in detail. The main difference between MemoryShell and Copagent lies in two points. The first difference is that MemoryShell uses whether there is a class file in the corresponding ClassLoader directory as the criterion for judging a webshell (e.g., if there is class A in memory, but there is no <italic>A.class</italic> file on the server, MemoryShell considers A is a webshell). By analyzing the content of the decompiled Java bytecode, Copagent takes whether there are dangerous keywords as the criterion for judging the fileless webshell. The second difference is that MemoryShell specifically adds detection conditions for Interceptor-based webshells. It blacklists <italic>org.springframework.web.servlet.HandlerInterceptor</italic>, which is a class that must be used to construct an Interceptor-based webshell. On the contrary, Copagent lacks the processing logic for Interceptor-based webshells.</p>
<p>In fact, MemoryShell, which uses the existence of class files in the corresponding ClassLoader directory as the only criterion for judging, is very easy to cause false negatives. Although the fileless webshell will not leave traces on the hard disk, if the attacker injects by exploiting the traditional file upload vulnerability in the real attack scenario, as long as the corresponding class file exists, the MemoryShell will be invalid. From the experimental results, the advantage of Copagent compared to our detection tool is that it can detect fileless webshells with encrypted strings. This is because Copagent directly lists <italic>javax.crypto</italic> as a dangerous keyword, and most fileless webshells with encrypted strings call this class for encryption and decryption. However, these two tools are based on the blacklist mechanism for the suspicious class filter. This means that Copagent and MemoryShell cannot detect malicious behavior that does not inherit dangerous parent classes or implement specific interfaces. JShellDetector does not have these problems and has better performance on the fileless webshell based on the Spring framework.</p>
</sec>
<sec id="s5_3_3"><label>5.3.3</label><title>Answering RQ3: Resource Consuming</title>
<p>The additional resource consumption of the system is an important indicator for evaluating the usability of a tool. In order to reduce the pressure on the web server, JShellDetector uses offline analysis to detect webshells. Only method probes consume web server resources. We counted the resource consumption of the test case, and the additional memory resources consumed are all less than 1&#x0025; of the cyber range SecExample.</p>
</sec>
</sec>
</sec>
<sec id="s6"><label>6</label><title>Conclusion and Future Work</title>
<p>Webshell is a common method for persistent attacks with injection vulnerabilities. As the cybersecurity arms race escalates, traditional file-based webshells have struggled to escape anti-virus software. Attackers are looking for more stealthy solutions. Due to its invisible characteristics, Java fileless webshell makes it challenging for the traditional detection method, and is being used more and more to attack web applications. To address this problem, we propose JShellDetector, a detector based on JVM monitoring and taint analysis. Compared with other blacklist-based or matching-based approaches, our approach has a higher detection rate. In order to systematically evaluate the effectiveness of JShellDetector, we selected other two Java fileless webshell detection tools for comparison. The experimental results show that the detection rate of JShellDetector is about 11&#x0025; higher than that of these two tools. In addition, the collected test cases are publicly accessed which can help future researchers.</p>
<p>Although JShellDetector performs well on test cases, we must recognize that it still has some limitations. First, the number of test cases is not sufficient, so we cannot determine the performance of JShellDetector on more complex webshells. The lack of test cases also limits the techniques we can use. Approaches based on machine learning or statistical features do not work well on small samples. Therefore, collecting test cases will continue in our future work. Second, JShellDetector cannot handle encrypted strings. Although there are some existing works to detect webshells with encrypted strings based on statistical features, our collection of Java fileless webshells is not sufficient. In future work, we will try to extract statistical features of traditional file-based webshells and then migrate them to fileless webshell detection.</p>
</sec>
</body>
<back>
<sec><title>Funding Statement</title>
<p>This work was supported by the <funding-source>National Natural Science Foundation of China</funding-source> under Grant Number <award-id>62001055</award-id>.</p></sec>
<sec sec-type="data-availability"><title>Availability of Data and Materials</title>
<p>Experimental dataset is freely available at <ext-link ext-link-type="uri" xlink:href="https://github.com/java-security/webshelldataset">https://github.com/java-security/webshelldataset</ext-link>.</p></sec>
<sec sec-type="COI-statement"><title>Conflicts of Interest</title>
<p>The authors declare that they have no conflicts of interest to report regarding the present study.</p></sec>
<ref-list content-type="authoryear"><title>References</title>
<ref id="ref-1"><label>[1]</label><mixed-citation publication-type="other"><person-group person-group-type="author"><collab>OWASP Top 10 2021 team</collab></person-group>, <italic>Welcome to the OWASP Top 10-2021</italic>, <year>2021</year>. [Online]. Available: <ext-link ext-link-type="uri" xlink:href="https://owasp.org/Top10">https://owasp.org/Top10</ext-link>.</mixed-citation></ref>
<ref id="ref-2"><label>[2]</label><mixed-citation publication-type="conf-proc"><person-group person-group-type="author"><string-name><given-names>D. A.</given-names> <surname>Kindy</surname></string-name> and <string-name><given-names>A. K.</given-names> <surname>Pathan</surname></string-name></person-group>, &#x201C;<article-title>A survey on SQL injection: Vulnerabilities, attacks, and prevention techniques</article-title>,&#x201D; in <conf-name>Proc. of 2011 IEEE 15th Int. Symp. on Consumer Electronics (ISCE)</conf-name>, <conf-loc>Singapore</conf-loc>, pp. <fpage>468</fpage>&#x2013;<lpage>471</lpage>, <year>2011</year>.</mixed-citation></ref>
<ref id="ref-3"><label>[3]</label><mixed-citation publication-type="journal"><person-group person-group-type="author"><string-name><given-names>A.</given-names> <surname>Hannousse</surname></string-name> and <string-name><given-names>S.</given-names> <surname>Yahiouche</surname></string-name></person-group>, &#x201C;<article-title>Handling webshell attacks: A systematic mapping and survey</article-title>,&#x201D; <source>Computers &#x0026; Security</source>, vol. <volume>108</volume>, pp. <fpage>1</fpage>&#x2013;<lpage>26</lpage>, <year>2021</year>.</mixed-citation></ref>
<ref id="ref-4"><label>[4]</label><mixed-citation publication-type="other"><person-group person-group-type="author"><collab>WatchGuard Threat Lab</collab></person-group>, <italic>Internet Security Report-Q4 2020</italic>, <year>2020</year>. [Online]. Available: <ext-link ext-link-type="uri" xlink:href="https://www.watchguard.com/wgrd-resource-center/security-report-q4-2020">https://www.watchguard.com/wgrd-resource-center/security-report-q4-2020</ext-link>.</mixed-citation></ref>
<ref id="ref-5"><label>[5]</label><mixed-citation publication-type="other"><person-group person-group-type="author"><string-name><given-names>J.</given-names> <surname>Astle</surname></string-name>, <string-name><given-names>K.</given-names> <surname>Budnick</surname></string-name>, <string-name><given-names>S.</given-names> <surname>Clark</surname></string-name>, <string-name><given-names>A.</given-names> <surname>Dider</surname></string-name>, <string-name><given-names>B.</given-names> <surname>Donohue</surname></string-name> <etal>et al.,</etal></person-group> <italic>2022 Threat Detection Report</italic>, <year>2022</year>. [Online]. Available: <ext-link ext-link-type="uri" xlink:href="https://redcanary.com/resources/guides/threat-detection-report">https://redcanary.com/resources/guides/threat-detection-report</ext-link>.</mixed-citation></ref>
<ref id="ref-6"><label>[6]</label><mixed-citation publication-type="conf-proc"><person-group person-group-type="author"><string-name><given-names>W.</given-names> <surname>Kang</surname></string-name>, <string-name><given-names>S.</given-names> <surname>Zhong</surname></string-name>, <string-name><given-names>K.</given-names> <surname>Chen</surname></string-name>, <string-name><given-names>J.</given-names> <surname>Lai</surname></string-name> and <string-name><given-names>G.</given-names> <surname>Xu</surname></string-name></person-group>, &#x201C;<article-title>RF-AdaCost: WebShell detection method that combines statistical features and opcode</article-title>,&#x201D; in <conf-name>Proc. of Int. Conf. on Frontiers in Cyber Security</conf-name>, <conf-loc>Tianjin, China</conf-loc>, pp. <fpage>667</fpage>&#x2013;<lpage>682</lpage>, <year>2020</year>.</mixed-citation></ref>
<ref id="ref-7"><label>[7]</label><mixed-citation publication-type="conf-proc"><person-group person-group-type="author"><string-name><given-names>W.</given-names> <surname>Yang</surname></string-name>, <string-name><given-names>B.</given-names> <surname>Sun</surname></string-name> and <string-name><given-names>B.</given-names> <surname>Cui</surname></string-name></person-group>, &#x201C;<article-title>A webshell detection technology based on HTTP traffic analysis</article-title>,&#x201D; in <conf-name>Proc. of Int. Conf. on Innovative Mobile and Internet Services in Ubiquitous Computing</conf-name>, <conf-loc>Matsue, Japan</conf-loc>, pp. <fpage>336</fpage>&#x2013;<lpage>342</lpage>, <year>2018</year>.</mixed-citation></ref>
<ref id="ref-8"><label>[8]</label><mixed-citation publication-type="journal"><person-group person-group-type="author"><string-name><given-names>G.</given-names> <surname>You</surname></string-name>, <string-name><given-names>H.</given-names> <surname>Marco-Gisbert</surname></string-name> and <string-name><given-names>P.</given-names> <surname>Keir</surname></string-name></person-group>, &#x201C;<article-title>Mitigating webshell attacks through machine learning techniques</article-title>,&#x201D; <source>Future Internet</source>, vol. <volume>12</volume>, pp. <fpage>1</fpage>&#x2013;<lpage>12</lpage>, <year>2020</year>.</mixed-citation></ref>
<ref id="ref-9"><label>[9]</label><mixed-citation publication-type="other"><person-group person-group-type="author"><collab>TIOBE Software BV</collab></person-group>, <italic>TIOBE Index for July 2022</italic>, <year>2022</year>. [Online]. Available: <ext-link ext-link-type="uri" xlink:href="https://www.tiobe.com/tiobe-index">https://www.tiobe.com/tiobe-index</ext-link>.</mixed-citation></ref>
<ref id="ref-10"><label>[10]</label><mixed-citation publication-type="journal"><person-group person-group-type="author"><string-name><given-names>T.</given-names> <surname>Zhu</surname></string-name>, <string-name><given-names>Z.</given-names> <surname>Weng</surname></string-name>, <string-name><given-names>L.</given-names> <surname>Fu</surname></string-name> and <string-name><given-names>L.</given-names> <surname>Ruan</surname></string-name></person-group>, &#x201C;<article-title>A web shell detection method based on multiview feature fusion</article-title>,&#x201D; <source>Applied Sciences</source>, vol. <volume>10</volume>, no. <issue>18</issue>, pp. <fpage>6274</fpage>&#x2013;<lpage>6290</lpage>, <year>2020</year>.</mixed-citation></ref>
<ref id="ref-11"><label>[11]</label><mixed-citation publication-type="journal"><person-group person-group-type="author"><string-name><given-names>A.</given-names> <surname>Kurniawan</surname></string-name>, <string-name><given-names>B. S.</given-names> <surname>Abbas</surname></string-name>, <string-name><given-names>A.</given-names> <surname>Trisetyarso</surname></string-name> and <string-name><given-names>S. M.</given-names> <surname>Isa</surname></string-name></person-group>, &#x201C;<article-title>Classification of web backdoor malware based on function call execution of static analysis</article-title>,&#x201D; <source>ICIC Express Letters</source>, vol. <volume>13</volume>, no. <issue>6</issue>, pp. <fpage>445</fpage>&#x2013;<lpage>452</lpage>, <year>2019</year>.</mixed-citation></ref>
<ref id="ref-12"><label>[12]</label><mixed-citation publication-type="journal"><person-group person-group-type="author"><string-name><given-names>W.</given-names> <surname>Huang</surname></string-name>, <string-name><given-names>C.</given-names> <surname>Jia</surname></string-name>, <string-name><given-names>M.</given-names> <surname>Yu</surname></string-name>, <string-name><given-names>K.</given-names> <surname>Chow</surname></string-name>, <string-name><given-names>J.</given-names> <surname>Chen</surname></string-name> <etal>et al.,</etal></person-group> &#x201C;<article-title>Enhancing the feature profiles of Web shells by analyzing the performance of multiple detectors</article-title>,&#x201D; <source>IFIP International Conference on Digital Forensics</source>, vol. <volume>589</volume>, pp. <fpage>57</fpage>&#x2013;<lpage>72</lpage>, <year>2020</year>.</mixed-citation></ref>
<ref id="ref-13"><label>[13]</label><mixed-citation publication-type="conf-proc"><person-group person-group-type="author"><string-name><given-names>Y.</given-names> <surname>Tian</surname></string-name>, <string-name><given-names>J.</given-names> <surname>Wang</surname></string-name>, <string-name><given-names>Z.</given-names> <surname>Zhou</surname></string-name> and <string-name><given-names>S.</given-names> <surname>Zhou</surname></string-name></person-group>, &#x201C;<article-title>CNN-webshell: Malicious Web shell detection with convolutional neural network</article-title>,&#x201D; in <conf-name>Proc. of 2017 VI Int. Conf. on Network, Communication and Computing (ICNCC 2017)</conf-name>, <conf-loc>New York, NY, USA</conf-loc>, pp. <fpage>75</fpage>&#x2013;<lpage>79</lpage>, <year>2017</year>.</mixed-citation></ref>
<ref id="ref-14"><label>[14]</label><mixed-citation publication-type="journal"><person-group person-group-type="author"><string-name><given-names>Z.</given-names> <surname>Wang</surname></string-name>, <string-name><given-names>J.</given-names> <surname>Yang</surname></string-name>, <string-name><given-names>M.</given-names> <surname>Dai</surname></string-name>, <string-name><given-names>R.</given-names> <surname>Xu</surname></string-name> and <string-name><given-names>X.</given-names> <surname>Liang</surname></string-name></person-group>, &#x201C;<article-title>A method of detecting webshell based on multi-layer perception</article-title>,&#x201D; <source>Academic Journal of Computing &#x0026; Information Science</source>, vol. <volume>2</volume>, pp. <fpage>81</fpage>&#x2013;<lpage>91</lpage>, <year>2019</year>.</mixed-citation></ref>
<ref id="ref-15"><label>[15]</label><mixed-citation publication-type="conf-proc"><person-group person-group-type="author"><string-name><given-names>H.</given-names> <surname>Cui</surname></string-name>, <string-name><given-names>D.</given-names> <surname>Huang</surname></string-name>, <string-name><given-names>Y.</given-names> <surname>Fang</surname></string-name>, <string-name><given-names>L.</given-names> <surname>Liu</surname></string-name> and <string-name><given-names>C.</given-names> <surname>Huang</surname></string-name></person-group>, &#x201C;<article-title>Webshell detection based on random forest&#x2013;gradient boosting decision tree algorithm</article-title>,&#x201D; in <conf-name>Proc. of 2018 IEEE Third Int. Conf. on Data Science in Cyberspace (DSC)</conf-name>, <conf-loc>Guangzhou, China</conf-loc>, pp. <fpage>153</fpage>&#x2013;<lpage>160</lpage>, <year>2018</year>.</mixed-citation></ref>
<ref id="ref-16"><label>[16]</label><mixed-citation publication-type="conf-proc"><person-group person-group-type="author"><string-name><given-names>Y.</given-names> <surname>Fang</surname></string-name>, <string-name><given-names>Y.</given-names> <surname>Qiu</surname></string-name>, <string-name><given-names>L.</given-names> <surname>Liu</surname></string-name> and <string-name><given-names>C.</given-names> <surname>Huang</surname></string-name></person-group>, &#x201C;<article-title>Detecting webshell based on random forest with FastText</article-title>,&#x201D; in <conf-name>Proc. of the 2018 Int. Conf. on Computing and Artificial Intelligence (ICCAI 2018)</conf-name>, <conf-loc>New York, NY, USA</conf-loc>, pp. <fpage>52</fpage>&#x2013;<lpage>56</lpage>, <year>2018</year>.</mixed-citation></ref>
<ref id="ref-17"><label>[17]</label><mixed-citation publication-type="other"><person-group person-group-type="author"><collab>Apache Software Foundation</collab></person-group>, <italic>Apache Tomcat</italic>, <year>2022</year>. [Online]. Available: <ext-link ext-link-type="uri" xlink:href="https://tomcat.apache.org">https://tomcat.apache.org</ext-link>.</mixed-citation></ref>
<ref id="ref-18"><label>[18]</label><mixed-citation publication-type="other"><person-group person-group-type="author"><collab>Oracle Corporation</collab></person-group>, <italic>Oracle WebLogic Server</italic>, <year>2022</year>. [Online]. Available: <ext-link ext-link-type="uri" xlink:href="https://www.oracle.com/java/weblogic">https://www.oracle.com/java/weblogic</ext-link>.</mixed-citation></ref>
<ref id="ref-19"><label>[19]</label><mixed-citation publication-type="other"><person-group person-group-type="author"><collab>IBM Corporation</collab></person-group>, <italic>Java Servlets 3.0</italic>, <year>2022</year>. [Online]. Available: <ext-link ext-link-type="uri" xlink:href="https://www.ibm.com/docs/en/was-liberty/base?topic=features-java-servlets-30">https://www.ibm.com/docs/en/was-liberty/base?topic=features-java-servlets-30</ext-link>.</mixed-citation></ref>
<ref id="ref-20"><label>[20]</label><mixed-citation publication-type="conf-proc"><person-group person-group-type="author"><string-name><given-names>S.</given-names> <surname>Chiba</surname></string-name></person-group>, &#x201C;<article-title>Javassist&#x2014;a reflection-based programming wizard for java</article-title>,&#x201D; in <conf-name>Proc. of OOPSLA&#x2019;98 Workshop on Reflective Programming in C&#x002B;&#x002B; and Java</conf-name>, <conf-loc>Vancouver, British Columbia, Canada</conf-loc>, vol. <volume>174</volume>, pp. <fpage>21</fpage>&#x2013;<lpage>26</lpage>, <year>1998</year>.</mixed-citation></ref>
<ref id="ref-21"><label>[21]</label><mixed-citation publication-type="conf-proc"><person-group person-group-type="author"><string-name><given-names>S.</given-names> <surname>Chiba</surname></string-name></person-group>, &#x201C;<article-title>Load-time structural reflection in java</article-title>,&#x201D; in <conf-name>Proc. of European Conf. on Object-Oriented Programming</conf-name>, <conf-loc>Sophia Antipolis and Cannes, France</conf-loc>, vol. <volume>1850</volume>, pp. <fpage>313</fpage>&#x2013;<lpage>336</lpage>, <year>2015</year>.</mixed-citation></ref>
<ref id="ref-22"><label>[22]</label><mixed-citation publication-type="conf-proc"><person-group person-group-type="author"><string-name><given-names>P.</given-names> <surname>Derakhshanfar</surname></string-name>, <string-name><given-names>X.</given-names> <surname>Devroey</surname></string-name>, <string-name><given-names>A.</given-names> <surname>Panichella</surname></string-name> and <string-name><given-names>A. V.</given-names> <surname>Deursen</surname></string-name></person-group>, &#x201C;<article-title>Botsing, a search-based crash reproduction framework for java</article-title>,&#x201D; in <conf-name>Proc. of the 35th IEEE/ACM Int. Conf. on Automated Software Engineering (ASE)</conf-name>, <conf-loc>Melbourne, Australia</conf-loc>, pp. <fpage>1278</fpage>&#x2013;<lpage>1280</lpage>, <year>2020</year>.</mixed-citation></ref>
<ref id="ref-23"><label>[23]</label><mixed-citation publication-type="other"><person-group person-group-type="author"><string-name><given-names>S.</given-names> <surname>Nusbaum</surname></string-name></person-group>, <italic>Dumping embedded Java classes</italic>, <year>2018</year>. [Online]. Available: <ext-link ext-link-type="uri" xlink:href="https://www.trustedsec.com/blog/dumping-embedded-java-classes">https://www.trustedsec.com/blog/dumping-embedded-java-classes</ext-link>.</mixed-citation></ref>
<ref id="ref-24"><label>[24]</label><mixed-citation publication-type="conf-proc"><person-group person-group-type="author"><string-name><given-names>P.</given-names> <surname>Ferrara</surname></string-name>, <string-name><given-names>L.</given-names> <surname>Olivieri</surname></string-name> and <string-name><given-names>F.</given-names> <surname>Spoto</surname></string-name></person-group>, &#x201C;<article-title>BackFlow: Backward context-sensitive flow reconstruction of taint analysis results</article-title>,&#x201D; in <conf-name>Proc. of Int. Conf. on Verification, Model Checking, and Abstract Interpretation</conf-name>, <conf-loc>New Orleans, LA, USA</conf-loc>, pp. <fpage>23</fpage>&#x2013;<lpage>43</lpage>, <year>2020</year>.</mixed-citation></ref>
<ref id="ref-25"><label>[25]</label><mixed-citation publication-type="journal"><person-group person-group-type="author"><string-name><given-names>O.</given-names> <surname>Tripp</surname></string-name>, <string-name><given-names>M.</given-names> <surname>Pistoia</surname></string-name>, <string-name><given-names>S. J.</given-names> <surname>Fink</surname></string-name>, <string-name><given-names>M.</given-names> <surname>Sridharan</surname></string-name> and <string-name><given-names>O.</given-names> <surname>Weisman</surname></string-name></person-group>, &#x201C;<article-title>TAJ: Effective taint analysis of web applications</article-title>,&#x201D; <source>ACM Sigplan Notices</source>, vol. <volume>44</volume>, no. <issue>6</issue>, pp. <fpage>87</fpage>&#x2013;<lpage>97</lpage>, <year>2009</year>.</mixed-citation></ref>
<ref id="ref-26"><label>[26]</label><mixed-citation publication-type="conf-proc"><person-group person-group-type="author"><string-name><given-names>Y.</given-names> <surname>Ren</surname></string-name>, <string-name><given-names>J.</given-names> <surname>Zhao</surname></string-name> and <string-name><given-names>C.</given-names> <surname>Zhang</surname></string-name></person-group>, &#x201C;<article-title>The propagation strategy model of taint analysis</article-title>,&#x201D; in <conf-name>Proc. of the 4th Int. Seminar on Computer Technology, Mechanical and Electrical Engineering (ISCME)</conf-name>, <conf-loc>Chengdu, China, vol. 1486, no. 4</conf-loc>, pp. <fpage>1</fpage>&#x2013;<lpage>7</lpage>, <year>2020</year>.</mixed-citation></ref>
<ref id="ref-27"><label>[27]</label><mixed-citation publication-type="conf-proc"><person-group person-group-type="author"><string-name><given-names>X.</given-names> <surname>Zhang</surname></string-name>, <string-name><given-names>X.</given-names> <surname>Wang</surname></string-name>, <string-name><given-names>R.</given-names> <surname>Slavin</surname></string-name> and <string-name><given-names>J.</given-names> <surname>Niu</surname></string-name></person-group>, &#x201C;<article-title>Condysta: Context-aware dynamic supplement to static taint analysis</article-title>,&#x201D; in <conf-name>Proc. of 2021 IEEE Symp. on Security and Privacy (SP)</conf-name>, <conf-loc>San Francisco, CA, USA</conf-loc>, pp. <fpage>796</fpage>&#x2013;<lpage>812</lpage>, <year>2021</year>.</mixed-citation></ref>
<ref id="ref-28"><label>[28]</label><mixed-citation publication-type="conf-proc"><person-group person-group-type="author"><string-name><given-names>P.</given-names> <surname>Lam</surname></string-name>, <string-name><given-names>E.</given-names> <surname>Bodden</surname></string-name>, <string-name><given-names>O.</given-names> <surname>Lhotak</surname></string-name> and <string-name><given-names>L.</given-names> <surname>Hendren</surname></string-name></person-group>, &#x201C;<article-title>The soot framework for java program analysis: A retrospective</article-title>,&#x201D; in <conf-name>Proc. of Cetus Users and Compiler Infrastructure Workshop (CETUS 2011)</conf-name>, <conf-loc>Galveston Island, TX, USA, vol. 15, no. 35</conf-loc>, pp. <fpage>1</fpage>&#x2013;<lpage>8</lpage>, <year>2011</year>.</mixed-citation></ref>
<ref id="ref-29"><label>[29]</label><mixed-citation publication-type="conf-proc"><person-group person-group-type="author"><string-name><given-names>A.</given-names> <surname>Bartel</surname></string-name>, <string-name><given-names>J.</given-names> <surname>Klein</surname></string-name>, <string-name><given-names>M.</given-names> <surname>Monperrus</surname></string-name> and <string-name><given-names>Y. L.</given-names> <surname>Traon</surname></string-name></person-group>, &#x201C;<article-title>Dexpler: Converting android dalvik bytecode to jimple for static analysis with soot</article-title>,&#x201D; in <conf-name>Proc. of ACM SIGPLAN Int. Workshop on State of the Art in Java Program Analysis</conf-name>, <conf-loc>New York, NY, USA</conf-loc>, pp. <fpage>27</fpage>&#x2013;<lpage>38</lpage>, <year>2012</year>.</mixed-citation></ref>
<ref id="ref-30"><label>[30]</label><mixed-citation publication-type="conf-proc"><person-group person-group-type="author"><string-name><given-names>S.</given-names> <surname>Olin</surname></string-name></person-group>, &#x201C;<article-title>Control-flow analysis in scheme</article-title>,&#x201D; in <conf-name>Proc. of ACM SIGPLAN&#x2019;88 Conf. on Programming Language Design and Implementation (PLDI)</conf-name>, Atlanta, Georgia, USA, vol. <volume>23</volume>, no. <issue>7</issue>, pp. <fpage>164</fpage>&#x2013;<lpage>174</lpage>, <year>1988</year>.</mixed-citation></ref>
<ref id="ref-31"><label>[31]</label><mixed-citation publication-type="other"><person-group person-group-type="author"><collab>tangxiaofeng7</collab></person-group>, <italic>SecExample</italic>, <year>2021</year>. [Online]. Available: <ext-link ext-link-type="uri" xlink:href="https://github.com/tangxiaofeng7/SecExample">https://github.com/tangxiaofeng7/SecExample</ext-link>.</mixed-citation></ref>
<ref id="ref-32"><label>[32]</label><mixed-citation publication-type="journal"><person-group person-group-type="author"><string-name><given-names>M. M.</given-names> <surname>Yamin</surname></string-name>, <string-name><given-names>B.</given-names> <surname>Katt</surname></string-name> and <string-name><given-names>V.</given-names> <surname>Gkioulos</surname></string-name></person-group>, &#x201C;<article-title>Cyber ranges and security testbeds: Scenarios, functions, tools and architecture</article-title>,&#x201D; <source>Computers &#x0026; Security</source>, vol. <volume>88</volume>, pp. <fpage>1</fpage>&#x2013;<lpage>26</lpage>, <year>2020</year>.</mixed-citation></ref>
<ref id="ref-33"><label>[33]</label><mixed-citation publication-type="other"><person-group person-group-type="author"><collab>National Vulnerability Database</collab></person-group>, <italic>CVE-2017-18349 Detail</italic>, <year>2017</year>. [Online]. Available: <ext-link ext-link-type="uri" xlink:href="https://nvd.nist.gov/vuln/detail/CVE-2017-18349">https://nvd.nist.gov/vuln/detail/CVE-2017-18349</ext-link>.</mixed-citation></ref>
<ref id="ref-34"><label>[34]</label><mixed-citation publication-type="other"><person-group person-group-type="author"><collab>mbechler</collab></person-group>, <italic>marshalsec</italic>, <year>2021</year>. [Online]. Available: <ext-link ext-link-type="uri" xlink:href="https://github.com/mbechler/marshalsec">https://github.com/mbechler/marshalsec</ext-link>.</mixed-citation></ref>
<ref id="ref-35"><label>[35]</label><mixed-citation publication-type="journal"><person-group person-group-type="author"><string-name><given-names>Z.</given-names> <surname>Pan</surname></string-name>, <string-name><given-names>Y.</given-names> <surname>Chen</surname></string-name>, <string-name><given-names>Y.</given-names> <surname>Chen</surname></string-name>, <string-name><given-names>Y.</given-names> <surname>Shen</surname></string-name> and <string-name><given-names>X.</given-names> <surname>Guo</surname></string-name></person-group>, <article-title>Webshell detection based on executable data characteristics of PHP code</article-title>, <source>Wireless Communications and Mobile Computing</source>, vol. <volume>2021</volume>, pp. <fpage>1</fpage>&#x2013;<lpage>12</lpage>, <year>2021</year>.</mixed-citation></ref>
<ref id="ref-36"><label>[36]</label><mixed-citation publication-type="journal"><person-group person-group-type="author"><string-name><given-names>Y.</given-names> <surname>Wu</surname></string-name>, <string-name><given-names>Y.</given-names>, <surname>Sun</surname></string-name>, <string-name><given-names>C.</given-names> <surname>Huang</surname></string-name>, <string-name><given-names>P.</given-names> <surname>Jia</surname></string-name> and <string-name><given-names>L.</given-names> <surname>Liu</surname></string-name></person-group>, &#x201C;<article-title>Session-based webshell detection using machine learning in web logs</article-title>,&#x201D; <source>Security and Communication Networks</source>, vol. <volume>2019</volume>, pp. <fpage>1</fpage>&#x2013;<lpage>12</lpage>, <year>2019</year>.</mixed-citation></ref>
<ref id="ref-37"><label>[37]</label><mixed-citation publication-type="other"><person-group person-group-type="author"><collab>LandGrey</collab></person-group>, <italic>copagent</italic>, <year>2021</year>. [Online]. Available: <ext-link ext-link-type="uri" xlink:href="https://github.com/LandGrey/copagent">https://github.com/LandGrey/copagent</ext-link>.</mixed-citation></ref>
<ref id="ref-38"><label>[38]</label><mixed-citation publication-type="other"><person-group person-group-type="author"><collab>su18</collab></person-group>, <italic>MemoryShell</italic>, <year>2021</year>. [Online]. Available: <ext-link ext-link-type="uri" xlink:href="https://github.com/su18/MemoryShell">https://github.com/su18/MemoryShell</ext-link>.</mixed-citation></ref>
</ref-list>
</back>
</article>