Internet Forensics

PowerShell offers an intriguing option for getting Web content to a PowerShell session. By using a combination of the .NET Web client object and PowerShell's native support for XML, it is a snap to pull data from a Web site and display it in a PowerShell console. As an example, the following script queries Microsoft's basic RSS feed for security bulletins and displays bulletin information in a color coded console:

GetSecurityRSS.ps1

#GetSecurityRSS.ps1 #Query Microsoft's Basic Security Feed for latest bulletins #Critical bulletins will be displayed in Red #Important bulletins will be display in Yellow #Everything else will be displayed in Green [void] [System.Reflection.Assembly]::LoadWithPartialName("System.Web") $webclient = new-object System.Net.WebClient $url="http://www.microsoft.com/technet/security/bulletin/secrss.aspx" ## Get the web page into a single string $data =[xml]$webclient.downloadstring($url) if ($data -ne $Null) { Write-Host -backgroundcolor Yellow -foregroundcolor blue ` $data.rss.channel.Title Write-Host "Last Updated" $data.rss.channel.LastBuildDate `n $i=0 do { write-Host -foregroundcolor White ` $data.rss.channel.item[$i].Title #color code description based on severity if ($data.rss.channel.item[$i].Description ` -Like "*Rating:Critical*") { $color="Red" } elseif ($data.rss.channel.item[$i].Description ` -Like "*Rating:Important*"){ $color="Yellow" } else { $color="Green" } Write-Host -foregroundcolor $color ` $data.rss.channel.item[$i].Description `n $i++ } until ($i -gt ($data.rss.channel.item).count) } else { Write-Host -foregroundcolor Red "Could not get " $url }

The script requires the System.Web .NET assembly that is loaded at the beginning of the script. With this assembly we can create a webclient object and use it to connect to a URL. We use the DownloadString method to return the URL contents and save them to a variable. Because the URL is an RSS feed, the file structure is XML so we specifically cast $data to be an XML object.

Assuming there no errors occurred when retrieving the data, now it's only a matter of exploiting PowerShell's ability to pull apart the XML file and display the information we needn. All you need to know is the structure of the XML file and then you can navigate to the exact node. Here's an excerpt of the RSS XML file:

<rss version="2.0"> - <channel> <copyright>Copyright Microsoft Corporation 2005</copyright> <description>Microsoft Security Bulletins</description> - <link> http://www.microsoft.com/technet/security/current.aspx </link> <title>Microsoft Security Bulletins</title> <language>en-us</language> - <image> - <link> http://www.microsoft.com/technet/security/current.aspx </link> <title>Microsoft Security Bulletins</title> - <url> http://www.microsoft.com/library/toolbar/3.0/images/banners/ TechNetB_masthead_ltr.gif </url> <height>42</height> <width>225</width> </image> <lastBuildDate>Thu, 22 Jun 2006 02:43:20 GMT</lastBuildDate> - <item> - <title> MS06-032: Vulnerability in TCP/IP Could Allow Remote Code Execution (917953) </title> - <link> http://www.microsoft.com/technet/security/bulletin/ms06 -032.mspx?pubDate=2006-06-13 </link> - <guid isPermaLink="false"> http://www.microsoft.com/technet/security/bulletin/ms06-032.mspx </guid> <pubDate>Tue, 13 Jun 2006 08:00:00 GMT</pubDate> </item>

From this we can tell the XML hierarchy is an rss/channel/item and that within each item there are nodes for information such as title and description. When we use the $data object that holds the feed contents to get the description of the first item in the RSS feed, all we need to do in PowerShell is:

Write-host $Data.rss.channel.items[0].Description

The Do Until loop is the last item in the script we want to point out. Since we don't know how many items are actually in the XML file, we use a Do loop to get information about each item using a counter variable that starts at 0 (remember collections start at 0) and loops until the counter equals the number of nodes:

until ($i -gt ($data.rss.channel.item).count)

Another use for .NET web objects is to check if a company Web server is up:

CheckWebServer.ps1

#CheckWebServer.ps1 #if any errors occur continue so that our error #handling at the end of the script will run Trap { continue } $url="http://www.SAPIENPress.com" #create the web request .NET object $Request=[System.Net.WebRequest]::Create($url) #create the response object $response=$Request.GetResponse() #display properties of the http response ojbect $response #display a color coded status message if ($Response.StatusCode -eq "OK") { Write-Host -foregroundcolor Green $url "is OK" } Else } Write-Host -foregroundcolor Red $url "is NOT OK" {

This script is a little different in that it uses the System.Net.WebRequest object. Unlike the previous script, we're not interested in the contents of any particular file, just the response we get from the Web server. We use the Create method to create the request. Calling the GetResponse method will return an http Web response object:

$response=$Request.GetResponse()

This object will have a property set like this:

IsMutuallyAuthenticated : False Cookies : {} Headers : {Transfer-Encoding, Cache-Control, Content- ...} ContentLength : -1 ContentEncoding : ContentType : text/html CharacterSet : ISO-8859-1 Server : GWS/2.1 LastModified : 7/7/2006 5:47:07 PM StatusCode : OK StatusDescription : OK ProtocolVersion : 1.1 ResponseUri : http://www.google.com/ Method : GET IsFromCache : False

However, we're only interested in the Status code. If the Status code is OK, we'll display a message in green; otherwise we'll display a message in red.

There are other ways you can leverage the Web from a PowerShell console session. We've seen online examples that get current weather information or query Encarta. As you work more with PowerShell and learn more about all the different .NET classes, we're sure you'll come up with even more creative ways to Web-ify PowerShell.

Категории