<?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" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[BREAKDEV]]></title><description><![CDATA[Home of high quality offensive security tools & research to aid you in your red teaming endeavours.]]></description><link>https://breakdev.org/</link><image><url>https://breakdev.org/favicon.png</url><title>BREAKDEV</title><link>https://breakdev.org/</link></image><generator>Ghost 5.7</generator><lastBuildDate>Sun, 05 Apr 2026 00:05:19 GMT</lastBuildDate><atom:link href="https://breakdev.org/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Open source is dying.]]></title><description><![CDATA[<h2 id="open-source-is-dying-a-slow-painful-death">Open source is dying a slow, painful death.</h2><p>For the time being, the AI-related issues in the open-source space have been largely attributed to the flood of AI-slop-generated code contributions, which human project maintainers were unable to process because the effort required to validate each contribution far exceeded the quality</p>]]></description><link>https://breakdev.org/open-source-is-dying/</link><guid isPermaLink="false">69aac702d22a533d0a902ecb</guid><category><![CDATA[evilginx]]></category><dc:creator><![CDATA[Kuba Gretzky]]></dc:creator><pubDate>Fri, 06 Mar 2026 12:52:07 GMT</pubDate><media:content url="https://breakdev.org/content/images/2026/03/opensource-dead2.png" medium="image"/><content:encoded><![CDATA[<h2 id="open-source-is-dying-a-slow-painful-death">Open source is dying a slow, painful death.</h2><img src="https://breakdev.org/content/images/2026/03/opensource-dead2.png" alt="Open source is dying."><p>For the time being, the AI-related issues in the open-source space have been largely attributed to the flood of AI-slop-generated code contributions, which human project maintainers were unable to process because the effort required to validate each contribution far exceeded the quality of those contributions.</p><p>Now Cloudflare, by slop-forking Next.js, has just validated that it&apos;s okay to take an open-source project, shove it into an LLM, and have it vibe-code a completely new product based on the source code the engine was fed.</p><p>The question arises: if AI regenerates the source code of an open-source project entirely, does the original open-source license still apply?</p><p>We&apos;re approaching the Slop Ages, where protecting your IP from AI heists becomes virtually impossible. We&apos;ve seen it in the music industry, and the time has come for the software industry.</p><p>I am a software developer myself, and Evilginx has been open-sourced for over 8 years. That&apos;s why this news story rubs me the wrong way on a personal level.</p><p>Evilginx is an offensive security tool - a phishing framework focused on bypassing MFA. Due to its dual-use nature, it can be used either by the good guys to demonstrate the weaknesses of the company&apos;s MFA implementation or by the bad guys for malicious purposes, mainly to harm others.</p><p>I had countless second thoughts since the release of the open-source version, whether it was a good idea to put it out there, and later update it with new features, knowing that on one hand it will popularise the problems around weak MFA, and on the other hand give the bad guys a jump-start to expand their criminal enterprise.</p><p>It was no surprise to me to learn later that APT groups like Scattered Spider or Void Blizzard reportedly created their own phishing toolkits, based on publicly exposed Evilginx source code.</p><p>The main reason I launched Evilginx Pro as a closed-source, paid product last year was a combination of wanting to aid the good guys while gatekeeping the tool from the bad guys (and, of course, building a business out of it).</p><p>It has always been important to me to make the community version of the tool accessible to everyone. Still, I was not a fan of the collateral; this decision also carried.</p><p>Getting back to my original point.</p><p>We now live in a world where a threat actor can feed the GitHub source code of any offensive security tool into an AI and prompt it to create something completely different from scratch, with more features and easier to use. Security issues arising from vibe-coding become a secondary concern in this scenario and can be largely disregarded.</p><p>Over the last 2 years, I&apos;ve been making significant improvements to the Evilginx proxy engine. The majority of these changes have now been implemented in Evilginx Pro. One of the upcoming major updates is the introduction of the new Phishlets 2.0 format.</p><p>The plan is to release Phishlets 2.0, together with the proxy engine improvements, as part of the major update to the Evilginx community edition and make it accessible to everyone. As you may&apos;ve guessed by now, my main concern is whether to release it as open-source or closed-source.</p><p>Going the open-source route, I risk threat actors spending a few hundred bucks on a Claude subscription to create their own derivatives of Evilginx, which they can later rebrand and sell on the dark web.</p><p>The closed-source route allows me to still release the tool to the public, with proper guardrails to prevent misuse, while keeping it accessible to people who want to use Evilginx to learn hands-on how MFA is bypassed in phishing engagements.</p><p>I don&apos;t feel that open source is the proper delivery method for offensive security tooling anymore.</p><p>The AI has completely reshaped the open-source ecosystem. Writing code is no longer dark magic; it is more accessible than ever, but it has also introduced the cancer we will have to learn to live with.</p><p>I use AI to generate small helper libraries, while the rest of the Evilginx code is written by hand. Not because I reject the new AI-oriented reality we live in, but because I really enjoy programming. My love of programming brought me to this point in life.</p><p>I also enjoy the concept of ownership. By releasing your work into the world, you let everyone know that you made it, that you personally vouch for its quality, and that you own any mistakes you make. This is what builds trust and reputation.</p><p>With AI-generated software, there is neither.</p><p><em>- Kuba</em></p><p><em>P.S. I refrained from using an LLM to correct this post to avoid adding to the irony of the matter.</em></p><hr><h3 id="references">References:</h3><figure class="kg-card kg-bookmark-card"><a class="kg-bookmark-container" href="https://blog.cloudflare.com/vinext/"><div class="kg-bookmark-content"><div class="kg-bookmark-title">How we rebuilt Next.js with AI in one week</div><div class="kg-bookmark-description">One engineer used AI to rebuild Next.js on Vite in a week. vinext builds up to 4x faster, produces 57% smaller bundles, and deploys to Cloudflare Workers with a single command.</div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="https://blog.cloudflare.com/images/favicon-32x32.png" alt="Open source is dying."><span class="kg-bookmark-author">The Cloudflare Blog</span><span class="kg-bookmark-publisher">Steve Faulkner</span></div></div><div class="kg-bookmark-thumbnail"><img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/720QQcrdICiSJXrr9VoixA/4934fffd05d1ca10cc661238b381308e/BLOG-3194_OG.png" alt="Open source is dying."></div></a></figure><figure class="kg-card kg-bookmark-card"><a class="kg-bookmark-container" href="https://www.microsoft.com/en-us/security/blog/2025/05/27/new-russia-affiliated-actor-void-blizzard-targets-critical-sectors-for-espionage/"><div class="kg-bookmark-content"><div class="kg-bookmark-title">New Russia-affiliated actor Void Blizzard targets critical sectors for espionage | Microsoft Security Blog</div><div class="kg-bookmark-description">Microsoft Threat Intelligence has discovered a cluster of worldwide cloud abuse activity conducted by a threat actor we track as Void Blizzard, who we assess with high confidence is Russia-affiliated and has been active since at least April 2024. Void Blizzard&#x2019;s cyberespionage operations tend to be&#x2026;</div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="https://www.microsoft.com/favicon.ico" alt="Open source is dying."><span class="kg-bookmark-author">Microsoft Security Blog</span><span class="kg-bookmark-publisher">Microsoft Threat Intelligence</span></div></div><div class="kg-bookmark-thumbnail"><img src="https://www.microsoft.com/en-us/security/blog/wp-content/uploads/2025/05/Void-Blizzard-social.png" alt="Open source is dying."></div></a></figure><p><a href="https://x.com/lcamtuf/status/2029771844975501382">https://x.com/lcamtuf/status/2029771844975501382</a></p>]]></content:encoded></item><item><title><![CDATA[Evilginx Pro 4.3 - Event Notifications & Proxies Overhaul]]></title><description><![CDATA[The newest 4.3 update delivers real-time event notifications, an overhaul of the tunnelling proxy system and a new CSS canary token evasion.]]></description><link>https://breakdev.org/evilginx-pro-4-3/</link><guid isPermaLink="false">6926ff4ed22a533d0a902cd6</guid><category><![CDATA[evilginx]]></category><category><![CDATA[phishing]]></category><category><![CDATA[update]]></category><dc:creator><![CDATA[Kuba Gretzky]]></dc:creator><pubDate>Wed, 26 Nov 2025 15:53:11 GMT</pubDate><media:content url="https://breakdev.org/content/images/2025/11/evilginx-pro-43-update.png" medium="image"/><content:encoded><![CDATA[<img src="https://breakdev.org/content/images/2025/11/evilginx-pro-43-update.png" alt="Evilginx Pro 4.3 - Event Notifications &amp; Proxies Overhaul"><p>I&apos;m proud to announce that another major update to <strong>Evilginx Pro</strong> has just been released!</p><p>This update includes multiple bug fixes and introduces new features that were heavily requested. I strongly hope you will make great use of them!</p><p>This time, I&apos;ve finished documenting the new features beforehand, and the guides are already available in the <a href="https://help.evilginx.com">online documentation</a>.</p><p>Let&apos;s dive in!</p><h2 id="new-features">New Features</h2><p>Here are the highlights of this update:</p><h3 id="event-notifications">Event Notifications</h3><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://breakdev.org/content/images/2025/11/notify-demo.gif" class="kg-image" alt="Evilginx Pro 4.3 - Event Notifications &amp; Proxies Overhaul" loading="lazy" width="1200" height="600" srcset="https://breakdev.org/content/images/size/w600/2025/11/notify-demo.gif 600w, https://breakdev.org/content/images/size/w1000/2025/11/notify-demo.gif 1000w, https://breakdev.org/content/images/2025/11/notify-demo.gif 1200w" sizes="(min-width: 720px) 720px"><figcaption>Event notifications DEMO</figcaption></figure><p>This feature has been requested for a long time. The <strong>4.3</strong> update introduces real-time notifications, which can trigger for the following events in Evilginx:</p><ul><li>Lure URL was clicked.</li><li>The visitor passed Botguard validation and arrived at the phishing page.</li><li>Credential was captured.</li><li>Session tokens were captured.</li></ul><p>Notifications can be sent via <a href="https://slack.com/">Slack</a> messages, <a href="https://pushover.net/">Pushover</a> push notifications, or the most versatile option: <strong>webhook requests</strong> in JSON format.</p><p>Webhook event notifications allow you to use the data captured by Evilginx to build your own custom tooling. It will enable you to receive captured data in real time.</p><p>Use the retrieved data to generate phishing engagement reports or for lateral movement using the captured credentials and session tokens.</p><p>All that is required is an HTTP/HTTPS server written in Python, Go, or any other language you are comfortable with. The event data will be sent from the Evilginx server in JSON format as an HTTP request to the URL of your choosing.</p><p>You can find the complete documentation with usage examples in the official documentation:</p><div class="kg-card kg-button-card kg-align-center"><a href="https://help.evilginx.com/pro/usage/notify" class="kg-btn kg-btn-accent">Read the Event Notification documentation</a></div><h3 id="tunnelling-proxies">Tunnelling Proxies</h3><p>The proxy feature has been left abandoned for quite some time, and it badly needed an update.</p><p>A few months ago, I realised the JA4 signature spoofing would stop working when routing Evilginx connections through a proxy. Since I had to fix how the proxies are implemented in <strong>Evilginx Pro</strong>, I decided to give the feature a complete overhaul.</p><p>The tunnelling proxy overhaul now allows you to manage multiple proxy servers on a single server and assign them to route connections server-wide, only for specific phishlets, or only to particular lures.</p><p>These options should provide enough flexibility to evade geolocation-based access controls and prevent CAPTCHA prompts when connections are routed through particular countries during your phishing engagements.</p><p>You can find the complete documentation with usage examples in the official documentation:</p><div class="kg-card kg-button-card kg-align-center"><a href="https://help.evilginx.com/pro/usage/proxy" class="kg-btn kg-btn-accent">Read the Tunnelling Proxies documentation</a></div><h3 id="improved-css-canary-token-evasion">Improved CSS canary token evasion</h3><p>Thanks to <a href="https://x.com/rad9800">Rad Kawar</a> (check out his new tool <a href="https://deceptiq.com/">Deceptiq</a>!), I was informed that CSS canary tokens made by <a href="https://canary.tools/">Thinkst Canary</a> added a bit of obfuscation to the <code>url(...)</code> block, through escaping random characters with hex values, like:</p><figure class="kg-card kg-code-card"><pre><code class="language-css">body {
    background: url(&apos;abcdefg.\63loudfr\6fnt\2enet/012345/cGhpc2guZG9tYWluLmNvbQ%3D%3D/img.gif&apos;) !important;
}</code></pre><figcaption>Escaped URL pointing to the canary token</figcaption></figure><p>Here is the function, which handles the generation of escaped canary token URLs:</p><figure class="kg-card kg-image-card"><img src="https://breakdev.org/content/images/2025/11/image.png" class="kg-image" alt="Evilginx Pro 4.3 - Event Notifications &amp; Proxies Overhaul" loading="lazy" width="1886" height="1272" srcset="https://breakdev.org/content/images/size/w600/2025/11/image.png 600w, https://breakdev.org/content/images/size/w1000/2025/11/image.png 1000w, https://breakdev.org/content/images/size/w1600/2025/11/image.png 1600w, https://breakdev.org/content/images/2025/11/image.png 1886w" sizes="(min-width: 720px) 720px"></figure><p>The randomly escaped string would pretty effectively fool string rewriting implemented in phishlets, which looked for a string <code>.cloudfront.net</code> to replace it with something else to prevent the canary token from calling home:</p><figure class="kg-card kg-code-card"><pre><code class="language-yaml">sub_filters:
  - {triggers_on: &apos;aadcdn.msftauthimages.net&apos;, orig_sub: &apos;aadcdn&apos;, domain: &apos;msftauthimages.net&apos;, search: &apos;\.cloudfront\.net&apos;, replace: &apos;.nowhere.local&apos;, mimes: [&apos;text/css&apos;]} # disable canary tokens loaded from .cloudfront.net domain</code></pre><figcaption>String filtering in a phishlet</figcaption></figure><p>The Pro version in the <strong>4.3</strong> update will now detect all URLs in proxied CSS files, including the &quot;obfuscated&quot; (escaped) ones, which may carry canary tokens, and it will unescape them, so that you can freely replace them with <code>sub_filters</code>.</p><h3 id="other-improvements">Other improvements</h3><p>There are multiple quality-of-life improvements included with this update, including:</p><ul><li>Ability to uninstall servers with <code>servers uninstall</code> command.</li><li>Lure ID is now visible in the list of captured sessions, so you know which session originated from which lure.</li><li>Phishlets now support a <code>port</code> parameter in <code>proxy_hosts</code> entries, allowing you to target websites hosted on ports other than the standard TCP <code>443</code>.</li><li>Fixed server deployment for the latest versions of Debian and Ubuntu. The deployments will now work correctly for systems running the new <code>sysctl</code> version, which reads configuration files from the <code>/etc/sysctl.d/</code> directory.</li><li>The Gophish click event no longer triggers on URL clicks. Instead, it triggers once Botguard validates the connection and after the redirector redirects to the phishing page.</li></ul><p>Check out the complete changelog below:</p><div class="kg-card kg-button-card kg-align-center"><a href="https://help.evilginx.com/pro/changelog#430-2025-11-26" class="kg-btn kg-btn-accent">Evilginx Pro 4.3 - CHANGELOG</a></div><h2 id="closing-thoughts">Closing thoughts</h2><p>I strongly hope you enjoy this update, and the new event notifications feature allows you to create epic custom tooling integrated with your Evilginx phishing campaigns.</p><p>The next thing I&apos;ll be working on is the new <strong>Phishlets V2</strong> format, which is long overdue. The work has already started, and I have big plans to overhaul Evilginx to become an extremely versatile reverse proxy tool.</p><p>Another project I&apos;ve started looking into is how Evilginx phishing links can be hosted on a CDN. Stay tuned for that, as I may release a quick blog post about it once I figure out a working setup.</p><p>If you haven&apos;t already, make sure to apply and join our <a href="https://red.breakdev.org/join">BREAKDEV RED community for red teamers</a>. Our secure Discord server is a great place to discuss everything related to cybersecurity, and I&apos;d love to see you there!</p><p>If you&apos;re already using <strong><strong>Evilginx Pro </strong></strong>and would like something improved or added, feel free to let me know <a href>via email</a>, Twitter <a href="https://x.com/mrgretzky">@mrgretzky,</a> or <a href="https://www.linkedin.com/in/kubagretzky/">LinkedIn</a>.</p><p>Happy phishing! &#x1FA9D;&#x1F41F;</p><div class="kg-card kg-button-card kg-align-center"><a href="https://evilginx.com" class="kg-btn kg-btn-accent">Learn more about Evilginx Pro</a></div>]]></content:encoded></item><item><title><![CDATA[Evilginx Pro 4.2 - Anti-phishing evasions and more!]]></title><description><![CDATA[The latest update includes a complete proxy engine rewrite, new anti-phishing evasions, added support for new DNS providers, custom hostnames for lure URLs, better Gophish integration and more!]]></description><link>https://breakdev.org/evilginx-pro-4-2/</link><guid isPermaLink="false">68876f70d22a533d0a901f3e</guid><category><![CDATA[evilginx]]></category><category><![CDATA[phishing]]></category><category><![CDATA[update]]></category><dc:creator><![CDATA[Kuba Gretzky]]></dc:creator><pubDate>Thu, 14 Aug 2025 11:04:51 GMT</pubDate><media:content url="https://breakdev.org/content/images/2025/08/evilginx-pro-42-update.png" medium="image"/><content:encoded><![CDATA[<img src="https://breakdev.org/content/images/2025/08/evilginx-pro-42-update.png" alt="Evilginx Pro 4.2 - Anti-phishing evasions and more!"><p>It&apos;s been about five months, already, since the release of Evilginx Pro, and I&apos;m proud to release the second major update. This release was hugely influenced by the feedback I received from multiple <a href="https://evilginx.com"><strong>Evilginx Pro</strong></a><strong> </strong>users I met at the <a href="https://www.x33fcon.com/">x33fcon</a> conference, which took place in Gdynia in June 2025. Being able to communicate with you directly to exchange ideas and learn how you use the tool gives me confidence that I&apos;m moving in the right direction with the implementation of new features.</p><div class="kg-card kg-button-card kg-align-center"><a href="https://evilginx.com" class="kg-btn kg-btn-accent">Click here to learn more about Evilginx Pro</a></div><p>At <strong>x33fcon</strong> this year, I also had the opportunity to give a talk about the various anti-phishing techniques I&apos;ve come across in recent years and how an attacker would approach to evade them. The video of the talk can be found below:</p><figure class="kg-card kg-embed-card kg-card-hascaption"><iframe width="200" height="113" src="https://www.youtube.com/embed/cFd_glOusLo?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen title="9. Kuba Gretzky: Wise Phishermen Never Trust The Weather"></iframe><figcaption>Wise Phishermen Never Trust the Weather - Kuba Gretzky @ x33fcon 2025</figcaption></figure><p>I&apos;ve recently released the <a href="https://help.evilginx.com/pro/changelog#420-2025-07-18">4.2 update</a> for <a href="https://evilginx.com"><strong>Evilginx Pro</strong></a><strong> </strong>and thought it would be a good idea to share what&apos;s new and how to use the latest features.</p><p>Without further ado, let&apos;s jump into the changes, starting with the most significant ones.</p><h2 id="proxy-engine-rewrite">Proxy engine rewrite</h2><p>The first and most significant change is the complete rewrite of the proxy engine. Back when I released <a href="https://github.com/kgretzky/evilginx2">Evilginx 2.0</a>, I had only just started learning programming in the Go language. The code quality I produced then was... mediocre at best &#x1F605;. The proxy code residing in <code>http_proxy.go</code> eventually took the form of spaghetti and quickly spiralled out of control. The code worked, but at times caused Evilginx to behave erratically.</p><p>The eight-year-old legacy code made it impossible to add any new features, because even the most minor additions risked causing the whole proxy logic to crumble like a Jenga tower. Since this part of the code became the core of Evilginx, I was pretty reluctant to touch it, in order not to break the tool&apos;s main functionality. With the release of <strong>Evilginx Pro, </strong>it became clear that the time had come for a complete rewrite.</p><p>The proxy engine rewrite was introduced with <strong>Evilginx Pro </strong>version <a href="https://help.evilginx.com/pro/changelog#410-2025-04-30">4.1</a>. All of the proxy components now work together much more reliably, and most importantly, the proxy code is now ready to give more power to the users who&apos;d like to have complete control over the live modification of HTTP packets in transit. Full use of these changes will be made when <strong>Phishlets 4.0 </strong>format is released in future updates.</p><p><strong>Phishlets 4.0</strong> <em>(not yet available)</em> will allow you to:</p><ul><li>Capture data from the request &amp; response HTTP headers.</li><li>Capture data from the request &amp; response HTTP content body.</li><li>Inject custom headers into HTTP requests &amp; responses.</li><li>Modify the values of the request &amp; response HTTP headers.</li><li>Modify the content body in HTTP requests &amp; responses.</li></ul><p>Additionally, here are the most notable tweaks introduced with the proxy engine rewrite:</p><h3 id="improved-html-injection">Improved HTML injection</h3><p>Evilginx, from the beginning, has utilised string pattern recognition to identify suitable locations for injecting its meta tags or JavaScript code blocks into proxied HTML content. This approach was very error-prone, as regular expressions would sometimes miss the pattern detection, resulting in crucial injections being omitted.</p><p>After the changes, Evilginx will now correctly parse the whole structure of the HTML document, looking for the specific object types. When performing the injection, rather than inserting a string into the HTML code, it will generate a new HTML object, which will later get properly formatted when the HTML content is rendered to a string.</p><p>This change now allows you to select the location where you&apos;d like to inject your JavaScript <code>js_inject</code> injects.</p><pre><code class="language-yaml">js_inject:
  - trigger_domains: [&quot;login.microsoftonline.com&quot;]
    trigger_paths: [&quot;.*&quot;]
    location: &quot;&lt;location_string&gt;&quot;
</code></pre><p>Where the <code>&lt;location_string&gt;</code> can be one of the following:</p><!--kg-card-begin: markdown--><table>
<thead>
<tr>
<th>Location</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>head</code></td>
<td>Inject at the end of the <code>&lt;head&gt;</code> tag.</td>
</tr>
<tr>
<td><code>body_top</code></td>
<td>Inject at the beginning of the <code>&lt;body&gt;</code> tag.</td>
</tr>
<tr>
<td><code>body_bottom</code></td>
<td>Inject at the end of the <code>&lt;body&gt;</code> tag.</td>
</tr>
</tbody>
</table>
<!--kg-card-end: markdown--><h3 id="phishlet-collision-fixes">Phishlet collision fixes</h3><p>One of the fixes, which needs mentioning, is the fix when handling multiple active phishlets which target the same destination hostnames.</p><p>Let&apos;s say you have two phishlets <code>phishlet1</code> and <code>phishlet2</code>. Both of them have the same hostname defined in <code>proxy_hosts</code>. Evilginx now allows you to enable both phishlets as it will now recognise the target hostname based on the defined phishlet&apos;s hostname, rather than the target hostname.</p><h3 id="redirector-fixes">Redirector fixes</h3><p>If you had a redirector set up for your lure and you generated the lure URL with embedded custom parameters, Evilginx would lose the custom parameters and fail to forward them when the redirector redirected to the phishing page. The forwarding of custom parameters is now fixed, allowing you to use redirectors to their full potential.</p><h2 id="anti-phishing-evasion">Anti-phishing evasion</h2><p>One of the most prominent features, released in update <a href="https://help.evilginx.com/pro/changelog#410-2025-04-30">4.1</a>, was the option in phishlets to rewrite URL paths. Rewriting URL paths, while reverse proxying website content, allows you to protect your phishing pages from URL path pattern detection implemented by Google Chrome Safe Browsing protection.</p><p>Keep in mind that the following information is entirely speculative and the conclusion is based on my trial &amp; error testing, rather than on reverse engineering the code of the detection engine.</p><p>If you reverse proxy the Google sign-in page and Safe Browsing kicks in, it will try to match the URL path and URL query to one of its known patterns. As an example, Safe Browsing will see the following phishing URL:</p><pre><code>https://accounts.phishing.com/v3/signin/identifier?followup=https%3A%2F%2Faccounts.google.com%2F&amp;ifkv=ABCD01234&amp;passive=0123456789&amp;flowName=GlifWebSignIn&amp;flowEntry=ServiceLogin&amp;dsh=XYZXYZ1234</code></pre><p>It will first detect the URL path, which it marks as the known URL path for the Google sign-in page: <code>/v3/signin/identifier</code></p><p>Then it will try to match the keys and values of the URL query to look for known patterns. The keys it may match are as follows: <code>followup</code>, <code>ifkv</code>, <code>passive</code>, <code>flowName</code>, <code>flowEntry</code> or <code>dsh</code>.</p><p>Once it determines that the page, based on the URL path &amp; query, must be the Google sign-in page, it will check the website&apos;s domain. That&apos;s when it will see <code>phishing.com</code>, instead of <code>google.com</code> and detection will be triggered.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://breakdev.org/content/images/2025/07/chrome_warning.png" class="kg-image" alt="Evilginx Pro 4.2 - Anti-phishing evasions and more!" loading="lazy" width="850" height="611" srcset="https://breakdev.org/content/images/size/w600/2025/07/chrome_warning.png 600w, https://breakdev.org/content/images/2025/07/chrome_warning.png 850w" sizes="(min-width: 720px) 720px"><figcaption>Google Chrome Safe Browsing triggering the detection of the phishing page.</figcaption></figure><p>What I managed to figure out is that when the reverse proxy rewrites the URL path and modifies the URL query of the requests, Safe Browsing will have trouble detecting the phishing page, even with <strong>Enhanced protection turned on </strong>(it allegedly uses AI, so you know it must be good &#x1F609;).</p><p>That&apos;s where the new <code>rewrite_urls</code> feature comes in, exclusive to <a href="https://evilginx.com">Evilginx Pro</a>. We will now analyse the rewrite URL rules in the phishlet created to proxy the Microsoft 365 sign-in page:</p><pre><code class="language-yaml">rewrite_urls:
  - trigger:
        domains: [&apos;login.microsoftonline.com&apos;]
        paths: [&apos;/common/oauth2/v2.0/authorize&apos;]
    rewrite:
        path: &apos;/signin&apos;
        query:
          - key: &apos;boop&apos;
            value: &apos;{id}&apos;
        exclude_keys: [&apos;client_id&apos;]</code></pre><p>The MS365 sign-in page for our following example has the following URL:</p><figure class="kg-card kg-code-card"><pre><code>https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=4765445b-32c6-49b0-83e6-1d93765276ca&amp;response_type=code%20id_token&amp;scope=openid%20profile%20https%3A%2F%2Fwww.office.com%2Fv2%2FOfficeHome.All&amp;response_mode=form_post&amp;nonce=XXXYYYZZZ&amp;client-request-id=f4978b5c-2855-46a9-9d58-18c850118fc5&amp;state=ABCDEF0123</code></pre><figcaption>Forwarded URL, which triggers the phishlet&apos;s URL rewrite rule</figcaption></figure><p>Once the phishing link is opened in the browser, <strong>Evilginx Pro </strong>will attempt to proxy the URL above to display its contents to the user, and the phishlet&apos;s rewrite URL rules will trigger.</p><p>The proxy engine will detect a forwarded request to the URL with the hostname <code>login.microsoftonline.com</code> and URL path <code>/common/oauth2/v2.0/authorize</code>. Evilginx will then generate a new, rewritten URL and return it in the <code>Location</code> header of an HTTP 302 redirection response to redirect the user&apos;s browser:</p><figure class="kg-card kg-code-card"><pre><code>https://login.phishing.com/signin?client_id=4765445b-32c6-49b0-83e6-1d93765276ca&amp;boop=123456789</code></pre><figcaption>Dynamically generated rewritten URL, the web browser is redirected to</figcaption></figure><p>The proxy engine will also map the generated URL to the original URL that served as a trigger for the URL rewrite. Once the user&apos;s web browser switches to the rewritten URL, the new HTTP request will be sent to the rewritten URL.</p><p>When Evilginx receives the request, it sees that the provided URL is mapped to the previously cached URL, which triggered the rewrite URL rule and the URL the proxy forwards the request to is replaced with it. That way, Evilginx can seamlessly forward the spoofed URL, converting it to the legitimate one in real-time.</p><p>The <code>rewrite:path</code> value dictates the URL path that the proxy will redirect to. The <code>rewrite:query</code> includes the query keys with values, which will be added to the URL. <strong>At least one </strong>of the injected query parameters must contain the placeholder <code>{id}</code> within its <code>rewrite:query:value</code> field. It does not have to match exactly a string <code>{id}</code>, but it can also be combined with another string, e.g. <code>something-{id}-token</code>.</p><p>The <code>rewrite:exclude_keys</code> array contains the names of keys that Evilginx will preserve, preventing them from being rewritten. You can see in the example above that the generated rewritten URL preserved the key <code>client_id</code> with its original value. Some websites use JavaScript to access GET query parameters from the URL address bar. Removing these parameters may break the website&apos;s functionality. You need to verify yourself if the website starts acting up when GET parameters are removed. Of course, preventing too many GET parameters from being rewritten may result in pattern matching triggering detections, so use this with caution.</p><h2 id="dns-providers">DNS providers</h2><p>Update <a href="https://help.evilginx.com/pro/changelog#420-2025-07-18">4.2</a> expands on the number of DNS providers supported by <strong>Evilginx Pro</strong>. The tool now allows for automatic management of DNS records for the following providers:</p><ul><li>Route53 (AWS)</li><li>Cloudflare</li><li>Gandi.net</li></ul><p>For demonstration purposes, let&apos;s go through the process of setting up the <strong>Route53 </strong>DNS provider from AWS.</p><h3 id="how-to-configure-the-route53-dns-provider-with-evilginx-pro">How to configure the Route53 DNS provider with Evilginx Pro?</h3><p>At this point, I assume you already have an AWS account with access to the admin dashboard. The first step is to create a new user for managing DNS records on Route53 via <a href="https://console.aws.amazon.com/iam/">Identity and Access Management (IAM)</a>.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://breakdev.org/content/images/2025/07/SeH5BmjLu8.png" class="kg-image" alt="Evilginx Pro 4.2 - Anti-phishing evasions and more!" loading="lazy" width="1246" height="660" srcset="https://breakdev.org/content/images/size/w600/2025/07/SeH5BmjLu8.png 600w, https://breakdev.org/content/images/size/w1000/2025/07/SeH5BmjLu8.png 1000w, https://breakdev.org/content/images/2025/07/SeH5BmjLu8.png 1246w" sizes="(min-width: 720px) 720px"><figcaption>Create a new user via IAM</figcaption></figure><p>Once you pick the user name, you will be asked to specify the permissions for the created user. Since we want the user to have full access to Route53 domain management, select <strong>Attach policies directly</strong> and look for <code>AmazonRoute53FullAccess</code> policy name.</p><p>To keep things clean, you can create a group with the mentioned policy and add the user to this group instead.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://breakdev.org/content/images/2025/08/0B4qR480Hz.png" class="kg-image" alt="Evilginx Pro 4.2 - Anti-phishing evasions and more!" loading="lazy" width="998" height="875" srcset="https://breakdev.org/content/images/size/w600/2025/08/0B4qR480Hz.png 600w, https://breakdev.org/content/images/2025/08/0B4qR480Hz.png 998w" sizes="(min-width: 720px) 720px"><figcaption>Set the <code>AmazonRoute53FullAccess</code> permission policy for the created user.</figcaption></figure><p>Once the user is created, we will need to create an access key that will be used to configure <strong>Evilginx Pro </strong>for automatic DNS record management on Route53.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://breakdev.org/content/images/2025/07/Lv4o8OzWQU.png" class="kg-image" alt="Evilginx Pro 4.2 - Anti-phishing evasions and more!" loading="lazy" width="874" height="380" srcset="https://breakdev.org/content/images/size/w600/2025/07/Lv4o8OzWQU.png 600w, https://breakdev.org/content/images/2025/07/Lv4o8OzWQU.png 874w" sizes="(min-width: 720px) 720px"><figcaption>Create an access key for use with Evilginx Pro.</figcaption></figure><p>When asked to provide the use case, pick <code>Other</code>.</p><p>With the access key created, you will need to copy the <strong>Access key </strong>and <strong>Secret access key </strong>and store them in a safe place, preferably in a <a href="https://keepassxc.org/">password manager</a>. These keys will need to be entered to configure the Route53 DNS provider in <strong>Evilginx Pro</strong>.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://breakdev.org/content/images/2025/07/22wKdbRiMG.png" class="kg-image" alt="Evilginx Pro 4.2 - Anti-phishing evasions and more!" loading="lazy" width="942" height="299" srcset="https://breakdev.org/content/images/size/w600/2025/07/22wKdbRiMG.png 600w, https://breakdev.org/content/images/2025/07/22wKdbRiMG.png 942w" sizes="(min-width: 720px) 720px"><figcaption>Copy and securely store your access keys.</figcaption></figure><p>Now that you have created the access keys for Route 53 domain management, go to your <a href="https://console.aws.amazon.com/route53/v2/hostedzones">Route 53 dashboard</a>, open the <strong>Hosted Zones </strong>management panel and create a new hosted zone.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://breakdev.org/content/images/2025/07/tDxg2awFfy-3.png" class="kg-image" alt="Evilginx Pro 4.2 - Anti-phishing evasions and more!" loading="lazy" width="1247" height="271" srcset="https://breakdev.org/content/images/size/w600/2025/07/tDxg2awFfy-3.png 600w, https://breakdev.org/content/images/size/w1000/2025/07/tDxg2awFfy-3.png 1000w, https://breakdev.org/content/images/2025/07/tDxg2awFfy-3.png 1247w" sizes="(min-width: 720px) 720px"><figcaption>Create a new hosted zone.</figcaption></figure><p>Enter the name of your registered domain and click the <strong>Hosted zone details </strong>dropdown to see the nameservers you need to point your domain registrar to.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://breakdev.org/content/images/2025/07/CpukUTA6bC.png" class="kg-image" alt="Evilginx Pro 4.2 - Anti-phishing evasions and more!" loading="lazy" width="874" height="570" srcset="https://breakdev.org/content/images/size/w600/2025/07/CpukUTA6bC.png 600w, https://breakdev.org/content/images/2025/07/CpukUTA6bC.png 874w" sizes="(min-width: 720px) 720px"><figcaption>Examine the name servers that need to be configured for your domain.</figcaption></figure><p>You will now need to go to your domain registrar, where you purchased the domain, and set up custom nameservers for your domain by entering all of the nameserver hostnames from the list you obtained at Route 53. Keep in mind that DNS propagation worldwide usually takes up to an hour, but may also take up to 72 hours.</p><p>With everything set up, we can use the obtained access keys to configure the DNS providers in <strong>Evilginx Pro</strong>.</p><p>In the <strong>Evilginx Pro </strong>client, connect to the server you want to use the domain we set up with Route 53 and add the domain:</p><pre><code>domains add phishing.com</code></pre><p>Configure the domain to be managed by the Route 53 DNS provider with the generated access keys:</p><pre><code>domains config phishing.com route53 access_key_id=&lt;access_key&gt; secret_access_key=&lt;secret_access_key&gt;</code></pre><p>Once this is done, you can test if everything worked by typing:</p><pre><code>domains list phishing.com</code></pre><p>You should see the list of all of your DNS records obtained through the DNS provider. If there is an error, please investigate the error message and use it for troubleshooting. The most likely issue would be that you&apos;re using the access key for an account with insufficient permissions.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://breakdev.org/content/images/2025/08/s9TIRgpSe2.png" class="kg-image" alt="Evilginx Pro 4.2 - Anti-phishing evasions and more!" loading="lazy" width="1739" height="963" srcset="https://breakdev.org/content/images/size/w600/2025/08/s9TIRgpSe2.png 600w, https://breakdev.org/content/images/size/w1000/2025/08/s9TIRgpSe2.png 1000w, https://breakdev.org/content/images/size/w1600/2025/08/s9TIRgpSe2.png 1600w, https://breakdev.org/content/images/2025/08/s9TIRgpSe2.png 1739w" sizes="(min-width: 720px) 720px"><figcaption>Add a domain and configure it with Route 53 DNS provider.</figcaption></figure><p>If you prefer to use Cloudflare as the DNS provider for your domain, follow the same steps:</p><ul><li>Onboard your domain on Cloudflare</li><li>Obtain the Cloudflare name servers and set them for your domain in your domain registrar admin panel.</li></ul><p>You will need to <a href="https://developers.cloudflare.com/fundamentals/api/get-started/create-token/">create the Cloudflare API token</a> to use with <strong>Evilginx Pro</strong>. Set it up later in the client with the command:</p><pre><code>domains config &lt;domain&gt; cloudflare api_token=&lt;api_token&gt;</code></pre><h2 id="lures">Lures</h2><h3 id="custom-hostnames-for-lure-urls-are-back">Custom hostnames for Lure URLs are back</h3><p>In version <strong>4.1</strong>,<strong> </strong>I have removed the ability to configure custom hostnames for lure URLs. I made this decision due to issues with Evilginx proxy session management, through cookies stored for specific phishlet hostnames. The problems became apparent when the lure URL hostname had an entirely different hostname suffix than the hostname configured for the particular phishlet.</p><p>Suddenly, Evilginx had to manage TLS certificates for an entirely different hostname (since wildcard certificates work only for a subdomain one level up), and cookies to manage Evilginx proxy sessions had to be set for multiple domains, to recognise the same visitor across redirects. Since web browsers do not allow web servers to set cookies for a different domain than the domain of the server responding to the request, additional effort would have to be made to redirect between hostnames with one-shot tokens sent through GET query parameters. I did not want to overcomplicate this process.</p><p>As for version <strong>4.2</strong>, the customisable hostnames for lure URLs are back, although in a more simplified form. What Evilginx allows you to do now is only customise the first subdomain of the lure hostname.</p><p>For example, if you had your Google phishlet hostname set to <code>notgoogle.phishing.com</code>, the lure URL hostname would become <code>accounts.notgoogle.phishing.com</code>, since the primary sign-in subdomain for that phishlet is hardcoded to be <code>accounts</code>. Now you can change the subdomain prefix to be anything you want:</p><pre><code>lures set &lt;id&gt; hostname www.notgoogle.phishing.com</code></pre><p>This will change the lure hostname to <code>www.notgoogle.phishing.com</code>. You can pick any hostname you want as long as you only change the top subdomain of the phishlet&apos;s hostname. The hostname needs to end with <code>notgoogle.phishing.com</code> in this example.</p><p>I also added a feature in <strong>version 4.2</strong>, which was not available in previous versions of Evilginx. You can now specify an <em>empty </em>subdomain for your lure URL hostname. This is extremely helpful if you want your phishing URL hostname to consist entirely of your domain name.</p><p>First, you need to set your phishlet&apos;s hostname to your top-level domain name:</p><pre><code>phishlets set &lt;phishlet_name&gt; hostname phishing.com</code></pre><p>Your Google phishlet&apos;s lure URL hostname would become <code>accounts.phishing.com</code>, so we need to remove the subdomain with:</p><pre><code>lures set &lt;id&gt; hostname phishing.com</code></pre><p>Now your lure URL hostname will become your top-level domain name and will look similar to this:</p><pre><code>https://phishing.com/whatever/path/you/want.pdf</code></pre><h3 id="custom-url-queries-are-now-allowed">Custom URL queries are now allowed</h3><p>Another addition in <strong>4.2 </strong>is the ability to set up custom URL query parameters for your lure URLs. This was not possible before, as Evilginx would strip the URL queries from the customised lure URL path.</p><p>You can now add your own URL query parameters (like <code>archType=x64</code>) to make your lures better fit your social engineering pretext, thus making them more believable:</p><pre><code>lures set &lt;id&gt; path /client/6.5.9.11873/ZoomInstallerFull.exe?archType=x64</code></pre><h3 id="custom-parameters-can-now-be-encrypted">Custom parameters can now be encrypted</h3><p>Evilginx allows passing custom parameters through lure URLs. These parameters are encoded with base64 and embedded as a GET query parameter within the generated lure URLs. The following command allows for embedding custom parameters <code>email</code> and <code>from_name</code> in your lure URL:</p><pre><code>lures get-url &lt;id&gt; email=target@email.com from_name=Kuba</code></pre><p>This will generate the following URL:</p><pre><code>https://phishing.com/documents/Annual_Bonus_Report_2025.pdf?yui=dK-1zTbo6N5Bg9RYqI1QxahXeyIsHVPvKk87oDmFLKIm8hTWbMABxPynIVBaY1imev4mAkf4aRV-Yh4E4MwOKg</code></pre><p>The custom parameters can be used to customise the HTML content of your Redirectors, or they can be used in your <code>js_inject</code> JavaScript injects. Custom parameters are also used internally by the custom <a href="https://github.com/kgretzky/gophish">Gophish integration</a> for Evilginx.</p><p>Until now, the value <code>dK-1zTbo6N5Bg9RYqI1QxahXeyIsHVPvKk87oDmFLKIm8hTWbMABxPynIVBaY1imev4mAkf4aRV-Yh4E4MwOKg</code> could have been decoded by anyone who knew how, as Evilginx has never used encryption to protect the contents of the passed custom parameters. The source code for encoding custom parameters is publicly available, and I&apos;m pretty sure that defenders have already discovered how to utilise custom parameter decoding for phishing URL detection. If you enumerate all GET parameter values of the URL and find one that can be successfully decoded, you can be 100% sure the link was generated with Evilginx.</p><p>Changes in <strong>Evilginx Pro </strong>version <strong>4.2 </strong>now include an option to use AES-256 encryption, protecting your custom parameters embedded within generated lure URLs.</p><p>The only thing you need to do is configure the encryption key on your <strong>Evilginx Pro </strong>server with:</p><pre><code>config enc_key your-custom-encryption-passphrase</code></pre><p>Leaving the <code>enc_key</code> config option empty will use the previous method of encoding, which anyone can decode.</p><p>This change significantly impacts the <a href="https://github.com/kgretzky/gophish">Gophish integration</a> for Evilginx, which also had to be updated, as covered in the next section.</p><h2 id="gophish-integration">Gophish integration</h2><pre><code>[x] Gophish: Added an option to submit captured credentials to the Gophish server. Configure with command: `config gophish submit_credentials &lt;true/false&gt;`
[x] Gophish: Added an option to send the SHA256 hash of the captured password to the Gophish server instead of the clear text version. Configure with command: `config gophish hash_passwords &lt;true/false&gt;`
</code></pre><p>The <a href="https://github.com/kgretzky/gophish">Gophish integration</a> for Evilginx was updated to version <strong><a href="https://github.com/kgretzky/gophish/releases/tag/v0.12.2">0.12.2</a> </strong>from version <strong>0.12.1</strong>. This update introduces the encryption key support for custom parameters. If you configured <code>enc_key</code> on your <strong>Evilginx Pro </strong>server, you <strong>MUST</strong> enter the passphrase in the <strong>Lure Encryption Key </strong>field when creating a new Gophish campaign.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://breakdev.org/content/images/2025/08/5WANml4xoP.png" class="kg-image" alt="Evilginx Pro 4.2 - Anti-phishing evasions and more!" loading="lazy" width="746" height="450" srcset="https://breakdev.org/content/images/size/w600/2025/08/5WANml4xoP.png 600w, https://breakdev.org/content/images/2025/08/5WANml4xoP.png 746w" sizes="(min-width: 720px) 720px"><figcaption>Lure Encryption Key added to Gophish create campaign dialog.</figcaption></figure><p>You can also now use Lure URLs in Gophish with predefined GET query parameters or with your own custom parameters you want to pass to your Redirectors or JavaScript injects. Gophish will properly repackage the Lure URL with added Gophish-specific parameters for campaign tracking.</p><h3 id="send-captured-credentials-to-gophish">Send captured credentials to Gophish</h3><p>The long-requested feature has finally arrived in <strong>4.2</strong>. <strong>Evilginx Pro </strong>can now send the captured credentials to the Gophish instance. This feature is turned off by default due to security reasons. You can enable it on your server with the command:</p><pre><code>config gophish submit_credentials true</code></pre><p>If you prefer not to send the captured passwords in clear-text, you can opt for a more secure option to send an SHA-256 hash of the passwords instead. You can enable this feature with the command (<code>submit_credentials</code> needs to be set to <code>true</code>):</p><pre><code>config gophish hash_passwords true</code></pre><h2 id="phishlets">Phishlets</h2><pre><code>[x] Phishlet&apos;s enabled status can now be determined by looking at the list of `lures` with disabled phishlets being grayed out and enabled ones in color.
[x] Phishlet&apos;s hostname is now visible when listing the configured `lures`.
</code></pre><p>You can now see if the phishlet the lure refers to is disabled or enabled when listing your lures. The lures with a coloured phishlet name are enabled, while the greyed-out ones are not.</p><figure class="kg-card kg-image-card"><img src="https://breakdev.org/content/images/2025/08/npQdCSMIbG.png" class="kg-image" alt="Evilginx Pro 4.2 - Anti-phishing evasions and more!" loading="lazy" width="1481" height="665" srcset="https://breakdev.org/content/images/size/w600/2025/08/npQdCSMIbG.png 600w, https://breakdev.org/content/images/size/w1000/2025/08/npQdCSMIbG.png 1000w, https://breakdev.org/content/images/2025/08/npQdCSMIbG.png 1481w" sizes="(min-width: 720px) 720px"></figure><p>You can now also see the phishlet&apos;s configured hostname directly in the lures list table.</p><p>A minor tweak was added to warn you if the phishlet the lure refers to is disabled when you generate the lure URL:</p><figure class="kg-card kg-image-card"><img src="https://breakdev.org/content/images/2025/08/bd8becb5-6191-411f-80f3-aa01c89be9d3-11.png" class="kg-image" alt="Evilginx Pro 4.2 - Anti-phishing evasions and more!" loading="lazy" width="1432" height="422" srcset="https://breakdev.org/content/images/size/w600/2025/08/bd8becb5-6191-411f-80f3-aa01c89be9d3-11.png 600w, https://breakdev.org/content/images/size/w1000/2025/08/bd8becb5-6191-411f-80f3-aa01c89be9d3-11.png 1000w, https://breakdev.org/content/images/2025/08/bd8becb5-6191-411f-80f3-aa01c89be9d3-11.png 1432w" sizes="(min-width: 720px) 720px"></figure><p>Too many times have I opened the lure URL of a disabled phishlet, trying to figure out what happened when the phishing page would not load.</p><h2 id="javascript-obfuscation">Javascript obfuscation</h2><pre><code>[x] Improved the speed of multi-threaded Javascript obfuscation by increasing the number of concurrent socket connections to the Evilpuppet instance.
[x] Javascript obfuscation level can now be changed with command: `config obfuscation javascript &lt;off/low/medium/high/ultra&gt;`
</code></pre><p>The performance of dynamic JavaScript obfuscation was improved by increasing the number of concurrent socket connections to the Evilpuppet instance.</p><p>You can now also control the intensity of JavaScript obfuscation of proxied web content with the command:</p><pre><code>config obfuscation javascript &lt;off/low/medium/high/ultra&gt;</code></pre><p>The following table explains what each setting does:</p><!--kg-card-begin: markdown--><table>
<thead>
<tr>
<th>Level</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>off</code></td>
<td>Obfuscation completely disabled (<strong>not recommended</strong>).</td>
</tr>
<tr>
<td><code>low</code></td>
<td>Evilginx built-in injected scripts and scripts injected via <code>js_inject</code> through phishlets are obfuscated.</td>
</tr>
<tr>
<td><code>medium</code></td>
<td>Everything above and all scripts inlined within HTML pages are obfuscated. (<strong>recommended</strong>)</td>
</tr>
<tr>
<td><code>high</code></td>
<td>Everything above and all scripts requested through <code>&lt;script src=&apos;...&apos;&gt;&lt;/script&gt;</code> tags are obfuscated.</td>
</tr>
<tr>
<td><code>ultra</code></td>
<td>Everything above and all scripts dynamically generated for HTML obfuscation are obfuscated (may significantly slow down page loads).</td>
</tr>
</tbody>
</table>
<!--kg-card-end: markdown--><p>It is recommended to use the <code>medium</code> option for JavaScript obfuscation as it provides the best balance between speed and the risk of detection.</p><h2 id="fixes">Fixes</h2><p>I&apos;ve finally managed to resolve the infinite redirects issue when triggering lure URLs on conflicting URL paths.</p><p>Let&apos;s say you had your phishing lure URL path defined as <code>/login</code>, and the target&apos;s website sign-in page was also hosted at <code>/login</code> URL path. Once the lure URL was clicked on <code>/login</code> URL path and all BotGuard checks have completed, Evilginx would redirect the visitor to path <code>/login</code> on the same hostname, which is the URL path of the target website&apos;s sign-in page. When the redirect hit, Evilginx would detect <code>/login</code> URL path as the trigger for the phishing lure URL, and it would repeat the cycle. The redirects would continue until the web browser got tired of them, but more importantly, they would prevent the redirection to the sign-in page.</p><p>The temporary fix I released with version <strong>4.1.1 </strong>would make every phishing lure URL trigger <strong>ONLY ONCE </strong>to prevent any lure retriggers in the same proxy session. The drawback was that if the same user clicked the same phishing lure URL again, it would not redirect to the sign-in page at all, since technically the lure URL would work only once. This was not ideal, and I had to come up with a better solution.</p><p>I took advantage of the fact that most of the redirects happen internally through HTTP 301/302 responses. This gave me an opportunity to detect them and add unique GET query markers to the <code>Location</code> header URLs to make them ignored by lure URL triggers.</p><h2 id="other-changes">Other changes</h2><pre><code>[x] Added an option to enable debug output in the server logs for troubleshooting purposes. Configure with command: `config debug &lt;true/false&gt;`
[x] Added support to deploy servers running on Ubuntu 24.10.
</code></pre><p>The other minor changes that were added made it possible to enable debug output on the <strong>Evilginx Pro </strong>server easily. Just type the command:</p><pre><code>config debug true</code></pre><p>Then, after you SSH to your <strong>Evilginx Pro </strong>server, type:</p><pre><code>sudo journalctl -a -u evilginx</code></pre><p>This will allow you to browse the full server log for troubleshooting, which is sometimes very useful when debugging issues with phishlets during the engagements.</p><p>Oh, and you can now use automated deployment with <code>servers deploy</code> command to deploy <strong>Evilginx Pro </strong>servers to servers running on <strong>Ubuntu 24.10 </strong>due to popular demand.</p><h1 id="closing-thoughts">Closing thoughts</h1><p><strong>Evilginx Pro </strong>is currently in the state I envisioned it to be for release. Given the significant time spent on development (and hacking cons) over the past months, sacrifices had to be made. One of the essential sacrifices was the <a href="https://help.evilginx.com">documentation</a>. I wanted to let you know that I am aware the documentation is currently lacking in content (<em>as of August 2025</em>), and it is the next thing on the list I will be addressing. There is obviously no point in releasing new features without letting everyone know about them and how to use them. This blog post is just the first step.</p><p>I have several ideas and modules lined up that I want to work on. Some of them are:</p><ul><li><strong>Evilginx 4.0 CE </strong>- Release the new open-source version with the proxy engine rewrite and the SQLite support to the public.</li><li><strong>Phishlets 4.0 </strong>- Redo the phishlets format with a cleaned-up structure and syntax. Make it easier to create new phishlets and add support for embedding static web page content into the phishlets.</li><li><strong>Evilpuppet for MFA flow automation </strong>- New way to perform phishing attacks, focusing just on reverse proxying the MFA flow. This will probably be a talk I give next year!</li></ul><p>I want to thank all of you for your continued support. &#x2764;&#xFE0F;</p><p>I&apos;m incredibly lucky to be able to do this full time, and it wouldn&apos;t be possible without you giving me the benefit of the doubt.</p><p>If you haven&apos;t already, make sure to apply and join our <a href="https://red.breakdev.org/join">BREAKDEV RED community for red teamers</a>. Our secure Discord server is a great place to discuss everything related to cybersecurity, and I&apos;d love to see you there!</p><p>If you&apos;re already using <strong>Evilginx Pro </strong>and you&apos;d like something improved or added, feel free to let me know <a href="mailto:support@breakdev.org">via email</a>, on Twitter <a href="https://x.com/mrgretzky">@mrgretzky</a> or on <a href="https://www.linkedin.com/in/kubagretzky/">LinkedIn</a>.</p><p>Happy phishing! &#x1FA9D;&#x1F41F;</p><div class="kg-card kg-button-card kg-align-center"><a href="https://evilginx.com" class="kg-btn kg-btn-accent">Click here to learn more about Evilginx Pro</a></div><p><em>P.S. Nothing in this blog post was generated with LLMs. Let&apos;s keep the internet created by humans for humans.</em></p>]]></content:encoded></item><item><title><![CDATA[Evilginx Pro is finally here!]]></title><description><![CDATA[After over two years of development, Evilginx Pro reverse proxy phishing framework for red teams is finally live!]]></description><link>https://breakdev.org/evilginx-pro-release/</link><guid isPermaLink="false">67ced4a7d22a533d0a90194b</guid><category><![CDATA[evilginx]]></category><category><![CDATA[phishing]]></category><category><![CDATA[tool]]></category><dc:creator><![CDATA[Kuba Gretzky]]></dc:creator><pubDate>Wed, 12 Mar 2025 15:00:35 GMT</pubDate><media:content url="https://breakdev.org/content/images/2025/03/evilginx_pro_release_cover.png" medium="image"/><content:encoded><![CDATA[<img src="https://breakdev.org/content/images/2025/03/evilginx_pro_release_cover.png" alt="Evilginx Pro is finally here!"><p>This is it! After over two years of development, countless delays, and hundreds of manual company verifications, concluded with multiple hurdles related to export regulations, <a href="https://evilginx.com"><strong>Evilginx Pro</strong> is finally live!</a></p><p>To celebrate, the <a href="https://academy.breakdev.org/evilginx-mastery?coupon=EVILGINXPRO">Evilginx Mastery</a> course is having a <strong>30% OFF</strong> sale. Use this coupon to redeem a discount: <a href="https://academy.breakdev.org/evilginx-mastery?coupon=EVILGINXPRO">EVILGINXPRO</a>. </p><figure class="kg-card kg-image-card kg-card-hascaption"><a href="https://evilginx.com"><img src="https://breakdev.org/content/images/2025/03/screenshot_window.png" class="kg-image" alt="Evilginx Pro is finally here!" loading="lazy" width="1014" height="710" srcset="https://breakdev.org/content/images/size/w600/2025/03/screenshot_window.png 600w, https://breakdev.org/content/images/size/w1000/2025/03/screenshot_window.png 1000w, https://breakdev.org/content/images/2025/03/screenshot_window.png 1014w" sizes="(min-width: 720px) 720px"></a><figcaption>Evilginx Pro is out!</figcaption></figure><p>The idea to release a professional version of the <a href="https://github.com/kgretzky/evilginx2">Evilginx phishing framework</a> originated several years ago when I developed the first version of Evilpuppet to use a background browser to bypass the latest anti-phishing protections implemented by Google. I strongly wanted to share what I&apos;ve implemented, but I knew releasing this to the public would probably do more harm than good.</p><p>Since then, I&apos;ve met a large number of red teamers. Once I&apos;ve learned what issues they&apos;ve been facing at work, it became clear how hard red teaming has become when relying only on open-source tools, which do not always work as reliably as one would wish. <a href="https://www.linkedin.com/in/marcsmeets/">Marc Smeets</a> from Outflank gave a <a href="https://www.youtube.com/watch?v=JOxnNyduvoA">great talk</a> about this subject at x33fcon last year.</p><p>It has become my top priority to reinvent Evilginx and create a phishing framework which is reliable, easy to use and fast to deploy while solving most of the issues red teams struggled with worldwide.</p><p>At its core, I also wanted the Pro version to drive innovation in anti-phishing defense development by inventing and implementing the most advanced anti-phishing evasions I could to bypass the majority of commonly used protections.</p><p><strong>Evilginx Pro</strong> I&apos;m releasing today is the fruit of a passion I&apos;ve had for a long time in developing offensive security tools for cybersecurity enthusiasts. The journey has just begun, and now that the product is officially released, I can focus on making it even better by implementing all the ideas I&apos;ve planned for it.</p><div class="kg-card kg-button-card kg-align-center"><a href="https://help.evilginx.com/pro/quickstart" class="kg-btn kg-btn-accent">Evilginx Pro Quickstart Guide</a></div><h2 id="how-to-buy-evilginx-pro">How to buy Evilginx Pro?</h2><p>Since <strong>Evilginx Pro</strong> can cause harm when used with malicious intent, my priority has always been to make it only available to vetted red teamers or penetration testers who can prove they work in cybersecurity companies which perform offensive operations with legitimate intent.</p><p>That is why in 2023, I launched the <a href="https://breakdev.org/breakdev-red/">BREAKDEV RED</a> community for red teamers. The community hangs out on a Discord server where every single member is vetted by hand. Every member of the community gains access to the shop where you can purchase <strong>Evilginx Pro</strong>.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://breakdev.org/content/images/2025/03/image.png" class="kg-image" alt="Evilginx Pro is finally here!" loading="lazy" width="1172" height="553" srcset="https://breakdev.org/content/images/size/w600/2025/03/image.png 600w, https://breakdev.org/content/images/size/w1000/2025/03/image.png 1000w, https://breakdev.org/content/images/2025/03/image.png 1172w" sizes="(min-width: 720px) 720px"><figcaption>BREAKDEV RED cybersecurity software shop</figcaption></figure><p>We currently have over <strong>1500 members</strong> from over <strong>260 companies</strong> around the world! Joining the community is and will always be <strong>completely free</strong>!</p><p>If you haven&apos;t joined yet, please do so by clicking the button below and filling out the application form:</p><div class="kg-card kg-button-card kg-align-center"><a href="https://red.breakdev.org/join" class="kg-btn kg-btn-accent">Get Access to Evilginx Pro</a></div><p>After sending your application, please allow some time for us to process your request. Since 2023, I&apos;ve significantly improved the speed of the approval process, but it is still being improved to keep up with the demand.</p><p>Once you get approved and gain access to the community, before you can purchase Evilginx Pro, several requirements will need to be met to comply with the export regulations of dual-use goods.</p><p>I&apos;ve outlined them in the next paragraph.</p><h2 id="reason-for-delayed-launch">Reason for Delayed Launch</h2><p>The official release date was supposed to be February 25th 2025, but as you may&apos;ve <a href="https://evilginx.com/launch-delay">witnessed two weeks ago</a>, I had to pull an emergency break after I&apos;ve been informed by my legal team that the worldwide release of a tool, being a phishing framework, may be not as straight-forward as I expected.</p><p>As some of you may&apos;ve guessed, the primary issue was the export regulations. I was under the impression that if my tool did not <em>&quot;install itself on the external device without the user&apos;s consent&quot;</em>, it could not be considered dual-use and fall under export regulations under the <a href="https://en.wikipedia.org/wiki/Wassenaar_Arrangement">Wassenaar Arrangement</a>. Since I have already been doing the extra verification of all potential buyers with the screening process to join the <a href="https://red.breakdev.org/join">BREAKDEV RED community</a>, I thought it was enough. I was wrong, and I take full responsibility for the delay.</p><p>Now, the good news is that, after two weeks of hard work, the top-notch legal team handling the matter has figured out a solution. I now have all the guidelines on how to properly release Evilginx Pro while being compliant with all the necessary export regulations for exporting the dual-use goods from Poland.</p><p>The downside is that there will be a bit more paperwork involved regarding additional company verification, but on the positive note, you can now be 100% sure that the tool you are purchasing is doing absolutely everything possible to stay on the 100% legal side.</p><h2 id="company-verification-changes">Company Verification Changes</h2><p><strong>Update 2025-04-01: I&apos;ve updated this section with details on the improved verification process, which reduced the number of requested documents and decreased the verification time.</strong></p><p>Until now, the verification consisted of two steps:</p><ol><li>Verification that you are working in a cybersecurity company as a red teamer or pentester with a fairly decent public profile.</li><li>Verification of company details, such as the name, website, address, and tax identification number.</li></ol><p>Here are the additional steps required to green-light your BREAKDEV RED account and make it eligible to make a purchase:</p><h3 id="signed-end-user-statement">Signed End-user Statement</h3><p>An official company representative will need to <strong>fill out</strong> and <strong>sign</strong> an end-user statement <strong>with a handwritten signature</strong> and send it back to us. The contents of the statement state the nature of the product and the importer&apos;s commitments.</p><p>You can find the PDF with the end-user statement available for download on the <a href="https://red.breakdev.org/company">company page</a> in your BREAKDEV RED account panel.</p><p>Both the signed statement and the current extract from the commercial register are instrumental in obtaining the export license from the Ministry of Economic Development and Technology.</p><h3 id="export-license-processing-time">Export License Processing Time</h3><p>Once all required documents are received, the verification process takes up to <strong>24 hours</strong>.</p><p>Once the export license is granted, all members of the company eligible to make purchases will receive the notification email. From that moment, the ability to order <strong>Evilginx Pro</strong> licenses will be unlocked in the BREAKDEV RED account panel.</p><h2 id="what-is-new-in-evilginx-pro">What is new in Evilginx Pro?</h2><p>Since you&apos;re here, you may be asking how the Pro version differs from the already available open-source community version of Evilginx. Here is the list of changes and improvements. The latest version of this list can be found in the <a href="https://help.evilginx.com/pro/whats-new">official online documentation</a>.</p><h3 id="client-server-architecture%E2%80%8B">Client-Server Architecture<a href="https://help.evilginx.com/pro/whats-new#client-server-architecture">&#x200B;</a></h3><p>Evilginx has always worked as both the client and the server. You would deploy the application to an external server and control the server from the terminal while using SSH to connect to the remote server.</p><p><strong>Evilginx Pro</strong> allows you to deploy dedicated Evilginx servers, which work as background daemons and start automatically on every server reboot. You can control and deploy multiple Evilginx servers straight from a single Evilginx client instance, running in the terminal on your local PC, no matter if you&apos;re on Windows, Linux or Mac.</p><figure class="kg-card kg-image-card"><img src="https://breakdev.org/content/images/2025/03/servers_create_register.gif" class="kg-image" alt="Evilginx Pro is finally here!" loading="lazy" width="1200" height="600" srcset="https://breakdev.org/content/images/size/w600/2025/03/servers_create_register.gif 600w, https://breakdev.org/content/images/size/w1000/2025/03/servers_create_register.gif 1000w, https://breakdev.org/content/images/2025/03/servers_create_register.gif 1200w" sizes="(min-width: 720px) 720px"></figure><h3 id="evilginx-api%E2%80%8B">Evilginx API<a href="https://help.evilginx.com/pro/whats-new#evilginx-api">&#x200B;</a></h3><p>One of the most requested features of Evilginx was the ability to extract captured data from the server remotely. With the client-server architecture of <strong>Evilginx Pro,</strong> anyone can now write their own tool instrumentation using the exposed API on every Evilginx server instance.</p><p>The API is exposed via HTTPS, listening on the same TCP 443 as the main Evilginx HTTPS server. <strong>Evilginx Pro</strong> implements a stealth channel, which cannot be interacted with without knowing the internal secret hostname of the API request handler. The connection is additionally protected with a client certificate, allowing only legitimate and whitelisted <strong>Evilginx Pro</strong> users to connect to the Evilginx API server.</p><h3 id="wildcard-tls-certificates%E2%80%8B">Wildcard TLS Certificates<a href="https://help.evilginx.com/pro/whats-new#wildcard-tls-certificates">&#x200B;</a></h3><p>The biggest issue most red teams struggled with was the fact that once Evilginx obtained the TLS certificate, the phishing hostname would immediately get listed in the public TLS transparency report database. This resulted in dozens of security products immediately performing scans of the Evilginx server, looking for malicious activity. This often resulted in the phishing server getting blacklisted before it could&apos;ve been used for the engagement.</p><p><strong>Evilginx Pro</strong> will now obtain wildcard TLS certificates by default, which prevents the hostname of the phishing server from being fully exposed. Security products will be unable to scan the phishing server by looking at the registered TLS certificate since the subdomain in the wildcard TLS certificate is an asterisk. The full hostname of phishing pages is not disclosed in clear text.</p><h3 id="botguard%E2%80%8B">Botguard<a href="https://help.evilginx.com/pro/whats-new#botguard">&#x200B;</a></h3><p>Additionally, <strong>Evilginx Pro</strong> implements Botguard, which prevents security products from accessing the phishing website even if the hostname and full phishing URL are known to them.</p><p>Botguard uses multiple techniques, combining <a href="https://blog.foxio.io/ja4%2B-network-fingerprinting" rel="noopener noreferrer">JA4</a> signature fingerprinting and telemetry analysis retrieved from the client browser using JavaScript. These methods are used to determine if the phishing server was accessed by bots through automated means.</p><p>If bot-like behaviour is detected, <strong>Evilginx Pro</strong> will display a spoofed website reverse proxied from an external URL predefined by the red team operator. You can learn more about how it works in the <a href="https://www.youtube.com/watch?v=Nh99d3YnpI4" rel="noopener noreferrer">x33fcon keynote</a> I gave in 2024.</p><h3 id="community-phishlets-database%E2%80%8B">Community Phishlets Database<a href="https://help.evilginx.com/pro/whats-new#community-phishlets-database">&#x200B;</a></h3><p>Evilginx has always been considered to be a phishing framework, which can be extended with &quot;phishlets&quot; to target specific websites. The open-source version of the framework was made available without the ready-to-use phishlets. This decision was made due to ethical reasons to not make it too easy to use out of the box to wreak havoc by malicious actors. Since <strong>Evilginx Pro</strong> is now made available only to vetted red team professionals, the risk of phishing framework misuse is much lower.</p><p><strong>Evilginx Pro</strong> now lets you access the community-curated database of ready-to-use phishlets to use for your next phishing engagement. Keep in mind, though, that there is <u>no guarantee</u> that the phishlets will be constantly updated to work with the most recent version of the target websites.</p><figure class="kg-card kg-image-card"><img src="https://breakdev.org/content/images/2025/03/phishlets_db.gif" class="kg-image" alt="Evilginx Pro is finally here!" loading="lazy" width="1200" height="600" srcset="https://breakdev.org/content/images/size/w600/2025/03/phishlets_db.gif 600w, https://breakdev.org/content/images/size/w1000/2025/03/phishlets_db.gif 1000w, https://breakdev.org/content/images/2025/03/phishlets_db.gif 1200w" sizes="(min-width: 720px) 720px"></figure><h3 id="evilpuppet-background-browser%E2%80%8B">Evilpuppet (background browser)<a href="https://help.evilginx.com/pro/whats-new#evilpuppet-background-browser">&#x200B;</a></h3><p>With the increasing number of defenses against phishing implemented by industry leaders, Evilginx had to innovate to keep up with the changing ecosystem. Websites will often gather telemetry metadata from the user&apos;s web browser to determine if the user is not in the middle of getting phished by a malicious actor.</p><p>Evilpuppet implements a web browser, running on the Evilginx server in the background, to generate legitimate web browser telemetry, which can be extracted and injected into <strong>Evilginx Pro</strong> phishing sessions in real time during the phishing attack.</p><h3 id="external-dns-management%E2%80%8B">External DNS Management<a href="https://help.evilginx.com/pro/whats-new#external-dns-management">&#x200B;</a></h3><p>By default, apart from acting as an HTTP server, Evilginx also acted as a nameserver, listening on port UDP 53 for DNS requests. This allowed Evilginx to be flexible in managing an unlimited number of phishing hostnames required by various phishlets. This, however, made Evilginx fairly easy to detect, since if anyone investigated the nameservers set up in the phishing domain&apos;s registrar, they would notice that the phishing server is hosted on the same IP as the nameservers, tied to the domain.</p><p>Red teams were able to mitigate that issue by using external DNS providers, but in doing so, they lost flexibility since all DNS records had to be managed manually and not through Evilginx automation.</p><p><strong>Evilginx Pro</strong> now retains that flexibility even when using external DNS providers. Evilginx can now be configured to manage DNS records externally through the API of supported third-party DNS providers, making it more stealthy and easier to use.</p><h3 id="multi-domain-support%E2%80%8B">Multi-domain Support<a href="https://help.evilginx.com/pro/whats-new#multi-domain-support">&#x200B;</a></h3><p><strong>Evilginx Pro</strong>, unlike its community version counterpart, can now be configured to use more than one domain to run phishing campaigns. You can now set different base domains for each phishlet you want to use without the need to change your DNS settings.</p><p>Each domain can be set up with a different third-party DNS provider, be it internal or external, like Cloudflare or Digital Ocean.</p><h3 id="javascript-obfuscation%E2%80%8B">Javascript Obfuscation<a href="https://help.evilginx.com/pro/whats-new#javascript-obfuscation">&#x200B;</a></h3><p>Evilginx will often inject its own JavaScript code into the reverse-proxied websites to manage redirects, gather botguard telemetry or provide additional interaction with the viewed website through JavaScript injected from phishlets. The injected code could have been easily fingerprinted through static signatures, potentially resulting in reverse-proxied websites being flagged as phishing.</p><p><strong>Evilginx Pro</strong> will now automatically perform code obfuscation of all injected JavaScript code, using the <a href="https://obfuscator.io/" rel="noopener noreferrer">obfuscator.io</a> engine running locally. This results in JavaScript code taking different shapes with every page load, making the code impossible to fingerprint with pattern detection logic.</p><h3 id="automated-server-deployment%E2%80%8B">Automated Server Deployment<a href="https://help.evilginx.com/pro/whats-new#automated-server-deployment">&#x200B;</a></h3><p>The days of deploying Evilginx servers by hand are over. <strong>Evilginx Pro</strong> provides a straightforward way of deploying a new phishing server by issuing a single command. You only need to provide the server&apos;s IP address and root credentials (password or authorized private key) to access the server. Evilginx client will do the rest.</p><h3 id="website-spoofing%E2%80%8B">Website Spoofing<a href="https://help.evilginx.com/pro/whats-new#website-spoofing">&#x200B;</a></h3><p>When the <strong>Evilginx Pro</strong> server detects either a client requesting a URL which is not a valid phishing lure URL or determines the connection is made by automation software, it will not redirect the visitor to an external website anymore but render another website&apos;s content in the context of the current one.</p><p>This provides better phishing anti-detection capabilities and gives the impression that a legitimate website is hosted under the phishing URL.</p><h3 id="sqlite-database%E2%80%8B">SQLite Database<a href="https://help.evilginx.com/pro/whats-new#sqlite-database">&#x200B;</a></h3><p>Data storage for Evilginx data has been completely revamped. <strong>Evilginx Pro</strong> no longer uses BuntDB text-file storage, and it now uses a SQLite database for speed and ease of access.</p><h2 id="conclusion">Conclusion</h2><p>I have high hopes for <strong>Evilginx Pro,</strong> and I&apos;m very excited to see what it&apos;s going to become.</p><p>If you have any questions about Evilginx Pro, you can contact us at <a href="mailto:sales@breakdev.org">sales@breakdev.org</a>. Don&apos;t forget to check out the <a href="https://help.evilginx.com/">online documentation</a> and the official <a href="https://evilginx.com">Evilginx Pro</a> website.</p><p>You can find me on the following platforms:</p><p>LinkedIn: <a href="https://www.linkedin.com/in/kubagretzky">Kuba Gretzky</a></p><p>Bsky: <a href="https://bsky.app/profile/mrgretzky.breakdev.org">@mrgretzky.breakdev.org</a></p><p>Twitter: <a href="https://x.com/mrgretzky">@mrgretzky</a></p><p>I wish you all the best, and hopefully, I will see you at the <a href="https://red.breakdev.org/join">BREAKDEV RED</a> Discord server!</p>]]></content:encoded></item><item><title><![CDATA[Evilginx 3.3 - Go & Phish]]></title><description><![CDATA[Evilginx 3.3 update is here and it comes packing with the special feature everyone has been waiting for.]]></description><link>https://breakdev.org/evilginx-3-3-go-phish/</link><guid isPermaLink="false">6603f68eb2f8fc4f71e87c6d</guid><category><![CDATA[evilginx]]></category><category><![CDATA[phishing]]></category><category><![CDATA[update]]></category><dc:creator><![CDATA[Kuba Gretzky]]></dc:creator><pubDate>Tue, 02 Apr 2024 13:37:25 GMT</pubDate><media:content url="https://breakdev.org/content/images/2024/04/evilginx33.png" medium="image"/><content:encoded><![CDATA[<img src="https://breakdev.org/content/images/2024/04/evilginx33.png" alt="Evilginx 3.3 - Go &amp; Phish"><p>Long time no hear in terms of <a href="https://github.com/kgretzky/evilginx2">Evilginx</a> updates. While I&apos;m still working on the release of <a href="https://breakdev.org/evilginx-pro-reveal/">Evilginx Pro</a>, I&apos;ve decided to fix a few issues and add new features to the public version of Evilginx, in the meantime.</p><p>First of all, I wanted to thank everyone for the great feedback and insightful discussions in the <a href="https://breakdev.org/breakdev-red/">BREAKDEV RED</a> community Discord. All of the reported issues and suggestions led to the improvement of Evilginx and this update is the fruit of such great community feedback.</p><div class="kg-card kg-button-card kg-align-center"><a href="https://github.com/kgretzky/evilginx2" class="kg-btn kg-btn-accent">Get Evilginx 3.3 on GitHub</a></div><p>Additionally, I wanted to use this opportunity to thank everyone for sending their applications to access <strong>BREAKDEV RED</strong>. We&apos;ve gathered an incredible number of security professionals (almost <strong>850</strong> at the time of writing) and every day I&apos;m learning something new from you guys, which I&apos;m super grateful for. Hell, I&apos;ve even finally fully understood how to properly configure the SPF/DKIM/DMARC combo thanks to all the discussion on the subject.</p><p>Vetting the applications takes a lot of time and before I open the registrations again, to the public, I&apos;d like to automate the verification process a bit. Once I do this, requesting access to the community should be more accessible to everyone.</p><p>Allowing access only to red teamers with a clean conscience is still of utmost importance to me and it is the base for creating a friendly atmosphere, which fuels guilt-free information sharing.</p><hr><p>This time I have something special for you. Never before have I had a request so popular that it was mentioned in 90% of all <strong>BREAKDEV RED </strong>application forms. Let it be known that your pleas have been heard.</p><p>Evilginx has an <a href="https://github.com/kgretzky/gophish/">official integration</a> with <a href="https://getgophish.com/">GoPhish</a> by <a href="https://www.linkedin.com/in/jordan-wright-75279554/">Jordan Wright</a> from now on!</p><p>That&apos;s right - you will finally be able to create phishing campaigns for sending emails with valid Evilginx lure URLs and enjoy all the benefits of GoPhish&apos;s lovely UI, seeing which emails were opened, which lure URLs were clicked and which clicks resulted in successful session capture.</p><p>Here is the full list of changes coming in <strong>Evilginx 3.3</strong> together with a full guide on how to use all the new features.</p><h2 id="gophish-support">GoPhish Support</h2><p>I&apos;ve <a href="https://github.com/kgretzky/gophish">forked GoPhish</a> and added the integration with Evilginx in the cleanest way possible. If you were using your custom version of GoPhish, merging Evilginx integration with your own fork should be relatively easy.</p><p>I have made the integration in such a way that Evilginx will be notifying GoPhish of the following events, which occur:</p><ul><li><strong>A hidden image tracker is triggered when the email is opened. </strong>The tracker image is just a lure URL with specific parameters to let Evilginx know it should be used as a tracker.</li><li><strong>A phishing link is clicked within the email message. </strong>The<strong> </strong>phishing link within the email message sent through GoPhish is just the lure URL with embedded parameters.</li><li><strong>The session is successfully captured with Evilginx. </strong>Once Evilginx gathers the credentials and logs the cookies, it will notify GoPhish that the data has been submitted.</li></ul><p>I&apos;ve exposed additional API endpoints in GoPhish to make it possible to change the results status for every sent email.</p><p>Now, when you create a new campaign in GoPhish, you do not have a &quot;Landing Page&quot; to select. Instead, you will generate a lure URL in Evilginx and paste it into the &quot;Evilginx Lure URL&quot; text box.</p><p>What&apos;s more, GoPhish will automatically generate the encrypted custom parameters with personalized content, retrievable by Evilginx, for each embedded link. The personalized values embedded with every phishing link embedded within the generated email message are the following:</p><ul><li>First Name (<code>fname</code>)</li><li>Last Name (<code>lname</code>)</li><li>Email (<code>email</code>)</li></ul><p>This is super useful as you can use the custom parameters further to customize the content on your phishing pages within your <code>js_inject</code> scripts.</p><p>Let&apos;s say you wanted to pre-fill the email in the sign-in text box on the phishing page. Now you can just use the <code>{email}</code> placeholder within your injected script and you can be sure that GoPhish will deliver the right value for you. The same goes for <code>{fname}</code> and <code>{lname}</code>.</p><p>GoPhish will also embed the <code>rid</code> (Result ID) in the phishing link&apos;s parameters, so that Evilginx will know for which result it should update the status.</p><p>You can monitor the status of your mailing campaigns and check email deliverability, straight from GoPhish, but Evilginx will be the only side storing the credentials and authentication cookies.</p><h3 id="how-to-set-up-gophish-with-evilginx">How to set up GoPhish with Evilginx?</h3><p>First of all, you need to get GoPhish from my <a href="https://github.com/kgretzky/gophish">forked GoPhish repository</a>. You can either grab clone the source code and build it yourself or you can grab the binaries from <a href="https://github.com/kgretzky/gophish/releases">releases</a>.</p><p>Deploy GoPhish on the external server. It doesn&apos;t have to be the same server Evilginx is running on, but it will have to be reachable by your Evilginx instances. You can find out how to install GoPhish in <a href="https://docs.getgophish.com/user-guide/installation">its official documentation</a>.</p><p>Once you have GoPhish running on a remote server and you also have Evilginx deployed and ready for action, you will need to tell Evilginx how it can communicate with your GoPhish server.</p><h3 id="configuring-evilginx">Configuring Evilginx</h3><p>For this, you will need the Admin URL of your GoPhish instance and the API key. You can find the API key within the <em>Account Settings </em>in your GoPhish admin panel. To figure out the IP and port of your GoPhish instance, refer to the <a href="https://docs.getgophish.com/user-guide/installation#exposing-gophish-to-the-internet">official documentation</a>.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://breakdev.org/content/images/2024/04/image.png" class="kg-image" alt="Evilginx 3.3 - Go &amp; Phish" loading="lazy" width="1305" height="730" srcset="https://breakdev.org/content/images/size/w600/2024/04/image.png 600w, https://breakdev.org/content/images/size/w1000/2024/04/image.png 1000w, https://breakdev.org/content/images/2024/04/image.png 1305w" sizes="(min-width: 720px) 720px"><figcaption>You can find the GoPhish API key in the Account Settings</figcaption></figure><p>For example, if your GoPhish admin server is running on an IP <code>1.2.3.4</code> listening on port <code>3333</code>, with TLS enabled, you can set it up as follows:</p><pre><code>config gophish admin_url https://1.2.3.4:3333
config gophish api_key c60e5bce24856c2c473c4560772</code></pre><p>If you do not use a valid TLS certificate for the exposed GoPhish instance, you may need to allow insecure TLS connections as well (such connections can be man-in-the-middled, so tread carefully):</p><pre><code>config gophish insecure true</code></pre><p>Once all this is configured, your Evilginx instance is ready to go. You can test if the communication with GoPhish works properly by issuing the command:</p><pre><code>config gophish test</code></pre><h3 id="configuring-gophish">Configuring GoPhish</h3><p>Here I am assuming you are familiar with how to use GoPhish. If not, feel free to check out the <a href="https://docs.getgophish.com/user-guide/getting-started">documentation on how to get started</a>.</p><p>Make sure GoPhish is running either in a <code>tmux</code> session or you set it up to run as a daemon. You can find more information on how to do it <a href="https://github.com/gophish/gophish/issues/586">in this GitHub issue</a>.</p><p>Once you have everything properly set up, it is time to set up your <em>Campaign</em>. Create the new campaign and then select the <em>Email Template</em>, <em>Sending Profile </em>and the group of recipients. You may notice that instead of being asked for the <em>Landing Page profile </em>you need to provide the <em>Evilginx Lure URL</em>.</p><p>Open your Evilginx instance, create the lure and grab the lure URL you want to send out in your phishing campaign, using the command:</p><pre><code>lures get-url &lt;id&gt;</code></pre><p>Copy this URL and paste it into the <em>Evilginx Lure URL </em>text field of the campaign creation panel.</p><figure class="kg-card kg-image-card"><img src="https://breakdev.org/content/images/2024/04/image-1.png" class="kg-image" alt="Evilginx 3.3 - Go &amp; Phish" loading="lazy" width="730" height="714" srcset="https://breakdev.org/content/images/size/w600/2024/04/image-1.png 600w, https://breakdev.org/content/images/2024/04/image-1.png 730w" sizes="(min-width: 720px) 720px"></figure><p>That&apos;s it! You can now send out the campaign emails while enjoying the full overview of your campaign progress within the GoPhish UI.</p><h2 id="custom-tls-certificates">Custom TLS Certificates</h2><p>Since the release of Evilginx 3.0, the tool has been using <code>certmagic</code> library for TLS certificate management with automated LetsEncrypt TLS certificate registration. Having to use only LetsEncrypt certificates is often not ideal as it may mark your phishing server, on an engagement, as suspicious.</p><p>Many people have requested support to use their own TLS certificates with Evilginx, including the wildcard certificates. This feature has finally been implemented.</p><p>To add your own TLS certificates, first, create a new directory under <code>~/.evilginx/crt/sites/</code> with the name of your website or hostname. The name does not matter and it can be anything you choose.</p><p>Evilginx will scan these directories looking for the public X509 certificate and the private key used to sign the certificate. The X509 certificate should have either the <code>.pem</code> or <code>.crt</code> extension, while the private key should have the <code>.key</code> extension.</p><p>For convenience, Evilginx will also recognize the keypair generated by CertBot, where the public certificate is named <code>fullchain.pem</code> and the private key is <code>privkey.pem</code>. You can copy both files into the same directory to add such a TLS certificate generated by CertBot.</p><p>Once you put your custom TLS certificates in the right place, don&apos;t forget to disable automated LetsEncrypt certificate retrieval with:</p><pre><code>config autocert off</code></pre><p><strong>IMPORTANT! </strong>Make sure the private key files are not password-protected or otherwise Evilginx may fail to load them.</p><p>Example 1:</p><pre><code>~/.evilginx/crt/sites/wildcard.domain.com/fullchain.pem
~/.evilginx/crt/sites/wildcard.domain.com/privkey.pem</code></pre><p>Example 2:</p><pre><code>~/.evilginx/crt/sites/my_certificate/public.crt
~/.evilginx/crt/sites/my_certificate/private.key</code></pre><p>CertMagic library will automatically add the TLS certificates to the managed pool and it will automatically respond with a valid TLS certificate.</p><h2 id="http-proxy-ip-detection">HTTP Proxy IP Detection</h2><p>I know some of you use Caddy, Apache or Nginx as an additional proxy layer, sitting in front of the Evilginx instance. This created an issue for Evilginx to properly detect the origin IP address of incoming requests. Since all requests were proxied through a local web server, the origin IP would default to <code>127.0.0.1</code>, completely ignoring the additional HTTP headers added by the proxies, with the correct origin IP addresses as values.</p><p>Since this update, Evilginx will properly recognize the origin IP address of all proxied HTTP requests. The list of monitored HTTP headers is as follows:</p><pre><code>X-Forwarded-For
X-Real-IP
X-Client-IP
Connecting-IP
True-Client-IP
Client-IP</code></pre><h2 id="json-support-in-forcepost">JSON support in force_post</h2><p>Thanks to <a href="https://twitter.com/yudasm_">@yudasm_</a> contribution, you can now enjoy injecting your custom POST parameters within body contents transmitted in JSON format.</p><p>Check out Yehuda&apos;s recent blog post on how he used this feature to <a href="https://medium.com/@yudasm/bypassing-windows-hello-for-business-for-phishing-181f2271dc02">evade FIDO2 authentication when phishing MS365 accounts</a>.</p><h2 id="fixed-a-bug-used-to-detect-evilginx">Fixed a bug used to detect Evilginx</h2><p><a href="https://twitter.com/RedByte1337">Keanu Nys</a> reported an issue, in the BREAKDEV RED channel, where he found that one of the online URL scanners he used was able to open the phishing page by visiting the URL with just a hostname, without a valid lure URL path.</p><p>There was a bug in Evilginx, which would only enforce valid lure URLs for phishing hostnames, which were defined with <code>session: true</code> in the <code>proxy_hosts</code> section of the phishlet file.</p><p>Upon closer inspection, I&apos;ve decided that the <code>session</code> parameter never made sense and it is now obsolete. Every <code>proxy_hosts</code> entry is treated as if <code>session</code> was set to <code>true</code>.</p><figure class="kg-card kg-embed-card"><blockquote class="twitter-tweet"><p lang="en" dir="ltr">BUGFIX &#x1F41B;: Fixed a pretty serious flaw in Evilginx, which allowed scanners to detect phishing pages, bypassing the unauthorized requests protection and blacklist rules.<br><br>Pull from master and enjoy! &#x1F973;<br><br>Big thanks to Keanu Nys for finding this. &#x1F497;<a href="https://t.co/v7eQdK4Ugw">https://t.co/v7eQdK4Ugw</a></p>&#x2014; Kuba Gretzky (@mrgretzky) <a href="https://twitter.com/mrgretzky/status/1762831548456259647?ref_src=twsrc%5Etfw">February 28, 2024</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

</figure><p>Keanu wrote a great post-mortem post about the bug he found, so if you&apos;re interested in learning more about it, you can <a href="https://insights.spotit.be/2024/03/01/flaw-in-evilginx-allows-instant-detection-by-scanners-despite-blacklisting/">find it here</a>.</p><h2 id="fixed-the-infinite-redirection-loop">Fixed the infinite redirection loop</h2><p>Evilginx, since forever, had a very annoying bug, which would trigger the infinite redirection loop, whenever the lure URL path was set to be the same as the login path of the targeted website.</p><p>This has now been fixed and Evilginx will also make an additional check to compare if the lure URL contains the valid phishing domain used by the landing phishing page.</p><h2 id="added-support-for-more-tlds">Added support for more TLDs</h2><p>Over the years, there have been multiple new TLDs launched for registering domains. Evilginx will try hard to detect all URLs in proxied packets and convert them either from phishing domains to original domains or from original domains to phishing domains.</p><p>To be more efficient, it relies on the detection of URLs ending with known TLDs. Some of the newer TLDs have not been supported and this update changes that.</p><p>Here is the new list of all supported TLDs:</p><pre><code>aero
arpa
art
biz
bot
cat
click
cloud
club
com
coop
edu
game
gov
inc
info
ink
int
jobs
live
lol
mil
mobi
museum
name
net
online
org
pro
root
shop
site
tech
tel
today
travel
vip
wiki
xyz
[all known 2 character TLDs]</code></pre><h2 id="changelog">Changelog</h2><p>Here is the whole Evilginx 3.3 changelog with some additional changes and fixes I did not mention in this post:</p><!--kg-card-begin: markdown--><h1 id="330">3.3.0</h1>
<ul>
<li>Feature: Official GoPhish integration, using the fork: <a href="https://github.com/kgretzky/gophish">https://github.com/kgretzky/gophish</a></li>
<li>Feature: Added support to load custom TLS certificates from a public certificate file and a private key file stored in <code>~/.evilginx/crt/sites/&lt;hostname&gt;/</code>. Will load <code>fullchain.pem</code> and <code>privkey.pem</code> pair or a combination of a <code>.pem</code>/<code>.crt</code> (public certificate) and a <code>.key</code> (private key) file. Make sure to run without <code>-developer</code> flag and disable autocert retrieval with <code>config autocert off</code>.</li>
<li>Feature: Added ability to inject <code>force_post</code> POST parameters into JSON content body (by <a href="https://twitter.com/yudasm_">@yudasm_</a>).</li>
<li>Feature: Added ability to disable automated TLS certificate retrieval from LetsEncrypt with <code>config autocert &lt;on/off&gt;</code>.</li>
<li>Feature: Evilginx will now properly recognize origin IP for requests coming from behind a reverse proxy (nginx/apache2/cloudflare/azure).</li>
<li>Fixed: Infinite redirection loop if the lure URL path was the same as the login path defined in the phishlet.</li>
<li>Fixed: Added support for exported cookies with names prefixed with <code>__Host-</code> and <code>__Secure-</code>.</li>
<li>Fixed: Global <code>unauth_url</code> can now be set to an empty string to have the server return <code>403</code> on unauthorized requests.</li>
<li>Fixed: Unauthorized redirects and blacklisting would be ignored for <code>proxy_hosts</code> with <code>session: false</code> (default) making it easy to detect evilginx by external scanners.</li>
<li>Fixed: IP address <code>127.0.0.1</code> is now ignored from being added to the IP blacklist.</li>
<li>Fixed: Added support for more TLDs to use with phishing domains (e.g. <code>xyz</code>, <code>art</code>, <code>tech</code>, <code>wiki</code>, <code>lol</code> &amp; more)</li>
<li>Fixed: Credentials will now be captured also from intercepted requests.</li>
</ul>
<!--kg-card-end: markdown--><hr><h1 id="conclusion">Conclusion</h1><p>I&apos;m happy to have finally been able to include the most requested features, together with some quality-of-life improvements, before the <a href="https://breakdev.org/evilginx-pro-reveal/">Evilginx Pro</a> release this year.</p><p>Please let me know your feedback about the update, either on Twitter <a href="https://twitter.com/mrgretzky">@mrgretzky</a> or in <a href="https://breakdev.org/breakdev-red/">BREAKDEV RED</a> Discord.</p><p>Looking forward to your opinion!</p><p>If you&apos;re reading this before 3rd April 2024, you can still get a <strong>30% discount</strong> for the <a href="https://academy.breakdev.org/evilginx-mastery?coupon=HELLOSPRING">Evilginx Mastery</a> course, which I am constantly updating and you get access for a lifetime. Expect to see the GoPhish integration guide added sometime in the future.</p><div class="kg-card kg-button-card kg-align-center"><a href="https://academy.breakdev.org/evilginx-mastery?coupon=HELLOSPRING" class="kg-btn kg-btn-accent">Evilginx Mastery (30% OFF)</a></div><p>Happy phishing!</p><p>-- Kuba Gretzky</p>]]></content:encoded></item><item><title><![CDATA[Evilginx Pro - The Future of Phishing]]></title><description><![CDATA[<p>I&apos;ve teased the idea of <strong>Evilginx Pro</strong> long enough and I think it is finally time to make a proper reveal of what it exactly is.</p><p><strong>Evilginx Pro </strong>will be a paid professional version of <strong>Evilginx</strong>, with extra features and added advanced reverse proxy anti-detection techniques, available <u><strong>only</strong></u></p>]]></description><link>https://breakdev.org/evilginx-pro-reveal/</link><guid isPermaLink="false">65019e05b2f8fc4f71e86da4</guid><category><![CDATA[evilginx]]></category><category><![CDATA[phishing]]></category><category><![CDATA[tool]]></category><dc:creator><![CDATA[Kuba Gretzky]]></dc:creator><pubDate>Wed, 27 Sep 2023 11:08:50 GMT</pubDate><media:content url="https://breakdev.org/content/images/2023/09/evilginx-pro-reveal.png" medium="image"/><content:encoded><![CDATA[<img src="https://breakdev.org/content/images/2023/09/evilginx-pro-reveal.png" alt="Evilginx Pro - The Future of Phishing"><p>I&apos;ve teased the idea of <strong>Evilginx Pro</strong> long enough and I think it is finally time to make a proper reveal of what it exactly is.</p><p><strong>Evilginx Pro </strong>will be a paid professional version of <strong>Evilginx</strong>, with extra features and added advanced reverse proxy anti-detection techniques, available <u><strong>only</strong></u><strong> </strong>to <strong><a href="https://breakdev.org/breakdev-red/">BREAKDEV RED </a></strong><a href="https://breakdev.org/breakdev-red/">community</a> members.</p><p>If you&apos;ve not yet applied to the community or you did not receive the approval e-mail from the first round, you can apply again as<strong> <a href="https://forms.gle/MqpK9yDP4d9FK24n6">Round #2 of registration is currently ongoing</a>.</strong></p><div class="kg-card kg-button-card kg-align-center"><a href="https://forms.gle/MqpK9yDP4d9FK24n6" class="kg-btn kg-btn-accent">Apply to BREAKDEV RED here!</a></div><p>The Pro version is catered to professional red teamers and penetration testers, who want to see better results during phishing engagements and who want to make the job easier for themselves and have more time to focus on other aspects of the tasks at hand.</p><p>Without further ado, let&apos;s jump into the product presentation.</p><h1 id="features">Features</h1><p>The list of exclusive features available in the Pro version is not final. First of all, I wanted to outline the features I&apos;ve already implemented, which are guaranteed to be included on day one:</p><h3 id="evilpuppet">Evilpuppet</h3><p>Evilpuppet is an additional module running alongside Evilginx, responsible for managing a Chromium browser in the background, for various purposes.</p><p>I wanted to make a quick note here that, since there are already multiple ways to <a href="https://github.com/infosimples/detect-headless">detect headless browsers</a>, the Evilpuppet background browser does not launch in headless mode, to prevent unnecessary detections, while still running with a hidden interface.</p><p>The main reason why Evilpuppet was created, was due to new reverse proxy phishing detections, introduced on popular websites.</p><p>The module serves two purposes:</p><h4 id="secret-token-extraction">Secret Token Extraction</h4><p>More websites begin to implement extensive JavaScript obfuscation with the generation of what I call - &quot;secret tokens&quot;. The secret token, in general, is an encrypted buffer holding telemetry data gathered from the client&apos;s web browser. The telemetry data often holds the URL of the visited website, which in the case of the phishing website, would hold the name of the attacker&apos;s phishing domain.</p><p>The secret token value is often transmitted as a hidden POST parameter. Once retrieved by the server, the token is decrypted and its content is analyzed, in search for anomalies, which could indicate that sign-in originated from a reverse proxy server, hosted on a different domain than the legitimate website.</p><p>If you&apos;re interested in learning how secret tokens are generated and how they are used to protect users from reverse proxy phishing, you can watch my x33fcon talk <a href="https://www.youtube.com/watch?v=C-Fh4sIdY8c">where I explained how to properly implement such protections</a>.</p><p>The students of my <a href="https://academy.breakdev.org/evilginx-mastery">Evilginx Mastery</a> course can also learn how to evade secret token protection within the private Training Lab.</p><p>Sometimes reverse engineering the JavaScript responsible for gathering telemetry and generating the secret token&apos;s value, then hotpatching it, is simply not possible. </p><p>This is where Evilpuppet comes in.</p><p>Evilpuppet runs as a Node.js application, which controls a Chromium browser, automated through <a href="https://pptr.dev/">Puppeteer</a>. The process of bypassing the secret token protection can be described as follows:</p><ul><li>When a phished user begins the login process, in which a secret token is generated, Evilpuppet will spawn a browser in the background and open the legitimate website&apos;s sign-in page.</li><li>In the background session, Evilpuppet will enter the credentials supplied by the phished user and initiate the sign-in process.</li><li>Once the secret token is generated and embedded within the transmitted HTTP packet, Evilpuppet will extract its value and send it back to Evilginx.</li><li>The secret token generated within the reverse proxy phishing session is then replaced with the secret token extracted from the Evilpuppet background session.</li></ul><p>You may be thinking how is this possible? Why isn&apos;t the secret token tied to the specific sign-in session to prevent the attacker from re-using secret tokens generated in different sessions?</p><p>Unfortunately, what makes it possible is the fact that HTTP communication is stateless by design. You can emulate the state by including specific session tokens as cookies or authorization headers, but this can all be emulated by the attacker. If we could tie a sign-in session to a TLS handshake, for example, this would be a different story. There was once a lot of buzz about the concept of <a href="https://en.wikipedia.org/wiki/Token_Binding">Token Binding</a>, but I believe the idea did not take off.</p><p>If you&apos;ve recently tried using Evilginx to phish LinkedIn, you may have noticed the phished account is locked out immediately when a reverse proxy phishing attack succeeds. This happens, because Microsoft implemented reverse proxy phishing session detection, through the generation of a secret token.</p><p>You can see the secret token, transmitted with the POST login request as a hidden <code>apfc</code> parameter.</p><figure class="kg-card kg-image-card"><img src="https://breakdev.org/content/images/2023/09/image.png" class="kg-image" alt="Evilginx Pro - The Future of Phishing" loading="lazy" width="1764" height="586" srcset="https://breakdev.org/content/images/size/w600/2023/09/image.png 600w, https://breakdev.org/content/images/size/w1000/2023/09/image.png 1000w, https://breakdev.org/content/images/size/w1600/2023/09/image.png 1600w, https://breakdev.org/content/images/2023/09/image.png 1764w" sizes="(min-width: 720px) 720px"></figure><p><strong>Evilginx Pro</strong> with <strong>Evilpuppet </strong>will capture the value of <code>apfc</code> parameter in the background browser session and inject it into a reverse proxy session, effectively circumventing the protection and making the LinkedIn server think the sign-in happened on a legitimate website.</p><p>Here is a short video of Evilginx Pro successfully phishing a LinkedIn user, while extracting a secret token with the background browser. As a bonus enjoy some extra Cyberpunk music I made!</p><p><strong>NOTE: </strong>The background Chromium browser will be running in the background, on the Evilginx server and will not be visible. It is only visible in the video for demonstration purposes.</p><figure class="kg-card kg-embed-card"><blockquote class="twitter-tweet"><p lang="en" dir="ltr">&#x1F3AC;Phishing LinkedIn and bypassing MFA demo created for the upcoming Evilginx Pro post &#x1F525;<br><br>&#x1F4A1;Evilginx uses a background browser to capture the secret token from legitimate website and inject it back into the reverse proxy phishing session.<br><br>P.S. Enjoy that Cyberpunk tune I made &#x1F3B5; <a href="https://t.co/rkbOmVSdeb">pic.twitter.com/rkbOmVSdeb</a></p>&#x2014; Kuba Gretzky (@mrgretzky) <a href="https://twitter.com/mrgretzky/status/1706735382698582026?ref_src=twsrc%5Etfw">September 26, 2023</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
</figure><p>To learn more about how Evilpuppet can be automated with Evilginx Pro, you can look into the LinkedIn phishlet, which was used in the demo video:</p><pre><code class="language-yaml">min_ver: &apos;3.0.0&apos;
proxy_hosts:
  - {phish_sub: &apos;www&apos;, orig_sub: &apos;www&apos;, domain: &apos;linkedin.com&apos;, session: true, is_landing: true, auto_filter: true}
sub_filters:
  - {triggers_on: &apos;www.linkedin.com&apos;, orig_sub: &apos;&apos;, domain: &apos;www.linkedin.com&apos;, search: &apos;&lt;\/head&gt;&apos;, replace: &apos;&lt;style&gt;#artdeco-global-alert-container {display: none !important;} .alternate-signin-container {display: none !important;}&lt;/style&gt;&lt;/head&gt;&apos;, mimes: [&apos;text/html&apos;]}
auth_tokens:
  - domain: &apos;.www.linkedin.com&apos;
    keys: [&apos;li_at&apos;]
credentials:
  username:
    key: &apos;session_key&apos;
    search: &apos;(.*)&apos;
    type: &apos;post&apos;
  password:
    key: &apos;session_password&apos;
    search: &apos;(.*)&apos;
    type: &apos;post&apos;
login:
  domain: &apos;www.linkedin.com&apos;
  path: &apos;/login&apos;
js_inject:
  - trigger_domains: [&quot;www.linkedin.com&quot;]
    trigger_paths: [&quot;/login&quot;]
    trigger_params: [&quot;email&quot;]
    script: |
      function lp(){
        var email = document.querySelector(&quot;#username&quot;);
        var password = document.querySelector(&quot;#password&quot;);
        if (email != null &amp;&amp; password != null) {
          email.value = &quot;{email}&quot;;
          password.focus();
          return;
        }
        setTimeout(function(){lp();}, 100);
      }
      setTimeout(function(){lp();}, 100);
evilpuppet:
  triggers:
    - domains: [&apos;www.linkedin.com&apos;]
      paths: [&apos;/checkpoint/lg/login-submit&apos;]
      token: &apos;apfc&apos;
      open_url: &apos;https://www.linkedin.com/login&apos;
      actions:
        - selector: &apos;#username&apos;
          value: &apos;{username}&apos;
          enter: false
          click: false
          post_wait: 500
        - selector: &apos;#password&apos;
          value: &apos;{password}&apos;
          enter: false
          click: false
          post_wait: 500
        - selector: &apos;button[type=submit]&apos;
          click: true
          post_wait: 1000
  interceptors:
    - token: &apos;apfc&apos;
      url_re: &apos;/checkpoint/lg/login-submit&apos;
      post_re: &apos;apfc=([^&amp;]*)&apos;
      abort: true
</code></pre><p>Evilpuppet support is already included in the <a href="https://help.evilginx.com/docs/phishlet-format#evilpuppet">official documentation</a>, so please check that out if you want to learn how the <code>evilpuppet</code> section of a phishlet works.</p><p>For comparison, you can use the same phishlet with the <a href="https://github.com/kgretzky/evilginx2">public version of Evilginx</a> and observe how the account will be locked when phished successfully when there is no Evilpuppet to help with injecting the legitimate <code>apfc</code> secret token.</p><h4 id="post-phishing-automation">Post-Phishing Automation</h4><p>This feature is not yet completed, but the end goal is to allow Evilpuppet to use the captured session tokens and log into the phished service on behalf of the phished user.</p><p>Once logged in, it could be instrumented to perform specific actions on the phished user&apos;s account to change account settings or exfiltrate data.</p><p>The idea is to create a full-blown post-phishing automation framework similar to what <a href="https://github.com/muraenateam/necrobrowser">Necrobrowser</a> does in the <a href="https://github.com/muraenateam/muraena">Muraena</a> project.</p><h3 id="wildcard-tls-certificates">Wildcard TLS Certificates</h3><p><strong>Evilginx Pro</strong> is officially supporting the automatic retrieval and renewal of wildcard TLS certificates from LetsEncrypt.</p><p>One of the most annoying aspects of using Evilginx with LetsEncrypt was that whenever Evilginx requested the TLS certificates for all of the phishing subdomains, the TLS certificate for a given phishing domain would immediately be published within the <a href="https://certificate.transparency.dev/">Certificate Transparency Log</a>.</p><p>Once the certificate lands in the log, dozens of automated scanners will begin scanning the domains attached to generated TLS certificates, looking for malicious intent. You could observe this happening in the Evilginx terminal with multiple unauthorized requests popping up to your phishing domain, right after the TLS certificate, through LetsEncrypt was issued.</p><p>Wildcard certificates do not carry the same problem. Even though wildcard certificates will land in the same <a href="https://certificate.transparency.dev/">Certificate Transparency Log</a>, the automated scanners will have no idea what domains to scan, because the Common Name attached to the wildcard TLS certificate would look like <code>*.baddomain.com</code> and any subdomain could be used.</p><p>Using Evilginx Pro with wildcard certificates will prevent your phishing domains from being scanned when TLS certificates from LetsEncrypt are issued, allowing your phishing campaigns to remain undetected much longer.</p><h3 id="ja3-fingerprinting-evasion">JA3 Fingerprinting Evasion</h3><p>Methods to detect reverse proxy phishing have been similar to methods to detect web scraping bots. Very often scraper bots would be written in a specific programming language like Java, Go or Python. Each of these languages implements an HTTP library, which holds specific fingerprintable characteristics.</p><p>One such fingerprinting method is called <a href="https://engineering.salesforce.com/tls-fingerprinting-with-ja3-and-ja3s-247362855967/">JA3</a> and it is <a href="https://developers.cloudflare.com/bots/concepts/ja3-fingerprint/">more often implemented by major companies</a>.</p><p>The idea is to detect the specific combination of TLS ciphers supported by the HTTP client willing to connect to the server. The list of TLS ciphers is exchanged during the TLS handshake. As an example, Google Chrome will have a different list of supported TLS ciphers than the HTTP library used in Go or Python.</p><p>Evilginx Pro will make sure to always imitate a list of TLS ciphers of popular web browsers, to evade any form of JA3 fingerprinting and make its connections look as close to casual web browser traffic as possible.</p><h3 id="daemonization-and-multi-user-collaboration">Daemonization and Multi-User Collaboration</h3><p>Currently, Evilginx is both a client and a server, in one application. This makes Evilginx fairly easy to use, but it also introduces a set of problems, making it harder to deploy and manage at scale.</p><p>The only way to run Evilginx in the background, right now, is to execute it within a <code>tmux</code> or <code>screen</code> session. This complicates the process of launching Evilginx on boot, as the launch script needs to manage <code>tmux</code> sessions as well. &#xA0;It also means that every instance of <strong>Evilginx </strong>needs to be controlled over an SSH connection, which is often not ideal.</p><p>My plan with <strong>Evilginx Pro</strong> is to make the server fully daemonized and allow it to be controlled through exposed admin API by <strong>Evilginx Pro</strong> client applications. Both the <strong>Evilginx </strong>server and <strong>Evilpuppet </strong>Node.js application would be running as daemons, awaiting connections from <strong>Evilginx </strong>clients.</p><p><strong>Evilginx Pro</strong> server would expose a full API, accessible over a standard HTTPS connection on the default 443 port. API access would be protected with an authorization token to identify the <strong>Evilginx </strong>admin user.</p><p>This new client-server architecture would allow a multi-user collaboration across multiple <strong>Evilginx Pro</strong> instances. Every user with a valid <strong>Evilginx Pro</strong> license would be able to interact with any <strong>Evilginx Pro</strong> server instance, set up with the same license.</p><p><strong>Evilginx Pro</strong> clients will look and feel the same way as the current Evilginx terminal UI. The only difference with <strong>Evilginx Pro </strong>will be that you&apos;d be using one terminal to control multiple remote server instances. The introduction of a full-blown API to control <strong>Evilginx </strong>instances will also allow automating <strong>Evilginx </strong>server setup and, one day, it may even be possible to develop a web UI for <strong>Evilginx</strong>.</p><h3 id="licensing-system">Licensing System</h3><p>Important to note here is the fact that it will be required to have a valid <strong>BREAKDEV RED </strong>community account, in order to be eligible to obtain an <strong>Evilginx Pro</strong> license. This means that only people qualified to join the community will be allowed to purchase <strong>Evilginx Pro</strong> licenses. This is to limit the misuse of Evilginx Pro&apos;s extra offensive capabilities and make sure that only vetted personnel are using the Pro version.</p><p>Due to the separation of a server and a client in <strong>Evilginx Pro</strong>, communication with the <strong>BREAKDEV </strong>licensing server will only take place on the side of Evilginx client applications. Since Evilginx server instances are critical in terms of operational security during red team engagements or phishing simulations, they will not make any unnecessary outgoing connections to licensing servers. The only established connections will be the ones required for reverse proxy sessions to work properly.</p><h3 id="multiple-base-domains-support">Multiple Base Domains Support</h3><p>At the moment, <strong>Evilginx </strong>allows the use of only a single base domain, configured globally, which is used by every activated phishlet. If your configured base domain is <code>fake.com</code>, every lure URL you generate, even for different phishlets, will use a hostname ending with <code>fake.com</code>.</p><p><strong>Evilginx Pro</strong> allows more flexibility with the configuration of multiple base domains. These can later be assigned to individual phishlets or individual lures.</p><p>Phishlets will be assigned the last used domain from the list, which will be then automatically used for the generation of new lures, but you can also override the selected domain and pick a different one from the list of supported domains for each lure separately.</p><h3 id="no-detectable-artifacts">No Detectable Artifacts</h3><p>I made sure to deprive <strong>Evilginx Pro</strong> of any identifiable artifacts and I do not only mean the removal of the infamous <code>X-Evilginx</code> header.</p><p><strong>Evilginx Pro</strong> is much harder to identify by automated scanners and HTTP servers it connects to.</p><h3 id="server-stealth-overhaul">Server Stealth Overhaul</h3><p>You will now have an option for how to handle unauthorized requests. At the moment, unauthorized requests would redirect the visitor to a different URL, through the injection of <code>Location</code> header in the HTTP response or throw a 403 Forbidden HTTP error.</p><p><strong>Evilginx Pro</strong> allows you to either use the default method or:</p><ul><li>Display the contents of another website under the same domain, using a reverse proxy functionality similar to <code>proxy_pass</code> in Nginx.</li><li>Respond with custom HTML content stored in the local directory. </li></ul><h3 id="html-and-javascript-obfuscation">HTML and JavaScript Obfuscation</h3><p><strong>Evilginx Pro</strong> implements much smarter techniques for evading phishing page detection.</p><p>All of the JavaScript or HTML content, injected through <code>js_inject</code> or hosted through lure redirectors will be now delivered dynamically obfuscated, making it much harder for signature detections to determine the hosted content as malicious.</p><p>Some of you have had a lot of success hosting your phishing pages behind additional obfuscation layers like Cloudflare. Some research has also been<a href="https://www.r-tec.net/r-tec-blog-evade-signature-based-phishing-detections.html"> published</a> describing how effective content obfuscation is, to protect phishing pages.</p><p>It makes sense that HTML and JavaScript obfuscation should be natively supported by <strong>Evilginx</strong>, without having to use external services to overcomplicate your infrastructure setup.</p><h3 id="auto-deploy-scripts">Auto-Deploy Scripts</h3><p><strong>Evilginx Pro</strong> comes with easy-to-use bash scripts to easily deploy <strong>Evilginx </strong>to external servers.</p><p>You can deploy <strong>Evilginx </strong>to the remote server as easily as by running a single command:</p><pre><code class="language-bash">SSH_KEY_FILE=~/keys/ssh.key SSH_USER=admin ./deploy.sh 1.2.3.4</code></pre><p>You can learn more about the automatic deployment script <a href="https://help.evilginx.com/docs/getting-started/deployment/remote">here</a>. The usage may slightly change in the final product, but it will always remain as easy as using a single command.</p><h3 id="closed-source">Closed Source</h3><p>I wanted to make note here that Evilginx Pro <u>will not be released as open-source</u>. This decision comes from the fact that I want to lower the risk of possible source code leaks, which could lead to unauthorized use of the tool.</p><p>I expect to make exceptions for companies, which need to perform due diligence, before using the tool, to have guarantees that the tool securely stores and manages critical operational data, to protect their own customers.</p><h1 id="final-thoughts">Final Thoughts</h1><p>I expect <strong>Evilginx Pro </strong>to be released in <strong>Q4 2023</strong> or <strong>Q1 2024</strong>, with the license price tag of <strong>1200-1400 EUR</strong> per seat, billed annually. The price is not final and will depend heavily on product demand. The higher the demand, the lower the price will be.</p><p>There will be no limits to how many <strong>Evilginx Pro </strong>servers you deploy. The license will be required only by the <strong>Evilginx Pro </strong>client application, assigned to a specific user, from which it will be possible to communicate with all deployed servers. In short, every red teamer will require one named license to use <strong>Evilginx Pro </strong>to be able to connect to an unlimited number of <strong>Evilginx Pro </strong>server instances, created for the same license.</p><p>Everyone who has been accepted into the <strong>BREAKDEV RED </strong>community will soon receive a link to the form with several questions, through which I&apos;ll be gathering feedback on <strong>Evilginx Pro</strong>.</p><p>Thank you in advance if you spend the time to fill it out! Your answers will be used to make <strong>Evilginx Pro </strong>a better product.</p><p>If you haven&apos;t yet applied to become a member of the <strong>BREAKDEV RED </strong>community, round 2 of registrations is up! Please apply <a href="https://forms.gle/MqpK9yDP4d9FK24n6">here</a>.</p><p>Wish you all the best and as always expect updates to show up on my Twitter <a href="https://twitter.com/mrgretzky">@mrgretzky</a>. </p><p></p>]]></content:encoded></item><item><title><![CDATA[BREAKDEV RED - Red Team Community]]></title><description><![CDATA[Join the vetted Discord community, oriented around using Evilginx and ethical phishing, where everyone can safely share their phishing tips and tricks without worrying about them being misused by unknown parties.]]></description><link>https://breakdev.org/breakdev-red/</link><guid isPermaLink="false">64eef1a9b2f8fc4f71e86b2e</guid><category><![CDATA[breakdev]]></category><category><![CDATA[evilginx]]></category><category><![CDATA[phishing]]></category><dc:creator><![CDATA[Kuba Gretzky]]></dc:creator><pubDate>Wed, 30 Aug 2023 11:59:25 GMT</pubDate><media:content url="https://breakdev.org/content/images/2023/08/breakdev_red.png" medium="image"/><content:encoded><![CDATA[<img src="https://breakdev.org/content/images/2023/08/breakdev_red.png" alt="BREAKDEV RED - Red Team Community"><p>Today I want to announce my plan for creating a closed community for professional red teamers, working in red team companies, who perform phishing engagements as part of their job.</p><p>Read more about it below, but if you&apos;re already ready to sign up, here is the button, which will take you to the registration form:</p><div class="kg-card kg-button-card kg-align-center"><a href="https://red.breakdev.org/join" class="kg-btn kg-btn-accent">Sign me up!</a></div><h2 id="red-teams-united">Red Teams United</h2><p>My idea is to create a vetted Discord community, oriented around using Evilginx and ethical phishing, where <strong>everyone can safely share their phishing tips and tricks</strong> without having to worry about such information being misused by malicious parties.</p><p>I plan to launch a <strong>community repository for Evilginx phishlets</strong>, which will be maintained by me and other red teamers from the same trusted <strong>BREAKDEV RED </strong>community. Every community member will be granted free access to the repository and everyone will be able to contribute their own phishlets.</p><p>Additionally, all community members will be granted the ability to purchase licenses for <strong>Evilginx Pro </strong>as soon as it lands. The reveal of all the upcoming features will happen in the upcoming weeks. I expect <strong>Evilginx Pro </strong>to become a game-changer in professional phishing, solving a lot of issues around detection and adding the ability to bypass the latest reverse proxy phishing mitigations.</p><p>One of my main concerns is for <strong>Evilginx Pro </strong>to not fall into the hands of wrong-doers, which is the number one reason why I want to establish the trusted community in the first place.</p><h3 id="benefits-for-breakdev-red-members">Benefits for BREAKDEV RED members:</h3><ul><li><strong>FREE</strong> access to <strong>the private Evilginx phishlets repository </strong>on GitHub, maintained by me and<strong> </strong>other Evilginx power users.</li><li><strong>FREE </strong>access to the private <strong>BREAKDEV RED</strong> community on Discord, where you can interact with fellow red teamers, who went through the same vetting process as you did.</li><li><strong>(OPTIONAL) </strong>Ability to purchase licenses for <strong>Evilginx Pro </strong>when it comes out sometime later this year or early 2024.</li></ul><p>I have already confirmed that Discord communities can be highly beneficial for brainstorming and for Evilginx development. One of the great examples was when <a href="https://twitter.com/JackButton_">@JackButton_</a> shared how he implemented his own idea of <a href="https://www.r-tec.net/r-tec-blog-evade-signature-based-phishing-detections.html">signature base evasion</a> and automated scan preventions using CloudFlare, on <a href="https://academy.breakdev.org/evilginx-mastery">Evilginx Mastery</a> Discord.</p><h2 id="how-do-i-sign-up">How do I sign up?</h2><p>First of all, here is a list of requirements you need to fulfill, in order to be granted membership:</p><h3 id="registration-requirements">Registration requirements:</h3><ul><li>You&apos;re an employee or an owner of a cybersecurity company offering legal penetration testing services, with a focus on phishing simulations.</li><li>The provided contact e-mail should be hosted on the company domain. Sorry, no free domains (Gmail, Protonmail etc.), since those carry the risks of impersonation. </li><li>Your company should have a public website with outlined services provided in the area of cybersecurity. Once your status is approved, I will send you an email to the address you provided, with a final confirmation request.</li></ul><p>If by any chance you do not use company emails hosted on the company domain, please explain in the &quot;Comments&quot; section of the form and we will work something out.</p><p>If you&apos;re ready to sign up, clicking this button will lead you to the registration form:</p><div class="kg-card kg-button-card kg-align-center"><a href="https://red.breakdev.org/join" class="kg-btn kg-btn-accent">Sign me up!</a></div><h2 id="faq">FAQ</h2><h3 id="what-is-evilginx-pro">What is Evilginx Pro?</h3><p>It is a privately maintained version of Evilginx which employs:</p><ul><li>Evasion of widely employed phishing detection mechanisms.</li><li>Extra features like extraction of secret tokens, using an entirely new <strong><a href="https://help.evilginx.com/docs/phishlet-format#evilpuppet">Evilpuppet</a> </strong>module, responsible for interfacing Evilginx with a background browser.</li><li>Reverse proxy support for most popular services (including Google, LinkedIn and more).</li></ul><p>I will release a blog post soon, going into detail on what exactly the <strong>Pro </strong>version is about.</p><p><strong>Update: </strong>The blog post is <a href="https://breakdev.org/evilginx-pro-reveal/">out</a>.</p><h3 id="what-is-the-registration-form-about">What is the registration form about?</h3><p>Since I do not want any of the community benefits to be abused or misused, I want to offer them <strong>EXCLUSIVELY </strong>to legitimate cybersecurity companies, offering red teaming and/or penetration testing services.</p><p>Your answers allow me to learn more about your company and let me make a decision whether to put it on the list of trusted companies, interested in becoming Evilginx power users.</p>]]></content:encoded></item><item><title><![CDATA[Evilginx 3.2 - Swimming With The Phishes]]></title><description><![CDATA[The new free update for the Evilginx phishing framework is OUT NOW! Enjoy the new features and improvements!]]></description><link>https://breakdev.org/evilginx-3-2/</link><guid isPermaLink="false">64e32b63b2f8fc4f71e866a9</guid><category><![CDATA[evilginx]]></category><category><![CDATA[hacking]]></category><category><![CDATA[phishing]]></category><category><![CDATA[tool]]></category><category><![CDATA[update]]></category><dc:creator><![CDATA[Kuba Gretzky]]></dc:creator><pubDate>Thu, 24 Aug 2023 10:02:40 GMT</pubDate><media:content url="https://breakdev.org/content/images/2023/08/evilginx32-3.png" medium="image"/><content:encoded><![CDATA[<img src="https://breakdev.org/content/images/2023/08/evilginx32-3.png" alt="Evilginx 3.2 - Swimming With The Phishes"><p>Welcome back!</p><p>I&apos;ve recently managed to find some free time to work on <a href="https://twitter.com/mrgretzky/status/1686807176143061000">reverse proxy support for the latest Google updates</a> and in the process I&apos;ve made several additions to the Evilginx code base, which I think some of you will find useful.</p><p>To start, I wanted to give a big shoutout to Daniel (<a href="https://twitter.com/dunderhay">@dunderhay</a>) for <a href="https://research.aurainfosec.io/pentest/hook-line-and-phishlet/">publishing a great post on how he used Evilginx</a> to phish the Microsoft 365 ADFS environment and how he even made his modifications to succeed!</p><p>Evilginx is getting more love this year than in the last couple of years and I&apos;m very happy about it. I have big plans for Evilginx, which I will announce soon, but first I wanted to give you a rundown of what the latest 3.2 update consists of.</p><div class="kg-card kg-button-card kg-align-center"><a href="https://github.com/kgretzky/evilginx2" class="kg-btn kg-btn-accent">Download Evilginx 3.2 - GitHub</a></div><p>I will start with the most significant changes.</p><h2 id="dynamic-redirection-on-session-capture">Dynamic Redirection on Session Capture</h2><p>One of the behaviours, that annoyed me when using Evilginx, was the fact that sometimes it was not possible to immediately redirect the phished user to the configured <code>redirect_url</code>, once all session tokens were captured. Evilginx could only redirect the browser once the targeted website attempted to navigate to a different page, on its own.</p><p>It made redirects not work on single-page applications. I learned it first-hand during the development of the Training Lab for my <a href="https://academy.breakdev.org/evilginx-mastery">Evilginx Mastery</a> course. The main page of the lab changes its contents dynamically and never navigates to a different URL. This means that once session tokens are captured by Evilginx, the tool is unable to redirect the user to <code>redirect_url</code> address.</p><p>In the 3.2 update, I&apos;ve managed to solve the problem with injected JavaScript sending out HTTP long polling requests on every proxied page, to retrieve session capture status directly from the Evilginx proxy server in real-time. Evilginx will inject its own JavaScript code on every HTML page load, which will be responsible for querying <code>https://&lt;phish_domain&gt;/s/&lt;phish_session_id&gt;</code> infinitely. Evilginx proxy server will respond with a JSON structure, containing the <code>redirect_url</code> value only when the session is successfully captured. Otherwise, the connection will time out after 30 seconds and will be retried afterwards. Long polling allows Evilginx to let the injected script know that the session was captured immediately when it happens.</p><p>The script will then change the <code>window.location</code> URL to the retrieved <code>redirect_url</code> value, redirecting the user to a preconfigured page address. Redirection should now work great within <a href="https://academy.breakdev.org/evilginx-mastery">Evilginx Mastery</a> Training Lab.</p><p>Instead of HTTP long polling, I could&apos;ve used WebSockets, but I wanted to keep it simple without the need to rely on external libraries, which would need to be injected as well.</p><h2 id="temporary-lure-pausing">Temporary Lure Pausing</h2><figure class="kg-card kg-image-card"><img src="https://breakdev.org/content/images/2023/08/image-1.png" class="kg-image" alt="Evilginx 3.2 - Swimming With The Phishes" loading="lazy" width="806" height="668" srcset="https://breakdev.org/content/images/size/w600/2023/08/image-1.png 600w, https://breakdev.org/content/images/2023/08/image-1.png 806w" sizes="(min-width: 720px) 720px"></figure><p>Imagine a situation - you&apos;re on a phishing engagement and finally get to send out your phishing lures. Once the emails start arriving at the target inbox, the mailbox server opens them one by one and scans the HTML content of every phishing URL. The mail server then determines emails as phishing and they are sent to quarantine.</p><p>There are many ways to prevent automated scanners from seeing the content of your phishing pages, but the most straightforward method would be to simply hide your phishing pages for a brief moment, right before you send out the emails. Enough to hide their content from automated scanners, but not from the targeted user.</p><p>Now you can easily <a href="https://help.evilginx.com/docs/guides/lures#pause">hide your lures</a> from prying eyes by pausing them for a specific time duration with:</p><pre><code>lures pause &lt;id&gt; &lt;time_duration&gt;</code></pre><p>The best part is that you don&apos;t have to worry about unpausing a lure manually. Once the pause period expires, the lure with become active again and you will get a notification about it in the terminal. The pause state also persists between Evilginx restarts.</p><h2 id="interception-of-http-requests">Interception of HTTP Requests</h2><p>I found out that sometimes it would be useful to be able to block some of the proxied requests or have them return custom responses, without the proxied requests ever reaching the destination server.</p><p>Now you can detect specific requests within the new <code>intercept</code> section in your phishlets, which will match specific URL paths on domains within your <code>proxy_hosts</code> list. Once the request matches your filters, you will be able to detour the request and return your response with a custom HTTP status code.</p><pre><code class="language-yaml">intercept:
  - {domain: &apos;www.linkedin.com&apos;, path: &apos;^\/report_error$&apos;, http_status: 200, body: &apos;{&quot;error&quot;:0}&apos;&apos;, mime: &quot;application/json&quot;}
  - {domain: &apos;app.linkedin.com&apos;, path: &apos;^\/api\/v1\/log\/.*&apos;, http_status: 404}</code></pre><p>In the example above, any request to <code>https://www.linkedin.com/report_error</code> will be intercepted and will return HTTP status <code>200</code> with response body <code>{&quot;error&quot;:0}</code> and MIME type <code>application/json</code>.</p><p>The second entry will make sure that all requests to <code>https://app.linkedin.com/api/v1/log/&lt;whatever&gt;</code> will return <code>404 Not Found</code> HTTP response.</p><h2 id="redirect-url-added-to-phishlets">Redirect URL Added to Phishlets</h2><p>Sometimes for the phishlet to work properly and to not interrupt the phished user&apos;s experience, it needs to redirect the user&apos;s browser right after session tokens are successfully captured. For now, the redirect would happen only if <code>redirect_url</code> was specified for the lure, used with the phishing engagement.</p><p>At times, it is important to have a default <code>redirect_url</code> specified, especially if we want the user to be redirected to the home page of the phished website, by design. Sometimes the redirection to the home page will happen automatically, but sometimes it needs to be enforced.</p><p>From this Evilginx version, you can <a href="https://help.evilginx.com/docs/phishlet-format#header">set a default <code>redirect_url</code> in the phishlet</a> you are creating to make sure the phished user is redirected, once session tokens are captured, even if <code>redirect_url</code> has not been set up for the given lure.</p><h2 id="unauthorized-request-redirects-per-phishlet">Unauthorized Request Redirects Per Phishlet</h2><p>First of all, I&apos;ve changed the name <code>redirect_url</code> from global config to <code>unauth_url</code>, to better illustrate its purpose and so it doesn&apos;t get confused with <code>redirect_url</code> set up in phishlets or lures.</p><p><strong>IMPORTANT! </strong>Keep note that the URL you set for unauthorized request redirects may reset itself after the update, due to the name change.</p><p>Unauthorized URL or <code>unauth_url</code> holds the URL address where visitors will be redirected if they open any URL on the phishing domain, which doesn&apos;t correspond to any valid URL or if the lure is currently paused.</p><p>So far, it was possible to set up <code>unauth_url</code> globally, which would provide the same URL to redirect to for all active phishlets. With 3.2 you can now override the global <code>unauth_url</code> by specifying a value for each phishlet with:</p><pre><code>phishlets unauth_url &lt;phishlet&gt; &lt;url&gt;</code></pre><p>This feature was suggested by <a href="https://twitter.com/0x_aalex">@0x_aalex</a> who was also kind enough to <a href="https://github.com/kgretzky/evilginx2/pull/932">submit a PR</a> with his implementation. Thank you for that!</p><h2 id="tweaks-and-fixes">Tweaks and Fixes</h2><p>Additionally to several new features, Evilginx has also received some QoL tweaks and fixes, which should improve the overall phishing performance.</p><h3 id="disabled-caching-of-proxied-content-by-web-browsers">Disabled caching of proxied content by web browsers</h3><p>Sometimes it was especially frustrating to test the <code>sub_filters</code> of your phishlets because your web browser cached the content of your previous modification. Every time you made small changes and had to retest, it was required to clear the browser cache.</p><p>Starting from the 3.2 update, Evilginx will prevent web browsers from caching HTML, JavaScript and JSON content by injecting <code>Cache-Control: no-cache, no-store</code> HTTP header in proxied responses.</p><p>This should also make working with <code>js_inject</code> much more convenient.</p><h3 id="javascript-injected-through-external-references">JavaScript injected through external references</h3><p>Normally when your phishlets inject JavaScript, through <code>js_inject</code> functionality, Evilginx would drop the whole script into the content of the HTML page within <code>&lt;script&gt;...&lt;/script&gt;</code> tags. This approach was kind of messy, so I figured out a way to inject multiple scripts as external references, like this:</p><pre><code class="language-html">&lt;script type=&quot;application/javascript&quot; src=&quot;/s/48d378a85f0867ef16bf0fd28deda0d4b30139c54805033803e7fdcbc31f293c/2628b4fe94aa35effbe26d64ed6decd00c9d26fb53aa0dfb57836055a27e38cf.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;application/javascript&quot; src=&quot;/s/48d378a85f0867ef16bf0fd28deda0d4b30139c54805033803e7fdcbc31f293c.js&quot;&gt;&lt;/script&gt;
</code></pre><p>Requests to download external JavaScript resources will be intercepted by Evilginx proxy and the response will be delivered from Evilginx directly, without ever being forwarded to the destination website.</p><p>This approach should make it possible to introduce dynamic JS obfuscation, in the future. (Stay tuned!)</p><h2 id="changelog">Changelog</h2><p>Here is the full changelog for Evilginx 3.2:</p><!--kg-card-begin: markdown--><ul>
<li>Feature: URL redirects on successful token capture now work dynamically on every phishing page. Pages do not need to reload or redirect first for the redirects to happen.</li>
<li>Feature: Lures can now be paused for a fixed time duration with <code>lures pause &lt;id&gt;</code>. Useful when you want to briefly redirect your lure URL when you know sandboxes will try to scan them.</li>
<li>Feature: Added phishlet ability to intercept HTTP requests and return custom responses via a new <code>intercept</code> section.</li>
<li>Feature: Added a new optional <code>redirect_url</code> value for phishlet config, which can hold a default redirect URL, to redirect to, once tokens are successfully captured. <code>redirect_url</code> set for the specific lure will override this value.</li>
<li>Feature: You can now override globally set unauthorized redirect URL per phishlet with <code>phishlet unauth_url &lt;phishlet&gt; &lt;url&gt;</code>.</li>
<li>Fixed: Disabled caching for HTML and Javascript content to make on-the-fly proxied content replacements and injections more reliable.</li>
<li>Fixed: Blocked requests will now redirect using javascript, instead of HTTP location header.</li>
<li>Fixed: Improved JS injection by adding <code>&lt;script src&quot;...&quot;&gt;</code> references into HTML pages, instead of dumping the whole script there.</li>
<li>Fixed: Changed <code>redirect_url</code> to <code>unauth_url</code> in global config to avoid confusion.</li>
<li>Fixed: Fixed HTTP status code response for Javascript redirects.</li>
<li>Fixed: Javascript redirects now happen on <code>text/html</code> pages with valid HTML content.</li>
<li>Fixed: Removed <code>ua_filter</code> column from the lures list view. It is still viewable in lure detailed view.</li>
</ul>
<!--kg-card-end: markdown--><h2 id="closing-thoughts">Closing Thoughts</h2><p>Hope you enjoy this update and there is more to come for Evilginx!</p><p>If you are interested in mastering the Evilginx phishing framework, consider checking out my <a href="https://academy.breakdev.org/evilginx-mastery">Evilginx Mastery</a> course:</p><div class="kg-card kg-button-card kg-align-center"><a href="https://academy.breakdev.org/evilginx-mastery" class="kg-btn kg-btn-accent">Check out my Evilginx Mastery course HERE!</a></div><p>In the upcoming weeks, I want to show off a sneak peek of Evilginx Pro and outline all of its extra features. Evilginx Pro will be a paid product I want to distribute only to vetted red teaming companies around the world.</p><p>I will post more details when I&apos;m ready!</p><p>If you are interested in how to protect against reverse proxy phishing, do check out the talk I gave in May at <a href="https://www.x33fcon.com/">x33fcon</a> cybersecurity conference from this year:</p><figure class="kg-card kg-embed-card"><iframe width="200" height="113" src="https://www.youtube.com/embed/C-Fh4sIdY8c?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen title="16. How Much Is The Phish? Evolving Defences Against Evilginx Reverse Proxy Phishing by Kuba Gretzky"></iframe></figure><p>For now, stay tuned and you can always follow me on Twitter <a href="https://twitter.com/mrgretzky">@mrgretzky</a>.</p>]]></content:encoded></item><item><title><![CDATA[Evil QR - Phishing With QR Codes]]></title><description><![CDATA[Evil QR is a spin-off of a QRLJacking attack, demonstrating how attackers could take over accounts by convincing users to scan supplied QR codes, through phishing.]]></description><link>https://breakdev.org/evilqr-phishing/</link><guid isPermaLink="false">64931442b2f8fc4f71e85f09</guid><category><![CDATA[phishing]]></category><category><![CDATA[hacking]]></category><category><![CDATA[tool]]></category><category><![CDATA[research]]></category><dc:creator><![CDATA[Kuba Gretzky]]></dc:creator><pubDate>Wed, 05 Jul 2023 14:31:10 GMT</pubDate><media:content url="https://breakdev.org/content/images/2023/07/evilqr-blog-cover2.png" medium="image"/><content:encoded><![CDATA[<img src="https://breakdev.org/content/images/2023/07/evilqr-blog-cover2.png" alt="Evil QR - Phishing With QR Codes"><p>Today I&apos;m publishing the research I started to work on last year, but I was too busy with the <a href="https://academy.breakdev.org/evilginx-mastery">Evilginx Mastery</a> course, to publish it, at the time.</p><p>If you want a quick TL;DR rundown of what this blog post is about, check out the demo video I prepared:</p><figure class="kg-card kg-embed-card"><iframe width="200" height="113" src="https://www.youtube.com/embed/8pfodWzqMcU?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen title="Evil QR - Phishing With QR Codes"></iframe></figure><h1 id="background">Background</h1><p>In recent years, I&apos;ve noticed that more and more web applications begin to offer a new way to sign in - through QR code scanning. This method is especially convenient if you have a mobile app, on your phone, corresponding to the web application you are trying to sign into, in your web browser.</p><p>Here are the most popular websites, you can sign into, in any web browser, by scanning a QR code within the mobile application.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://breakdev.org/content/images/2023/07/chrome_MjsPYYQP9L.png" class="kg-image" alt="Evil QR - Phishing With QR Codes" loading="lazy" width="885" height="717" srcset="https://breakdev.org/content/images/size/w600/2023/07/chrome_MjsPYYQP9L.png 600w, https://breakdev.org/content/images/2023/07/chrome_MjsPYYQP9L.png 885w" sizes="(min-width: 720px) 720px"><figcaption>Discord</figcaption></figure><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://breakdev.org/content/images/2023/07/chrome_KNrCzWXZJY.png" class="kg-image" alt="Evil QR - Phishing With QR Codes" loading="lazy" width="885" height="717" srcset="https://breakdev.org/content/images/size/w600/2023/07/chrome_KNrCzWXZJY.png 600w, https://breakdev.org/content/images/2023/07/chrome_KNrCzWXZJY.png 885w" sizes="(min-width: 720px) 720px"><figcaption>Telegram</figcaption></figure><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://breakdev.org/content/images/2023/07/chrome_oT6hs4i5n9.png" class="kg-image" alt="Evil QR - Phishing With QR Codes" loading="lazy" width="885" height="717" srcset="https://breakdev.org/content/images/size/w600/2023/07/chrome_oT6hs4i5n9.png 600w, https://breakdev.org/content/images/2023/07/chrome_oT6hs4i5n9.png 885w" sizes="(min-width: 720px) 720px"><figcaption>Whatsapp</figcaption></figure><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://breakdev.org/content/images/2023/07/chrome_jaxSIkFFVQ.png" class="kg-image" alt="Evil QR - Phishing With QR Codes" loading="lazy" width="885" height="717" srcset="https://breakdev.org/content/images/size/w600/2023/07/chrome_jaxSIkFFVQ.png 600w, https://breakdev.org/content/images/2023/07/chrome_jaxSIkFFVQ.png 885w" sizes="(min-width: 720px) 720px"><figcaption>Steam</figcaption></figure><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://breakdev.org/content/images/2023/07/chrome_XeZrh4q1a8.png" class="kg-image" alt="Evil QR - Phishing With QR Codes" loading="lazy" width="885" height="717" srcset="https://breakdev.org/content/images/size/w600/2023/07/chrome_XeZrh4q1a8.png 600w, https://breakdev.org/content/images/2023/07/chrome_XeZrh4q1a8.png 885w" sizes="(min-width: 720px) 720px"><figcaption>TikTok</figcaption></figure><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://breakdev.org/content/images/2023/07/chrome_jt9fNtReWm.png" class="kg-image" alt="Evil QR - Phishing With QR Codes" loading="lazy" width="885" height="717" srcset="https://breakdev.org/content/images/size/w600/2023/07/chrome_jt9fNtReWm.png 600w, https://breakdev.org/content/images/2023/07/chrome_jt9fNtReWm.png 885w" sizes="(min-width: 720px) 720px"><figcaption>Binance</figcaption></figure><p>To sign in, you open the mobile application, navigate to &quot;Scan QR code&quot;, usually residing somewhere within your profile settings, in the mobile application, and scan the QR with your phone camera.</p><p>The QR code, displayed on every sign-in page, is nothing more than a dynamically generated session token, which you can authorize with your mobile application, to pair it with your account.</p><p>Try to scan any of these QR codes with your phone&apos;s camera and you&apos;ll see the code translates into a unique string, usually presented in URL format. Here are several examples:</p><p>Discord:</p><pre><code>https://discord.com/ra/GLt61XsN_fuakToqeSMV25pd3G-uwSbdScI1Zc9iwT8</code></pre><p>Whatsapp:</p><pre><code>2@o7Ugs+XwUVXgG2f8stGluhiItwCxbZJNLkpkeKEhz65GmPh6+/N1lp3fXpaSjxeARrE2JGXi3ikIFA==,it98cjNOA3qvp4i/TidKTeWZTrGkFUTnqsOzPPxFEzI=,AMV+jQ0gSnoFFKbuYzKdrDSPT7BVZ4R5iFxIGEbCqQI=,nVAlyqnDJiYfW/S1LzZoaVNsDm+pNaB1mGm8pGC0+/E=,1</code></pre><p>Steam:</p><pre><code>https://s.team/q/1/1711614348354244891</code></pre><p>TikTok:</p><pre><code>https://www.tiktok.com/t/ZGJXCraU8/</code></pre><p>Binance:</p><pre><code>https://www.binance.com/en/qr/93bd2ead7e504488bda81bf50deab7e8</code></pre><p>Now let&apos;s imagine if there is any potential way, attackers could convince users to scan the QR code with the session token they control.</p><h1 id="meet-evil-qr-phishing-aka-qrljacking">Meet Evil QR Phishing aka QRLJacking</h1><p>One day you receive an email, telling you that you&apos;ve been granted exclusive access to a private Discord server, where highly valuable information will be shared, among the participants. All you need to do is open the attached link and scan the QR code with your Discord application.</p><p>You click the link and the following website shows up in your web browser:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://breakdev.org/content/images/2023/07/chrome_ZDBusl819X.png" class="kg-image" alt="Evil QR - Phishing With QR Codes" loading="lazy" width="937" height="625" srcset="https://breakdev.org/content/images/size/w600/2023/07/chrome_ZDBusl819X.png 600w, https://breakdev.org/content/images/2023/07/chrome_ZDBusl819X.png 937w" sizes="(min-width: 720px) 720px"><figcaption>Phishing page deployed and hosted by the attacker</figcaption></figure><p>Since you are pretty excited to join, you open your Discord application and scan the QR code, showing up on the screen of your PC. Discord asks you to confirm if you want to sign in, using the scanned QR code. You think that it makes sense that you need to be signed in to join the Discord server, so you agree without hesitation.</p><p>Once you approve the login attempt, the website redirects you to the Discord server page. You lose interest and go back to your other activities. All this without realizing, you&apos;ve just given the attacker full access to your account.</p><h2 id="what-happened">What happened?</h2><p>Here is the step-by-step process of what the attacker did to pull off this phishing attack, using the <a href="https://github.com/kgretzky/evilqr">Evil QR</a> toolkit.</p><ol><li>The attacker opens the official <a href="https://discord.com/login">Discord login page</a> within their web browser to generate the sign-in QR code.</li><li>Using the <a href="https://github.com/kgretzky/evilqr">Evil QR</a> browser extension, the attacker is able to extract the sign-in QR code from the login page and upload it to the <a href="https://github.com/kgretzky/evilqr">Evil QR</a> server, where the phishing page is hosted.</li><li>The phishing page, hosted by the attacker, dynamically displays the most recent sign-in QR code controlled by the attacker.</li></ol><p>Once the target successfully scans the QR code, the attacker takes over the phished account.</p><p>The concept of phishing users with sign-in QR codes is not new and it has been <a href="https://seekurity.com/blog/2016/11/04/admin/phishing-analysis/qrljacking-your-qr-based-session-belongs-to-us">broadly documented</a> by <a href="https://twitter.com/SymbianSyMoh">Mohamed Abdelbasset Elnouby (@SymbianSyMoh)</a> from <a href="https://seekurity.com/">Seekurity</a> in 2016! I highly recommend you read this post as it covers a lot of information about the potential attack vectors, which could be used to pull off such attacks.</p><p>The technique was later officially recognized as <a href="https://owasp.org/www-community/attacks/Qrljacking">QRLJacking</a> and <a href="https://twitter.com/SymbianSyMoh/status/1675895436870139904">@SymbianSyMoh</a> also released a <a href="https://github.com/OWASP/QRLJacking">QRLJacker</a> tool in 2020 to demonstrate how such attacks can be executed. Evil QR idea is just a spin-off of the same idea.</p><h1 id="evil-qr-toolkit">Evil QR Toolkit</h1><p>To demonstrate this interesting phishing technique, I&apos;ve developed a set of proof-of-concept tools for demonstration purposes.</p><p>You can find the open-sourced <a href="https://github.com/kgretzky/evilqr">Evil QR</a> toolkit on my <a href="https://github.com/kgretzky/evilqr">GitHub</a> if you&apos;re interested in trying it out yourself.</p><p>As you can see below, the Evil QR attack can be customized using personalized phishing pre-text, with dynamic updates, for every website separately. Evil QR browser extension can detect and extract QR codes, within websites, no matter how they are rendered.</p><p>The extension supports extracting QR codes rendered as <code>CANVAS</code>, <code>IMG</code>, <code>SVG</code> or even <code>DIV</code> (by taking a screenshot with <a href="https://html2canvas.hertzen.com/">html2canvas</a> library).</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://breakdev.org/content/images/2023/07/evilqr-phishing.gif" class="kg-image" alt="Evil QR - Phishing With QR Codes" loading="lazy" width="1921" height="1079" srcset="https://breakdev.org/content/images/size/w600/2023/07/evilqr-phishing.gif 600w, https://breakdev.org/content/images/size/w1000/2023/07/evilqr-phishing.gif 1000w, https://breakdev.org/content/images/size/w1600/2023/07/evilqr-phishing.gif 1600w, https://breakdev.org/content/images/2023/07/evilqr-phishing.gif 1921w" sizes="(min-width: 1200px) 1200px"></figure><h3 id="evil-qr-server">Evil QR Server</h3><p>The server is developed in GO and its main purpose is to expose REST API for the browser extension and run an HTTP server to host the phishing page.</p><p>It awaits authenticated communication from the browser extension including QR code image with metadata in JSON format on <code>/qrcode/[qr_uuid]</code> endpoint:</p><pre><code class="language-json">{
    &quot;id&quot;: &quot;11111111-1111-1111-1111-111111111111&quot;,
    &quot;source&quot;: &quot;data:image/png;base64,iVBORw0K...&quot;,
    &quot;host&quot;: &quot;discord.com&quot;
}</code></pre><p>The retrieved QR code is then stored and is available for retrieval by the JavaScript, running on the phishing page. The phishing page is using <a href="https://www.pubnub.com/blog/http-long-polling/">HTTP Long Polling</a> to be able to retrieve QR code updates with minimal delays, without having to use Websockets.</p><p>The phishing page automatically detects which hostname the QR code was retrieved from and can dynamically adjust its CSS and text content to change the phishing pre-text, for social engineering purposes.</p><h3 id="evil-qr-browser-extension">Evil QR Browser Extension</h3><figure class="kg-card kg-image-card"><img src="https://breakdev.org/content/images/2023/07/image.png" class="kg-image" alt="Evil QR - Phishing With QR Codes" loading="lazy" width="412" height="222"></figure><p>The extension is used solely by the attacker and it needs to be enabled on the sign-in page of the web application, the target is phished for. It will automatically find the QR code image and detect if it changes. Once it changes, it will upload the updated image to the Evil QR server.</p><p>One of the most important characteristics of session tokens represented by sign-in QR codes, is that the tokens are short-lived by design. Every token is made to expire approximately after 30 seconds, which drastically shortens the time frame of the token&apos;s validity. Once the token expires, the website regenerates it and updates the displayed QR code, on the sign-in page.</p><p>If the sign-in session tokens did not expire, the attackers would hypothetically be able to print out the QR codes on a physical piece of paper and send them as phishing leaflets to potential victims, since the tokens would never expire.</p><p>Some websites will stop updating QR codes, after a certain period of inactivity, to save bandwidth. When this happens, they will usually display a &quot;Retry&quot; button of some sort, which the extension can automatically detect and click on, to not interrupt the process of updating QR codes.</p><p>The extension can also detect the presence of a specific DOM object, which will show up only when the attacker is signed in after the phishing attempt is successful. It will then send an update to the Evil QR server with <code>authorized: &quot;true&quot;</code> parameter, allowing the phishing page to decide on how to proceed.</p><h1 id="how-serious-is-this">How serious is this?</h1><p>In my personal opinion - not that serious. For the QRLJacking phishing attack to be successful, it requires a lot of prerequisites to be met prior to the attack taking place. Nevertheless, it was a very fun project to work on.</p><p>The classic phishing attacks, focused on capturing credentials and session tokens to <a href="https://breakdev.org/evilginx-3-0-evilginx-mastery/">bypass multi-factor authentication</a>, are still much more dangerous than this one and they can be executed on a much larger scale using a tool like <a href="https://github.com/kgretzky/evilginx2">Evilginx</a> for example.</p><p>I think the most realistic scenario of how QRLJacking phishing could be pulled off, would be to set up a phishing page with a QR code on display using an external device, deployed in public, like a <a href="https://youtu.be/8pfodWzqMcU">tablet or TV screen</a>. Once one person successfully signs in, by scanning a QR code, the attacker&apos;s Evil QR setup would save the captured session for later and reload the new sign-in page to generate a new QR code to phish another user.</p><p>That could in theory make it possible to phish a larger number of users, one at a time. I don&apos;t think QRLJacking phishing is a viable technique when sending phishing links via e-mail or other mediums. These days most people read incoming messages on their mobile phones and once the phishing page with a QR code shows up on their phone&apos;s screen, it is impossible to use the same phone&apos;s camera to scan it.</p><p>To summarize, here is a list of all pros and cons of executing this phishing attack technique, I could think of:</p><p><strong>Pros:</strong></p><ul><li>No need for the target to enter their username and password.</li><li>Could be potentially pulled off in public areas, having an external device displaying a phishing QR code, on display.</li></ul><p><strong>Cons:</strong></p><ul><li>Target needs to have the mobile app pre-installed for the given service.</li><li>Attacks are hard to pull off, on a wider scale, since there has to be a separate QR code generated for every target.</li><li>Usually pretty hard to find the setting to scan QR codes within mobile applications, involving multiple clicks, with every click lowering the chance of a successful social engineering attempt.</li><li>If a phishing page is opened on a mobile phone, there is no way for the target to scan the QR code with the same mobile phone.</li></ul><h1 id="closing-thoughts">Closing thoughts</h1><p>I decided not to implement this attack vector into <a href="https://github.com/kgretzky/evilginx2">Evilginx</a> phishing framework, since Evilginx is already powerful on its own.</p><p>While sign-in QR codes displayed on phishing pages, reverse proxied by Evilginx, will not let you sign in by scanning them, due to hostname mismatch, it is still possible to patch the JavaScript code, which generates them, to make them work on phishing pages.</p><p>If you&apos;re interested in learning more about reverse proxy phishing to bypass MFA, check out my <a href="https://academy.breakdev.org/evilginx-mastery">Evilginx Mastery</a> video course, which will teach you everything you need to know to perform successful red team phishing engagements.</p><p>Till next time!</p>]]></content:encoded></item><item><title><![CDATA[Evilginx 3.0 + Evilginx Mastery]]></title><description><![CDATA[I'm finally releasing the new update to Evilginx, together with Evilginx Mastery video course, created to teach you everything you need to know about reverse proxy phishing and using Evilginx in most efficient manner.]]></description><link>https://breakdev.org/evilginx-3-0-evilginx-mastery/</link><guid isPermaLink="false">6456c7fbb2f8fc4f71e85822</guid><category><![CDATA[evilginx]]></category><category><![CDATA[hacking]]></category><category><![CDATA[2fa]]></category><dc:creator><![CDATA[Kuba Gretzky]]></dc:creator><pubDate>Wed, 10 May 2023 09:16:44 GMT</pubDate><media:content url="https://breakdev.org/content/images/2023/05/evilginx_blog_title_30_mastery.png" medium="image"/><content:encoded><![CDATA[<img src="https://breakdev.org/content/images/2023/05/evilginx_blog_title_30_mastery.png" alt="Evilginx 3.0 + Evilginx Mastery"><p>This post has been long coming and I&apos;m glad to finally be able to make it happen!</p><p>Today I&apos;m finally releasing <a href="https://github.com/kgretzky/evilginx2">Evilginx 3.0</a>, together with <strong><a href="https://academy.breakdev.org/evilginx-mastery">Evilginx Mastery</a> </strong>online course, into which I&apos;ve poured everything I know about Evilginx and how to use it in the most effective manner.</p><p>Evilginx hasn&apos;t seen any updates for nearly two and a half years. That&apos;s why it was a great surprise to me to hear, that even though I haven&apos;t released any updates, a lot of red teamers still use this tool for phishing simulations with many successes. I&apos;ve been amazed to come across some great posts about Evilginx, like the ones by <a href="https://janbakker.tech/how-to-set-up-evilginx-to-phish-office-365-credentials/">Jan Bakker</a>, <a href="https://jeffreyappel.nl/protect-against-aitm-mfa-phishing-attacks-using-microsoft-technology/">Jeffrey Appel</a> or <a href="https://pberba.github.io/security/2020/05/28/lastpass-phishing/">Pepe Berba</a>.</p><p>Talking to people in the industry motivated me to give Evilginx a quality of life refresher, in order to build stronger foundations for future updates. It&apos;s been nearly 6 years, since I&apos;ve released the first version of Evilginx, which was nothing more than a LUA script for custom version of <em>nginx. </em>Back then I couldn&apos;t have foreseen such great reception, the tool would receive, over the years.</p><p>It&apos;s a fact, that a lot of people have been struggling to figure out how to properly use Evilginx or create their own phishlets. Lack of official documentation to guides didn&apos;t help and you could only get so far, analyzing public phishlets and trying to figure out how they work through trial &amp; error.</p><p>Additionally, to my surprise, during recent years, not many websites have attempted to develop their own detections for reverse proxy phishing. I need to actually hand it to Google and Microsoft as they seem to have been one of the few companies doing anything to protect their users against reverse proxy phishing.</p><p>All this will hopefully change today. Here is, in detail, what I&apos;ve been working on, for the past year, and what I&apos;m today releasing to the public:</p><h1 id="evilginx-mastery-course">Evilginx Mastery Course</h1><p>Public version of Evilginx will always remain open-source and free to use. You can use the tool as you see fit. To fund further development, I decided to publish a paid online course, with which I could demonstrate my whole knowledge about Evilginx and share hands-on step by step video footage showing how I personally use Evilginx, myself.</p><p>Big thanks to <a href="https://twitter.com/SEKTOR7net">SEKTOR7</a> and <a href="https://twitter.com/_RastaMouse">Rasta Mouse</a> for encouragement to make an attempt in creating an Evilginx course.</p><p>The course is also prepared with defenders in mind. Seeing how little websites do to protect from reverse proxy phishing, nowadays, I&apos;ve included tips on what defenders can do to make reverse proxy phishing attacks extremely hard or nearly impossible to pull off.</p><p>If you decide to purchase the course, thank you in advance and keep in mind that it helps me greatly to continue working on Evilginx and will definitely be a great contribution to my levels of motivation.</p><p>If you plan to purchase access to the course for multiple employees in your company, please contact me directly at <a href="mailto:kuba@breakdev.org">kuba@breakdev.org</a> and we can work out a discount.</p><p>You can buy the course online and watch the lessons, at your own pace, whenever you want: <a href="https://academy.breakdev.org/evilginx-mastery">Evilginx Mastery - Reverse Proxy MFA Phishing Guide For Red Teams</a></p><p>To know more about the course, take a look at my attempt to make a promotional video for the course. And yes I know how to blink :D</p><figure class="kg-card kg-embed-card"><iframe width="200" height="113" src="https://www.youtube.com/embed/yqu0Yt2CYEg?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen title="Evilginx Mastery - MFA Phishing for Red Teams"></iframe></figure><h1 id="evilginx-30">Evilginx 3.0</h1><p>This version is not delivering flashy big features, but rather it serves as a quality-of-life update. I&apos;ve fixed numerous issues, which have been lingering in Evilginx for a long time and updated some mechanics to make the tool work better than before.</p><p>GitHub: <a href="https://github.com/kgretzky/evilginx2"><a href="https://github.com/kgretzky/evilginx2">https://github.com/kgretzky/evilginx2</a></a></p><p>Here are some highlights of what has changed:</p><h3 id="improved-tls-certificate-management">Improved TLS certificate management</h3><p>I&apos;ve ditched the old GO library for managing LetsEncrypt certificates and switched to well-maintained <a href="https://github.com/caddyserver/certmagic">certmagic</a> library. This change now allows to perform automated retrieval of TLS certificates, from LetsEncrypt, more efficiently and most importantly, Evilginx will now <u>automatically renew expiring certificates</u>, so you won&apos;t have to ever worry about your phishing campaigns expiring without warning.</p><h3 id="session-tokens-can-now-be-extracted-from-response-body-or-http-headers">Session tokens can now be extracted from response body or HTTP Headers</h3><p>Ever since Evilginx was released, I&apos;ve only considered a single scenario where session tokens are to be transmitted as HTTP cookies. Over the years, I&apos;ve learned this approach was wrong, as now it is becoming more and more common for session tokens to be retrieved in JSON packets and later stored as <a href="https://blog.logrocket.com/localstorage-javascript-complete-guide/">LocalStorage</a> values. This is now especially common practice with web applications relying heavily on JavaScript functionality like messenger applications.</p><p>It is now possible to look for session tokens in HTTP response packets body or in contents of HTTP headers like the <code>Authorization</code> header.</p><p>I&apos;ve covered how to handle such scenario in one of the training labs from <a href="https://academy.breakdev.org/evilginx-mastery">Evilginx Mastery</a> course.</p><h3 id="example-phishlets-no-longer-available-in-main-repository">Example phishlets no longer available in main repository</h3><p>My main goal has always been to deliver a reverse proxy phishing framework for red teamers. The provided example phishlets were always meant to serve as a learning material to learn how to make your own phishlets. Keeping them updated, was honestly an impossible feat. This is why I&apos;ve made a decision to cease support for example phishlets in the main Evilginx repository.</p><p>Phishlets get outdated and stop working relatively fast and I always wanted to focus on developing the framework, rather then keeping the example phishlets constantly up-to-date. I encourage everyone to set up their own repositories with phishlets they want to share with the community. My priority now is to put effort into teaching people <a href="https://academy.breakdev.org/evilginx-mastery">how to create their own phishlets</a>.</p><p>Once I find several contributors, who may want to work on several phishlets for fun, I may set up a new repository just for aggregating several working and tested phishlets, made by others, and later have it integrated somehow with Evilginx installations.</p><h3 id="phishing-pages-can-now-be-embedded-within-iframes">Phishing pages can now be embedded within iframes</h3><p>Few months ago, the legendary <a href="https://twitter.com/mrd0x">mr.d0x</a>, released amazing research on <a href="https://mrd0x.com/browser-in-the-browser-phishing-attack/">BITB</a> (browser-in-the-browser) phishing, where you could create a fake popup window, with JavaScript, showing a spoofed URL in fake address bar. I liked the idea so much that I really wanted to see it working with Evilginx.</p><p>Displaying phishing pages in iframes turned out to not be supported, by default. Now you can fully enjoy displaying your phishing page within iframes. Just make sure to fully rewrite the default BITB templates as they have been heavily flagged by Google as malicious content.</p><p>Also make sure to check out <a href="https://twitter.com/mrd0x">mr.d0x</a> courses on <a href="https://maldevacademy.com/">Malware Development</a>!</p><h3 id="configuration-format-changed-to-json">Configuration format changed to JSON</h3><p>Evilginx configuration file was stored originally in YAML format. JSON, overall, is a much better option, with its syntax being easier to use than YAML, but maybe a bit harder to read. Nevertheless, with config file in JSON format, it will be easier to write custom deployment scripts, handling dynamic generation of configuration files.</p><p>Phishlets will remain in YAML format.</p><h3 id="phishing-sessions-are-now-created-always-when-valid-lure-url-is-opened">Phishing sessions are now created always when valid lure URL is opened</h3><p>Evilginx would whitelist IP addresses of every target, making requests to valid lure URLs. This is required to later allow the proxying of requests, which cannot contain Evilginx session cookies, due to web browsers not allowing some requests to transmit cookies.</p><p>The bug in Evilginx would prevent creation of new reverse proxy sessions for valid lure URLs coming from IP addresses, which have already been whitelisted.</p><p>In 3.0 update, every time a target opens a valid lure URL, they will be assigned a new reverse proxy session. This fix will also make it possible to properly track the clicks to your lure URLs.</p><h3 id="child-phishlets-derived-from-phishlet-templates">Child phishlets derived from phishlet templates</h3><p>One of the problematic issues Evilginx users have encountered was targeting websites, which were hosted under customized hostnames.</p><p>Say you wanted to target a specific company&apos;s Okta portal, hosted on <code>evilcorp.okta.com</code> domain. To target custom domains, you&apos;d have to manually edit the phishlet file and put the hardcoded <code>evilcorp.okta.com</code> into it.</p><p>With the phishlet templates feature, instead of having to modify a phishlet file manually, every time you&apos;d need to target a different hostname, now you can create a phishlet template for Okta, setting up a placeholder for custom variables in your phishlet file e.g. <code>{subdomain}.okta.com</code>.</p><p>Having such template, whenever you&apos;d need to target a specific hostname, you could just create a child phishlet as a derivative from your phishlet template and specify <code>subdomain=evilcorp</code>, as an example. Such created child phishlet can be then used as a normal phishlet with its own personalized setup.</p><p>You can learn how to create and use phishlet templates in my <a href="https://academy.breakdev.org/evilginx-mastery">Evilginx Mastery</a> course, as well.</p><h3 id="url-redirection-with-javascript">URL redirection with JavaScript</h3><p>Originally when all session tokens have been successfully captured, Evilginx would redirect the user to preconfigured <code>redirect_url</code> URL through HTTP <code>Location</code> header. I found this solution to not be ideal, since this approach exposed the phishing URL to destination website, through <code>Referer</code> header, when redirection took place.</p><p>Since 3.0, the redirection will happen via JavaScript injected into <code>text/html</code> content of the next web page, loaded after all session tokens have been captured. This approach will avoid populating the <code>Referer</code> header with your phishing URL. There is still one issue with redirecting the user if the website does not load any new pages after successful sign-in. This I will try to tackle in future updates.</p><h3 id="license-changed-from-gpl-to-bsd-3">License changed from GPL to BSD-3</h3><p>In short - GPL requires to redistribute the tool with full source code. BSD-3 is more permissive, allowing to redistribute the tool without it.</p><h3 id="changelog">Changelog</h3><p>The full changelog for <a href="https://github.com/kgretzky/evilginx2">Evilginx 3.0</a> is as follows:</p><!--kg-card-begin: markdown--><ul>
<li>Feature: TLS certificates from LetsEncrypt will now get automatically renewed.</li>
<li>Feature: Automated retrieval and renewal of LetsEncrypt TLS certificates is now managed by <code>certmagic</code> library.</li>
<li>Feature: Authentication tokens can now be captured not only from cookies, but also from response body and HTTP headers.</li>
<li>Feature: Phishing pages can now be embedded inside of iframes.</li>
<li>Feature: Changed redirection after successful session capture from <code>Location</code> header redirection to injected Javascript redirection.</li>
<li>Feature: Changed config file from <code>config.yaml</code> to <code>config.json</code>, permanently changing the configuration format to JSON.</li>
<li>Feature: Changed open-source license from GPL to BSD-3.</li>
<li>Feature: Added <code>always</code> modifier for capturing authentication cookies, forcing to capture a cookie even if it has no expiration time.</li>
<li>Feature: Added <code>phishlet &lt;phishlet&gt;</code> command to show details of a specific phishlet.</li>
<li>Feature: Added phishlet templates, allowing to create child phishlets with custom parameters like pre-configured subdomain or domain. Parameters can be defined anywhere in the phishlet file as <code>{param_name}</code> and every occurence will be replaced with pre-configured parameter values of the created child phishlet.</li>
<li>Feature: Added <code>phishlet create</code> command to create child phishlets from template phishlets.</li>
<li>Feature: Renamed lure <code>templates</code> to lure <code>redirectors</code> due to name conflict with phishlet templates.</li>
<li>Feature: Added <code>{orig_hostname}</code> and <code>{orig_domain}</code> support for <code>sub_filters</code> phishlet setting.</li>
<li>Feature: Added <code>{basedomain}</code> and <code>{basedomain_regexp}</code> support for <code>sub_filters</code> phishlet setting.</li>
<li>Fixed: One target can now have multiple phishing sessions active for several different phishlets.</li>
<li>Fixed: Cookie capture from HTTP packet response will not stop mid-term, ignoring missing <code>opt</code> cookies, when all authentication cookies are already captured.</li>
<li>Fixed: <code>trigger_paths</code> regexp will now match a full string instead of triggering true when just part of it is detected in URL path.</li>
<li>Fixed: Phishlet table rows are now sorted alphabetically.</li>
<li>Fixed: Improved phishing session management to always create a new session when lure URL is hit if session cookie is not present, even when IP whitelist is set.</li>
<li>Fixed: WebSocket connections are now properly proxied.</li>
</ul>
<!--kg-card-end: markdown--><h1 id="evilginx-online-documentation">Evilginx Online Documentation</h1><p>As Evilginx kept growing it become harder and harder to keep up with all the features. GitHub Wiki kind of worked to, at least, provide documentation for the latest phishlet format, but I&apos;ve never been fully satisfied with it.</p><p>I&apos;ve always wanted the documentation to be easily accessible, well structured, easy to navigate and to have a quality look &amp; feel. I can happily say, I may&apos;ve found the perfect solution with <a href="https://docusaurus.io/">Docusaurus</a>.</p><p>Evilginx most up-to-date documentation, since today, will always be accessible through one official URL: <a href="https://help.evilginx.com">https://help.evilginx.com</a></p><p>Check it out!</p><p>I honestly think, now with Evilginx having proper documentation, it will become much easier for everyone to use. I strongly hope you make good use of it! I&apos;m often using it myself when I forget how the tool I made is supposed to work :P</p><h1 id="closing-thoughts">Closing thoughts</h1><p>The last 6 years have been a wild ride and I can&apos;t thank everyone enough for giving Evilginx a shot. I&apos;ve never expected a tool, based on a simple idea, would eventually become a tool people use at work, to simulate phishing attacks. Mention of Evilginx even made it to <a href="https://techcrunch.com/2018/05/10/hacker-kevin-mitnick-shows-how-to-bypass-2fa/">TechCrunch</a>, at one point.</p><p>I really hope <a href="https://github.com/kgretzky/evilginx2">Evilginx</a> will continue to serve its purpose in aiding you during your phishing engagements. Thank you, again, and if you decide to give <a href="https://academy.breakdev.org/evilginx-mastery">Evilginx Mastery</a> course a try, accept my eternal gratitude!</p><p>To end with a cliffhanger, I will say that Evilginx story is not over and there may be <strong>Evilginx Pro </strong>in the works, with some special features I decided to keep private for now. The pro version will most likely be licensed only to cybersecurity companies. Some of you may find mentions about private features in the official <a href="https://help.evilginx.com">online documentation</a>.</p><p>For updates follow me on Twitter <a href="https://twitter.com/mrgretzky">@mrgretzky</a> and Mastodon <a href="https://infosec.exchange/@mrgretzky">@mrgretzky@infosec.exchange</a>.</p><p>If you have any inquires about company discounts or if you require any custom functionality in Evilginx, you can always contact me directly at: <a href="mailto:kuba@breakdev.org">kuba@breakdev.org</a>.</p><p>As always - enjoy and stay tuned!</p><figure class="kg-card kg-image-card kg-card-hascaption"><a href="https://academy.breakdev.org/evilginx-mastery"><img src="https://breakdev.org/content/images/2023/08/evilginx_mastery_cover.png" class="kg-image" alt="Evilginx 3.0 + Evilginx Mastery" loading="lazy" width="1280" height="720" srcset="https://breakdev.org/content/images/size/w600/2023/08/evilginx_mastery_cover.png 600w, https://breakdev.org/content/images/size/w1000/2023/08/evilginx_mastery_cover.png 1000w, https://breakdev.org/content/images/2023/08/evilginx_mastery_cover.png 1280w" sizes="(min-width: 720px) 720px"></a><figcaption>Evilginx Mastery - Available NOW</figcaption></figure><p></p>]]></content:encoded></item><item><title><![CDATA[Exploring ZIP Mark-of-the-Web Bypass Vulnerability (CVE-2022-41049)]]></title><description><![CDATA[Windows ZIP extraction bug (CVE-2022-41049) lets attackers craft ZIP files, which evade warnings on attempts to execute packaged files, even if ZIP file was downloaded from the Internet.]]></description><link>https://breakdev.org/zip-motw-bug-analysis/</link><guid isPermaLink="false">636261b888520f0bb9d22352</guid><category><![CDATA[windows]]></category><category><![CDATA[vulnerability]]></category><category><![CDATA[research]]></category><dc:creator><![CDATA[Kuba Gretzky]]></dc:creator><pubDate>Tue, 08 Nov 2022 20:12:41 GMT</pubDate><media:content url="https://breakdev.org/content/images/2022/11/zip-motw.png" medium="image"/><content:encoded><![CDATA[<img src="https://breakdev.org/content/images/2022/11/zip-motw.png" alt="Exploring ZIP Mark-of-the-Web Bypass Vulnerability (CVE-2022-41049)"><p>In October 2022, I&apos;ve come across a tweet from 5th July, from <a href="https://twitter.com/wdormann">@wdormann</a>, who reported a discovery of a new method for bypassing <a href="https://twitter.com/wdormann">MOTW</a>, using a flaw in how Windows handles file extraction from ZIP files.</p><figure class="kg-card kg-embed-card"><blockquote class="twitter-tweet"><p lang="en" dir="ltr">So if it were a ZIP instead of ISO, would MotW be fine?<br>Not really. Even though Windows tries to apply MotW to extracted ZIP contents, it&apos;s really quite bad at it.<br>Without trying too hard, here I&apos;ve got a ZIP file where the contents retain NO protection from Mark of the Web. <a href="https://t.co/1SOuzfca5q">pic.twitter.com/1SOuzfca5q</a></p>&#x2014; Will Dormann (@wdormann) <a href="https://twitter.com/wdormann/status/1544416883419619333?ref_src=twsrc%5Etfw">July 5, 2022</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
</figure><p>This sounded to me like a nice challenge to freshen up my rusty RE skills. The bug was also a 0-day, at the time. It has already been reported to Microsoft, without a fix deployed for more than 90 days.</p><p>What I always find the most interesting about vulnerability research write-ups is the process on how one found the bug, what tools were used and what approach was taken. I wanted this post to be like this.</p><p>Now that the vulnerability has been fixed, I can freely publish the details.</p><h1 id="background">Background</h1><p>What I found out, based on public information about the bug and demo videos, was that Windows, somehow, does not append MOTW to files extracted from ZIP files.</p><p>Mark-of-the-web is really another file attached as an Alternate Data Stream (ADS), named <code>Zone.Identifier</code>, and it is only available on NTFS filesystems. The ADS file always contains the same content:</p><pre><code>[ZoneTransfer]
ZoneId=3
</code></pre><p>For example, when you download a ZIP file <code>file.zip</code>, from the Internet, the browser will automatically add <code>file.zip:Zone.Identifier</code> ADS to it, with the above contents, to indicate that the file has been downloaded from the Internet and that Windows needs to warn the user of any risks involving this file&apos;s execution.</p><p>This is what happens when you try to execute an executable like a JScript file, through double-clicking, stored in a ZIP file, with MOTW attached.</p><figure class="kg-card kg-image-card"><img src="https://breakdev.org/content/images/2022/11/image.png" class="kg-image" alt="Exploring ZIP Mark-of-the-Web Bypass Vulnerability (CVE-2022-41049)" loading="lazy" width="466" height="325"></figure><p>Clearly the user would think twice before opening it when such popup shows up. This is not the case, though, for specially crafted ZIP files bypassing that feature.</p><p>Let&apos;s find the cause of the bug.</p><h1 id="identifying-the-culprit">Identifying the culprit</h1><p>What I knew already from my observation is that the bug was triggered when <code>explorer.exe</code> process handles the extraction of ZIP files. I figured the process must be using some internal Windows library for handling ZIP files unpacking and I was not mistaken.</p><figure class="kg-card kg-image-card"><img src="https://breakdev.org/content/images/2022/11/image-1.png" class="kg-image" alt="Exploring ZIP Mark-of-the-Web Bypass Vulnerability (CVE-2022-41049)" loading="lazy" width="483" height="573"></figure><p>ProcessHacker revealed <code>zipfldr.dll</code> module loaded within Explorer process and it looked like a good starting point. I booted up IDA with conveniently provided symbols from Microsoft, to look around.</p><p><code>ExtractFromZipToFile</code> function immediately caught my attention. I created a sample ZIP file with a packaged JScript file, for testing, which had a single instruction:</p><pre><code class="language-js">WScript.Echo(&quot;YOU GOT HACKED!!1&quot;);
</code></pre><p>I then added a MOTW ADS file with Notepad and filled it with MOTW contents, mentioned above:</p><pre><code>notepad file.zip:Zone.Identifier</code></pre><p>I loaded up <code>x64dbg</code> debugger, attached it to <code>explorer.exe</code> and set up a breakpoint on <code>ExtractFromZipToFile</code>. When I double-clicked the JS file, the breakpoint triggered and I could confirm I&apos;m on the right path.</p><h1 id="checkunzippedfile">CheckUnZippedFile</h1><p>One of the function calls I noticed nearby, revealed an interesting pattern in IDA. Right after the file is extracted and specific conditions are meet, <code>CheckUnZippedFile</code> function is called, followed by a call to <code>_OpenExplorerTempFile</code>, which opens the extracted file.</p><figure class="kg-card kg-image-card"><img src="https://breakdev.org/content/images/2022/11/image-2.png" class="kg-image" alt="Exploring ZIP Mark-of-the-Web Bypass Vulnerability (CVE-2022-41049)" loading="lazy" width="1323" height="1125" srcset="https://breakdev.org/content/images/size/w600/2022/11/image-2.png 600w, https://breakdev.org/content/images/size/w1000/2022/11/image-2.png 1000w, https://breakdev.org/content/images/2022/11/image-2.png 1323w" sizes="(min-width: 720px) 720px"></figure><p>Having a hunch that <code>CheckUnZippedFile</code> is the function responsible for adding MOTW to extracted file, I nopped its call and found that I stopped getting the MOTW warning popup, when I tried executing a JScript file from within the ZIP.</p><p>It was clear to me that if I managed to manipulate the execution flow in such a way that the branch, executing this function is skipped, I will be able to achieve the desired effect of bypassing the creation of MOTW on extracted files. I looked into the function to investigate further.</p><p>I noticed that <code>CheckUnZippedFile</code> tries to combine the TEMP folder path with the zipped file filename, extracted from the ZIP file, and when this function fails, the function quits, skipping the creation of MOTW file.</p><figure class="kg-card kg-image-card"><img src="https://breakdev.org/content/images/2022/11/image-3.png" class="kg-image" alt="Exploring ZIP Mark-of-the-Web Bypass Vulnerability (CVE-2022-41049)" loading="lazy" width="1920" height="1200" srcset="https://breakdev.org/content/images/size/w600/2022/11/image-3.png 600w, https://breakdev.org/content/images/size/w1000/2022/11/image-3.png 1000w, https://breakdev.org/content/images/size/w1600/2022/11/image-3.png 1600w, https://breakdev.org/content/images/2022/11/image-3.png 1920w" sizes="(min-width: 720px) 720px"></figure><p>Considering that I controlled the filename of the extracted ZIP file, I could possibly manipulate its content to trigger <code>PathCombineW</code> to fail and as a result achieve my goal.</p><p><code>PathCombineW</code> turned out to be a wrapper around <code>PathCchCombineExW</code> function with output buffer size limit set to fixed value of <code>260</code> bytes. I thought that if I managed to create a really long filename or use some special characters, which would be ignored by the function handling the file extraction, but would trigger the length check in <code>CheckUnZippedFile</code> to fail, it could work.</p><p>I opened <a href="https://www.sweetscape.com/010editor/">010 Editor</a>, which I highly recommend for any kind of hex editing work, and opened my sample ZIP file with a built-in ZIP template.</p><figure class="kg-card kg-image-card"><img src="https://breakdev.org/content/images/2022/11/image-4.png" class="kg-image" alt="Exploring ZIP Mark-of-the-Web Bypass Vulnerability (CVE-2022-41049)" loading="lazy" width="1225" height="948" srcset="https://breakdev.org/content/images/size/w600/2022/11/image-4.png 600w, https://breakdev.org/content/images/size/w1000/2022/11/image-4.png 1000w, https://breakdev.org/content/images/2022/11/image-4.png 1225w" sizes="(min-width: 720px) 720px"></figure><p>I spent few hours testing with different filename lengths, with different special characters, just to see if the extraction function would behave in erratic way. Unfortunately I found out that there was another path length check, called prior to the one I&apos;ve been investigating. It triggered much earlier and prevented me from exploiting this one specific check. I had to start over and consider this path a dead end.</p><p>I looked if there are any controllable branching conditions, that would result in not triggering the call to <code>CheckUnZippedFile</code> at all, but none of them seemed to be dependent on any of the internal ZIP file parameters. I considered looking deeper into <code>CheckUnZippedFile</code> function and found out that when <code>PathCombineW</code> call succeeds, it creates a <code>CAttachmentServices</code> COM objects, which has its three methods called:</p><pre><code>CAttachmentServices::SetReferrer(unsigned short const * __ptr64)
CAttachmentServices::SetSource(unsigned short const * __ptr64)
CAttachmentServices::SaveWithUI(struct HWND__ * __ptr64)</code></pre><p>I realized I am about to go deep down a rabbit hole and I may spend there much longer than a hobby project like that should require. I had to get a public exploit sample to speed things up.</p><p>Huge thanks you <a href="https://twitter.com/bohops">@bohops</a> &amp; <a href="https://twitter.com/buffaloverflow">@bufalloveflow</a> for all the help in getting the sample!</p><h1 id="detonating-the-live-sample">Detonating the live sample</h1><p>I managed to copy over all relevant ZIP file parameters from the obtained exploit sample into my test sample and I confirmed that MOTW was gone, when I extracted the sample JScript file.</p><p>I decided to dig deeper into <code>SaveWithUI</code> COM method to find the exact place where creation of <code>Zone.Identifier</code> ADS fails. Navigating through <code>shdocvw.dll</code>, I ended up in <code>urlmon.dll</code> with a failing call to <code><a href="https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-writeprivateprofilestringw">WritePrivateProfileStringW</a></code>.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://breakdev.org/content/images/2022/11/image-5.png" class="kg-image" alt="Exploring ZIP Mark-of-the-Web Bypass Vulnerability (CVE-2022-41049)" loading="lazy" width="693" height="178" srcset="https://breakdev.org/content/images/size/w600/2022/11/image-5.png 600w, https://breakdev.org/content/images/2022/11/image-5.png 693w"></figure><p>This is the Windows API function for handling the creation of INI configuration files. Considering that <code>Zone.Identifier</code> ADS file is an INI file containing section <code>ZoneTransfer</code>, it was definitely relevant. I dug deeper.</p><p>The search led me to the final call of <code><a href="https://learn.microsoft.com/en-us/windows/win32/api/winternl/nf-winternl-ntcreatefile">NtCreateFile</a></code>, trying to create the <code>Zone.Identifier</code> ADS file, which failed with <code>ACCESS_DENIED</code> error, when using the exploit sample and succeeded when using the original, untampered test sample.</p><figure class="kg-card kg-image-card"><img src="https://breakdev.org/content/images/2022/11/image-6.png" class="kg-image" alt="Exploring ZIP Mark-of-the-Web Bypass Vulnerability (CVE-2022-41049)" loading="lazy" width="341" height="242"></figure><p>It looked like the majority of parameters were constant, as you can see on the screenshot above. The only place where I&apos;d expect anything dynamic was in the structure of <code>ObjectAttributes</code> parameter. After closer inspection and half an hour of closely comparing the contents of the parameter structures from two calls, I concluded that both failing and succeeding calls use exactly the same parameters.</p><p>This led me to realize that something had to be happening prior to the creation of the ADS file, which I did not account for. There was no better way to figure that out than to use <a href="https://learn.microsoft.com/en-us/sysinternals/downloads/procmon">Process Monitor</a>, which honestly I should&apos;ve used long before I even opened IDA &#x1F61B;.</p><h1 id="backtracking">Backtracking</h1><p>I set up my filters to only list file operations related to files extracted to TEMP directory, starting with <code>Temp</code> prefix.</p><figure class="kg-card kg-image-card"><img src="https://breakdev.org/content/images/2022/11/image-10.png" class="kg-image" alt="Exploring ZIP Mark-of-the-Web Bypass Vulnerability (CVE-2022-41049)" loading="lazy" width="508" height="365"></figure><p>The test sample clearly succeeded in creating the <code>Zone.Identifier</code> ADS file:</p><figure class="kg-card kg-image-card"><img src="https://breakdev.org/content/images/2022/11/image-11.png" class="kg-image" alt="Exploring ZIP Mark-of-the-Web Bypass Vulnerability (CVE-2022-41049)" loading="lazy" width="1348" height="636" srcset="https://breakdev.org/content/images/size/w600/2022/11/image-11.png 600w, https://breakdev.org/content/images/size/w1000/2022/11/image-11.png 1000w, https://breakdev.org/content/images/2022/11/image-11.png 1348w" sizes="(min-width: 720px) 720px"></figure><p>While the exploit sample failed:</p><figure class="kg-card kg-image-card"><img src="https://breakdev.org/content/images/2022/11/image-9.png" class="kg-image" alt="Exploring ZIP Mark-of-the-Web Bypass Vulnerability (CVE-2022-41049)" loading="lazy" width="1348" height="636" srcset="https://breakdev.org/content/images/size/w600/2022/11/image-9.png 600w, https://breakdev.org/content/images/size/w1000/2022/11/image-9.png 1000w, https://breakdev.org/content/images/2022/11/image-9.png 1348w" sizes="(min-width: 720px) 720px"></figure><p>Through comparison of these two listings, I could not clearly see any drastic differences. I exported the results as text files and compared them in a text editor. That&apos;s when I could finally spot it.</p><p>Prior to creating <code>Zone.Identifier</code> ADS file, the call to <code>SetBasicInformationFile</code> was made with <code>FileAttributes</code> set to <code>RN</code>.</p><figure class="kg-card kg-image-card"><img src="https://breakdev.org/content/images/2022/11/image-12.png" class="kg-image" alt="Exploring ZIP Mark-of-the-Web Bypass Vulnerability (CVE-2022-41049)" loading="lazy" width="490" height="573"></figure><p>I looked up what was that <code>R</code> attribute, which apparently is not set for the file when extracting from the original test sample and then...</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://breakdev.org/content/images/2022/11/image-13.png" class="kg-image" alt="Exploring ZIP Mark-of-the-Web Bypass Vulnerability (CVE-2022-41049)" loading="lazy" width="895" height="503" srcset="https://breakdev.org/content/images/size/w600/2022/11/image-13.png 600w, https://breakdev.org/content/images/2022/11/image-13.png 895w" sizes="(min-width: 720px) 720px"><figcaption>Facepalm</figcaption></figure><p>The <code>R</code> file attribute stands for <code>read-only</code>. The file stored in a ZIP file has the read-only attribute set, which is set also on the file extracted from the ZIP. Obviously when Windows tries to attach the <code>Zone.Identifier</code> ADS, to it, it fails, because the file has a read-only attribute and any write operation on it will fail with <code>ACCESS_DENIED</code> error.</p><p>It doesn&apos;t even seem to be a bug, since everything is working as expected &#x1F61B;. The file attributes in a ZIP file are set in <code>ExternalAttributes</code> parameter of the <code>ZIPDIRENTRY</code> structure and its value corresponds to the ones, which carried over from MS-DOS times, as stated in <a href="https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT">ZIP file format documentation</a> I found online.</p><pre><code>   4.4.15 external file attributes: (4 bytes)

       The mapping of the external attributes is
       host-system dependent (see &apos;version made by&apos;).  For
       MS-DOS, the low order byte is the MS-DOS directory
       attribute byte.  If input came from standard input, this
       field is set to zero.

   4.4.2 version made by (2 bytes)

        4.4.2.1 The upper byte indicates the compatibility of the file
        attribute information.  If the external file attributes 
        are compatible with MS-DOS and can be read by PKZIP for 
        DOS version 2.04g then this value will be zero.  If these 
        attributes are not compatible, then this value will 
        identify the host system on which the attributes are 
        compatible.  Software can use this information to determine
        the line record format for text files etc.  

        4.4.2.2 The current mappings are:

         0 - MS-DOS and OS/2 (FAT / VFAT / FAT32 file systems)
         1 - Amiga                     2 - OpenVMS
         3 - UNIX                      4 - VM/CMS
         5 - Atari ST                  6 - OS/2 H.P.F.S.
         7 - Macintosh                 8 - Z-System
         9 - CP/M                     10 - Windows NTFS
        11 - MVS (OS/390 - Z/OS)      12 - VSE
        13 - Acorn Risc               14 - VFAT
        15 - alternate MVS            16 - BeOS
        17 - Tandem                   18 - OS/400
        19 - OS X (Darwin)            20 thru 255 - unused

        4.4.2.3 The lower byte indicates the ZIP specification version 
        (the version of this document) supported by the software 
        used to encode the file.  The value/10 indicates the major 
        version number, and the value mod 10 is the minor version 
        number.  
</code></pre><p>Changing the value of external attributes to anything with the lowest bit set e.g. <code>0x21</code> or <code>0x01</code>, would effectively make the file read-only with Windows being unable to create MOTW for it, after extraction.</p><h1 id="conclusion">Conclusion</h1><p>I honestly expected the bug to be much more complicated and I definitely shot myself in the foot, getting too excited to start up IDA, instead of running Process Monitor first. I started with IDA first as I didn&apos;t have an exploit sample in the beginning and I was hoping to find the bug, through code analysis. Bottom line, I managed to learn something new about Windows internals and how extraction of ZIP files is handled.</p><p>As a bonus, <a href="https://twitter.com/mkolsek">Mitja Kolsek</a> from <a href="https://0patch.com/">0patch</a> asked me to confirm if their patch worked and I was happy to confirm that it did!</p><figure class="kg-card kg-embed-card"><blockquote class="twitter-tweet"><p lang="en" dir="ltr">Nice work. Care to verify that our micropatches fix this? (A free 0patch account suffices.) <a href="https://t.co/us8FVWczXk">https://t.co/us8FVWczXk</a></p>&#x2014; Mitja Kolsek (@mkolsek) <a href="https://twitter.com/mkolsek/status/1587266936605401088?ref_src=twsrc%5Etfw">November 1, 2022</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
</figure><p>The patch was clean and reliable as seen in the screenshot from a debugger:</p><figure class="kg-card kg-image-card"><img src="https://breakdev.org/content/images/2022/11/NVIDIA_Share_DHioXmg5yD.png" class="kg-image" alt="Exploring ZIP Mark-of-the-Web Bypass Vulnerability (CVE-2022-41049)" loading="lazy" width="1091" height="219" srcset="https://breakdev.org/content/images/size/w600/2022/11/NVIDIA_Share_DHioXmg5yD.png 600w, https://breakdev.org/content/images/size/w1000/2022/11/NVIDIA_Share_DHioXmg5yD.png 1000w, https://breakdev.org/content/images/2022/11/NVIDIA_Share_DHioXmg5yD.png 1091w" sizes="(min-width: 720px) 720px"></figure><p>I&apos;ve been also able to have a nice chat with <a href="https://twitter.com/wdormann">Will Dormann</a>, who initially discovered this bug, and his story on how he found it is hilarious:</p><blockquote>I merely wanted to demonstrate how an exploit in a ZIP was safer (by way of prompting the user) than that *same* exploit in an ISO. &#xA0;So how did I make the ZIP? &#xA0;I:<br>1) Dragged the files out of the mounted ISO<br>2) Zipped them. That&apos;s it. &#xA0;The ZIP contents behaved the same as the ISO.</blockquote><p>Every mounted ISO image is listing all files in read-only mode. Drag &amp; dropping files from read-only partition, to a different one, preserves the read-only attribute set for created files. This is how Will managed to unknowingly trigger the bug.</p><p>Will also made me realize that 7zip extractor, even though having announced they began to add MOTW to every file extracted from MOTW marked archive, does not add MOTW by default and this feature has to be enabled manually.</p><figure class="kg-card kg-image-card"><img src="https://breakdev.org/content/images/2022/11/image-14.png" class="kg-image" alt="Exploring ZIP Mark-of-the-Web Bypass Vulnerability (CVE-2022-41049)" loading="lazy" width="940" height="1110" srcset="https://breakdev.org/content/images/size/w600/2022/11/image-14.png 600w, https://breakdev.org/content/images/2022/11/image-14.png 940w" sizes="(min-width: 720px) 720px"></figure><figure class="kg-card kg-image-card"><img src="https://breakdev.org/content/images/2022/11/image-15.png" class="kg-image" alt="Exploring ZIP Mark-of-the-Web Bypass Vulnerability (CVE-2022-41049)" loading="lazy" width="330" height="208"></figure><p>I mentioned it as it may explain why MOTW is not always considered a valid security boundary. Vulnerabilities related to it may be given low priority and be even ignored by Microsoft for 90 days.</p><p>When 7zip announced <a href="https://www.bleepingcomputer.com/news/microsoft/7-zip-now-supports-windows-mark-of-the-web-security-feature/">support for MOTW</a> in June, I honestly took for granted that it would be enabled by default, but apparently the developer <a href="https://sourceforge.net/p/sevenzip/bugs/1649/">doesn&apos;t know exactly what he is doing</a>.</p><p>I haven&apos;t yet analyzed how the patch made by Microsoft works, but do let me know if you did and I will gladly update this post with additional information.</p><p>Hope you enjoyed the write-up!</p>]]></content:encoded></item><item><title><![CDATA[Hacked Discord - Bookmarklet Strikes Back]]></title><description><![CDATA[Discord accounts are getting hacked. This is my analysis of how most recent bookmarklet attacks work, with guidelines on what Discord can do to mitigate these attacks.]]></description><link>https://breakdev.org/hacked-discord-bookmarklet-attacks/</link><guid isPermaLink="false">630884a488520f0bb9d21778</guid><category><![CDATA[hacking]]></category><category><![CDATA[research]]></category><category><![CDATA[security]]></category><category><![CDATA[xss]]></category><category><![CDATA[2fa]]></category><dc:creator><![CDATA[Kuba Gretzky]]></dc:creator><pubDate>Wed, 31 Aug 2022 10:00:07 GMT</pubDate><media:content url="https://breakdev.org/content/images/2022/08/discord-hacks-4.png" medium="image"/><content:encoded><![CDATA[<img src="https://breakdev.org/content/images/2022/08/discord-hacks-4.png" alt="Hacked Discord - Bookmarklet Strikes Back"><p>For the past couple of months, I&apos;ve been hearing about increasing numbers of <a href="https://web3isgoinggreat.com/?theme=hack">account takeover attacks</a> in the Discord community. Discord has somehow become a de facto official messenger application among the cryptocurrency community, with new channels oriented around NFTs, popping up like mushrooms.</p><p>Hacking Discord accounts has suddenly become a very lucrative business for cybercriminals, who are going in for the kill, to make some easy money. They take over admin accounts in cryptocurrency-oriented communities to spread malware and launch further social engineering attacks. My focus is going to be purely on Discord account security, which should be of concern to everyone using Discord.</p><p>In recent weeks I thought the attackers are using some new reverse-proxy phishing techniques to hijack WebSocket sessions with similar tools to <a href="https://breakdev.org/evilginx-2-4-gone-phishing/">Evilginx</a>, but in reality the hacks, I discovered, are much easier to execute than I anticipated.</p><p>In this post I will be explaining how the attacks work, what everyone can do to protect themselves and more importantly what Discord can do to mitigate such attacks.</p><p>Please bear in mind that this post covers my personal point of view on how I feel the mitigations should be implemented and I am well aware that some of you may have much better ideas. I encourage you to contact me <a href="https://twitter.com/mrgretzky">@mrgretzky</a> or at <a href="mailto:kuba@breakdev.org">kuba@breakdev.org</a> if you feel I missed anything or was mistaken.</p><p>Criticism is welcomed!</p><h1 id="the-master-key">The Master Key</h1><p>When you log in to your Discord account, either by entering your account credentials on the login screen, or by scanning a QR code with your Discord mobile app, Discord will send you your account<strong> token</strong>, in form of a string of data.</p><p><strong>This token is the only key required to access your Discord account.</strong></p><p>From now on I will refer to that token as the <strong>master token</strong>, since it works like a master key for your Discord account. That single line of text, consisting of around 70 characters, is what the attackers are after. When they manage to extract the master token from your account, it is game over and third parties can now freely access your account, bypassing both the login screen and any <a href="https://en.wikipedia.org/wiki/Multi-factor_authentication">multi-factor authentication</a> you may&apos;ve set up.</p><p>Now that we know what the attackers are after, let&apos;s analyze the attack flow.</p><h1 id="deception-tactics">Deception Tactics</h1><p>Attacker&apos;s main goal is to convince you in any way possible to reveal your account token, with the most likely approach being social engineering. First, attackers will create a story to set themselves up as a people you can trust, who will resolve your pressing issue, like unban your account on a Discord channel or elevate your community status.</p><figure class="kg-card kg-embed-card"><blockquote class="twitter-tweet"><p lang="en" dir="ltr">There is a hack/scam(bypasses 2fa) that scammers are using to compromise discord accounts. If you are a project founder/admin, this is IMPORTANT.<br> <br>Our server just got attacked.<br> <br>Here&apos;s how, a&#x1F9F5;</p>&#x2014; Little Lemon Friends (@LittlelemonsNFT) <a href="https://twitter.com/LittlelemonsNFT/status/1477923368053706755?ref_src=twsrc%5Etfw">January 3, 2022</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
</figure><p>In this thread you can read how attackers managed to convince the target to do a screen share from their computer with <a href="https://developer.chrome.com/docs/devtools/">Chrome DevTools</a> opened, on the side. DevTools allowed them to extract the master token, through revealing the contents of Discord&apos;s <a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage">LocalStorage</a>.</p><p>Discord now purposefully renames the <code>window.localStorage</code> object, when it loads, to make it inaccessible to injected JavaScript. It also hides the <code>token</code> variable, containing the master token&apos;s value, from the storage. This was done to prevent attackers from stealing master tokens, by convincing the targets to open LocalStorage through screen share.</p><p>Discord also shows a pretty warning, informing users about the risks of pasting unknown code into the DevTools console.</p><figure class="kg-card kg-image-card"><img src="https://breakdev.org/content/images/2022/08/chrome_discord_holdup.png" class="kg-image" alt="Hacked Discord - Bookmarklet Strikes Back" loading="lazy" width="943" height="304" srcset="https://breakdev.org/content/images/size/w600/2022/08/chrome_discord_holdup.png 600w, https://breakdev.org/content/images/2022/08/chrome_discord_holdup.png 943w" sizes="(min-width: 720px) 720px"></figure><p>The renaming of <code>localStorage</code> object and concealment of <code>token</code> variable did not fix the issue. Attackers figured out they can force Discord window to reload and then retrieve the data before implemented mitigations are executed.</p><p>This is exactly how the most recent bookmarklet attack works. Attackers convince their victim to bookmark JavaScript code in their bookmarks tab and trick them later to click the saved bookmark, with Discord app in focus, to execute attacker&apos;s malicious code.</p><p>Attacker&apos;s code retrieves the victim&apos;s Discord master token and sends it to the attacker.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://breakdev.org/content/images/2022/08/bookmarklet.png" class="kg-image" alt="Hacked Discord - Bookmarklet Strikes Back" loading="lazy" width="1083" height="413" srcset="https://breakdev.org/content/images/size/w600/2022/08/bookmarklet.png 600w, https://breakdev.org/content/images/size/w1000/2022/08/bookmarklet.png 1000w, https://breakdev.org/content/images/2022/08/bookmarklet.png 1083w" sizes="(min-width: 720px) 720px"><figcaption>Saved malicious bookmarklet would look like this.</figcaption></figure><p>The malicious JavaScript to access the master token looks like this:</p><pre><code class="language-javascript">javascript:(function(){location.reload();var i = document.createElement(&apos;iframe&apos;);document.body.appendChild(i);alert(i.contentWindow.localStorage.token)})()</code></pre><p>To try it out, open Discord website, go to the console tab in Chrome DevTools (<em>Control+Shift+I</em>) and paste this code into it, which is something you should never do when asked &#x1F609;. After you press Enter, you should see the popup box with your master token value in it.</p><p>Attackers will exfiltrate the token through Discord WebHooks. This is done to bypass current <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP">Content Security Policy</a> rules as obviously <code>discord.com</code> domain is allowed to be connected to from Discord client.</p><p>Most users have no idea that saved bookmarks can run malicious JavaScript in context of the website they are currently viewing. This is why this type of attack may be successful among even the security savvy users.</p><p>Another much harder approach, the attackers can take, is deploying malware onto target computer. Once you install malware on your PC the consequences can be far greater than just losing your Discord account. Just wanted to make note here that browser&apos;s LocalStorage will store the tokens in unencrypted form.</p><p>LocalStorage database files for Chrome reside in:</p><pre><code>%LOCALAPPDATA%\Google\Chrome\User Data\&lt;PROFILE&gt;\Local Storage\leveldb\</code></pre><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://breakdev.org/content/images/2022/08/chrome_localstorage_discord_token.png" class="kg-image" alt="Hacked Discord - Bookmarklet Strikes Back" loading="lazy" width="1028" height="666" srcset="https://breakdev.org/content/images/size/w600/2022/08/chrome_localstorage_discord_token.png 600w, https://breakdev.org/content/images/size/w1000/2022/08/chrome_localstorage_discord_token.png 1000w, https://breakdev.org/content/images/2022/08/chrome_localstorage_discord_token.png 1028w" sizes="(min-width: 720px) 720px"><figcaption>Discord master token found inside one of the LocalStorage database files</figcaption></figure><p>Once the attacker retrieves your Discord master token, they can inject it into their browser&apos;s LocalStorage, with <code>token</code> as a variable name. It can easily be done using <a href="https://chrome.google.com/webstore/detail/localstorage-manager/fkhoimdhngkiicbjobkinobjkoefhkap">LocalStorage Manager</a> extension for Chrome.</p><p>Discord on reload will detect the valid token in its LocalStorage and allow full control over the hijacked account. All this is possible even with multi-factor authentication enabled on hijacked account.</p><h1 id="proposed-mitigations">Proposed Mitigations</h1><p>The fact that a single token, accessible through JavaScript, lets you impersonate and fully control another user&apos;s account is what makes the bookmarklet attack possible.</p><p>The attacker needs to execute their malicious JavaScript in context of the user&apos;s Discord session. This can happen either through exploitation of an <a href="https://owasp.org/www-community/attacks/xss/">XSS</a> vulnerability or by tricking a user into bookmarking and clicking the JavaScript bookmarklet.</p><p>There is unfortunately no definitive fix to this problem, but there are definitely ways to increase the costs for attackers and make the attacks much harder to execute.</p><h2 id="store-token-as-an-httponly-cookie">Store Token as an <code>HttpOnly</code> Cookie</h2><p>Modern web services rely heavily on communication with REST APIs and Discord is no different. REST APIs, to conform with the standard, must implement a <a href="https://restfulapi.net/statelessness/">stateless</a> architecture, meaning that each request from the client to the server must contain all of the information necessary to understand and complete the request.</p><p>The session token, included with requests to REST API, is usually embedded within the <code>Authorization</code> HTTP header. We can see that Discord app does it the same way:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://breakdev.org/content/images/2022/08/burp_authorization_token-1.png" class="kg-image" alt="Hacked Discord - Bookmarklet Strikes Back" loading="lazy" width="781" height="592" srcset="https://breakdev.org/content/images/size/w600/2022/08/burp_authorization_token-1.png 600w, https://breakdev.org/content/images/2022/08/burp_authorization_token-1.png 781w" sizes="(min-width: 720px) 720px"><figcaption>Master token sent via <code>Authorization</code> HTTP header</figcaption></figure><p>For the web application to be able to include the session token within the <code>Authorization</code> header or request body, the token value itself must be accessible through JavaScript. Token accessible through JavaScript will be always vulnerable to XSS bugs or other JavaScript injection attacks (like bookmarklets).</p><p>Some people may not agree with me, but I think that critical authorization tokens should be handled through cookie storage, inaccessible to JavaScript. Support for <code>Authorization</code> header server-side can also be allowed, but it should be optional. For reasons unknown to me, majority of REST API developers ignore token authorization via cookies altogether.</p><p>Server should be sending the authorization session token value as a cookie with <code><a href="https://owasp.org/www-community/HttpOnly">HttpOnly</a></code> flag, in <code>Set-Cookie</code> HTTP header.</p><p>Storing the session token with <code>HttpOnly</code> flag, in the browser, will make sure that the cookie can never be retrieved from JavaScript code. The session token will be automatically sent with every HTTP request to domains, the cookie was set up for. </p><p>The request, which sends authentication token as a cookie, could look like this:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://breakdev.org/content/images/2022/08/burp_token_via_cookie.png" class="kg-image" alt="Hacked Discord - Bookmarklet Strikes Back" loading="lazy" width="810" height="572" srcset="https://breakdev.org/content/images/size/w600/2022/08/burp_token_via_cookie.png 600w, https://breakdev.org/content/images/2022/08/burp_token_via_cookie.png 810w" sizes="(min-width: 720px) 720px"><figcaption>How Discord may be sending the session token via cookies, instead of <code>Authorization</code> header</figcaption></figure><p>I&apos;ve noticed that Discord&apos;s functionality does not rely solely on interaction with its API, but the major part of its functionality is handled through WebSocket connections.</p><p>The WebSocket connection is established with <code>gateway.discord.gg</code> endpoint, instead of the main <code>discord.com</code> domain.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://breakdev.org/content/images/2022/08/burp_open_websockets_conn.png" class="kg-image" alt="Hacked Discord - Bookmarklet Strikes Back" loading="lazy" width="781" height="302" srcset="https://breakdev.org/content/images/size/w600/2022/08/burp_open_websockets_conn.png 600w, https://breakdev.org/content/images/2022/08/burp_open_websockets_conn.png 781w" sizes="(min-width: 720px) 720px"><figcaption>Discord initiating a WebSocket connection</figcaption></figure><p>If the session token cookie was delivered as a response to request delivered to domain <code>discord.com</code>, it would not be possible to set a cookie for domain <code>discord.gg</code> due to security boundaries.</p><p>To counter that, Discord would either need to implement some smart routing allowing Discord clients to use WebSocket connections through <code>discord.com</code> domain or it would have to implement authorization using one-time token with <code>discord.gg</code> endpoint, once the user successfully logs in, to have <code>discord.gg</code> &#xA0;return a valid session token as a cookie, for its own domain.</p><p>Right now Discord permits establishing WebSocket connection through <code>gateway.discord.gg</code> to anyone and the authorization token validation happens during internal WebSocket messages exchange.</p><p>This means that the session token is also required during WebSocket communication, increasing its reliance on being accessible through JavaScript. This brings me to another mitigation that can be implemented.</p><h2 id="ephemeral-session-tokens">Ephemeral Session Tokens</h2><p>Making a strict requirement for tokens to be delivered as <code>HttpOnly</code> cookies, will never work. There needs to be some way to have authorization tokens accessible to JavaScript and not give the attacker all the keys to the castle once that token gets compromised.</p><p>That&apos;s why I&apos;d make authentication reliant on two types of tokens:</p><ol><li>Authentication token stored only as a cookie with <code>HttpOnly</code> flag, which will be used to authenticate with REST API and to initiate a WebSocket connection.</li><li>Session token generated dynamically with short expiration time (few hours), accompanied by a refresh token used for creating new session tokens. Session tokens will be used only in internal WebSocket communication. WebSocket connections will allow to be established only after presenting a valid authentication token as a cookie.</li></ol><p>If you wish to learn more about ephemeral session tokens and refresh tokens, I recommend <a href="https://auth0.com/blog/refresh-tokens-what-are-they-and-when-to-use-them/">this post</a>.</p><h2 id="but-wait-attacker-controls-the-session-anyway">But, wait! Attacker controls the session anyway!</h2><p>Before you yell at me about all of these mitigations being futile, because the attacker, with his injected JavaScript, is already able to fully impersonate and control the hacked user session, hear me out.</p><p>Me and <a href="https://twitter.com/buherator">@buherator</a> exchanged opinions about possible mitigations and he made a good point:</p><figure class="kg-card kg-embed-card"><blockquote class="twitter-tweet"><p lang="en" dir="ltr">I don&apos;t see how this would make a difference. The app needs to maintain long term sessions, thus the attacker in control of the app can have them too (if she can&apos;t achive her goal in millis). Having to request new tokens periodically is an implementation nuance.</p>&#x2014; buherator (@buherator) <a href="https://twitter.com/buherator/status/1563577385345110017?ref_src=twsrc%5Etfw">August 27, 2022</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
</figure><p>In short - the attacker is able to inject their own JavaScript, which will work in context of the Discord app. Running malicious code in context of Discord allows the attacker to make any request to Discord API, with all required security tokens attached. This also includes cookies stored with <code>HttpOnly</code> flag, since attacker&apos;s requests can have them included automatically with <code>withCredentials</code> set to <code>true</code>:</p><figure class="kg-card kg-code-card"><pre><code class="language-javascript">var req = new XmlHttpRequest();
req.open(&quot;GET&quot;, &#x201C;http://discord.com/api/v9/do_something&#x201D;, true);
req.withCredentials = true;
req.send(null);
</code></pre><figcaption>How attacker could be able to make HTTP requests to Discord API with valid authentication cookies.</figcaption></figure><p>No matter how well the tokens are protected, Discord client needs access to all of them, which means attacker executing code, in context of the app, will be able to forge valid client requests, potentially being able to change user&apos;s settings or sending spam messages to subscribed channels.</p><p>I&apos;ve been thinking about it for few days and reached a conclusion that implementing the mitigations I mentioned would still be worth it. At the moment the attack is extremely easy to pull off, which is what makes it so dangerous. Ability to forge packets, impersonating a target user is not as bad as being able to completely recreate victim&apos;s session within a Discord client remotely.</p><p>With token cookie protected with <code>HttpOnly</code> flag, the attacker will only be able to use the token to perform actions, impersonating the hacked user, but they will never be able to exfiltrate the token&apos;s value, in order to inject it into their own browser.</p><p>In my opinion this will still vastly lower the severity of the attack and will force the attackers to increase the complexity of the attack in technical terms, requiring knowledge of Discord API, in order to perform the attacker&apos;s tasks, once the user&apos;s session is hijacked.</p><p>Another thing to note here is that the attacker will remain in charge of the user&apos;s hijacked session only until the Discord app is closed or reloaded. They will not be able to spawn their own session to freely impersonate the hacked user at any time they want. Currently the stolen master token gives the attacker lifetime access to victim&apos;s account. Token is invalidated and recreated only when user changes their password.</p><h1 id="takeaways">Takeaways</h1><p>It is important to note that the attackers are only able to exfiltrate the master token value, using <code><a href="https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest">XMLHttpRequest</a></code> and <a href="https://support.discord.com/hc/en-us/articles/228383668-Intro-to-Webhooks">Discord&apos;s Webhooks</a>, by sending it to Discord channels they control. Using WebHooks allows them to comply with Discord&apos;s <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP">Content Security Policy</a>.</p><p>If it weren&apos;t for WebHooks, attackers would have to figure out another way to exfiltrate the stolen tokens. At the time of writing the article, the <code>connect-src</code> CSP rules for <code>discord.com</code>, which tell the browser the domains it should only allow Discord app to connect to, are as follows:</p><pre><code class="language-http">connect-src &apos;self&apos; https://discordapp.com https://discord.com https://connect.facebook.net https://api.greenhouse.io https://api.github.com https://sentry.io https://www.google-analytics.com https://hackerone-api.discord.workers.dev https://*.hcaptcha.com https://hcaptcha.com https://geolocation.onetrust.com/cookieconsentpub/v1/geo/location ws://127.0.0.1:* http://127.0.0.1:*;</code></pre><p>There seem to be other services allowed, which could be used to exfiltrate the tokens through them, like GitHub API, Sentry or Google Analytics.</p><p>Not sure if Discord client needs access to WebHooks through <code>XMLHttpRequest</code>, but if it doesn&apos;t, it may&apos;ve been a better choice for Discord to host WebHook handlers on a different domain than <code>discord.com</code> and control access to them with additional CSP rules.</p><p>There is also one question, which remains unanswered:</p><blockquote>Should web browsers still support bookmarklets?</blockquote><p>As asked by <a href="https://twitter.com/zh4ck/status/1562734600941891589">@zh4ck</a> in his tweet, which triggered my initial curiosity about the attacks.</p><p>Bookmarklets were useful in the days when it was convenient to click them to spawn an HTML popup for quickly sharing the URL on social media. These days I&apos;m not sure if anyone still needs them.</p><p>I have no idea if letting bookmarks start with <code>javascript:</code> is needed anymore, but it can easily become one of those legacy features that will keep coming back to haunt us.</p><h1 id="wrap-up">Wrap-up</h1><p>I hope you liked the post and hopefully it managed to teach you something.</p><p>I am constantly looking for interesting projects to work on. If you think my skills may be of help to you, do reach out, through the <a href="https://breakdev.org/contact/">contact page</a>.</p><p>Until next time!</p><h4 id="references">References</h4><ul><li>Chrome Inspector hack <a href="https://twitter.com/LittlelemonsNFT/status/1477923368053706755">https://twitter.com/LittlelemonsNFT/status/1477923368053706755</a></li><li>Bookmarklet Discord hack <a href="https://twitter.com/Serpent/status/1485002655953211392">https://twitter.com/Serpent/status/1485002655953211392</a></li><li>Bookmarklet Discussion <a href="https://twitter.com/zh4ck/status/1562734600941891589">https://twitter.com/zh4ck/status/1562734600941891589</a></li><li>LocalStorage Manager: <a href="https://chrome.google.com/webstore/detail/localstorage-manager/fkhoimdhngkiicbjobkinobjkoefhkap">https://chrome.google.com/webstore/detail/localstorage-manager/fkhoimdhngkiicbjobkinobjkoefhkap</a></li></ul>]]></content:encoded></item><item><title><![CDATA[Evilginx 2.4 - Gone Phishing]]></title><description><![CDATA["Gone Phishing" 2.4 update to your favorite phishing framework is here. May the phishing season begin!]]></description><link>https://breakdev.org/evilginx-2-4-gone-phishing/</link><guid isPermaLink="false">62eba9295e4f4b09d79d0f00</guid><category><![CDATA[evilginx]]></category><category><![CDATA[2fa]]></category><category><![CDATA[hacking]]></category><category><![CDATA[mitm]]></category><category><![CDATA[phishing]]></category><category><![CDATA[tool]]></category><category><![CDATA[update]]></category><dc:creator><![CDATA[Kuba Gretzky]]></dc:creator><pubDate>Mon, 14 Sep 2020 11:37:04 GMT</pubDate><media:content url="https://breakdev.org/content/images/2020/09/evilginx_gone_phishing_blog.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://breakdev.org/content/images/2020/09/evilginx_gone_phishing_blog.jpg" alt="Evilginx 2.4 - Gone Phishing"><p>Welcome back everyone! I can expect everyone being quite hungry for Evilginx updates! I am happy to announce that the tool is still kicking.</p><p>It&apos;s been a while since I&apos;ve released the last update. This blog tells me that version 2.3 was released on January 18th 2019. One and a half year is enough to collect some dust.</p><p>I&apos;ll make sure the wait was worth it. </p><p>First of all, I wanted to thank all you for invaluable support over these past years. I&apos;ve learned about many of you using Evilginx on assessments and how it is providing you with results. Such feedback always warms my heart and pushes me to expand the project. It was an amazing experience to learn how you are using the tool and what direction you would like the tool to expand in. There were some great ideas introduced in your feedback and partially this update was released to address them.</p><p>I&apos;d like to give out some honorable mentions to people who provided some quality contributions and who made this update happen:</p><!--kg-card-begin: html--><center><h3><a href="https://github.com/kgretzky/evilginx2">&gt;&gt; GET EVILGINX HERE &lt;&lt;</a></h3></center><!--kg-card-end: html--><hr><h3 id="special-thanks-">Special Thanks!</h3><p><a href="https://twitter.com/juliocesarfort">Julio @juliocesarfort</a> - For constantly proving to me and himself that the tool works (sometimes even too well)!</p><p><a href="https://twitter.com/TheColonial">OJ Reeves @TheColonial</a> - For constant great source of Australian positive energy and feedback and also for being always humble and a wholesome and awesome guy! Check out OJ&apos;s live hacking streams on <a href="https://www.twitch.tv/ojreeves">Twitch.tv</a> and pray you&apos;re not matched against him in Rocket League!</p><p><a href="https://twitter.com/pry0cc">pry @<a href="https://twitter.com/pry0cc">pry0c</a>c</a> - For pouring me many cups of great ideas, which resulted in great solutions! Also check out his great tool <a href="https://github.com/pry0cc/axiom">axiom</a>!</p><p><a href="https://twitter.com/curi0usJack">Jason Lang @curiousjack</a> - For being able to bend Evilginx to his will and in turn gave me ideas on what features are missing and needed.</p><p><a href="https://twitter.com/an0nud4y">@an0nud4y</a> - For sending that PR with amazingly well done phishlets, which inspired me to get back to Evilginx development.</p><p><a href="https://twitter.com/__pberba__">Pepe Berba</a> - For his incredible research and development of custom version of <a href="https://pberba.github.io/security/2020/05/28/lastpass-phishing/">LastPass harvester</a>! I still need to implement this incredible idea in future updates.</p><p><a href="https://twitter.com/thehappydinoa">Aidan Holland @thehappydinoa</a> - For spending his free time creating these super helpful <a href="https://www.youtube.com/watch?v=k4bq5A-icBw">demo videos</a> and helping keep things in order on Github.</p><p><a href="https://twitter.com/TurvSec">Luke Turvey @TurvSec</a> - For featuring Evilginx and for creating high quality tutorial hacking videos on his <a href="https://www.youtube.com/c/MrTurvey/">Youtube channel</a></p><p>So, again - thank you very much and I hope this tool will stay relevant to your work for the years to come and may it bring you lots of pwnage! Just remember to let me know on <a href="https://twitter.com/mrgretzky">Twitter</a> via DM that you are using it and about any ideas you&apos;re having on how to expand it further!</p><p>Here is the list of upcoming changes:</p><!--kg-card-begin: markdown--><p><strong>2.4.0</strong></p>
<ul>
<li><strong>Feature:</strong> Create and set up pre-phish HTML templates for your campaigns. Create your HTML file and place <code>{lure_url_html}</code> or <code>{lure_url_js}</code> in code to manage redirection to the phishing page with any form of user interaction. Command: <code>lures edit &lt;id&gt; template &lt;template&gt;</code></li>
<li><strong>Feature:</strong> Create customized hostnames for every phishing lure. Command: <code>lures edit &lt;id&gt; hostname &lt;hostname&gt;</code>.</li>
<li><strong>Feature:</strong> Support for routing connection via SOCKS5 and HTTP(S) proxies. Command: <code>proxy</code>.</li>
<li><strong>Feature:</strong> IP blacklist with automated IP address blacklisting and blocking on all or unauthorized requests. Command: <code>blacklist</code></li>
<li><strong>Feature:</strong> Custom parameters can now be embedded encrypted in the phishing url. Command: <code>lures get-url &lt;id&gt; param1=value1 param2=&quot;value2 with spaces&quot;</code>.</li>
<li><strong>Feature:</strong> Requests to phishing urls can now be rejected if User-Agent of the visitor doesn&apos;t match the whitelist regular expression filter for given lure. Command: <code>lures edit &lt;id&gt; ua_filter &lt;regexp&gt;</code></li>
<li>List of custom parameters can now be imported directly from file (text, csv, json). Command: <code>lures get-url &lt;id&gt; import &lt;params_file&gt;</code>.</li>
<li>Generated phishing urls can now be exported to file (text, csv, json). Command: <code>lures get-url &lt;id&gt; import &lt;params_file&gt; export &lt;export_file&gt; &lt;text|csv|json&gt;</code>.</li>
<li>Fixed: Requesting LetsEncrypt certificates multiple times without restarting. Subsequent requests would result in &quot;No embedded JWK in JWS header&quot; error.</li>
<li>Removed setting custom parameters in lures options. Parameters will now only be sent encoded with the phishing url.</li>
<li>Added <code>with_params</code> option to <code>sub_filter</code> allowing to enable the sub_filter only when specific parameter was set with the phishing url.</li>
<li>Made command help screen easier to read.</li>
<li>Improved autofill for <code>lures edit</code> commands and switched positions of <code>&lt;id&gt;</code> and the variable name.</li>
<li>Increased the duration of whitelisting authorized connections for whole IP address from 15 seconds to 10 minutes.</li>
</ul>
<!--kg-card-end: markdown--><p>I&apos;ll explain the most prominent new features coming in this update, starting with the most important feature of them all.</p><h2 id="pre-phish-html-templates">Pre-phish HTML Templates</h2><p>First of all let&apos;s focus on what happens when Evilginx phishing link is clicked. It verifies that the URL path corresponds to a valid existing lure and immediately shows you proxied login page of the targeted website.</p><p>If that link is sent out into the internet, every web scanner can start analyzing it right away and eventually, if they do their job, they will identify and flag the phishing page.</p><p>Pre-phish HTML templates add another step in, before the redirection to phishing page takes place. You can create your own HTML page, which will show up before anything else. On this page, you can decide how the visitor will be redirected to the phishing page.</p><p>One idea would be to show up a &quot;Loading&quot; page with a spinner and have the page wait for 5 seconds before redirecting to the destination phishing page. Another one would be to combine it with some social engineering narration, showing the visitor a modal dialog of a file shared with them and the redirection would happen after visitor clicks the &quot;Download&quot; button.</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://breakdev.org/content/images/2020/09/prephish_template1.png" class="kg-image" alt="Evilginx 2.4 - Gone Phishing" loading="lazy"><figcaption>Pre-phish page requiring the visitor to click the download button before being redirected to the phishing page.</figcaption></figure><p>Every HTML template supports customizable variables, which values can be delivered embedded with the phishing link (<em>more info on that below</em>).</p><p>There are also two variables which Evilginx will fill out on its own. These are:</p><p><code>{lure_url}</code>: This will be substituted with an <strong>unquoted </strong>URL of the phishing page. This one is to be used inside your HTML code. Example output: <code>https://your.phish.domain/path/to/phish</code></p><p><code>{lure_url_js}</code>: This will be substituted with <strong>obfuscated quoted</strong> URL of the phishing page. Obfuscation is randomized with every page load. This one is to be used inside of your Javascript code. Example output:</p><pre><code class="language-javascript">&apos;h&apos; + &apos;t&apos; + &apos;tp&apos; + &apos;s:/&apos; + &apos;/&apos; + &apos;c&apos; + &apos;hec&apos; + &apos;k.&apos; + &apos;t&apos; + &apos;his&apos; + &apos;.ou&apos; + &apos;t&apos; + &apos;.fa&apos; + &apos;k&apos; + &apos;e&apos; + &apos;.&apos; + &apos;co&apos; + &apos;m&apos; + &apos;/se&apos; + &apos;cur&apos; + &apos;it&apos; + &apos;y/&apos; + &apos;c&apos; + &apos;hec&apos; + &apos;k?&apos; + &apos;C&apos; + &apos;=g&apos; + &apos;3&apos; + &apos;Ct&apos; + &apos;p&apos; + &apos;sA&apos;</code></pre><p>The first variable can be used with <code>&lt;a href=...&gt;</code> HTML tags like so:</p><pre><code class="language-html">&lt;a href=&quot;{lure_url}&quot;&gt;Click here&lt;/a&gt;</code></pre><p>While the second one should be used with your Javascript code:</p><pre><code class="language-javascript">window.location.assign({lure_url_js});</code></pre><p>If you want to use values coming from custom parameters, which will be delivered embedded with the phishing URL, put placeholders in your template with the parameter name surrounded by curly brackets: <code>{parameter_name}</code></p><p>You can check out one of the sample HTML templates I released, here: <a href="https://github.com/kgretzky/evilginx2/templates/download_example.html">download_example.html</a></p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://breakdev.org/content/images/2020/09/prephish_template2.png" class="kg-image" alt="Evilginx 2.4 - Gone Phishing" loading="lazy"><figcaption>HTML source code of example template</figcaption></figure><p>Once you create your HTML template, you need to set it for any lure of your choosing. Remember to put your template file in <code>/templates</code> directory in the root Evilginx directory or somewhere else and run Evilginx by specifying the templates directory location with <code>-t &lt;templates_path&gt;</code> command line argument.</p><p>Set up templates for your lures using this command in Evilginx:</p><pre><code>lures edit &lt;id&gt; templates &lt;template_name&gt;</code></pre><h2 id="custom-parameters-in-phishing-links">Custom Parameters in Phishing Links</h2><p>In previous versions of Evilginx, you could set up custom parameters for every created lure. This didn&apos;t work well at all as you could only provide custom parameters hardcoded for one specific lure, since the parameter values were stored in database assigned to lure ID and were not dynamically delivered.</p><p>This is changing with this version. Storing custom parameter values in lures has been removed and it&apos;s been replaced with attaching custom parameters during phishing link generation. This allows for dynamic customization of parameters depending on who will receive the generated phishing link.</p><p>In the example template, mentioned above, there are two custom parameter placeholders used. You can specify <code>{from_name}</code> and <code>{filename}</code> to display a message who shared a file and the name of the file itself, which will be visible on the download button.</p><p>To generate a phishing link using these custom parameters, you&apos;d do the following:</p><pre><code>lures get-url 0 from_name=&quot;Ronald Rump&quot; filename=&quot;Annual Salary Report.xlsx&quot;</code></pre><p><strong>Remember</strong> - quoting values is only required if you want to include <em>spaces </em>in parameter values. You can also escape quotes with <code>\</code> e.g. <code>variable1=with\&quot;quote</code>.</p><p>This will generate a link, which may look like this:</p><pre><code>https://onedrive.live.fake.com/download/912381236/Annual_Salary_Report.xlsx?vLT=hvQzgP8bXoSOWvfYKkd5aMsvRgsLEXqL6_4SX3VYI95Jji1JPUnPDNmQUnsdSW9hPbpESDausLz2ckLb6MBT</code></pre><p>As you can see both custom parameter values were embedded into a single GET parameter. The parameter name is randomly generated and its value consists of a random RC4 encryption key, checksum and a base64 encoded encrypted value of all embedded custom parameter. This ensures that the generated link is different every time, making it hard to write static detection signatures for. There is also a simple checksum mechanism implemented, which invalidates the delivered custom parameters if the link ever gets corrupted in transit.</p><p><strong>Don&apos;t forget</strong> that custom parameters specified during phishing link generation will also apply to variable placeholders in your <code>js_inject</code> injected Javascript scripts in your phishlets.</p><p>It is important to note that you can change the name of the GET parameter, which holds the encrypted custom parameters. You can also add your own GET parameters to make the URL look how you want it. Evilginx is smart enough to go through all GET parameters and find the one which it can decrypt and load custom parameters from.</p><p>For example if you wanted to modify the URL generated above, it could look like this:</p><pre><code>https://onedrive.live.fake.com/download/912381236/Annual_Salary_Report.xlsx?token=hvQzgP8bXoSOWvfYKkd5aMsvRgsLEXqL6_4SX3VYI95Jji1JPUnPDNmQUnsdSW9hPbpESDausLz2ckLb6MBT&amp;region=en-US&amp;date=20200907&amp;something=totally_irrelevant_get_parameter</code></pre><p>Generating phishing links one by one is all fun until you need 200 of them, with each requiring different sets of custom parameters. Thankfully this update also got you covered.</p><p>You can now import custom parameters from file in <em>text</em>, <em>CSV </em>and <em>JSON </em>format and also export the generated links to <em>text</em>, <em>CSV </em>or <em>JSON</em>. You can also just print them on the screen if you want.</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://breakdev.org/content/images/2020/09/lures_import.png" class="kg-image" alt="Evilginx 2.4 - Gone Phishing" loading="lazy"><figcaption>Importing custom parameters from file to generate three phishing links</figcaption></figure><p>Custom parameters to be imported in <em>text </em>format would look the same way as you would type in the parameters after <code>lures get-url</code> command in Evilginx interface:</p><figure class="kg-card kg-code-card"><pre><code class="language-text">email=honeybunny@gmail.com name=&quot;Katelyn Wells&quot;
email=muchdork@yahoo.com name=&quot;George Doh&quot; delay=5000
email=i.r.john@hotmail.com name=&quot;John Cena&quot;
</code></pre><figcaption>params.txt</figcaption></figure><p>If you wanted to use <em>CSV </em>format:</p><figure class="kg-card kg-code-card"><pre><code class="language-csv">email,name,delay
honeybunny@gmail.com,&quot;Katelyn Wells&quot;,
muchdork@yahoo.com,&quot;George Doh&quot;,5000
i.r.john@hotmail.com,&quot;John Cena&quot;,
</code></pre><figcaption>params.csv</figcaption></figure><p>And lastly <em>JSON</em>:</p><figure class="kg-card kg-code-card"><pre><code class="language-json">[
	{
		&quot;email&quot;:&quot;honeybunny@gmail.com&quot;,
		&quot;name&quot;:&quot;Katelyn Wells&quot;
	},
	{
		&quot;email&quot;:&quot;muchdork@yahoo.com&quot;,
		&quot;name&quot;:&quot;George Doh&quot;,
		&quot;delay&quot;:&quot;5000&quot;
	},
	{
		&quot;email&quot;:&quot;i.r.john@hotmail.com&quot;,
		&quot;name&quot;:&quot;John Cena&quot;
	}
]
</code></pre><figcaption>params.json</figcaption></figure><p>For import files, make sure to suffix a filename with file extension according to the data format you&apos;ve decided to use, so <code>.txt</code> for <em>text </em>format, <code>.csv</code> for <em>CSV </em>format and <code>.json</code> for <em>JSON</em>.</p><p>Generating phishing links by importing custom parameters from file can be done as easily as:</p><pre><code>lures get-url &lt;id&gt; import &lt;import_file&gt;</code></pre><p>Now if you also want to export the generated phishing links, you can do it with <code>export</code> parameter:</p><pre><code>lures get-url &lt;id&gt; import &lt;import_file&gt; export &lt;export_file&gt; &lt;text|csv|json&gt;</code></pre><p>Last command parameter selects the output file format.</p><h2 id="custom-hostnames-for-phishing-links">Custom Hostnames for Phishing Links</h2><p>Normally if you generated a phishing URL from a given lure, it would use a hostname which would be a combination of your phishlet hostname and a primary subdomain assigned to your phishlet. During assessments, most of the time hostname doesn&apos;t matter much, but sometimes you may want to give it a more personalized feel to it.</p><p>That&apos;s why I wanted to do something about it and make the phishing hostname, for any lure, fully customizable. Since Evilginx is running its own DNS, it can successfully respond to any DNS A request coming its way.</p><p>So now instead of being forced to use a phishing hostname of e.g. <code>www.linkedin.phishing.com</code>, you can change it to whatever you want like <code>this.is.totally.not.phishing.com</code>. Of course this is a bad example, but it shows that you can go totally wild with the hostname customization and you&apos;re no longer constrained by pre-defined phishlet hostnames. Just remember that every custom hostname must end with the domain you set in the config.</p><p>You can change lure&apos;s hostname with a following command:</p><pre><code>lures edit &lt;id&gt; hostname &lt;your_hostname&gt;</code></pre><p>After the change, you will notice that links generated with <code>get-url</code> will use the new hostname.</p><h2 id="user-agent-filtering">User-Agent Filtering</h2><p>This is a feature some of you requested. It allows you to filter requests to your phishing link based on the originating <code>User-Agent</code> header. Just set an <code>ua_filter</code> option for any of your lures, as a whitelist regular expression, and only requests with matching <code>User-Agent</code> header will be authorized.</p><p>As an example, if you&apos;d like only requests from iPhone or Android to go through, you&apos;d set a filter like so:</p><pre><code>lures edit &lt;id&gt; ua_filter &quot;.*(Android|iPhone).*&quot;</code></pre><h2 id="http-socks5-proxy-support">HTTP &amp; SOCKS5 Proxy Support</h2><p>You can finally route the connection between Evilginx and targeted website through an external proxy.</p><p>This may be useful if you want the connections to specific website originate from a specific IP range or specific geographical region. It may also prove useful if you want to debug your Evilginx connection and inspect packets using Burp proxy.</p><p>You can check all available commands on how to set up your proxy by typing in:</p><pre><code>help proxy</code></pre><p>Make sure to always restart Evilginx after you enable proxy mode, since it is the only surefire way to reset all already established connections.</p><h2 id="ip-blacklist">IP Blacklist</h2><p>If you don&apos;t want your Evilginx instance to be accessed from unwanted sources on the internet, you may want to add specific IPs or IP ranges to blacklist. You can always find the current blacklist file in:</p><pre><code>~/.evilginx/blacklist.txt</code></pre><p>By default automatic blacklist creation is disabled, but you can easily enable it using one of the following options:</p><pre><code>blacklist unauth</code></pre><p>This will automatically blacklist IPs of unauthorized requests. This includes all requests, which did not point to a valid URL specified by any of the created lures.</p><pre><code>blacklist on</code></pre><p>This will blacklist IP of <strong>EVERY</strong> incoming request, despite it being authorized or not, so use caution. This will effectively block access to any of your phishing links. You can use this option if you want to send out your phishing link and want to see if any online scanners pick it up.</p><p>If you want to add IP ranges manually to your blacklist file, you can do so by editing <code>blacklist.txt</code> file in any text editor and add the netmask to the IP:</p><pre><code>134.123.0.0/16</code></pre><p>You can also freely add comments prepending them with semicolon:</p><pre><code>; this is a comment
18.123.445.0/24 ;another comment</code></pre><h2 id="new-with_params-option-for-phishlets">New <code>with_params</code> Option for Phishlets</h2><p>You can now make any of your phishlet&apos;s <code>sub_filter</code> entries optional and have them kick in only if a specific custom parameter is delivered with the phishing link.</p><p>You may for example want to remove or replace some HTML content only if a custom parameter <code>target_name</code> is supplied with the phishing link. This may allow you to add some unique behavior to proxied websites. All <code>sub_filters</code> with that option will be ignored if specified custom parameter is not found.</p><p>You can add it like this:</p><pre><code class="language-yaml">sub_filters:
- {triggers_on: &apos;auth.website.com&apos;, orig_sub: &apos;auth&apos;, domain: &apos;website.com&apos;, search: &apos;&lt;body\s&apos;, replace: &apos;&lt;body style=&quot;visibility: hidden;&quot; &apos;, mimes: [&apos;text/html&apos;], with_params: [&apos;target_name&apos;]}
</code></pre><p>This will hide the page&apos;s <code>body</code> only if <code>target_name</code> is specified. Later the added <code>style</code> can be removed through injected Javascript in <code>js_inject</code> at any point.</p><h2 id="quality-of-life-updates">Quality of Life Updates</h2><p>I&apos;ve also included some minor updates. There are some improvements to Evilginx UI making it a bit more visually appealing. Fixed some bugs I found on the way and did some refactoring. All the changes are listed in the CHANGELOG above.</p><h1 id="epilogue">Epilogue</h1><p>I&apos;m glad Evilginx has become a go-to offensive software for red teamers to simulate phishing attacks. It shows that it is not being just a proof-of-concept toy, but a full-fledged tool, which brings reliability and results during pentests.</p><p>I hope some of you will start using the new templates feature. I welcome all quality HTML templates contributions to Evilginx repository!</p><p>If you have any ideas/feedback regarding Evilginx or you just want to say &quot;Hi&quot; and tell me what you think about it, do not hesitate to send me a DM on <a href="https://twitter.com/mrgretzky">Twitter</a>.</p><p>Also please don&apos;t ask me about phishlets targeting XYZ website as I will not provide you with any or help you create them. Evilginx is a framework and I leave the creation of phishlets to you. There are already plenty of examples available, which you can use to learn how to create your own.</p><p><strong>Happy phishing!</strong></p><!--kg-card-begin: html--><center><h3><a href="https://github.com/kgretzky/evilginx2">&gt;&gt; GET EVILGINX HERE &lt;&lt;</a></h3></center><!--kg-card-end: html--><hr><p>Find me on Twitter: <a href="https://twitter.com/mrgretzky">@mrgretzky</a></p><p>Email: <a href="mailto:kuba@breakdev.org">kuba@breakdev.org</a></p>]]></content:encoded></item><item><title><![CDATA[Pwndrop - Self-hosting Your Red Team Payloads]]></title><description><![CDATA[Pwndrop is a self-deployable file hosting service for red teamers, allowing to easily upload and share payloads over HTTP and WebDAV.]]></description><link>https://breakdev.org/pwndrop/</link><guid isPermaLink="false">62eba9295e4f4b09d79d0eff</guid><category><![CDATA[pwndrop]]></category><category><![CDATA[hacking]]></category><category><![CDATA[tool]]></category><category><![CDATA[security]]></category><category><![CDATA[hosting]]></category><category><![CDATA[fileserver]]></category><dc:creator><![CDATA[Kuba Gretzky]]></dc:creator><pubDate>Thu, 16 Apr 2020 10:07:58 GMT</pubDate><media:content url="https://breakdev.org/content/images/2020/04/pwndrop-blog.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://breakdev.org/content/images/2020/04/pwndrop-blog.jpg" alt="Pwndrop - Self-hosting Your Red Team Payloads"><p>I have to admit, I took my sweet time to write this post and release this tool, but the time has finally come. I am finally ready to publish <strong>pwndrop</strong>, which has been in development for the last two years. Rewritten from scratch once (Angular.js was not a right choice) and stalled for multiple months due to busy times at work.</p><p>The timing for the release isn&apos;t ideal, but at least I hope using <strong>pwndrop</strong> can help you get through these tough weeks/months.</p><p><strong><em>Also stay at home, don&apos;t eat bats and do not burn any 5G antennas.</em></strong></p><p>If you want to jump straight in and grab the tool, follow this link to Github:</p><!--kg-card-begin: html--><center><a href="https://github.com/kgretzky/pwndrop"><span style="font-size: 36px; font-weight: bold;">pwndrop - Github</span></a></center><!--kg-card-end: html--><h2 id="what-is-pwndrop">What is pwndrop?</h2><p><strong>Pwndrop </strong>is a self-deployable file hosting service for red teamers, allowing to easily upload and share payloads over HTTP and WebDAV.</p><figure class="kg-card kg-image-card kg-width-full"><img src="https://breakdev.org/content/images/2020/04/gcGrmkWwBC.gif" class="kg-image" alt="Pwndrop - Self-hosting Your Red Team Payloads" loading="lazy"></figure><p>If you&apos;ve ever wasted a whole evening setting up a web server just to host a few files and get that <code>.htaccess</code> file redirection working, fear no more. Your future evenings are safe from being wasted again!</p><p>With <strong>pwndrop</strong> you can set up your own on-premise file server. The features are specifically tailored for red teamers, willing to host their payloads, but the tool can also be used as a normal file sharing service. All uploaded files are accessible via HTTP, HTTPS and WebDAV.</p><p>Before jumping into describing what features are present on release, I wanted to give away some information on the tool&apos;s development process.</p><h2 id="under-the-hood">Under the hood</h2><p>For a long time I wanted a self-hosted Dropbox, which would allow me to easily upload and share files with custom URL paths. There is of course Python&apos;s SimpleHTTPServer, which has a decent fanbase, but I badly wanted something that would have a web UI with drag &amp; drop interface and deployable with a single command. The idea was born. I knew I&apos;d make a backend in GO, but I had no experience in using any of the modern frontend libraries. It was 2018 back then and I decided it will be a good opportunity to learn something new.</p><p>First came in an idea of using Angular.js, since it is a very robust and well supported framework. In the end, it turned out to be too bloated for my needs and the amount of things I had to learn to just to make a simple UI (I&apos;m looking at you TypeScript) was staggering. I managed to get a proof of concept version working and then scratched the whole project to start anew, almost a year later.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://breakdev.org/content/images/2020/04/alpha1.gif" class="kg-image" alt="Pwndrop - Self-hosting Your Red Team Payloads" loading="lazy"><figcaption>You can see that I had absolutely no regrets killing off this monstrosity.</figcaption></figure><p>Then in 2019, a really smart and creative red teamer <a href="https://twitter.com/jaredhaight">Jared Haight @jaredhaight</a> released his C2 framework <a href="https://www.factionc2.com/">FactionC2</a> at TROOPERS19. I immediately fell in love with the web UI he did and after chatting a bit with him, I learned he used Vue.js. Vue seemed to be lightweight, relatively new and already pretty popular, which made it a perfect choice. Thanks Jared for inspiration!</p><p>I bought Vue.js course at Udemy and in few weeks I was ready to go. If you want to make a tool with a web interface, do check out Vue as it may fit your needs as well.</p><p>For my own and your convenience I got rid of all of the npm + webpack clutter to slim down the project as much as possible. When I found out that a small project like <strong>pwndrop</strong> requires 1000MB of preinstalled packages through <code>npm init</code>, the decision to put the project on a diet was made. I wanted to simplify working with the project as much as possible and cut out the unnecessary middleware. Even using webpack requires learning a ton on how to configure it and I definitely didn&apos;t want to spend any extra time on that. Now the project doesn&apos;t take more than 70MB of precious hard drive space.</p><p>All in all, I&apos;ve detached the frontend entirely from the build process, allowing the UI files to reside in their own folder, making them easily accessible for modifications and updates. The backend, on the other hand, is a single executable file, which installs itself and runs as a daemon in a background.</p><p>My main goal was to dumb down the installation process to the greatest extent and I&apos;m pretty proud of the outcome. The whole project has <u>ZERO</u> dependencies and can be installed as easily as copying the precompiled files to your server and entering a single command to install and launch the server.</p><p>Let&apos;s now jump into the most important part - the features!</p><h2 id="features">Features</h2><p>Here is the list of features, which you can use from the get-go in the release version.</p><h3 id="drag-drop-uploading-of-files">Drag &amp; drop uploading of files</h3><p>Easily drag &amp; drop your files onto <strong>pwndrop </strong>admin panel to upload them.</p><figure class="kg-card kg-image-card"><img src="https://breakdev.org/content/images/2020/04/HHhnCMEXt6.gif" class="kg-image" alt="Pwndrop - Self-hosting Your Red Team Payloads" loading="lazy"></figure><h3 id="works-on-mobile">Works on mobile</h3><p>Since the UI is made with Bootstrap, I made sure it is responsive and looks good on every device.</p><p>Fun way to use <strong>pwndrop </strong>on your phone is to take photos with phone camera through the admin panel and they will be automatically uploaded to your server.</p><h3 id="share-files-over-http-https-and-even-webdav">Share files over HTTP, HTTPS and even WebDAV</h3><p>Best part of <strong>pwndrop</strong> is that it is not just an ordinary web server. My main focus was to support serving files also over WebDAV, which is used for pulling 2nd stage payloads through variety of different methods.</p><p>You can even use it with your l33t <a href="https://twitter.com/0x09AL/status/1245302844099567617">&quot;UNC Path 0-days&quot;</a> ;)</p><p>In the future I plan to also add support for serving files over SMB. This will also allow to steal Net-NTLMv2 hashes from the machines making the request.</p><p>Click any of the &quot;copy link&quot; buttons to get a shareable link in your clipboard.</p><figure class="kg-card kg-image-card"><img src="https://breakdev.org/content/images/2020/04/chrome_RQmP3aPayg.png" class="kg-image" alt="Pwndrop - Self-hosting Your Red Team Payloads" loading="lazy"></figure><h3 id="enable-and-disable-your-file-downloads">Enable and disable your file downloads</h3><p>You can enable or disable file&apos;s ability to be downloaded, with a single click. Disabled files will return 404 or follow the pre-configured redirection when requested. </p><figure class="kg-card kg-image-card"><img src="https://breakdev.org/content/images/2020/04/chrome_kwMY3oxxfq.png" class="kg-image" alt="Pwndrop - Self-hosting Your Red Team Payloads" loading="lazy"></figure><h3 id="set-up-facade-files-to-return-a-different-file-from-the-same-url">Set up facade files to return a different file from the same URL</h3><p>Each uploaded file can be set up with a facade file, which will be served when a facade is enabled.</p><p>For example, you may want to share a link to a Word document with your custom macro payload, but you don&apos;t want your macro to be analyzed by online scanners as soon as you paste the link. To protect your payload, you can upload a facade clean document file under your payload file.</p><p>When facade mode is enabled all online scanners requesting the file, will receive your clean facade file. This can give you a brief window of evading detection. To have your link return the payload file, you need to manually disable facade mode.</p><figure class="kg-card kg-image-card"><img src="https://breakdev.org/content/images/2020/04/LoAcKac3rM.gif" class="kg-image" alt="Pwndrop - Self-hosting Your Red Team Payloads" loading="lazy"></figure><h3 id="create-custom-url-paths-without-creating-directories">Create custom URL paths without creating directories</h3><p>You can set whatever URL path you want for your payloads and <strong>pwndrop</strong> will always return a file when that URL is reached. There is no need to put files into physical directories.</p><p>By default, the tool will put every uploaded file under a randomly generated subdirectory. You can easily change it uploaded file&apos;s settings.</p><figure class="kg-card kg-image-card"><img src="https://breakdev.org/content/images/2020/04/bnlEF9qTJs.gif" class="kg-image" alt="Pwndrop - Self-hosting Your Red Team Payloads" loading="lazy"></figure><h3 id="url-redirects-to-spoof-file-extension">URL redirects to spoof file extension</h3><p>Let&apos;s say you want to have a shared link, pointing to <code>/download/Salary Charts 2020.docx</code>, but after the user clicks it it should download an HTA payload <code>Salary Charts 2020.docx.hta</code> instead.</p><p>Normally you&apos;d have to write some custom <code>.htaccess</code> files to use with Apache&apos;s <code>mod_rewrite</code> or fight with nginx configuration files.</p><p>With <strong>pwndrop </strong>you just need to specify the URL path, the file should automatically redirect to.</p><figure class="kg-card kg-image-card"><img src="https://breakdev.org/content/images/2020/04/ksKjtrawjZ.gif" class="kg-image" alt="Pwndrop - Self-hosting Your Red Team Payloads" loading="lazy"></figure><p>I will describe the whole setup process in the <strong>Quickstart</strong> section below.</p><h3 id="change-mime-types">Change MIME types</h3><p>In most web servers, web server decides what should be the MIME type of the downloaded file. This gives the web browser information what to do with a file once it is downloaded.</p><p>For example a file with <code>text/plain</code> MIME type will be treated as a simple text file and will be displayed in the browser window. The same text file with <code>application/octet-stream</code> MIME type will be treated as a binary file and the browser will save it to a file on disk.</p><figure class="kg-card kg-image-card"><img src="https://breakdev.org/content/images/2020/04/chrome_rUs2VFQMiw.png" class="kg-image" alt="Pwndrop - Self-hosting Your Red Team Payloads" loading="lazy"></figure><p>This allows for some interesting manipulation, especially with MIME type confusion exploits.</p><p>You can find the list of common MIME types <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Complete_list_of_MIME_types">here</a>.</p><figure class="kg-card kg-image-card"><img src="https://breakdev.org/content/images/2020/04/chrome_6KT5kryrnH.png" class="kg-image" alt="Pwndrop - Self-hosting Your Red Team Payloads" loading="lazy"></figure><h3 id="automatic-retrieval-of-tls-certificates-from-letsencrypt">Automatic retrieval of TLS certificates from LetsEncrypt</h3><p>Once you install <strong>pwndrop </strong>and point your domain&apos;s DNS A records to it, the first attempted HTTPS connection to <strong>pwndrop</strong> will initiate an automatic retrieval of a TLS certificate from LetsEncrypt.</p><p>Secure connections should work out of the box, but do check the readme on <a href="https://github.com/kgretzky/pwndrop">Github </a>to learn more about setting it up, especially if you want to use the tool locally or without a domain.</p><h3 id="password-protected-and-hidden-admin-panel">Password protected and hidden admin panel</h3><p>I wanted to make sure that the admin panel of <strong>pwndrop</strong> is never visible to people who are not meant to see it. Being able to control the web server fully, I was able to completely lock down access to it. If the viewer&apos;s web browser does not have the proper authorization cookie, <strong>pwndrop </strong>will either redirect to predefined URL or return a 404.</p><p>In order to authorize your browser, you need to open a secret URL path on your <strong>pwndrop</strong> domain. The default path is <code>/pwndrop</code> and should be changed in the settings as soon as the tool is deployed to your server.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://breakdev.org/content/images/2020/04/chrome_gSbl7p561N.png" class="kg-image" alt="Pwndrop - Self-hosting Your Red Team Payloads" loading="lazy"><figcaption>Remember to change Secret Path to something unique</figcaption></figure><p>If you want to relock access to the admin panel, just change the <em>Secret-Cookie</em> name or value and you will need to visit the <em>Secret-Path</em> again, in order to regain access.</p><h2 id="quickstart">Quickstart</h2><p>Now that I hope I&apos;ve managed to highlight all of the features. I wanted to give you a rundown of how to set up your first uploaded file with a facade and redirection.</p><p><strong>Goal: </strong>Host our <code>payload.exe</code> payload and disguise it as <code>https://www.evilserver.com/uploads/MyResume.pdf</code> shared link. The payload file will be delivered through redirection as <code>MyResume.pdf.exe</code>. The <code>MyResume.pdf</code> file will be set up as a facade file and it will be served as a legitimate PDF file if facade mode is enabled, in order to temporarily hide its true form from online scanners.</p><p>Here we go.</p><h3 id="0-deployment">0. Deployment</h3><p>If you don&apos;t yet have the server to deploy <strong>pwndrop </strong>to I highly recommend Digital Ocean. The cheapest $5/mo Debian 9 server with 25GB of storage space will work wonders for you. You can use my referral link to <a href="https://m.do.co/c/50338abc7ffe">get an extra $100 to spend on your servers in 60 days for free</a>.</p><p>I won&apos;t be covering the deployment process of <strong>pwndrop </strong>here on the blog as it may get outdated at some point. Instead check out the always up-to-date <a href="https://github.com/kgretzky/pwndrop">README with all the deployment instructions</a> on Github.</p><p>If you are in a hurry, though, you can install <strong>pwndrop </strong>on Linux with a single command:</p><pre><code class="language-bash">curl https://raw.githubusercontent.com/kgretzky/pwndrop/master/install_linux.sh | sudo bash</code></pre><h3 id="1-upload-your-payload-executable-file">1. Upload your payload executable file</h3><p>Make sure you authorize your browser first, by opening: <code>https://&lt;yourdomain.com&gt;/pwndrop</code> </p><p>Then open <code>https://&lt;yourdomain.com&gt;</code> and follow the instructions on the screen to create your admin account.</p><p><strong>IMPORTANT! Do not forget to change the <em>Secret-Path </em>from </strong><code>/pwndrop</code><strong> to something of your choice in the settings.</strong></p><p>Use the <em>Upload </em>button or drag &amp; drop <code>payload.exe</code> onto <strong>pwndrop </strong>to upload your payload file.</p><figure class="kg-card kg-image-card"><img src="https://breakdev.org/content/images/2020/04/chrome_q42HorY1cB.png" class="kg-image" alt="Pwndrop - Self-hosting Your Red Team Payloads" loading="lazy"></figure><h3 id="2-upload-your-pdf-facade-file">2. Upload your PDF facade file</h3><p>Click the top-left cog icon on your newly uploaded file and the settings dialog will pop out.</p><p>Click the facade file upload area or directly drop <code>MyResume.pdf</code> file onto it.</p><figure class="kg-card kg-image-card"><img src="https://breakdev.org/content/images/2020/04/chrome_sdT3Ngd5Gm.png" class="kg-image" alt="Pwndrop - Self-hosting Your Red Team Payloads" loading="lazy"></figure><h3 id="3-set-up-redirection">3. Set up redirection</h3><p>Now you need to change the <em>Path </em>to what it should look like in your shared link. We want it to point to <code>MyResume.pdf</code> so change it to, say: <code>/uploads/MyResume.pdf</code> (you can choose whatever path you want).</p><p>Then click the <em>Copy </em>button at the right side of <em>Redirect Path </em>editbox and it will copy the contents of <em>Path </em>editbox to the editbox below<em>.</em></p><p>Just add <code>.exe</code> to the copied path making it <code>/uploads/MyResume.pdf.exe</code>. This will be the path <strong>pwndrop</strong> redirects to, to serve the payload executable after the user clicks the shared link.</p><p>Keep in mind that the redirection will only happen when facade mode is disabled. When facade mode is enabled, <strong>pwndrop </strong>will serve the facade PDF file instead, not triggering any red flags.</p><p>We will also change the MIME type of the facade file, which will show you the power of this feature. While <code>application/x-msdownload</code> MIME type for PDF facade file is valid, the Chrome browser will initiate a download when the shared link is clicked. When you change the MIME type to <code>application/pdf</code> , though, Chrome will open the preview of the PDF file as it will know it is dealing with a PDF file.</p><p>Depending on what effect you want to achieve, either having the user download the PDF or have it previewed in the web browser, you can play with different options.</p><figure class="kg-card kg-image-card"><img src="https://breakdev.org/content/images/2020/04/chrome_lAhDcrA9Gn.png" class="kg-image" alt="Pwndrop - Self-hosting Your Red Team Payloads" loading="lazy"></figure><p>Don&apos;t forget to click <em>Save </em>once you&apos;re finished with setting up the file.</p><h3 id="4-sharing-your-file">4. Sharing your file</h3><p>Now you&apos;re done. You can get the <strong>HTTP shared link</strong>, by clicking the <em>HTTP </em>button. <code>http://</code> or <code>https://</code> prefix will be picked based on how you&apos;re currently browsing the admin panel. Similarly, if you click the <em>WebDAV </em>button, you will get the WebDAV link copied to your clipboard.</p><figure class="kg-card kg-image-card"><img src="https://breakdev.org/content/images/2020/04/chrome_LW0jostNVs.png" class="kg-image" alt="Pwndrop - Self-hosting Your Red Team Payloads" loading="lazy"></figure><p>If you ever decide, you want to <strong>temporarily disable sharing</strong> for this file, just click the power button and it will effectively make the file hidden and links to it will stop working.</p><figure class="kg-card kg-image-card"><img src="https://breakdev.org/content/images/2020/04/chrome_FoOaQprx8O.png" class="kg-image" alt="Pwndrop - Self-hosting Your Red Team Payloads" loading="lazy"></figure><p>Next important thing is <strong>enabling the facade</strong>. Just click the third button from the left to flip the on/off switch to enable/disable facade mode. When the facade mode is enabled, <strong>pwndrop </strong>will serve the facade file, which you&apos;ve uploaded for the given payload, instead of the original payload file. In our example it will deliver the PDF file instead of the payload executable.</p><figure class="kg-card kg-image-card"><img src="https://breakdev.org/content/images/2020/04/chrome_96s99XXN9j.png" class="kg-image" alt="Pwndrop - Self-hosting Your Red Team Payloads" loading="lazy"></figure><p>Aaand that&apos;s it. Enjoy your first shared payload! Hope I&apos;ve managed to not make the process too complex and that it was pretty easy to follow.</p><h2 id="future-development">Future Development</h2><p>I have a lot of ideas I want implemented into <strong>pwndrop</strong>, but instead of never releasing the tool and keep adding features, because &quot;it is always not yet perfect&quot;, I&apos;ve decided to release the tool as it is now. I will iteratively expand on it by adding new features from time to time.</p><p>So before you send me your feedback, check out what I plan to implement in near and far future. I really want to hear what features you&apos;d like to see and how you&apos;d want to use the tool.</p><h3 id="download-counter">Download Counter</h3><p>This one should be implemented quite fast. It would add a download counter for each file, specifying the number of times the file is allowed to be downloaded. When the limit is reached, <strong>pwndrop </strong>will either serve a facade file or return file not found.</p><h3 id="download-tracker">Download Tracker</h3><p>This feature is a much needed one, but requires a bit of work. I want to add a separate view panel, which will display in real-time all download requests for every payload file. The log should contain the visitor&apos;s User-Agent, IP address and some additional metadata that can be gathered from the particular request.</p><h3 id="file-dropping-with-javascript">File dropping with Javascript</h3><p>There is a method to initiate a file download directly through Javascript executed on an HTML page. It is an effective method for bypassing request scanners of several EDRs.</p><p>The idea is that the whole payload file gets embedded into an HTML page as an encrypted blob, which is then decrypted in real-time and served as a download to the web browser. That way there is never a direct request made to a file resource with specific URL, meaning there is nothing to download and scan. EDRs would have to implement Javascript emulation engines in order to execute a dropper script in a sandbox and analyze the decrypted payload.</p><h3 id="conditional-facades">Conditional facades</h3><p>At the moment, facade mode can only be enabled/disabled manually, but eventually I&apos;d like this process to be somewhat automated. <strong>Pwndrop </strong>could check if the request is made with specific cookie, User-Agent or from targeted IP range and then decide whether to serve a payload file or a facade file instead.</p><h3 id="password-protected-downloads">Password protected downloads</h3><p>Sometimes it is good to share a file, which downloads only after entering a valid password. This is the feature I&apos;d also like to have in <strong>pwndrop</strong>. I&apos;m not yet sure if it should be done with basic HTTP authentication or something custom. Let me know if you have any ideas.</p><h2 id="the-end-for-now-">The End (for now!)</h2><p>This is only the end of this post, but definitely not the end of <strong>pwndrop</strong>&apos;s development. I&apos;d really like to see how you, the red teamers, plan to use this tool and how it can aid you in managing your payloads.</p><p>I also hope that you can use this tool not only for work. I hope it helps you share any files you want with the people you want, without having to worry about privacy and/or security issues. Self-hosting is always the best way to go.</p><p>Expect future updates on this blog and if you have any feedback you want to share, do contact and follow me on Twitter <a href="https://twitter.com/mrgretzky">@mrgretzky</a>.</p><p>Get the latest version of <strong>pwndrop </strong>here:</p><!--kg-card-begin: html--><div style="height: 64px;"><center><a href="https://github.com/kgretzky/pwndrop"><span style="font-size: 36px; font-weight: bold; margin-bottom: 16px;">pwndrop - Github</span></a></center></div><!--kg-card-end: html--><p>Enjoy and I&apos;m waiting for your feedback!</p>]]></content:encoded></item><item><title><![CDATA[Evilginx 2.3 - Phisherman's Dream]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p><strong>Welcome to 2019!</strong></p>
<p>As was <a href="https://twitter.com/antisnatchor/status/1081891995533148160">noted</a>, this will be the year of phishing automation. We&apos;ve already seen a release of new reverse-proxy tool <a href="https://github.com/drk1wi/Modlishka">Modlishka</a> and it is only January.</p>
<p>This release would not have happened without the inspiration I received from Michele Orru (<a href="https://twitter.com/antisnatchor">@antisnatchor</a>), Giuseppe Trotta (<a href="https://twitter.com/Giutro">@Giutro</a>) and</p>]]></description><link>https://breakdev.org/evilginx-2-3-phishermans-dream/</link><guid isPermaLink="false">62eba9295e4f4b09d79d0efe</guid><category><![CDATA[evilginx]]></category><category><![CDATA[2fa]]></category><category><![CDATA[security]]></category><category><![CDATA[phishing]]></category><category><![CDATA[mitm]]></category><category><![CDATA[tool]]></category><category><![CDATA[hacking]]></category><category><![CDATA[update]]></category><dc:creator><![CDATA[Kuba Gretzky]]></dc:creator><pubDate>Fri, 18 Jan 2019 05:44:00 GMT</pubDate><media:content url="https://breakdev.org/content/images/2019/01/evilginx_blog_title_phisherman.jpg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://breakdev.org/content/images/2019/01/evilginx_blog_title_phisherman.jpg" alt="Evilginx 2.3 - Phisherman&apos;s Dream"><p><strong>Welcome to 2019!</strong></p>
<p>As was <a href="https://twitter.com/antisnatchor/status/1081891995533148160">noted</a>, this will be the year of phishing automation. We&apos;ve already seen a release of new reverse-proxy tool <a href="https://github.com/drk1wi/Modlishka">Modlishka</a> and it is only January.</p>
<p>This release would not have happened without the inspiration I received from Michele Orru (<a href="https://twitter.com/antisnatchor">@antisnatchor</a>), Giuseppe Trotta (<a href="https://twitter.com/Giutro">@Giutro</a>) and Piotr Duszy&#x144;ski (<a href="https://twitter.com/drk1wi">@drk1wi</a>). <strong>Thank you!</strong></p>
<p>This is by far the most significant update since the release of Evilginx. The 2.3 update makes it unnecessary to manually create your own <code>sub_filters</code>. I talked to many professional red teamers (hello <a href="https://twitter.com/_RastaMouse">@_RastaMouse</a>) who have struggled with creating their own phishlets, because of the unfair, steep learning curve of figuring out what strings to replace and where, in the proxied HTTP content. I can proudly say that these days are over and it should now be much easier to create phishlets from scratch.</p>
<p>If you arrived here by accident and you have no idea what I&apos;m talking about, check out the <a href="https://breakdev.org/evilginx-2-next-generation-of-phishing-2fa-tokens/">first post on Evilginx</a>. It is a phishing framework acting as a reverse proxy, allowing to bypass 2FA authentication.</p>
<p>Let&apos;s jump straight into the changes.</p>
<h4 id="changelogversion23">Changelog - version 2.3</h4>
<p>Here is a full list of changes in this version:</p>
<ul>
<li>Proxy can now create most of required <code>sub_filters</code> on its own, making it much easier to create new phishlets.</li>
<li>Added <strong>lures</strong>, with which you can prepare custom phishing URLs, each having its own set of unique options (<code>help lures</code> for more info).</li>
<li>Added OpenGraph settings for lures, allowing to create enticing content for link previews.</li>
<li>Added ability to inject custom Javascript into proxied pages.</li>
<li>Injected Javascript can be customized with attacker-defined data, specified in <strong>lure</strong> options.</li>
<li>Deprecated <code>landing_path</code> and replaced it with a <code>login</code> section, which contains the domain and path for website&apos;s login page.</li>
</ul>
<p>Diving into more detail now.</p>
<blockquote>
<p><strong>Automatic handling of <code>sub_filters</code></strong></p>
</blockquote>
<p>In order for Evilginx to properly proxy a website, it must not stray off its path and it should make sure that all proxied links and redirections are converted from original URLs to the phishing URLs. If the browser navigates to the original URL, the user will no longer be proxied through Evilginx and the phishing will simply fail.</p>
<p>I am aware it was super hard to manually figure out what strings to replace and it took considerable amounts of time to analyze HTML content of every page to manage substitutions, using trial and error method.</p>
<p>Initially I thought that doing the automatic URL substitution, in page body, will just not work well. The guys I mentioned at the top of this post, proved me wrong and I was amazed how well it can work when properly executed. When I saw this method successfully implemented and demonstrated in <a href="https://github.com/drk1wi/Modlishka">Modlishka</a>, I was blown away. I knew I had to try and do the same for Evilginx.</p>
<p>It took me a whole weekend to implement the required changes and I&apos;m very happy with the outcome. You can now start creating your phishlet without any <code>sub_filters</code> at all. Just define the <code>proxy_hosts</code> for the domains and subdomains that you want to proxy through and it should work out-of-the-box. You may need to create your own <code>sub_filters</code> only if there is some unusual substitution required to bypass security checks or you just want to modify some HTML to make the phishing scenario look better.</p>
<p>Best thing with automated <code>sub_filters</code> generation is the fact that the whole website&apos;s functionality may fully work, through the proxy, even after the user is authenticated (e.g. Gmail&apos;s inbox).</p>
<blockquote>
<p><strong>Phishing with lures</strong></p>
</blockquote>
<p>The tokenized phishing link with redirection URL, encoded in base64 format, was pretty ugly and definitely not perfect for carefully planned phishing attacks. As an improvement, I thought of creating custom URLs with attacker-defined path. Each assigned with a different redirection URL, which would be navigated to on successful authentication through the phishing proxy. This idea eventually surfaced in form of <strong>lures</strong>.</p>
<p><img src="https://breakdev.org/content/images/2019/01/Console_aglKFTi8wX.png" alt="Evilginx 2.3 - Phisherman&apos;s Dream" loading="lazy"></p>
<p>You can now create as many lures as you want for specific phishlets and you are able to give each of them following options:</p>
<ul>
<li><strong>Custom path</strong> to make your phishing URLs look more inviting to be clicked.</li>
<li><strong>Redirection URL</strong> to navigate the user to, after they successfully authenticate.</li>
<li><strong>OpenGraph</strong> features, which will inject <code>&lt;og:...&gt;</code> meta tags into proxied website to make the phishing links generate enticing previews when sent in messengers or posted to social media.</li>
<li><strong>Customized script content</strong>, which will be embedded into your injected Javascript code (e.g. for pre-filling the user&apos;s email address).</li>
<li><strong>Description</strong> for your own eyes to not forget what the lure was for.</li>
</ul>
<p>Here is how OpenGraph <strong>lure</strong> configuration can be used to generate an enticing preview for WhatsApp:</p>
<p><img src="https://breakdev.org/content/images/2019/01/fC6ePnbG7m.png" alt="Evilginx 2.3 - Phisherman&apos;s Dream" loading="lazy"></p>
<p>On clicking the link, the user will be taken to the attacker-controlled proxied Google login page and on successful authentication, he can be redirected to any document hosted on Google Drive.</p>
<p>The command for generating tokenized phishing links through <code>phishlets get-url</code> still works, although I&apos;d consider it obsolete now. You should now generate phishing URLs with pre-created <strong>lures</strong> instead: <code>lures get-url 0</code></p>
<p>To get more information on how to use <strong>lures</strong>, type in <code>help lures</code> and you will get a list of all sub-commands you can use.</p>
<blockquote>
<p><strong>Javascript injection</strong></p>
</blockquote>
<p>Now you can inject any javascript code into the proxied HTML content, based on URL path or domain. This gives incredible capabilities for customizing your phishing attack. You could for example make the website pre-fill the email of your target in the authentication form and display their profile photo.</p>
<p>Here is the example of injected javascript that pre-fills the target&apos;s email on LinkedIn login page:</p>
<pre><code class="language-language-yaml">js_inject:
  - trigger_domains: [&quot;www.linkedin.com&quot;]
    trigger_paths: [&quot;/uas/login&quot;]
    trigger_params: [&quot;email&quot;]
    script: |
      function lp(){
        var email = document.querySelector(&quot;#username&quot;);
        var password = document.querySelector(&quot;#password&quot;);
        if (email != null &amp;&amp; password != null) {
          email.value = &quot;{email}&quot;;
          password.focus();
          return;
        }
        setTimeout(function(){lp();}, 100);
      }
      setTimeout(function(){lp();}, 100);
</code></pre>
<p>You can notice that the email value is set to <code>{email}</code>, which lets Evilginx know that this will be replaced with the value set in the created <strong>lure</strong>. Setting the <code>email</code> value would be done the following way.</p>
<pre><code class="language-language-bash">: lures edit params 0 email=target@domain.com
</code></pre>
<p>See that the <code>trigger_params</code> variable contains the <code>email</code> value, which means that this javascript will <strong>ONLY</strong> be injected if the <code>email</code> parameter is configured in the <strong>lure</strong> used in the phishing attack.</p>
<p>Here is a demo of what a creative attacker could do with Javascript injection on Google, pre-filling his target&apos;s details for him:</p>
<p><img src="https://breakdev.org/content/images/2019/01/Y1RPTFeggy.gif" alt="Evilginx 2.3 - Phisherman&apos;s Dream" loading="lazy"></p>
<blockquote>
<p><strong>Removal of <code>landing_url</code> section</strong></p>
</blockquote>
<p>To upgrade your phishlets to version 2.3, you have to remove <code>landing_url</code> section and replace it with a <code>login</code> section.</p>
<p>I figured you may want to use a different domain for your phishing URL than the one, which is used to display the login page. For example Google&apos;s login page is always at domain <code>accounts.google.com</code>, but you may want the phishing link to point to a different sub-domain like <code>docs.phished-google.com</code>. That way you can add <code>docs.google.com</code> to <code>proxy_hosts</code> and set the option to <code>is_landing: true</code>.</p>
<p>The <code>login</code> section should contain:</p>
<pre><code>login:
  domain: &apos;accounts.google.com&apos;
  path: &apos;/signin/v2/identifier&apos;
</code></pre>
<p><strong>IMPORTANT!</strong> The <code>login</code> section always defines where the login page resides on the targeted website.</p>
<p>That way the user will be automatically redirected to the login page domain even when the phishing link originated on a different domain.</p>
<p>Refer to the official <a href="https://github.com/kgretzky/evilginx2/wiki/Phishlet-File-Format-(2.3.0)">phishlets 2.3.0 documentation</a> for more information.</p>
<h4 id="havefun">Have fun!</h4>
<p>I can proudly say that now the phishlet format is close to being perfect and, since the difficulty of creating one from scratch significantly dropped, I will be starting a series of blog posts teaching how to create a phishlet from scratch, including how to configure everything.</p>
<p>The series will start very soon and posts will be written in hands-on step by step format, showing the whole process of phishlet creation from start to finish, for the website that I pick.</p>
<p>Make sure to <a href="https://twitter.com/mrgretzky">follow me</a> on Twitter if you want up-to-date information on Evilginx development.</p>
<center><h6>[Follow me on Twitter](https://twitter.com/mrgretzky)</h6></center>
<center><h6>[Download Evilginx 2 from GitHub](https://github.com/kgretzky/evilginx2)</h6></center>
<!--kg-card-end: markdown-->]]></content:encoded></item></channel></rss>