PowerShell Phishing Response Toolkit (PPRT)

Yesterday I gave a talk at ShowMeCon in St. Louis regarding PPRT. ¬†I also gave this talk at CircleCityCon, but had some technical issues.ūüôā ¬†I wanted to write this quick post to share out my PowerPoint Slides from this presentation. ¬†If you have any questions about PPRT, please reach out via this blog or create an issue on my GitHub page:¬†https://github.com/MSAdministrator/PPRT—PowerShell-Phishing-Response-Toolkit

Enjoy!

Slides: PowerShell Phishing Response Toolkit

PowerShell & Qualys: Get Asset Group Info – Part 2

Today I decided to write another post regarding PowerShell and Qualys Vulnerability Management API.  This post will focus on gathering information about your enrolled Asset Groups.   You can find the complete script on GitHub: https://github.com/MSAdministrator/POSH-Guard/blob/master/Get-QualysAssetGroupInformation

We start of by opening up PowerShell ISE and using our handy “Snippet” shortcut:

PowerShell_ISE_CTRL_+_J

We select the “Cmdlet (Advanced function) – complete” option in the “Snippet” context menu.¬† Once we have our advanced function template, we then proceed by entering a name for our Qualys Asset Group function.

Since we will be gathering some additional information about our Asset Groups, I am going to name my function:


function Get-QualysAssetGroupInformation

Next, we will start by filling out our “Help” info.¬† At this point, a lot of people skip this step; I HIGHLY recommend that you do not.¬† It will help you and anyone else viewing your code, understand what your intention was when writing this function.

Next, we start by looking at our advanced functions template within the body of this function.¬† The first thing you will see is some default parameters for [CmdletBinding].¬† With my function, I’m going to weed these parameters down a bit, as they are not really needed.¬† Your function should look something like this when complete:

function Get-QualysAssetGroupInformation
{
    [CmdletBinding(SupportsShouldProcess=$true, 
                  HelpUri = 'https://raw.githubusercontent.com/MSAdministrator/POSH-Guard/master/Get-QualysAssetGroupInformation',
                  ConfirmImpact='Medium')]
    [Alias()]
    Param
    (
        # Param1 help description
        [parameter(Mandatory=$true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true,
                   HelpMessage="Please provide a credential obejct")]
                   [ValidateNotNullOrEmpty()]
                   [System.Management.Automation.CredentialAttribute()]$credential
        ) 

    Begin
    {
    }
    Process
    {
        
    }
    End
    {
    }
}

After we have the base of this function setup and ready to go, we will start off by adding some code into our Begin block.  Remember, the Begin block will always run once for every call to the function.

	$results = @()
	$assetGroupInfo = @()
        [xml]$assetGroupInfo = Invoke-RestMethod -Uri "https://qualysapi.qualys.com/msp/asset_group_list.php" -Credential $credential

Here I am setting my $assetGroupInfo and a $results variable as empty array’s/hash-table’s. Next, I’m casting my $assetGroupInfo variable as an XML object. This ensures that we receive XML from Invoke-RestMethod Cmdlet.

If we want to make sure that any errors are caught, we should add a Try/Catch block to our Invoke-RestMethod call. Your code should look like this:

 Begin
    {
        $results = @()
        $assetGroupInfo = @()

        Try
        {
            [xml]$assetGroupInfo = Invoke-RestMethod -Uri "https://qualysapi.qualys.com/msp/asset_group_list.php" -Credential $credential
        }
        Catch
        {
            Write-Debug "Error using Invoke-RestMethod: $_"
        }
    }

Now we move to the Process block. This is where we will be parsing our data into our objects. As I mentioned above, we are wanting to gather all our Asset Groups Titles, their assigned IP Addresses, their role, and the users login ID. To do this, we must loop through each item, or branch returned by our query above. Each $item can be considered as an Asset Group. Additionally, we need to loop through each of the users assigned to that Asset Group.

Once we have that data, we want to create a Custom PSObject to hold all of this data. Your code should look like this:

Process
{
	foreach ($item in $assetGroupInfo.SelectNodes("/ASSET_GROUP_LIST/ASSET_GROUP"))
	{
		for ($u=0; $u -lt $($item.ASSIGNED_USERS.ASSIGNED_USER.LOGIN).count;$u++)
		{
			$tempAssetGroupInfo = @()
		                            
                                $props = @{
				userlogin=$($item.ASSIGNED_USERS.ASSIGNED_USER[$u].LOGIN.InnerText)
				userrole=$($item.ASSIGNED_USERS.ASSIGNED_USER[$u].ROLE.InnerText)
                                           assetgrouptitle=$($item.TITLE.InnerText)
                                           ip=$($item.SCANIPS.IP)
                                          }
		
			$tempAssetGroupInfo = New-Object PSObject -Property $props
		        
                                $results += $tempAssetGroupInfo
		}
	}
}

Now, we can either simply put the following line in our End block:

return $results

But, I actually like it to be saved into an XML file. This means that I can use this data with other functions without having to call Qualys again. To be quite frank, as you may know, Qualys is not the fastest website/service out there. Don’t get me wrong, the scanning engines are fast, but their database(s) – not so much.

To return both the object and export the results to an XML, we can just add this one line of code:

Export-Clixml -Path "$env:USERPROFILE\Desktop\QualysData\assetgroupinfo.xml" -InputObject $results

That’s it. We now have a function that can return some details about our Asset Groups within Qualys. Next time, I will focus on creating a function that gathers our enrolled IP Addresses, split’s them into a single list.

Hint: Qualys loves IP ranges (192.168.0.1-192.168.0.123) and their API calls return it the same way.ūüôā

PowerShell & Qualys: Authentication – Part 1

I always mean to post more on my blog, but as life gets in the way and work keeps me busy, I always seem to push it to the back-burner. This time, I am hoping to make it stick as a regular routine.

To kick off my new-found motivation to blog more, I am starting a series of posts surrounding PowerShell and Qualys Vulnerability Management API.

To start this off, first I’m going to share some my basic steps with regards to authentication to Qualys VM API v1. This is really basic, but I see a lot of posts around that seem to try to create some “advanced” way of authenticating to Qualys API. You don’t need to do anything fancy.

As with all scripts/modules/etc., I suggest that you get into the habit of using PowerShell ISE and it’s many great keyboard shortcuts to help you get on the right path.

First, open PowerShell ISE and enter the following keyboard shortcut:


CRT + J

Once the “Show Snippets” context menu shows up, select “Advanced Function (Complete)”. I always recommend that you start with a ‘Complete’ Advanced FUnction. This makes your script look much better, and it’s all around a good idea.

Once you have the Snippet loaded, I would begin by coming up with a name; following Microsoft’s approved Verb-Noun naming convention:

Approved Verbs – https://technet.microsoft.com/en-us/library/ms714428(v=vs.85).aspx
Get-Verb Documentation: https://technet.microsoft.com/en-us/library/hh852690.aspx

Next, start adding a “Credential” object parameter to your code. Qualys uses “Basic” authentication, so using Invoke-RestMethod in combination with a “Credential” object is extremely easy.

To capture your credentials into a Credential Object used by Invoke-RestMethod, you simply need the following before you run your function or within your function:


$cred = Get-Credential

Enter your Qualys API username and password.

*NOTE: Do not try to save this credential object to disk or to a file. It’s NOT hard to enter your username and password every time you connect to Qualys API.

Next, you should have the following code in your function:


[xml]$hostinfo = Invoke-RestMethod -Uri "https://qualysapi.qualys.com/msp/get_host_info.php?host_netbios=$netbios&general_info=1"-Credential $credential

I recommend that your $credential object should be passed into your function as a parameter. This will help when you move into more advanced interaction and multiple calls to Qualys VM API.

Now that you have your XML (Type cast) $hostinfo variable, you can then parse the data very, very, very easily.

In my next post I will share with you how to do this to gather some very important data for any Qualys Vulnerability Management Administrator.

If you have any questions, then please leave a comment.


function Test-QualysAuthentication ()
{

[cmdletbinding()]
param (
[parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
HelpMessage="Please provide a credential obejct")]
[ValidateNotNullOrEmpty()]
[System.Management.Automation.CredentialAttribute()]$credential
)

<# .SYNOPSIS This function tests your Qualys VM API Credentials .PARAMETER Credential Specifices a set of credentials used to query the QualysGuard API .EXAMPLE C:\PS> $cred = Get-Credential
C:\PS> Test-QualysAuthentication -credential $cred

#>

[xml]$hostinfo = Invoke-RestMethod -Uri "https://qualysapi.qualys.com/msp/get_host_info.php?host_netbios=$netbios&general_info=1" -Credential $credential

return $hostinfo
}

PhishReporter: PowerShell Module

If you work in the Info Sec world you know that phishing is a pain in the neck, especially when you’ve been targeted by a large phishing campaign. ¬†I’ve been through these massive phishing attacks, and it is not fun!

One such attack, about a year ago, was especially difficult because the attackers were using very unique tactics and spoofing lots of internal e-mail communications.

Our procedure was to go and find the company that was hosting these phishing URLs and e-mail them to tell them to shut the site down immediately.  Hosting companies like weebly.com, jimdo.com, webs.com, etc. were pretty good at shutting these sites down as soon as they were put online, but this process would take about 5 to 10 minutes and sucked!

Since this last attack, I decided to automate this process.  This new script/tool is a PowerShell Module called PhishReporter.

The PowerShell module can be downloaded on GitHub: https://github.com/MSAdministrator/PhishReporter

This PowerShell Module is designed to send notifications to hosting companies that host phishing URLs by utilizing the major WHOIS/RDAP Abuse Point of Contact (POC) information.

  1. This function takes in a .msg file and strips links from a phishing URL.
  2. After getting the phishig email, it is then converted to it’s IP Address.
  3. Once the IP Address of the hosting website is identified, then we check which WHOIS/RDAP to search.
  4. Each major WHOIS/RDAP is represented: ARIN, APNIC, AFRNIC, LACNIC, & RIPE.
  5. We call the specific WHOIS/RDAP’s API to determine the Abuse POC.
  6. Once we have the POC, we send them an email telling them to shut the website down. This email contains the original email as an attachment, the original phishing link, and e-mail body telling them to remove the website.

This Module came out of necessity. I was sick of trying to contact these individual sites, so I have began automating our response time to these events.

The next steps for this project are to fully integrate into Outlook and automate this even further by enabling a simple text search or based on a selected ‘folder’ event. Please share with the Security community and contribute/improve as you deem fit. I only ask that you share your edits back with this project.

Presentation: Securing Windows with Group Policy

Recently I gave a presentation at MORENet’s 2015 Annual Conference about “Securing Windows with Group Policy”. ¬†This presentation was part of their “Advanced” technology track, and really focused on looking at the current permission levels of your users and deciding if they really need those rights/permissions.

I hope some people find these slides useful or at least a good reference point.  If you have any questions about these slides then please do not hesitate to contact me by leaving a comment below.

Slides can be downloaded here: Securing Windows with Group Policy

NOTE: MORENet’s conference is focused on technology and educational initiatives affecting¬†K-12 & Higher Education within the State of Missouri.